summaryrefslogtreecommitdiffstats
path: root/arch/riscv/include/asm/insn-def.h
blob: 16044affa57cc7e6d30e8d068ebffa6bf87e7729 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __ASM_INSN_DEF_H
#define __ASM_INSN_DEF_H

#include <asm/asm.h>

#define INSN_R_FUNC7_SHIFT		25
#define INSN_R_RS2_SHIFT		20
#define INSN_R_RS1_SHIFT		15
#define INSN_R_FUNC3_SHIFT		12
#define INSN_R_RD_SHIFT			 7
#define INSN_R_OPCODE_SHIFT		 0

#ifdef __ASSEMBLY__

#ifdef CONFIG_AS_HAS_INSN

	.macro insn_r, opcode, func3, func7, rd, rs1, rs2
	.insn	r \opcode, \func3, \func7, \rd, \rs1, \rs2
	.endm

#else

#include <asm/gpr-num.h>

	.macro insn_r, opcode, func3, func7, rd, rs1, rs2
	.4byte	((\opcode << INSN_R_OPCODE_SHIFT) |		\
		 (\func3 << INSN_R_FUNC3_SHIFT) |		\
		 (\func7 << INSN_R_FUNC7_SHIFT) |		\
		 (.L__gpr_num_\rd << INSN_R_RD_SHIFT) |		\
		 (.L__gpr_num_\rs1 << INSN_R_RS1_SHIFT) |	\
		 (.L__gpr_num_\rs2 << INSN_R_RS2_SHIFT))
	.endm

#endif

#define __INSN_R(...)	insn_r __VA_ARGS__

#else /* ! __ASSEMBLY__ */

#ifdef CONFIG_AS_HAS_INSN

#define __INSN_R(opcode, func3, func7, rd, rs1, rs2)	\
	".insn	r " opcode ", " func3 ", " func7 ", " rd ", " rs1 ", " rs2 "\n"

#else

#include <linux/stringify.h>
#include <asm/gpr-num.h>

#define DEFINE_INSN_R							\
	__DEFINE_ASM_GPR_NUMS						\
"	.macro insn_r, opcode, func3, func7, rd, rs1, rs2\n"		\
"	.4byte	((\\opcode << " __stringify(INSN_R_OPCODE_SHIFT) ") |"	\
"		 (\\func3 << " __stringify(INSN_R_FUNC3_SHIFT) ") |"	\
"		 (\\func7 << " __stringify(INSN_R_FUNC7_SHIFT) ") |"	\
"		 (.L__gpr_num_\\rd << " __stringify(INSN_R_RD_SHIFT) ") |"    \
"		 (.L__gpr_num_\\rs1 << " __stringify(INSN_R_RS1_SHIFT) ") |"  \
"		 (.L__gpr_num_\\rs2 << " __stringify(INSN_R_RS2_SHIFT) "))\n" \
"	.endm\n"

#define UNDEFINE_INSN_R							\
"	.purgem insn_r\n"

#define __INSN_R(opcode, func3, func7, rd, rs1, rs2)			\
	DEFINE_INSN_R							\
	"insn_r " opcode ", " func3 ", " func7 ", " rd ", " rs1 ", " rs2 "\n" \
	UNDEFINE_INSN_R

#endif

#endif /* ! __ASSEMBLY__ */

#define INSN_R(opcode, func3, func7, rd, rs1, rs2)		\
	__INSN_R(RV_##opcode, RV_##func3, RV_##func7,		\
		 RV_##rd, RV_##rs1, RV_##rs2)

#define RV_OPCODE(v)		__ASM_STR(v)
#define RV_FUNC3(v)		__ASM_STR(v)
#define RV_FUNC7(v)		__ASM_STR(v)
#define RV_RD(v)		__ASM_STR(v)
#define RV_RS1(v)		__ASM_STR(v)
#define RV_RS2(v)		__ASM_STR(v)
#define __RV_REG(v)		__ASM_STR(x ## v)
#define RV___RD(v)		__RV_REG(v)
#define RV___RS1(v)		__RV_REG(v)
#define RV___RS2(v)		__RV_REG(v)

#define RV_OPCODE_SYSTEM	RV_OPCODE(115)

#define HFENCE_VVMA(vaddr, asid)				\
	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(17),		\
	       __RD(0), RS1(vaddr), RS2(asid))

#define HFENCE_GVMA(gaddr, vmid)				\
	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(49),		\
	       __RD(0), RS1(gaddr), RS2(vmid))

#define HLVX_HU(dest, addr)					\
	INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(50),		\
	       RD(dest), RS1(addr), __RS2(3))

#define HLV_W(dest, addr)					\
	INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(52),		\
	       RD(dest), RS1(addr), __RS2(0))

#ifdef CONFIG_64BIT
#define HLV_D(dest, addr)					\
	INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(54),		\
	       RD(dest), RS1(addr), __RS2(0))
#else
#define HLV_D(dest, addr)					\
	__ASM_STR(.error "hlv.d requires 64-bit support")
#endif

#define SINVAL_VMA(vaddr, asid)					\
	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(11),		\
	       __RD(0), RS1(vaddr), RS2(asid))

#define SFENCE_W_INVAL()					\
	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(12),		\
	       __RD(0), __RS1(0), __RS2(0))

#define SFENCE_INVAL_IR()					\
	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(12),		\
	       __RD(0), __RS1(0), __RS2(1))

#define HINVAL_VVMA(vaddr, asid)				\
	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(19),		\
	       __RD(0), RS1(vaddr), RS2(asid))

#define HINVAL_GVMA(gaddr, vmid)				\
	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(51),		\
	       __RD(0), RS1(gaddr), RS2(vmid))

#endif /* __ASM_INSN_DEF_H */