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