xref: /linux/arch/riscv/include/asm/insn-def.h (revision f9bff0e31881d03badf191d3b0005839391f5f2b)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef __ASM_INSN_DEF_H
4 #define __ASM_INSN_DEF_H
5 
6 #include <asm/asm.h>
7 
8 #define INSN_R_FUNC7_SHIFT		25
9 #define INSN_R_RS2_SHIFT		20
10 #define INSN_R_RS1_SHIFT		15
11 #define INSN_R_FUNC3_SHIFT		12
12 #define INSN_R_RD_SHIFT			 7
13 #define INSN_R_OPCODE_SHIFT		 0
14 
15 #define INSN_I_SIMM12_SHIFT		20
16 #define INSN_I_RS1_SHIFT		15
17 #define INSN_I_FUNC3_SHIFT		12
18 #define INSN_I_RD_SHIFT			 7
19 #define INSN_I_OPCODE_SHIFT		 0
20 
21 #ifdef __ASSEMBLY__
22 
23 #ifdef CONFIG_AS_HAS_INSN
24 
25 	.macro insn_r, opcode, func3, func7, rd, rs1, rs2
26 	.insn	r \opcode, \func3, \func7, \rd, \rs1, \rs2
27 	.endm
28 
29 	.macro insn_i, opcode, func3, rd, rs1, simm12
30 	.insn	i \opcode, \func3, \rd, \rs1, \simm12
31 	.endm
32 
33 #else
34 
35 #include <asm/gpr-num.h>
36 
37 	.macro insn_r, opcode, func3, func7, rd, rs1, rs2
38 	.4byte	((\opcode << INSN_R_OPCODE_SHIFT) |		\
39 		 (\func3 << INSN_R_FUNC3_SHIFT) |		\
40 		 (\func7 << INSN_R_FUNC7_SHIFT) |		\
41 		 (.L__gpr_num_\rd << INSN_R_RD_SHIFT) |		\
42 		 (.L__gpr_num_\rs1 << INSN_R_RS1_SHIFT) |	\
43 		 (.L__gpr_num_\rs2 << INSN_R_RS2_SHIFT))
44 	.endm
45 
46 	.macro insn_i, opcode, func3, rd, rs1, simm12
47 	.4byte	((\opcode << INSN_I_OPCODE_SHIFT) |		\
48 		 (\func3 << INSN_I_FUNC3_SHIFT) |		\
49 		 (.L__gpr_num_\rd << INSN_I_RD_SHIFT) |		\
50 		 (.L__gpr_num_\rs1 << INSN_I_RS1_SHIFT) |	\
51 		 (\simm12 << INSN_I_SIMM12_SHIFT))
52 	.endm
53 
54 #endif
55 
56 #define __INSN_R(...)	insn_r __VA_ARGS__
57 #define __INSN_I(...)	insn_i __VA_ARGS__
58 
59 #else /* ! __ASSEMBLY__ */
60 
61 #ifdef CONFIG_AS_HAS_INSN
62 
63 #define __INSN_R(opcode, func3, func7, rd, rs1, rs2)	\
64 	".insn	r " opcode ", " func3 ", " func7 ", " rd ", " rs1 ", " rs2 "\n"
65 
66 #define __INSN_I(opcode, func3, rd, rs1, simm12)	\
67 	".insn	i " opcode ", " func3 ", " rd ", " rs1 ", " simm12 "\n"
68 
69 #else
70 
71 #include <linux/stringify.h>
72 #include <asm/gpr-num.h>
73 
74 #define DEFINE_INSN_R							\
75 	__DEFINE_ASM_GPR_NUMS						\
76 "	.macro insn_r, opcode, func3, func7, rd, rs1, rs2\n"		\
77 "	.4byte	((\\opcode << " __stringify(INSN_R_OPCODE_SHIFT) ") |"	\
78 "		 (\\func3 << " __stringify(INSN_R_FUNC3_SHIFT) ") |"	\
79 "		 (\\func7 << " __stringify(INSN_R_FUNC7_SHIFT) ") |"	\
80 "		 (.L__gpr_num_\\rd << " __stringify(INSN_R_RD_SHIFT) ") |"    \
81 "		 (.L__gpr_num_\\rs1 << " __stringify(INSN_R_RS1_SHIFT) ") |"  \
82 "		 (.L__gpr_num_\\rs2 << " __stringify(INSN_R_RS2_SHIFT) "))\n" \
83 "	.endm\n"
84 
85 #define DEFINE_INSN_I							\
86 	__DEFINE_ASM_GPR_NUMS						\
87 "	.macro insn_i, opcode, func3, rd, rs1, simm12\n"		\
88 "	.4byte	((\\opcode << " __stringify(INSN_I_OPCODE_SHIFT) ") |"	\
89 "		 (\\func3 << " __stringify(INSN_I_FUNC3_SHIFT) ") |"	\
90 "		 (.L__gpr_num_\\rd << " __stringify(INSN_I_RD_SHIFT) ") |"   \
91 "		 (.L__gpr_num_\\rs1 << " __stringify(INSN_I_RS1_SHIFT) ") |" \
92 "		 (\\simm12 << " __stringify(INSN_I_SIMM12_SHIFT) "))\n"	\
93 "	.endm\n"
94 
95 #define UNDEFINE_INSN_R							\
96 "	.purgem insn_r\n"
97 
98 #define UNDEFINE_INSN_I							\
99 "	.purgem insn_i\n"
100 
101 #define __INSN_R(opcode, func3, func7, rd, rs1, rs2)			\
102 	DEFINE_INSN_R							\
103 	"insn_r " opcode ", " func3 ", " func7 ", " rd ", " rs1 ", " rs2 "\n" \
104 	UNDEFINE_INSN_R
105 
106 #define __INSN_I(opcode, func3, rd, rs1, simm12)			\
107 	DEFINE_INSN_I							\
108 	"insn_i " opcode ", " func3 ", " rd ", " rs1 ", " simm12 "\n" \
109 	UNDEFINE_INSN_I
110 
111 #endif
112 
113 #endif /* ! __ASSEMBLY__ */
114 
115 #define INSN_R(opcode, func3, func7, rd, rs1, rs2)		\
116 	__INSN_R(RV_##opcode, RV_##func3, RV_##func7,		\
117 		 RV_##rd, RV_##rs1, RV_##rs2)
118 
119 #define INSN_I(opcode, func3, rd, rs1, simm12)			\
120 	__INSN_I(RV_##opcode, RV_##func3, RV_##rd,		\
121 		 RV_##rs1, RV_##simm12)
122 
123 #define RV_OPCODE(v)		__ASM_STR(v)
124 #define RV_FUNC3(v)		__ASM_STR(v)
125 #define RV_FUNC7(v)		__ASM_STR(v)
126 #define RV_SIMM12(v)		__ASM_STR(v)
127 #define RV_RD(v)		__ASM_STR(v)
128 #define RV_RS1(v)		__ASM_STR(v)
129 #define RV_RS2(v)		__ASM_STR(v)
130 #define __RV_REG(v)		__ASM_STR(x ## v)
131 #define RV___RD(v)		__RV_REG(v)
132 #define RV___RS1(v)		__RV_REG(v)
133 #define RV___RS2(v)		__RV_REG(v)
134 
135 #define RV_OPCODE_MISC_MEM	RV_OPCODE(15)
136 #define RV_OPCODE_SYSTEM	RV_OPCODE(115)
137 
138 #define HFENCE_VVMA(vaddr, asid)				\
139 	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(17),		\
140 	       __RD(0), RS1(vaddr), RS2(asid))
141 
142 #define HFENCE_GVMA(gaddr, vmid)				\
143 	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(49),		\
144 	       __RD(0), RS1(gaddr), RS2(vmid))
145 
146 #define HLVX_HU(dest, addr)					\
147 	INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(50),		\
148 	       RD(dest), RS1(addr), __RS2(3))
149 
150 #define HLV_W(dest, addr)					\
151 	INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(52),		\
152 	       RD(dest), RS1(addr), __RS2(0))
153 
154 #ifdef CONFIG_64BIT
155 #define HLV_D(dest, addr)					\
156 	INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(54),		\
157 	       RD(dest), RS1(addr), __RS2(0))
158 #else
159 #define HLV_D(dest, addr)					\
160 	__ASM_STR(.error "hlv.d requires 64-bit support")
161 #endif
162 
163 #define SINVAL_VMA(vaddr, asid)					\
164 	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(11),		\
165 	       __RD(0), RS1(vaddr), RS2(asid))
166 
167 #define SFENCE_W_INVAL()					\
168 	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(12),		\
169 	       __RD(0), __RS1(0), __RS2(0))
170 
171 #define SFENCE_INVAL_IR()					\
172 	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(12),		\
173 	       __RD(0), __RS1(0), __RS2(1))
174 
175 #define HINVAL_VVMA(vaddr, asid)				\
176 	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(19),		\
177 	       __RD(0), RS1(vaddr), RS2(asid))
178 
179 #define HINVAL_GVMA(gaddr, vmid)				\
180 	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(51),		\
181 	       __RD(0), RS1(gaddr), RS2(vmid))
182 
183 #define CBO_inval(base)						\
184 	INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0),		\
185 	       RS1(base), SIMM12(0))
186 
187 #define CBO_clean(base)						\
188 	INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0),		\
189 	       RS1(base), SIMM12(1))
190 
191 #define CBO_flush(base)						\
192 	INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0),		\
193 	       RS1(base), SIMM12(2))
194 
195 #define CBO_zero(base)						\
196 	INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0),		\
197 	       RS1(base), SIMM12(4))
198 
199 #endif /* __ASM_INSN_DEF_H */
200