xref: /linux/arch/loongarch/include/asm/asm.h (revision b61104e7a6349bd2c2b3e2fb3260d87f15eda8f4)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Some useful macros for LoongArch assembler code
4  *
5  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
6  *
7  * Derived from MIPS:
8  * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
9  * Copyright (C) 1999 by Silicon Graphics, Inc.
10  * Copyright (C) 2001 MIPS Technologies, Inc.
11  * Copyright (C) 2002  Maciej W. Rozycki
12  */
13 #ifndef __ASM_ASM_H
14 #define __ASM_ASM_H
15 
16 /* LoongArch pref instruction. */
17 #ifdef CONFIG_CPU_HAS_PREFETCH
18 
19 #define PREF(hint, addr, offs)				\
20 		preld	hint, addr, offs;		\
21 
22 #define PREFX(hint, addr, index)			\
23 		preldx	hint, addr, index;		\
24 
25 #else /* !CONFIG_CPU_HAS_PREFETCH */
26 
27 #define PREF(hint, addr, offs)
28 #define PREFX(hint, addr, index)
29 
30 #endif /* !CONFIG_CPU_HAS_PREFETCH */
31 
32 /*
33  * Stack alignment
34  */
35 #define STACK_ALIGN	~(0xf)
36 
37 /*
38  * Macros to handle different pointer/register sizes for 32/64-bit code
39  */
40 
41 /*
42  * Size of a register
43  */
44 #ifndef __loongarch64
45 #define SZREG	4
46 #else
47 #define SZREG	8
48 #endif
49 
50 /*
51  * Use the following macros in assemblercode to load/store registers,
52  * pointers etc.
53  */
54 #if (SZREG == 4)
55 #define REG_L		ld.w
56 #define REG_S		st.w
57 #define REG_ADD		add.w
58 #define REG_SUB		sub.w
59 #else /* SZREG == 8 */
60 #define REG_L		ld.d
61 #define REG_S		st.d
62 #define REG_ADD		add.d
63 #define REG_SUB		sub.d
64 #endif
65 
66 /*
67  * How to add/sub/load/store/shift C int variables.
68  */
69 #if (__SIZEOF_INT__ == 4)
70 #define INT_ADD		add.w
71 #define INT_ADDI	addi.w
72 #define INT_SUB		sub.w
73 #define INT_L		ld.w
74 #define INT_S		st.w
75 #define INT_SLLI	slli.w
76 #define INT_SLLV	sll.w
77 #define INT_SRLI	srli.w
78 #define INT_SRLV	srl.w
79 #define INT_SRAI	srai.w
80 #define INT_SRAV	sra.w
81 #endif
82 
83 #if (__SIZEOF_INT__ == 8)
84 #define INT_ADD		add.d
85 #define INT_ADDI	addi.d
86 #define INT_SUB		sub.d
87 #define INT_L		ld.d
88 #define INT_S		st.d
89 #define INT_SLLI	slli.d
90 #define INT_SLLV	sll.d
91 #define INT_SRLI	srli.d
92 #define INT_SRLV	srl.d
93 #define INT_SRAI	srai.d
94 #define INT_SRAV	sra.d
95 #endif
96 
97 /*
98  * How to add/sub/load/store/shift C long variables.
99  */
100 #if (__SIZEOF_LONG__ == 4)
101 #define LONG_ADD	add.w
102 #define LONG_ADDI	addi.w
103 #define LONG_ALSL	alsl.w
104 #define LONG_BSTRINS	bstrins.w
105 #define LONG_BSTRPICK	bstrpick.w
106 #define LONG_SUB	sub.w
107 #define LONG_L		ld.w
108 #define LONG_LI		li.w
109 #define LONG_LPTR	ld.w
110 #define LONG_S		st.w
111 #define LONG_SPTR	st.w
112 #define LONG_SLLI	slli.w
113 #define LONG_SLLV	sll.w
114 #define LONG_SRLI	srli.w
115 #define LONG_SRLV	srl.w
116 #define LONG_SRAI	srai.w
117 #define LONG_SRAV	sra.w
118 #define LONG_ROTR	rotr.w
119 #define LONG_ROTRI	rotri.w
120 
121 #ifdef __ASSEMBLER__
122 #define LONG		.word
123 #endif
124 #define LONGSIZE	4
125 #define LONGMASK	3
126 #define LONGLOG		2
127 #endif
128 
129 #if (__SIZEOF_LONG__ == 8)
130 #define LONG_ADD	add.d
131 #define LONG_ADDI	addi.d
132 #define LONG_ALSL	alsl.d
133 #define LONG_BSTRINS	bstrins.d
134 #define LONG_BSTRPICK	bstrpick.d
135 #define LONG_SUB	sub.d
136 #define LONG_L		ld.d
137 #define LONG_LI		li.d
138 #define LONG_LPTR	ldptr.d
139 #define LONG_S		st.d
140 #define LONG_SPTR	stptr.d
141 #define LONG_SLLI	slli.d
142 #define LONG_SLLV	sll.d
143 #define LONG_SRLI	srli.d
144 #define LONG_SRLV	srl.d
145 #define LONG_SRAI	srai.d
146 #define LONG_SRAV	sra.d
147 #define LONG_ROTR	rotr.d
148 #define LONG_ROTRI	rotri.d
149 
150 #ifdef __ASSEMBLER__
151 #define LONG		.dword
152 #endif
153 #define LONGSIZE	8
154 #define LONGMASK	7
155 #define LONGLOG		3
156 #endif
157 
158 /*
159  * How to add/sub/load/store/shift pointers.
160  */
161 #if (__SIZEOF_POINTER__ == 4)
162 #define PTR_ADD		add.w
163 #define PTR_ADDI	addi.w
164 #define PTR_ALSL	alsl.w
165 #define PTR_BSTRINS	bstrins.w
166 #define PTR_BSTRPICK	bstrpick.w
167 #define PTR_SUB		sub.w
168 #define PTR_L		ld.w
169 #define PTR_LI		li.w
170 #define PTR_LPTR	ld.w
171 #define PTR_S		st.w
172 #define PTR_SPTR	st.w
173 #define PTR_SLLI	slli.w
174 #define PTR_SLLV	sll.w
175 #define PTR_SRLI	srli.w
176 #define PTR_SRLV	srl.w
177 #define PTR_SRAI	srai.w
178 #define PTR_SRAV	sra.w
179 #define PTR_ROTR	rotr.w
180 #define PTR_ROTRI	rotri.w
181 
182 #define PTR_SCALESHIFT	2
183 
184 #ifdef __ASSEMBLER__
185 #define PTR		.word
186 #endif
187 #define PTRSIZE		4
188 #define PTRLOG		2
189 #endif
190 
191 #if (__SIZEOF_POINTER__ == 8)
192 #define PTR_ADD		add.d
193 #define PTR_ADDI	addi.d
194 #define PTR_ALSL	alsl.d
195 #define PTR_BSTRINS	bstrins.d
196 #define PTR_BSTRPICK	bstrpick.d
197 #define PTR_SUB		sub.d
198 #define PTR_L		ld.d
199 #define PTR_LI		li.d
200 #define PTR_LPTR	ldptr.d
201 #define PTR_S		st.d
202 #define PTR_SPTR	stptr.d
203 #define PTR_SLLI	slli.d
204 #define PTR_SLLV	sll.d
205 #define PTR_SRLI	srli.d
206 #define PTR_SRLV	srl.d
207 #define PTR_SRAI	srai.d
208 #define PTR_SRAV	sra.d
209 #define PTR_ROTR	rotr.d
210 #define PTR_ROTRI	rotri.d
211 
212 #define PTR_SCALESHIFT	3
213 
214 #ifdef __ASSEMBLER__
215 #define PTR		.dword
216 #endif
217 #define PTRSIZE		8
218 #define PTRLOG		3
219 #endif
220 
221 /* Annotate a function as being unsuitable for kprobes. */
222 #ifdef CONFIG_KPROBES
223 #ifdef CONFIG_32BIT
224 #define _ASM_NOKPROBE(name)				\
225 	.pushsection "_kprobe_blacklist", "aw";		\
226 	.long	name;					\
227 	.popsection
228 #else
229 #define _ASM_NOKPROBE(name)				\
230 	.pushsection "_kprobe_blacklist", "aw";		\
231 	.quad	name;					\
232 	.popsection
233 #endif
234 #else
235 #define _ASM_NOKPROBE(name)
236 #endif
237 
238 #endif /* __ASM_ASM_H */
239