~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/loongarch/include/asm/inst.h

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php