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/types.h>
9 #include <asm/asm.h>
10 
11 #define INSN_BREAK		0x002a0000
12 
13 #define ADDR_IMMMASK_LU52ID	0xFFF0000000000000
14 #define ADDR_IMMMASK_LU32ID	0x000FFFFF00000000
15 #define ADDR_IMMMASK_ADDU16ID	0x00000000FFFF0000
16 
17 #define ADDR_IMMSHIFT_LU52ID	52
18 #define ADDR_IMMSHIFT_LU32ID	32
19 #define ADDR_IMMSHIFT_ADDU16ID	16
20 
21 #define ADDR_IMM(addr, INSN)	((addr & ADDR_IMMMASK_##INSN) >> ADDR_IMMSHIFT_##INSN)
22 
23 enum reg0i26_op {
24 	b_op		= 0x14,
25 	bl_op		= 0x15,
26 };
27 
28 enum reg1i20_op {
29 	lu12iw_op	= 0x0a,
30 	lu32id_op	= 0x0b,
31 	pcaddu12i_op	= 0x0e,
32 	pcaddu18i_op	= 0x0f,
33 };
34 
35 enum reg1i21_op {
36 	beqz_op		= 0x10,
37 	bnez_op		= 0x11,
38 };
39 
40 enum reg2_op {
41 	revb2h_op	= 0x0c,
42 	revb4h_op	= 0x0d,
43 	revb2w_op	= 0x0e,
44 	revbd_op	= 0x0f,
45 	revh2w_op	= 0x10,
46 	revhd_op	= 0x11,
47 };
48 
49 enum reg2i5_op {
50 	slliw_op	= 0x81,
51 	srliw_op	= 0x89,
52 	sraiw_op	= 0x91,
53 };
54 
55 enum reg2i6_op {
56 	sllid_op	= 0x41,
57 	srlid_op	= 0x45,
58 	sraid_op	= 0x49,
59 };
60 
61 enum reg2i12_op {
62 	addiw_op	= 0x0a,
63 	addid_op	= 0x0b,
64 	lu52id_op	= 0x0c,
65 	andi_op		= 0x0d,
66 	ori_op		= 0x0e,
67 	xori_op		= 0x0f,
68 	ldb_op		= 0xa0,
69 	ldh_op		= 0xa1,
70 	ldw_op		= 0xa2,
71 	ldd_op		= 0xa3,
72 	stb_op		= 0xa4,
73 	sth_op		= 0xa5,
74 	stw_op		= 0xa6,
75 	std_op		= 0xa7,
76 	ldbu_op		= 0xa8,
77 	ldhu_op		= 0xa9,
78 	ldwu_op		= 0xaa,
79 };
80 
81 enum reg2i14_op {
82 	llw_op		= 0x20,
83 	scw_op		= 0x21,
84 	lld_op		= 0x22,
85 	scd_op		= 0x23,
86 	ldptrw_op	= 0x24,
87 	stptrw_op	= 0x25,
88 	ldptrd_op	= 0x26,
89 	stptrd_op	= 0x27,
90 };
91 
92 enum reg2i16_op {
93 	jirl_op		= 0x13,
94 	beq_op		= 0x16,
95 	bne_op		= 0x17,
96 	blt_op		= 0x18,
97 	bge_op		= 0x19,
98 	bltu_op		= 0x1a,
99 	bgeu_op		= 0x1b,
100 };
101 
102 enum reg2bstrd_op {
103 	bstrinsd_op	= 0x2,
104 	bstrpickd_op	= 0x3,
105 };
106 
107 enum reg3_op {
108 	addw_op		= 0x20,
109 	addd_op		= 0x21,
110 	subw_op		= 0x22,
111 	subd_op		= 0x23,
112 	nor_op		= 0x28,
113 	and_op		= 0x29,
114 	or_op		= 0x2a,
115 	xor_op		= 0x2b,
116 	orn_op		= 0x2c,
117 	andn_op		= 0x2d,
118 	sllw_op		= 0x2e,
119 	srlw_op		= 0x2f,
120 	sraw_op		= 0x30,
121 	slld_op		= 0x31,
122 	srld_op		= 0x32,
123 	srad_op		= 0x33,
124 	mulw_op		= 0x38,
125 	mulhw_op	= 0x39,
126 	mulhwu_op	= 0x3a,
127 	muld_op		= 0x3b,
128 	mulhd_op	= 0x3c,
129 	mulhdu_op	= 0x3d,
130 	divw_op		= 0x40,
131 	modw_op		= 0x41,
132 	divwu_op	= 0x42,
133 	modwu_op	= 0x43,
134 	divd_op		= 0x44,
135 	modd_op		= 0x45,
136 	divdu_op	= 0x46,
137 	moddu_op	= 0x47,
138 	ldxb_op		= 0x7000,
139 	ldxh_op		= 0x7008,
140 	ldxw_op		= 0x7010,
141 	ldxd_op		= 0x7018,
142 	stxb_op		= 0x7020,
143 	stxh_op		= 0x7028,
144 	stxw_op		= 0x7030,
145 	stxd_op		= 0x7038,
146 	ldxbu_op	= 0x7040,
147 	ldxhu_op	= 0x7048,
148 	ldxwu_op	= 0x7050,
149 	amswapw_op	= 0x70c0,
150 	amswapd_op	= 0x70c1,
151 	amaddw_op	= 0x70c2,
152 	amaddd_op	= 0x70c3,
153 	amandw_op	= 0x70c4,
154 	amandd_op	= 0x70c5,
155 	amorw_op	= 0x70c6,
156 	amord_op	= 0x70c7,
157 	amxorw_op	= 0x70c8,
158 	amxord_op	= 0x70c9,
159 };
160 
161 enum reg3sa2_op {
162 	alslw_op	= 0x02,
163 	alslwu_op	= 0x03,
164 	alsld_op	= 0x16,
165 };
166 
167 struct reg0i26_format {
168 	unsigned int immediate_h : 10;
169 	unsigned int immediate_l : 16;
170 	unsigned int opcode : 6;
171 };
172 
173 struct reg1i20_format {
174 	unsigned int rd : 5;
175 	unsigned int immediate : 20;
176 	unsigned int opcode : 7;
177 };
178 
179 struct reg1i21_format {
180 	unsigned int immediate_h  : 5;
181 	unsigned int rj : 5;
182 	unsigned int immediate_l : 16;
183 	unsigned int opcode : 6;
184 };
185 
186 struct reg2_format {
187 	unsigned int rd : 5;
188 	unsigned int rj : 5;
189 	unsigned int opcode : 22;
190 };
191 
192 struct reg2i5_format {
193 	unsigned int rd : 5;
194 	unsigned int rj : 5;
195 	unsigned int immediate : 5;
196 	unsigned int opcode : 17;
197 };
198 
199 struct reg2i6_format {
200 	unsigned int rd : 5;
201 	unsigned int rj : 5;
202 	unsigned int immediate : 6;
203 	unsigned int opcode : 16;
204 };
205 
206 struct reg2i12_format {
207 	unsigned int rd : 5;
208 	unsigned int rj : 5;
209 	unsigned int immediate : 12;
210 	unsigned int opcode : 10;
211 };
212 
213 struct reg2i14_format {
214 	unsigned int rd : 5;
215 	unsigned int rj : 5;
216 	unsigned int immediate : 14;
217 	unsigned int opcode : 8;
218 };
219 
220 struct reg2i16_format {
221 	unsigned int rd : 5;
222 	unsigned int rj : 5;
223 	unsigned int immediate : 16;
224 	unsigned int opcode : 6;
225 };
226 
227 struct reg2bstrd_format {
228 	unsigned int rd : 5;
229 	unsigned int rj : 5;
230 	unsigned int lsbd : 6;
231 	unsigned int msbd : 6;
232 	unsigned int opcode : 10;
233 };
234 
235 struct reg3_format {
236 	unsigned int rd : 5;
237 	unsigned int rj : 5;
238 	unsigned int rk : 5;
239 	unsigned int opcode : 17;
240 };
241 
242 struct reg3sa2_format {
243 	unsigned int rd : 5;
244 	unsigned int rj : 5;
245 	unsigned int rk : 5;
246 	unsigned int immediate : 2;
247 	unsigned int opcode : 15;
248 };
249 
250 union loongarch_instruction {
251 	unsigned int word;
252 	struct reg0i26_format	reg0i26_format;
253 	struct reg1i20_format	reg1i20_format;
254 	struct reg1i21_format	reg1i21_format;
255 	struct reg2_format	reg2_format;
256 	struct reg2i5_format	reg2i5_format;
257 	struct reg2i6_format	reg2i6_format;
258 	struct reg2i12_format	reg2i12_format;
259 	struct reg2i14_format	reg2i14_format;
260 	struct reg2i16_format	reg2i16_format;
261 	struct reg2bstrd_format	reg2bstrd_format;
262 	struct reg3_format	reg3_format;
263 	struct reg3sa2_format	reg3sa2_format;
264 };
265 
266 #define LOONGARCH_INSN_SIZE	sizeof(union loongarch_instruction)
267 
268 enum loongarch_gpr {
269 	LOONGARCH_GPR_ZERO = 0,
270 	LOONGARCH_GPR_RA = 1,
271 	LOONGARCH_GPR_TP = 2,
272 	LOONGARCH_GPR_SP = 3,
273 	LOONGARCH_GPR_A0 = 4,	/* Reused as V0 for return value */
274 	LOONGARCH_GPR_A1,	/* Reused as V1 for return value */
275 	LOONGARCH_GPR_A2,
276 	LOONGARCH_GPR_A3,
277 	LOONGARCH_GPR_A4,
278 	LOONGARCH_GPR_A5,
279 	LOONGARCH_GPR_A6,
280 	LOONGARCH_GPR_A7,
281 	LOONGARCH_GPR_T0 = 12,
282 	LOONGARCH_GPR_T1,
283 	LOONGARCH_GPR_T2,
284 	LOONGARCH_GPR_T3,
285 	LOONGARCH_GPR_T4,
286 	LOONGARCH_GPR_T5,
287 	LOONGARCH_GPR_T6,
288 	LOONGARCH_GPR_T7,
289 	LOONGARCH_GPR_T8,
290 	LOONGARCH_GPR_FP = 22,
291 	LOONGARCH_GPR_S0 = 23,
292 	LOONGARCH_GPR_S1,
293 	LOONGARCH_GPR_S2,
294 	LOONGARCH_GPR_S3,
295 	LOONGARCH_GPR_S4,
296 	LOONGARCH_GPR_S5,
297 	LOONGARCH_GPR_S6,
298 	LOONGARCH_GPR_S7,
299 	LOONGARCH_GPR_S8,
300 	LOONGARCH_GPR_MAX
301 };
302 
303 #define is_imm12_negative(val)	is_imm_negative(val, 12)
304 
is_imm_negative(unsigned long val,unsigned int bit)305 static inline bool is_imm_negative(unsigned long val, unsigned int bit)
306 {
307 	return val & (1UL << (bit - 1));
308 }
309 
is_branch_ins(union loongarch_instruction * ip)310 static inline bool is_branch_ins(union loongarch_instruction *ip)
311 {
312 	return ip->reg1i21_format.opcode >= beqz_op &&
313 		ip->reg1i21_format.opcode <= bgeu_op;
314 }
315 
is_ra_save_ins(union loongarch_instruction * ip)316 static inline bool is_ra_save_ins(union loongarch_instruction *ip)
317 {
318 	/* st.d $ra, $sp, offset */
319 	return ip->reg2i12_format.opcode == std_op &&
320 		ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
321 		ip->reg2i12_format.rd == LOONGARCH_GPR_RA &&
322 		!is_imm12_negative(ip->reg2i12_format.immediate);
323 }
324 
is_stack_alloc_ins(union loongarch_instruction * ip)325 static inline bool is_stack_alloc_ins(union loongarch_instruction *ip)
326 {
327 	/* addi.d $sp, $sp, -imm */
328 	return ip->reg2i12_format.opcode == addid_op &&
329 		ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
330 		ip->reg2i12_format.rd == LOONGARCH_GPR_SP &&
331 		is_imm12_negative(ip->reg2i12_format.immediate);
332 }
333 
334 u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm);
335 u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm);
336 u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, unsigned long pc, unsigned long dest);
337 
signed_imm_check(long val,unsigned int bit)338 static inline bool signed_imm_check(long val, unsigned int bit)
339 {
340 	return -(1L << (bit - 1)) <= val && val < (1L << (bit - 1));
341 }
342 
unsigned_imm_check(unsigned long val,unsigned int bit)343 static inline bool unsigned_imm_check(unsigned long val, unsigned int bit)
344 {
345 	return val < (1UL << bit);
346 }
347 
348 #define DEF_EMIT_REG0I26_FORMAT(NAME, OP)				\
349 static inline void emit_##NAME(union loongarch_instruction *insn,	\
350 			       int offset)				\
351 {									\
352 	unsigned int immediate_l, immediate_h;				\
353 									\
354 	immediate_l = offset & 0xffff;					\
355 	offset >>= 16;							\
356 	immediate_h = offset & 0x3ff;					\
357 									\
358 	insn->reg0i26_format.opcode = OP;				\
359 	insn->reg0i26_format.immediate_l = immediate_l;			\
360 	insn->reg0i26_format.immediate_h = immediate_h;			\
361 }
362 
363 DEF_EMIT_REG0I26_FORMAT(b, b_op)
364 
365 #define DEF_EMIT_REG1I20_FORMAT(NAME, OP)				\
366 static inline void emit_##NAME(union loongarch_instruction *insn,	\
367 			       enum loongarch_gpr rd, int imm)		\
368 {									\
369 	insn->reg1i20_format.opcode = OP;				\
370 	insn->reg1i20_format.immediate = imm;				\
371 	insn->reg1i20_format.rd = rd;					\
372 }
373 
374 DEF_EMIT_REG1I20_FORMAT(lu12iw, lu12iw_op)
375 DEF_EMIT_REG1I20_FORMAT(lu32id, lu32id_op)
376 DEF_EMIT_REG1I20_FORMAT(pcaddu18i, pcaddu18i_op)
377 
378 #define DEF_EMIT_REG2_FORMAT(NAME, OP)					\
379 static inline void emit_##NAME(union loongarch_instruction *insn,	\
380 			       enum loongarch_gpr rd,			\
381 			       enum loongarch_gpr rj)			\
382 {									\
383 	insn->reg2_format.opcode = OP;					\
384 	insn->reg2_format.rd = rd;					\
385 	insn->reg2_format.rj = rj;					\
386 }
387 
388 DEF_EMIT_REG2_FORMAT(revb2h, revb2h_op)
389 DEF_EMIT_REG2_FORMAT(revb2w, revb2w_op)
390 DEF_EMIT_REG2_FORMAT(revbd, revbd_op)
391 
392 #define DEF_EMIT_REG2I5_FORMAT(NAME, OP)				\
393 static inline void emit_##NAME(union loongarch_instruction *insn,	\
394 			       enum loongarch_gpr rd,			\
395 			       enum loongarch_gpr rj,			\
396 			       int imm)					\
397 {									\
398 	insn->reg2i5_format.opcode = OP;				\
399 	insn->reg2i5_format.immediate = imm;				\
400 	insn->reg2i5_format.rd = rd;					\
401 	insn->reg2i5_format.rj = rj;					\
402 }
403 
404 DEF_EMIT_REG2I5_FORMAT(slliw, slliw_op)
405 DEF_EMIT_REG2I5_FORMAT(srliw, srliw_op)
406 DEF_EMIT_REG2I5_FORMAT(sraiw, sraiw_op)
407 
408 #define DEF_EMIT_REG2I6_FORMAT(NAME, OP)				\
409 static inline void emit_##NAME(union loongarch_instruction *insn,	\
410 			       enum loongarch_gpr rd,			\
411 			       enum loongarch_gpr rj,			\
412 			       int imm)					\
413 {									\
414 	insn->reg2i6_format.opcode = OP;				\
415 	insn->reg2i6_format.immediate = imm;				\
416 	insn->reg2i6_format.rd = rd;					\
417 	insn->reg2i6_format.rj = rj;					\
418 }
419 
420 DEF_EMIT_REG2I6_FORMAT(sllid, sllid_op)
421 DEF_EMIT_REG2I6_FORMAT(srlid, srlid_op)
422 DEF_EMIT_REG2I6_FORMAT(sraid, sraid_op)
423 
424 #define DEF_EMIT_REG2I12_FORMAT(NAME, OP)				\
425 static inline void emit_##NAME(union loongarch_instruction *insn,	\
426 			       enum loongarch_gpr rd,			\
427 			       enum loongarch_gpr rj,			\
428 			       int imm)					\
429 {									\
430 	insn->reg2i12_format.opcode = OP;				\
431 	insn->reg2i12_format.immediate = imm;				\
432 	insn->reg2i12_format.rd = rd;					\
433 	insn->reg2i12_format.rj = rj;					\
434 }
435 
436 DEF_EMIT_REG2I12_FORMAT(addiw, addiw_op)
437 DEF_EMIT_REG2I12_FORMAT(addid, addid_op)
438 DEF_EMIT_REG2I12_FORMAT(lu52id, lu52id_op)
439 DEF_EMIT_REG2I12_FORMAT(andi, andi_op)
440 DEF_EMIT_REG2I12_FORMAT(ori, ori_op)
441 DEF_EMIT_REG2I12_FORMAT(xori, xori_op)
442 DEF_EMIT_REG2I12_FORMAT(ldbu, ldbu_op)
443 DEF_EMIT_REG2I12_FORMAT(ldhu, ldhu_op)
444 DEF_EMIT_REG2I12_FORMAT(ldwu, ldwu_op)
445 DEF_EMIT_REG2I12_FORMAT(ldd, ldd_op)
446 DEF_EMIT_REG2I12_FORMAT(stb, stb_op)
447 DEF_EMIT_REG2I12_FORMAT(sth, sth_op)
448 DEF_EMIT_REG2I12_FORMAT(stw, stw_op)
449 DEF_EMIT_REG2I12_FORMAT(std, std_op)
450 
451 #define DEF_EMIT_REG2I14_FORMAT(NAME, OP)				\
452 static inline void emit_##NAME(union loongarch_instruction *insn,	\
453 			       enum loongarch_gpr rd,			\
454 			       enum loongarch_gpr rj,			\
455 			       int imm)					\
456 {									\
457 	insn->reg2i14_format.opcode = OP;				\
458 	insn->reg2i14_format.immediate = imm;				\
459 	insn->reg2i14_format.rd = rd;					\
460 	insn->reg2i14_format.rj = rj;					\
461 }
462 
463 DEF_EMIT_REG2I14_FORMAT(llw, llw_op)
464 DEF_EMIT_REG2I14_FORMAT(scw, scw_op)
465 DEF_EMIT_REG2I14_FORMAT(lld, lld_op)
466 DEF_EMIT_REG2I14_FORMAT(scd, scd_op)
467 DEF_EMIT_REG2I14_FORMAT(ldptrw, ldptrw_op)
468 DEF_EMIT_REG2I14_FORMAT(stptrw, stptrw_op)
469 DEF_EMIT_REG2I14_FORMAT(ldptrd, ldptrd_op)
470 DEF_EMIT_REG2I14_FORMAT(stptrd, stptrd_op)
471 
472 #define DEF_EMIT_REG2I16_FORMAT(NAME, OP)				\
473 static inline void emit_##NAME(union loongarch_instruction *insn,	\
474 			       enum loongarch_gpr rj,			\
475 			       enum loongarch_gpr rd,			\
476 			       int offset)				\
477 {									\
478 	insn->reg2i16_format.opcode = OP;				\
479 	insn->reg2i16_format.immediate = offset;			\
480 	insn->reg2i16_format.rj = rj;					\
481 	insn->reg2i16_format.rd = rd;					\
482 }
483 
484 DEF_EMIT_REG2I16_FORMAT(beq, beq_op)
485 DEF_EMIT_REG2I16_FORMAT(bne, bne_op)
486 DEF_EMIT_REG2I16_FORMAT(blt, blt_op)
487 DEF_EMIT_REG2I16_FORMAT(bge, bge_op)
488 DEF_EMIT_REG2I16_FORMAT(bltu, bltu_op)
489 DEF_EMIT_REG2I16_FORMAT(bgeu, bgeu_op)
490 DEF_EMIT_REG2I16_FORMAT(jirl, jirl_op)
491 
492 #define DEF_EMIT_REG2BSTRD_FORMAT(NAME, OP)				\
493 static inline void emit_##NAME(union loongarch_instruction *insn,	\
494 			       enum loongarch_gpr rd,			\
495 			       enum loongarch_gpr rj,			\
496 			       int msbd,				\
497 			       int lsbd)				\
498 {									\
499 	insn->reg2bstrd_format.opcode = OP;				\
500 	insn->reg2bstrd_format.msbd = msbd;				\
501 	insn->reg2bstrd_format.lsbd = lsbd;				\
502 	insn->reg2bstrd_format.rj = rj;					\
503 	insn->reg2bstrd_format.rd = rd;					\
504 }
505 
506 DEF_EMIT_REG2BSTRD_FORMAT(bstrpickd, bstrpickd_op)
507 
508 #define DEF_EMIT_REG3_FORMAT(NAME, OP)					\
509 static inline void emit_##NAME(union loongarch_instruction *insn,	\
510 			       enum loongarch_gpr rd,			\
511 			       enum loongarch_gpr rj,			\
512 			       enum loongarch_gpr rk)			\
513 {									\
514 	insn->reg3_format.opcode = OP;					\
515 	insn->reg3_format.rd = rd;					\
516 	insn->reg3_format.rj = rj;					\
517 	insn->reg3_format.rk = rk;					\
518 }
519 
520 DEF_EMIT_REG3_FORMAT(addd, addd_op)
521 DEF_EMIT_REG3_FORMAT(subd, subd_op)
522 DEF_EMIT_REG3_FORMAT(muld, muld_op)
523 DEF_EMIT_REG3_FORMAT(divdu, divdu_op)
524 DEF_EMIT_REG3_FORMAT(moddu, moddu_op)
525 DEF_EMIT_REG3_FORMAT(and, and_op)
526 DEF_EMIT_REG3_FORMAT(or, or_op)
527 DEF_EMIT_REG3_FORMAT(xor, xor_op)
528 DEF_EMIT_REG3_FORMAT(sllw, sllw_op)
529 DEF_EMIT_REG3_FORMAT(slld, slld_op)
530 DEF_EMIT_REG3_FORMAT(srlw, srlw_op)
531 DEF_EMIT_REG3_FORMAT(srld, srld_op)
532 DEF_EMIT_REG3_FORMAT(sraw, sraw_op)
533 DEF_EMIT_REG3_FORMAT(srad, srad_op)
534 DEF_EMIT_REG3_FORMAT(ldxbu, ldxbu_op)
535 DEF_EMIT_REG3_FORMAT(ldxhu, ldxhu_op)
536 DEF_EMIT_REG3_FORMAT(ldxwu, ldxwu_op)
537 DEF_EMIT_REG3_FORMAT(ldxd, ldxd_op)
538 DEF_EMIT_REG3_FORMAT(stxb, stxb_op)
539 DEF_EMIT_REG3_FORMAT(stxh, stxh_op)
540 DEF_EMIT_REG3_FORMAT(stxw, stxw_op)
541 DEF_EMIT_REG3_FORMAT(stxd, stxd_op)
542 DEF_EMIT_REG3_FORMAT(amaddw, amaddw_op)
543 DEF_EMIT_REG3_FORMAT(amaddd, amaddd_op)
544 DEF_EMIT_REG3_FORMAT(amandw, amandw_op)
545 DEF_EMIT_REG3_FORMAT(amandd, amandd_op)
546 DEF_EMIT_REG3_FORMAT(amorw, amorw_op)
547 DEF_EMIT_REG3_FORMAT(amord, amord_op)
548 DEF_EMIT_REG3_FORMAT(amxorw, amxorw_op)
549 DEF_EMIT_REG3_FORMAT(amxord, amxord_op)
550 DEF_EMIT_REG3_FORMAT(amswapw, amswapw_op)
551 DEF_EMIT_REG3_FORMAT(amswapd, amswapd_op)
552 
553 #define DEF_EMIT_REG3SA2_FORMAT(NAME, OP)				\
554 static inline void emit_##NAME(union loongarch_instruction *insn,	\
555 			       enum loongarch_gpr rd,			\
556 			       enum loongarch_gpr rj,			\
557 			       enum loongarch_gpr rk,			\
558 			       int imm)					\
559 {									\
560 	insn->reg3sa2_format.opcode = OP;				\
561 	insn->reg3sa2_format.immediate = imm;				\
562 	insn->reg3sa2_format.rd = rd;					\
563 	insn->reg3sa2_format.rj = rj;					\
564 	insn->reg3sa2_format.rk = rk;					\
565 }
566 
567 DEF_EMIT_REG3SA2_FORMAT(alsld, alsld_op)
568 
569 #endif /* _ASM_INST_H */
570