xref: /linux/tools/arch/loongarch/include/asm/inst.h (revision 6b9c4a05ae2b539bfd4d64a46eb861a57cc08351)
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 
10 #define LOONGARCH_INSN_NOP		0x03400000
11 
12 enum reg0i15_op {
13 	break_op	= 0x54,
14 };
15 
16 enum reg0i26_op {
17 	b_op		= 0x14,
18 	bl_op		= 0x15,
19 };
20 
21 enum reg1i21_op {
22 	beqz_op		= 0x10,
23 	bnez_op		= 0x11,
24 	bceqz_op	= 0x12, /* bits[9:8] = 0x00 */
25 	bcnez_op	= 0x12, /* bits[9:8] = 0x01 */
26 };
27 
28 enum reg2_op {
29 	ertn_op		= 0x1920e,
30 };
31 
32 enum reg2i12_op {
33 	addid_op	= 0x0b,
34 	andi_op		= 0x0d,
35 	ldd_op		= 0xa3,
36 	std_op		= 0xa7,
37 };
38 
39 enum reg2i14_op {
40 	ldptrd_op	= 0x26,
41 	stptrd_op	= 0x27,
42 };
43 
44 enum reg2i16_op {
45 	jirl_op		= 0x13,
46 	beq_op		= 0x16,
47 	bne_op		= 0x17,
48 	blt_op		= 0x18,
49 	bge_op		= 0x19,
50 	bltu_op		= 0x1a,
51 	bgeu_op		= 0x1b,
52 };
53 
54 enum reg3_op {
55 	amswapw_op	= 0x70c0,
56 };
57 
58 struct reg0i15_format {
59 	unsigned int immediate : 15;
60 	unsigned int opcode : 17;
61 };
62 
63 struct reg0i26_format {
64 	unsigned int immediate_h : 10;
65 	unsigned int immediate_l : 16;
66 	unsigned int opcode : 6;
67 };
68 
69 struct reg1i21_format {
70 	unsigned int immediate_h  : 5;
71 	unsigned int rj : 5;
72 	unsigned int immediate_l : 16;
73 	unsigned int opcode : 6;
74 };
75 
76 struct reg2_format {
77 	unsigned int rd : 5;
78 	unsigned int rj : 5;
79 	unsigned int opcode : 22;
80 };
81 
82 struct reg2i12_format {
83 	unsigned int rd : 5;
84 	unsigned int rj : 5;
85 	unsigned int immediate : 12;
86 	unsigned int opcode : 10;
87 };
88 
89 struct reg2i14_format {
90 	unsigned int rd : 5;
91 	unsigned int rj : 5;
92 	unsigned int immediate : 14;
93 	unsigned int opcode : 8;
94 };
95 
96 struct reg2i16_format {
97 	unsigned int rd : 5;
98 	unsigned int rj : 5;
99 	unsigned int immediate : 16;
100 	unsigned int opcode : 6;
101 };
102 
103 struct reg3_format {
104 	unsigned int rd : 5;
105 	unsigned int rj : 5;
106 	unsigned int rk : 5;
107 	unsigned int opcode : 17;
108 };
109 
110 union loongarch_instruction {
111 	unsigned int word;
112 	struct reg0i15_format	reg0i15_format;
113 	struct reg0i26_format	reg0i26_format;
114 	struct reg1i21_format	reg1i21_format;
115 	struct reg2_format	reg2_format;
116 	struct reg2i12_format	reg2i12_format;
117 	struct reg2i14_format	reg2i14_format;
118 	struct reg2i16_format	reg2i16_format;
119 	struct reg3_format	reg3_format;
120 };
121 
122 #define LOONGARCH_INSN_SIZE	sizeof(union loongarch_instruction)
123 
124 enum loongarch_gpr {
125 	LOONGARCH_GPR_ZERO = 0,
126 	LOONGARCH_GPR_RA = 1,
127 	LOONGARCH_GPR_TP = 2,
128 	LOONGARCH_GPR_SP = 3,
129 	LOONGARCH_GPR_A0 = 4,	/* Reused as V0 for return value */
130 	LOONGARCH_GPR_A1,	/* Reused as V1 for return value */
131 	LOONGARCH_GPR_A2,
132 	LOONGARCH_GPR_A3,
133 	LOONGARCH_GPR_A4,
134 	LOONGARCH_GPR_A5,
135 	LOONGARCH_GPR_A6,
136 	LOONGARCH_GPR_A7,
137 	LOONGARCH_GPR_T0 = 12,
138 	LOONGARCH_GPR_T1,
139 	LOONGARCH_GPR_T2,
140 	LOONGARCH_GPR_T3,
141 	LOONGARCH_GPR_T4,
142 	LOONGARCH_GPR_T5,
143 	LOONGARCH_GPR_T6,
144 	LOONGARCH_GPR_T7,
145 	LOONGARCH_GPR_T8,
146 	LOONGARCH_GPR_FP = 22,
147 	LOONGARCH_GPR_S0 = 23,
148 	LOONGARCH_GPR_S1,
149 	LOONGARCH_GPR_S2,
150 	LOONGARCH_GPR_S3,
151 	LOONGARCH_GPR_S4,
152 	LOONGARCH_GPR_S5,
153 	LOONGARCH_GPR_S6,
154 	LOONGARCH_GPR_S7,
155 	LOONGARCH_GPR_S8,
156 	LOONGARCH_GPR_MAX
157 };
158 
159 #define DEF_EMIT_REG2I16_FORMAT(NAME, OP)				\
160 static inline void emit_##NAME(union loongarch_instruction *insn,	\
161 			       enum loongarch_gpr rj,			\
162 			       enum loongarch_gpr rd,			\
163 			       int offset)				\
164 {									\
165 	insn->reg2i16_format.opcode = OP;				\
166 	insn->reg2i16_format.immediate = offset;			\
167 	insn->reg2i16_format.rj = rj;					\
168 	insn->reg2i16_format.rd = rd;					\
169 }
170 
171 DEF_EMIT_REG2I16_FORMAT(jirl, jirl_op)
172 
173 #endif /* _ASM_INST_H */
174