Merge branch 'next' into for-linus
[linux-2.6-microblaze.git] / arch / loongarch / include / asm / inst.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4  */
5 #ifndef _ASM_INST_H
6 #define _ASM_INST_H
7
8 #include <linux/bitops.h>
9 #include <linux/types.h>
10 #include <asm/asm.h>
11 #include <asm/ptrace.h>
12
13 #define INSN_NOP                0x03400000
14 #define INSN_BREAK              0x002a0000
15
16 #define ADDR_IMMMASK_LU52ID     0xFFF0000000000000
17 #define ADDR_IMMMASK_LU32ID     0x000FFFFF00000000
18 #define ADDR_IMMMASK_LU12IW     0x00000000FFFFF000
19 #define ADDR_IMMMASK_ORI        0x0000000000000FFF
20 #define ADDR_IMMMASK_ADDU16ID   0x00000000FFFF0000
21
22 #define ADDR_IMMSHIFT_LU52ID    52
23 #define ADDR_IMMSBIDX_LU52ID    11
24 #define ADDR_IMMSHIFT_LU32ID    32
25 #define ADDR_IMMSBIDX_LU32ID    19
26 #define ADDR_IMMSHIFT_LU12IW    12
27 #define ADDR_IMMSBIDX_LU12IW    19
28 #define ADDR_IMMSHIFT_ORI       0
29 #define ADDR_IMMSBIDX_ORI       63
30 #define ADDR_IMMSHIFT_ADDU16ID  16
31 #define ADDR_IMMSBIDX_ADDU16ID  15
32
33 #define ADDR_IMM(addr, INSN)    \
34         (sign_extend64(((addr & ADDR_IMMMASK_##INSN) >> ADDR_IMMSHIFT_##INSN), ADDR_IMMSBIDX_##INSN))
35
36 enum reg0i15_op {
37         break_op        = 0x54,
38 };
39
40 enum reg0i26_op {
41         b_op            = 0x14,
42         bl_op           = 0x15,
43 };
44
45 enum reg1i20_op {
46         lu12iw_op       = 0x0a,
47         lu32id_op       = 0x0b,
48         pcaddi_op       = 0x0c,
49         pcalau12i_op    = 0x0d,
50         pcaddu12i_op    = 0x0e,
51         pcaddu18i_op    = 0x0f,
52 };
53
54 enum reg1i21_op {
55         beqz_op         = 0x10,
56         bnez_op         = 0x11,
57         bceqz_op        = 0x12, /* bits[9:8] = 0x00 */
58         bcnez_op        = 0x12, /* bits[9:8] = 0x01 */
59 };
60
61 enum reg2_op {
62         revb2h_op       = 0x0c,
63         revb4h_op       = 0x0d,
64         revb2w_op       = 0x0e,
65         revbd_op        = 0x0f,
66         revh2w_op       = 0x10,
67         revhd_op        = 0x11,
68 };
69
70 enum reg2i5_op {
71         slliw_op        = 0x81,
72         srliw_op        = 0x89,
73         sraiw_op        = 0x91,
74 };
75
76 enum reg2i6_op {
77         sllid_op        = 0x41,
78         srlid_op        = 0x45,
79         sraid_op        = 0x49,
80 };
81
82 enum reg2i12_op {
83         addiw_op        = 0x0a,
84         addid_op        = 0x0b,
85         lu52id_op       = 0x0c,
86         andi_op         = 0x0d,
87         ori_op          = 0x0e,
88         xori_op         = 0x0f,
89         ldb_op          = 0xa0,
90         ldh_op          = 0xa1,
91         ldw_op          = 0xa2,
92         ldd_op          = 0xa3,
93         stb_op          = 0xa4,
94         sth_op          = 0xa5,
95         stw_op          = 0xa6,
96         std_op          = 0xa7,
97         ldbu_op         = 0xa8,
98         ldhu_op         = 0xa9,
99         ldwu_op         = 0xaa,
100         flds_op         = 0xac,
101         fsts_op         = 0xad,
102         fldd_op         = 0xae,
103         fstd_op         = 0xaf,
104 };
105
106 enum reg2i14_op {
107         llw_op          = 0x20,
108         scw_op          = 0x21,
109         lld_op          = 0x22,
110         scd_op          = 0x23,
111         ldptrw_op       = 0x24,
112         stptrw_op       = 0x25,
113         ldptrd_op       = 0x26,
114         stptrd_op       = 0x27,
115 };
116
117 enum reg2i16_op {
118         jirl_op         = 0x13,
119         beq_op          = 0x16,
120         bne_op          = 0x17,
121         blt_op          = 0x18,
122         bge_op          = 0x19,
123         bltu_op         = 0x1a,
124         bgeu_op         = 0x1b,
125 };
126
127 enum reg2bstrd_op {
128         bstrinsd_op     = 0x2,
129         bstrpickd_op    = 0x3,
130 };
131
132 enum reg3_op {
133         asrtle_op       = 0x02,
134         asrtgt_op       = 0x03,
135         addw_op         = 0x20,
136         addd_op         = 0x21,
137         subw_op         = 0x22,
138         subd_op         = 0x23,
139         nor_op          = 0x28,
140         and_op          = 0x29,
141         or_op           = 0x2a,
142         xor_op          = 0x2b,
143         orn_op          = 0x2c,
144         andn_op         = 0x2d,
145         sllw_op         = 0x2e,
146         srlw_op         = 0x2f,
147         sraw_op         = 0x30,
148         slld_op         = 0x31,
149         srld_op         = 0x32,
150         srad_op         = 0x33,
151         mulw_op         = 0x38,
152         mulhw_op        = 0x39,
153         mulhwu_op       = 0x3a,
154         muld_op         = 0x3b,
155         mulhd_op        = 0x3c,
156         mulhdu_op       = 0x3d,
157         divw_op         = 0x40,
158         modw_op         = 0x41,
159         divwu_op        = 0x42,
160         modwu_op        = 0x43,
161         divd_op         = 0x44,
162         modd_op         = 0x45,
163         divdu_op        = 0x46,
164         moddu_op        = 0x47,
165         ldxb_op         = 0x7000,
166         ldxh_op         = 0x7008,
167         ldxw_op         = 0x7010,
168         ldxd_op         = 0x7018,
169         stxb_op         = 0x7020,
170         stxh_op         = 0x7028,
171         stxw_op         = 0x7030,
172         stxd_op         = 0x7038,
173         ldxbu_op        = 0x7040,
174         ldxhu_op        = 0x7048,
175         ldxwu_op        = 0x7050,
176         fldxs_op        = 0x7060,
177         fldxd_op        = 0x7068,
178         fstxs_op        = 0x7070,
179         fstxd_op        = 0x7078,
180         amswapw_op      = 0x70c0,
181         amswapd_op      = 0x70c1,
182         amaddw_op       = 0x70c2,
183         amaddd_op       = 0x70c3,
184         amandw_op       = 0x70c4,
185         amandd_op       = 0x70c5,
186         amorw_op        = 0x70c6,
187         amord_op        = 0x70c7,
188         amxorw_op       = 0x70c8,
189         amxord_op       = 0x70c9,
190         ammaxw_op       = 0x70ca,
191         ammaxd_op       = 0x70cb,
192         amminw_op       = 0x70cc,
193         ammind_op       = 0x70cd,
194         ammaxwu_op      = 0x70ce,
195         ammaxdu_op      = 0x70cf,
196         amminwu_op      = 0x70d0,
197         ammindu_op      = 0x70d1,
198         amswapdbw_op    = 0x70d2,
199         amswapdbd_op    = 0x70d3,
200         amadddbw_op     = 0x70d4,
201         amadddbd_op     = 0x70d5,
202         amanddbw_op     = 0x70d6,
203         amanddbd_op     = 0x70d7,
204         amordbw_op      = 0x70d8,
205         amordbd_op      = 0x70d9,
206         amxordbw_op     = 0x70da,
207         amxordbd_op     = 0x70db,
208         ammaxdbw_op     = 0x70dc,
209         ammaxdbd_op     = 0x70dd,
210         ammindbw_op     = 0x70de,
211         ammindbd_op     = 0x70df,
212         ammaxdbwu_op    = 0x70e0,
213         ammaxdbdu_op    = 0x70e1,
214         ammindbwu_op    = 0x70e2,
215         ammindbdu_op    = 0x70e3,
216         fldgts_op       = 0x70e8,
217         fldgtd_op       = 0x70e9,
218         fldles_op       = 0x70ea,
219         fldled_op       = 0x70eb,
220         fstgts_op       = 0x70ec,
221         fstgtd_op       = 0x70ed,
222         fstles_op       = 0x70ee,
223         fstled_op       = 0x70ef,
224         ldgtb_op        = 0x70f0,
225         ldgth_op        = 0x70f1,
226         ldgtw_op        = 0x70f2,
227         ldgtd_op        = 0x70f3,
228         ldleb_op        = 0x70f4,
229         ldleh_op        = 0x70f5,
230         ldlew_op        = 0x70f6,
231         ldled_op        = 0x70f7,
232         stgtb_op        = 0x70f8,
233         stgth_op        = 0x70f9,
234         stgtw_op        = 0x70fa,
235         stgtd_op        = 0x70fb,
236         stleb_op        = 0x70fc,
237         stleh_op        = 0x70fd,
238         stlew_op        = 0x70fe,
239         stled_op        = 0x70ff,
240 };
241
242 enum reg3sa2_op {
243         alslw_op        = 0x02,
244         alslwu_op       = 0x03,
245         alsld_op        = 0x16,
246 };
247
248 struct reg0i15_format {
249         unsigned int immediate : 15;
250         unsigned int opcode : 17;
251 };
252
253 struct reg0i26_format {
254         unsigned int immediate_h : 10;
255         unsigned int immediate_l : 16;
256         unsigned int opcode : 6;
257 };
258
259 struct reg1i20_format {
260         unsigned int rd : 5;
261         unsigned int immediate : 20;
262         unsigned int opcode : 7;
263 };
264
265 struct reg1i21_format {
266         unsigned int immediate_h  : 5;
267         unsigned int rj : 5;
268         unsigned int immediate_l : 16;
269         unsigned int opcode : 6;
270 };
271
272 struct reg2_format {
273         unsigned int rd : 5;
274         unsigned int rj : 5;
275         unsigned int opcode : 22;
276 };
277
278 struct reg2i5_format {
279         unsigned int rd : 5;
280         unsigned int rj : 5;
281         unsigned int immediate : 5;
282         unsigned int opcode : 17;
283 };
284
285 struct reg2i6_format {
286         unsigned int rd : 5;
287         unsigned int rj : 5;
288         unsigned int immediate : 6;
289         unsigned int opcode : 16;
290 };
291
292 struct reg2i12_format {
293         unsigned int rd : 5;
294         unsigned int rj : 5;
295         unsigned int immediate : 12;
296         unsigned int opcode : 10;
297 };
298
299 struct reg2i14_format {
300         unsigned int rd : 5;
301         unsigned int rj : 5;
302         unsigned int immediate : 14;
303         unsigned int opcode : 8;
304 };
305
306 struct reg2i16_format {
307         unsigned int rd : 5;
308         unsigned int rj : 5;
309         unsigned int immediate : 16;
310         unsigned int opcode : 6;
311 };
312
313 struct reg2bstrd_format {
314         unsigned int rd : 5;
315         unsigned int rj : 5;
316         unsigned int lsbd : 6;
317         unsigned int msbd : 6;
318         unsigned int opcode : 10;
319 };
320
321 struct reg3_format {
322         unsigned int rd : 5;
323         unsigned int rj : 5;
324         unsigned int rk : 5;
325         unsigned int opcode : 17;
326 };
327
328 struct reg3sa2_format {
329         unsigned int rd : 5;
330         unsigned int rj : 5;
331         unsigned int rk : 5;
332         unsigned int immediate : 2;
333         unsigned int opcode : 15;
334 };
335
336 union loongarch_instruction {
337         unsigned int word;
338         struct reg0i15_format   reg0i15_format;
339         struct reg0i26_format   reg0i26_format;
340         struct reg1i20_format   reg1i20_format;
341         struct reg1i21_format   reg1i21_format;
342         struct reg2_format      reg2_format;
343         struct reg2i5_format    reg2i5_format;
344         struct reg2i6_format    reg2i6_format;
345         struct reg2i12_format   reg2i12_format;
346         struct reg2i14_format   reg2i14_format;
347         struct reg2i16_format   reg2i16_format;
348         struct reg2bstrd_format reg2bstrd_format;
349         struct reg3_format      reg3_format;
350         struct reg3sa2_format   reg3sa2_format;
351 };
352
353 #define LOONGARCH_INSN_SIZE     sizeof(union loongarch_instruction)
354
355 enum loongarch_gpr {
356         LOONGARCH_GPR_ZERO = 0,
357         LOONGARCH_GPR_RA = 1,
358         LOONGARCH_GPR_TP = 2,
359         LOONGARCH_GPR_SP = 3,
360         LOONGARCH_GPR_A0 = 4,   /* Reused as V0 for return value */
361         LOONGARCH_GPR_A1,       /* Reused as V1 for return value */
362         LOONGARCH_GPR_A2,
363         LOONGARCH_GPR_A3,
364         LOONGARCH_GPR_A4,
365         LOONGARCH_GPR_A5,
366         LOONGARCH_GPR_A6,
367         LOONGARCH_GPR_A7,
368         LOONGARCH_GPR_T0 = 12,
369         LOONGARCH_GPR_T1,
370         LOONGARCH_GPR_T2,
371         LOONGARCH_GPR_T3,
372         LOONGARCH_GPR_T4,
373         LOONGARCH_GPR_T5,
374         LOONGARCH_GPR_T6,
375         LOONGARCH_GPR_T7,
376         LOONGARCH_GPR_T8,
377         LOONGARCH_GPR_FP = 22,
378         LOONGARCH_GPR_S0 = 23,
379         LOONGARCH_GPR_S1,
380         LOONGARCH_GPR_S2,
381         LOONGARCH_GPR_S3,
382         LOONGARCH_GPR_S4,
383         LOONGARCH_GPR_S5,
384         LOONGARCH_GPR_S6,
385         LOONGARCH_GPR_S7,
386         LOONGARCH_GPR_S8,
387         LOONGARCH_GPR_MAX
388 };
389
390 #define is_imm12_negative(val)  is_imm_negative(val, 12)
391
392 static inline bool is_imm_negative(unsigned long val, unsigned int bit)
393 {
394         return val & (1UL << (bit - 1));
395 }
396
397 static inline bool is_break_ins(union loongarch_instruction *ip)
398 {
399         return ip->reg0i15_format.opcode == break_op;
400 }
401
402 static inline bool is_pc_ins(union loongarch_instruction *ip)
403 {
404         return ip->reg1i20_format.opcode >= pcaddi_op &&
405                         ip->reg1i20_format.opcode <= pcaddu18i_op;
406 }
407
408 static inline bool is_branch_ins(union loongarch_instruction *ip)
409 {
410         return ip->reg1i21_format.opcode >= beqz_op &&
411                 ip->reg1i21_format.opcode <= bgeu_op;
412 }
413
414 static inline bool is_ra_save_ins(union loongarch_instruction *ip)
415 {
416         /* st.d $ra, $sp, offset */
417         return ip->reg2i12_format.opcode == std_op &&
418                 ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
419                 ip->reg2i12_format.rd == LOONGARCH_GPR_RA &&
420                 !is_imm12_negative(ip->reg2i12_format.immediate);
421 }
422
423 static inline bool is_stack_alloc_ins(union loongarch_instruction *ip)
424 {
425         /* addi.d $sp, $sp, -imm */
426         return ip->reg2i12_format.opcode == addid_op &&
427                 ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
428                 ip->reg2i12_format.rd == LOONGARCH_GPR_SP &&
429                 is_imm12_negative(ip->reg2i12_format.immediate);
430 }
431
432 static inline bool is_self_loop_ins(union loongarch_instruction *ip, struct pt_regs *regs)
433 {
434         switch (ip->reg0i26_format.opcode) {
435         case b_op:
436         case bl_op:
437                 if (ip->reg0i26_format.immediate_l == 0
438                     && ip->reg0i26_format.immediate_h == 0)
439                         return true;
440         }
441
442         switch (ip->reg1i21_format.opcode) {
443         case beqz_op:
444         case bnez_op:
445         case bceqz_op:
446                 if (ip->reg1i21_format.immediate_l == 0
447                     && ip->reg1i21_format.immediate_h == 0)
448                         return true;
449         }
450
451         switch (ip->reg2i16_format.opcode) {
452         case beq_op:
453         case bne_op:
454         case blt_op:
455         case bge_op:
456         case bltu_op:
457         case bgeu_op:
458                 if (ip->reg2i16_format.immediate == 0)
459                         return true;
460                 break;
461         case jirl_op:
462                 if (regs->regs[ip->reg2i16_format.rj] +
463                     ((unsigned long)ip->reg2i16_format.immediate << 2) == (unsigned long)ip)
464                         return true;
465         }
466
467         return false;
468 }
469
470 void simu_pc(struct pt_regs *regs, union loongarch_instruction insn);
471 void simu_branch(struct pt_regs *regs, union loongarch_instruction insn);
472
473 bool insns_not_supported(union loongarch_instruction insn);
474 bool insns_need_simulation(union loongarch_instruction insn);
475 void arch_simulate_insn(union loongarch_instruction insn, struct pt_regs *regs);
476
477 int larch_insn_read(void *addr, u32 *insnp);
478 int larch_insn_write(void *addr, u32 insn);
479 int larch_insn_patch_text(void *addr, u32 insn);
480
481 u32 larch_insn_gen_nop(void);
482 u32 larch_insn_gen_b(unsigned long pc, unsigned long dest);
483 u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest);
484
485 u32 larch_insn_gen_break(int imm);
486
487 u32 larch_insn_gen_or(enum loongarch_gpr rd, enum loongarch_gpr rj, enum loongarch_gpr rk);
488 u32 larch_insn_gen_move(enum loongarch_gpr rd, enum loongarch_gpr rj);
489
490 u32 larch_insn_gen_lu12iw(enum loongarch_gpr rd, int imm);
491 u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm);
492 u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm);
493 u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm);
494
495 static inline bool signed_imm_check(long val, unsigned int bit)
496 {
497         return -(1L << (bit - 1)) <= val && val < (1L << (bit - 1));
498 }
499
500 static inline bool unsigned_imm_check(unsigned long val, unsigned int bit)
501 {
502         return val < (1UL << bit);
503 }
504
505 #define DEF_EMIT_REG0I15_FORMAT(NAME, OP)                               \
506 static inline void emit_##NAME(union loongarch_instruction *insn,       \
507                                int imm)                                 \
508 {                                                                       \
509         insn->reg0i15_format.opcode = OP;                               \
510         insn->reg0i15_format.immediate = imm;                           \
511 }
512
513 DEF_EMIT_REG0I15_FORMAT(break, break_op)
514
515 #define DEF_EMIT_REG0I26_FORMAT(NAME, OP)                               \
516 static inline void emit_##NAME(union loongarch_instruction *insn,       \
517                                int offset)                              \
518 {                                                                       \
519         unsigned int immediate_l, immediate_h;                          \
520                                                                         \
521         immediate_l = offset & 0xffff;                                  \
522         offset >>= 16;                                                  \
523         immediate_h = offset & 0x3ff;                                   \
524                                                                         \
525         insn->reg0i26_format.opcode = OP;                               \
526         insn->reg0i26_format.immediate_l = immediate_l;                 \
527         insn->reg0i26_format.immediate_h = immediate_h;                 \
528 }
529
530 DEF_EMIT_REG0I26_FORMAT(b, b_op)
531 DEF_EMIT_REG0I26_FORMAT(bl, bl_op)
532
533 #define DEF_EMIT_REG1I20_FORMAT(NAME, OP)                               \
534 static inline void emit_##NAME(union loongarch_instruction *insn,       \
535                                enum loongarch_gpr rd, int imm)          \
536 {                                                                       \
537         insn->reg1i20_format.opcode = OP;                               \
538         insn->reg1i20_format.immediate = imm;                           \
539         insn->reg1i20_format.rd = rd;                                   \
540 }
541
542 DEF_EMIT_REG1I20_FORMAT(lu12iw, lu12iw_op)
543 DEF_EMIT_REG1I20_FORMAT(lu32id, lu32id_op)
544 DEF_EMIT_REG1I20_FORMAT(pcaddu18i, pcaddu18i_op)
545
546 #define DEF_EMIT_REG2_FORMAT(NAME, OP)                                  \
547 static inline void emit_##NAME(union loongarch_instruction *insn,       \
548                                enum loongarch_gpr rd,                   \
549                                enum loongarch_gpr rj)                   \
550 {                                                                       \
551         insn->reg2_format.opcode = OP;                                  \
552         insn->reg2_format.rd = rd;                                      \
553         insn->reg2_format.rj = rj;                                      \
554 }
555
556 DEF_EMIT_REG2_FORMAT(revb2h, revb2h_op)
557 DEF_EMIT_REG2_FORMAT(revb2w, revb2w_op)
558 DEF_EMIT_REG2_FORMAT(revbd, revbd_op)
559
560 #define DEF_EMIT_REG2I5_FORMAT(NAME, OP)                                \
561 static inline void emit_##NAME(union loongarch_instruction *insn,       \
562                                enum loongarch_gpr rd,                   \
563                                enum loongarch_gpr rj,                   \
564                                int imm)                                 \
565 {                                                                       \
566         insn->reg2i5_format.opcode = OP;                                \
567         insn->reg2i5_format.immediate = imm;                            \
568         insn->reg2i5_format.rd = rd;                                    \
569         insn->reg2i5_format.rj = rj;                                    \
570 }
571
572 DEF_EMIT_REG2I5_FORMAT(slliw, slliw_op)
573 DEF_EMIT_REG2I5_FORMAT(srliw, srliw_op)
574 DEF_EMIT_REG2I5_FORMAT(sraiw, sraiw_op)
575
576 #define DEF_EMIT_REG2I6_FORMAT(NAME, OP)                                \
577 static inline void emit_##NAME(union loongarch_instruction *insn,       \
578                                enum loongarch_gpr rd,                   \
579                                enum loongarch_gpr rj,                   \
580                                int imm)                                 \
581 {                                                                       \
582         insn->reg2i6_format.opcode = OP;                                \
583         insn->reg2i6_format.immediate = imm;                            \
584         insn->reg2i6_format.rd = rd;                                    \
585         insn->reg2i6_format.rj = rj;                                    \
586 }
587
588 DEF_EMIT_REG2I6_FORMAT(sllid, sllid_op)
589 DEF_EMIT_REG2I6_FORMAT(srlid, srlid_op)
590 DEF_EMIT_REG2I6_FORMAT(sraid, sraid_op)
591
592 #define DEF_EMIT_REG2I12_FORMAT(NAME, OP)                               \
593 static inline void emit_##NAME(union loongarch_instruction *insn,       \
594                                enum loongarch_gpr rd,                   \
595                                enum loongarch_gpr rj,                   \
596                                int imm)                                 \
597 {                                                                       \
598         insn->reg2i12_format.opcode = OP;                               \
599         insn->reg2i12_format.immediate = imm;                           \
600         insn->reg2i12_format.rd = rd;                                   \
601         insn->reg2i12_format.rj = rj;                                   \
602 }
603
604 DEF_EMIT_REG2I12_FORMAT(addiw, addiw_op)
605 DEF_EMIT_REG2I12_FORMAT(addid, addid_op)
606 DEF_EMIT_REG2I12_FORMAT(lu52id, lu52id_op)
607 DEF_EMIT_REG2I12_FORMAT(andi, andi_op)
608 DEF_EMIT_REG2I12_FORMAT(ori, ori_op)
609 DEF_EMIT_REG2I12_FORMAT(xori, xori_op)
610 DEF_EMIT_REG2I12_FORMAT(ldbu, ldbu_op)
611 DEF_EMIT_REG2I12_FORMAT(ldhu, ldhu_op)
612 DEF_EMIT_REG2I12_FORMAT(ldwu, ldwu_op)
613 DEF_EMIT_REG2I12_FORMAT(ldd, ldd_op)
614 DEF_EMIT_REG2I12_FORMAT(stb, stb_op)
615 DEF_EMIT_REG2I12_FORMAT(sth, sth_op)
616 DEF_EMIT_REG2I12_FORMAT(stw, stw_op)
617 DEF_EMIT_REG2I12_FORMAT(std, std_op)
618
619 #define DEF_EMIT_REG2I14_FORMAT(NAME, OP)                               \
620 static inline void emit_##NAME(union loongarch_instruction *insn,       \
621                                enum loongarch_gpr rd,                   \
622                                enum loongarch_gpr rj,                   \
623                                int imm)                                 \
624 {                                                                       \
625         insn->reg2i14_format.opcode = OP;                               \
626         insn->reg2i14_format.immediate = imm;                           \
627         insn->reg2i14_format.rd = rd;                                   \
628         insn->reg2i14_format.rj = rj;                                   \
629 }
630
631 DEF_EMIT_REG2I14_FORMAT(llw, llw_op)
632 DEF_EMIT_REG2I14_FORMAT(scw, scw_op)
633 DEF_EMIT_REG2I14_FORMAT(lld, lld_op)
634 DEF_EMIT_REG2I14_FORMAT(scd, scd_op)
635 DEF_EMIT_REG2I14_FORMAT(ldptrw, ldptrw_op)
636 DEF_EMIT_REG2I14_FORMAT(stptrw, stptrw_op)
637 DEF_EMIT_REG2I14_FORMAT(ldptrd, ldptrd_op)
638 DEF_EMIT_REG2I14_FORMAT(stptrd, stptrd_op)
639
640 #define DEF_EMIT_REG2I16_FORMAT(NAME, OP)                               \
641 static inline void emit_##NAME(union loongarch_instruction *insn,       \
642                                enum loongarch_gpr rj,                   \
643                                enum loongarch_gpr rd,                   \
644                                int offset)                              \
645 {                                                                       \
646         insn->reg2i16_format.opcode = OP;                               \
647         insn->reg2i16_format.immediate = offset;                        \
648         insn->reg2i16_format.rj = rj;                                   \
649         insn->reg2i16_format.rd = rd;                                   \
650 }
651
652 DEF_EMIT_REG2I16_FORMAT(beq, beq_op)
653 DEF_EMIT_REG2I16_FORMAT(bne, bne_op)
654 DEF_EMIT_REG2I16_FORMAT(blt, blt_op)
655 DEF_EMIT_REG2I16_FORMAT(bge, bge_op)
656 DEF_EMIT_REG2I16_FORMAT(bltu, bltu_op)
657 DEF_EMIT_REG2I16_FORMAT(bgeu, bgeu_op)
658 DEF_EMIT_REG2I16_FORMAT(jirl, jirl_op)
659
660 #define DEF_EMIT_REG2BSTRD_FORMAT(NAME, OP)                             \
661 static inline void emit_##NAME(union loongarch_instruction *insn,       \
662                                enum loongarch_gpr rd,                   \
663                                enum loongarch_gpr rj,                   \
664                                int msbd,                                \
665                                int lsbd)                                \
666 {                                                                       \
667         insn->reg2bstrd_format.opcode = OP;                             \
668         insn->reg2bstrd_format.msbd = msbd;                             \
669         insn->reg2bstrd_format.lsbd = lsbd;                             \
670         insn->reg2bstrd_format.rj = rj;                                 \
671         insn->reg2bstrd_format.rd = rd;                                 \
672 }
673
674 DEF_EMIT_REG2BSTRD_FORMAT(bstrpickd, bstrpickd_op)
675
676 #define DEF_EMIT_REG3_FORMAT(NAME, OP)                                  \
677 static inline void emit_##NAME(union loongarch_instruction *insn,       \
678                                enum loongarch_gpr rd,                   \
679                                enum loongarch_gpr rj,                   \
680                                enum loongarch_gpr rk)                   \
681 {                                                                       \
682         insn->reg3_format.opcode = OP;                                  \
683         insn->reg3_format.rd = rd;                                      \
684         insn->reg3_format.rj = rj;                                      \
685         insn->reg3_format.rk = rk;                                      \
686 }
687
688 DEF_EMIT_REG3_FORMAT(addd, addd_op)
689 DEF_EMIT_REG3_FORMAT(subd, subd_op)
690 DEF_EMIT_REG3_FORMAT(muld, muld_op)
691 DEF_EMIT_REG3_FORMAT(divdu, divdu_op)
692 DEF_EMIT_REG3_FORMAT(moddu, moddu_op)
693 DEF_EMIT_REG3_FORMAT(and, and_op)
694 DEF_EMIT_REG3_FORMAT(or, or_op)
695 DEF_EMIT_REG3_FORMAT(xor, xor_op)
696 DEF_EMIT_REG3_FORMAT(sllw, sllw_op)
697 DEF_EMIT_REG3_FORMAT(slld, slld_op)
698 DEF_EMIT_REG3_FORMAT(srlw, srlw_op)
699 DEF_EMIT_REG3_FORMAT(srld, srld_op)
700 DEF_EMIT_REG3_FORMAT(sraw, sraw_op)
701 DEF_EMIT_REG3_FORMAT(srad, srad_op)
702 DEF_EMIT_REG3_FORMAT(ldxbu, ldxbu_op)
703 DEF_EMIT_REG3_FORMAT(ldxhu, ldxhu_op)
704 DEF_EMIT_REG3_FORMAT(ldxwu, ldxwu_op)
705 DEF_EMIT_REG3_FORMAT(ldxd, ldxd_op)
706 DEF_EMIT_REG3_FORMAT(stxb, stxb_op)
707 DEF_EMIT_REG3_FORMAT(stxh, stxh_op)
708 DEF_EMIT_REG3_FORMAT(stxw, stxw_op)
709 DEF_EMIT_REG3_FORMAT(stxd, stxd_op)
710 DEF_EMIT_REG3_FORMAT(amaddw, amaddw_op)
711 DEF_EMIT_REG3_FORMAT(amaddd, amaddd_op)
712 DEF_EMIT_REG3_FORMAT(amandw, amandw_op)
713 DEF_EMIT_REG3_FORMAT(amandd, amandd_op)
714 DEF_EMIT_REG3_FORMAT(amorw, amorw_op)
715 DEF_EMIT_REG3_FORMAT(amord, amord_op)
716 DEF_EMIT_REG3_FORMAT(amxorw, amxorw_op)
717 DEF_EMIT_REG3_FORMAT(amxord, amxord_op)
718 DEF_EMIT_REG3_FORMAT(amswapw, amswapw_op)
719 DEF_EMIT_REG3_FORMAT(amswapd, amswapd_op)
720
721 #define DEF_EMIT_REG3SA2_FORMAT(NAME, OP)                               \
722 static inline void emit_##NAME(union loongarch_instruction *insn,       \
723                                enum loongarch_gpr rd,                   \
724                                enum loongarch_gpr rj,                   \
725                                enum loongarch_gpr rk,                   \
726                                int imm)                                 \
727 {                                                                       \
728         insn->reg3sa2_format.opcode = OP;                               \
729         insn->reg3sa2_format.immediate = imm;                           \
730         insn->reg3sa2_format.rd = rd;                                   \
731         insn->reg3sa2_format.rj = rj;                                   \
732         insn->reg3sa2_format.rk = rk;                                   \
733 }
734
735 DEF_EMIT_REG3SA2_FORMAT(alsld, alsld_op)
736
737 struct pt_regs;
738
739 void emulate_load_store_insn(struct pt_regs *regs, void __user *addr, unsigned int *pc);
740 unsigned long unaligned_read(void __user *addr, void *value, unsigned long n, bool sign);
741 unsigned long unaligned_write(void __user *addr, unsigned long value, unsigned long n);
742
743 #endif /* _ASM_INST_H */