xref: /linux/arch/nios2/include/asm/asm-macros.h (revision a4eb44a6435d6d8f9e642407a4a06f65eb90ca04)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Macro used to simplify coding multi-line assembler.
4  * Some of the bit test macro can simplify down to one line
5  * depending on the mask value.
6  *
7  * Copyright (C) 2004 Microtronix Datacom Ltd.
8  *
9  * All rights reserved.
10  */
11 #ifndef _ASM_NIOS2_ASMMACROS_H
12 #define _ASM_NIOS2_ASMMACROS_H
13 /*
14  * ANDs reg2 with mask and places the result in reg1.
15  *
16  * You cannnot use the same register for reg1 & reg2.
17  */
18 
19 .macro ANDI32	reg1, reg2, mask
20 .if \mask & 0xffff
21 	.if \mask & 0xffff0000
22 		movhi	\reg1, %hi(\mask)
23 		movui	\reg1, %lo(\mask)
24 		and	\reg1, \reg1, \reg2
25 	.else
26 		andi	\reg1, \reg2, %lo(\mask)
27 	.endif
28 .else
29 	andhi	\reg1, \reg2, %hi(\mask)
30 .endif
31 .endm
32 
33 /*
34  * ORs reg2 with mask and places the result in reg1.
35  *
36  * It is safe to use the same register for reg1 & reg2.
37  */
38 
39 .macro ORI32	reg1, reg2, mask
40 .if \mask & 0xffff
41 	.if \mask & 0xffff0000
42 		orhi	\reg1, \reg2, %hi(\mask)
43 		ori	\reg1, \reg2, %lo(\mask)
44 	.else
45 		ori	\reg1, \reg2, %lo(\mask)
46 	.endif
47 .else
48 	orhi	\reg1, \reg2, %hi(\mask)
49 .endif
50 .endm
51 
52 /*
53  * XORs reg2 with mask and places the result in reg1.
54  *
55  * It is safe to use the same register for reg1 & reg2.
56  */
57 
58 .macro XORI32	reg1, reg2, mask
59 .if \mask & 0xffff
60 	.if \mask & 0xffff0000
61 		xorhi	\reg1, \reg2, %hi(\mask)
62 		xori	\reg1, \reg1, %lo(\mask)
63 	.else
64 		xori	\reg1, \reg2, %lo(\mask)
65 	.endif
66 .else
67 	xorhi	\reg1, \reg2, %hi(\mask)
68 .endif
69 .endm
70 
71 /*
72  * This is a support macro for BTBZ & BTBNZ.  It checks
73  * the bit to make sure it is valid 32 value.
74  *
75  * It is safe to use the same register for reg1 & reg2.
76  */
77 
78 .macro BT	reg1, reg2, bit
79 .if \bit > 31
80 	.err
81 .else
82 	.if \bit < 16
83 		andi	\reg1, \reg2, (1 << \bit)
84 	.else
85 		andhi	\reg1, \reg2, (1 << (\bit - 16))
86 	.endif
87 .endif
88 .endm
89 
90 /*
91  * Tests the bit in reg2 and branches to label if the
92  * bit is zero.  The result of the bit test is stored in reg1.
93  *
94  * It is safe to use the same register for reg1 & reg2.
95  */
96 
97 .macro BTBZ	reg1, reg2, bit, label
98 	BT	\reg1, \reg2, \bit
99 	beq	\reg1, r0, \label
100 .endm
101 
102 /*
103  * Tests the bit in reg2 and branches to label if the
104  * bit is non-zero.  The result of the bit test is stored in reg1.
105  *
106  * It is safe to use the same register for reg1 & reg2.
107  */
108 
109 .macro BTBNZ	reg1, reg2, bit, label
110 	BT	\reg1, \reg2, \bit
111 	bne	\reg1, r0, \label
112 .endm
113 
114 /*
115  * Tests the bit in reg2 and then compliments the bit in reg2.
116  * The result of the bit test is stored in reg1.
117  *
118  * It is NOT safe to use the same register for reg1 & reg2.
119  */
120 
121 .macro BTC	reg1, reg2, bit
122 .if \bit > 31
123 	.err
124 .else
125 	.if \bit < 16
126 		andi	\reg1, \reg2, (1 << \bit)
127 		xori	\reg2, \reg2, (1 << \bit)
128 	.else
129 		andhi	\reg1, \reg2, (1 << (\bit - 16))
130 		xorhi	\reg2, \reg2, (1 << (\bit - 16))
131 	.endif
132 .endif
133 .endm
134 
135 /*
136  * Tests the bit in reg2 and then sets the bit in reg2.
137  * The result of the bit test is stored in reg1.
138  *
139  * It is NOT safe to use the same register for reg1 & reg2.
140  */
141 
142 .macro BTS	reg1, reg2, bit
143 .if \bit > 31
144 	.err
145 .else
146 	.if \bit < 16
147 		andi	\reg1, \reg2, (1 << \bit)
148 		ori	\reg2, \reg2, (1 << \bit)
149 	.else
150 		andhi	\reg1, \reg2, (1 << (\bit - 16))
151 		orhi	\reg2, \reg2, (1 << (\bit - 16))
152 	.endif
153 .endif
154 .endm
155 
156 /*
157  * Tests the bit in reg2 and then resets the bit in reg2.
158  * The result of the bit test is stored in reg1.
159  *
160  * It is NOT safe to use the same register for reg1 & reg2.
161  */
162 
163 .macro BTR	reg1, reg2, bit
164 .if \bit > 31
165 	.err
166 .else
167 	.if \bit < 16
168 		andi	\reg1, \reg2, (1 << \bit)
169 		andi	\reg2, \reg2, %lo(~(1 << \bit))
170 	.else
171 		andhi	\reg1, \reg2, (1 << (\bit - 16))
172 		andhi	\reg2, \reg2, %lo(~(1 << (\bit - 16)))
173 	.endif
174 .endif
175 .endm
176 
177 /*
178  * Tests the bit in reg2 and then compliments the bit in reg2.
179  * The result of the bit test is stored in reg1.  If the
180  * original bit was zero it branches to label.
181  *
182  * It is NOT safe to use the same register for reg1 & reg2.
183  */
184 
185 .macro BTCBZ	reg1, reg2, bit, label
186 	BTC	\reg1, \reg2, \bit
187 	beq	\reg1, r0, \label
188 .endm
189 
190 /*
191  * Tests the bit in reg2 and then compliments the bit in reg2.
192  * The result of the bit test is stored in reg1.  If the
193  * original bit was non-zero it branches to label.
194  *
195  * It is NOT safe to use the same register for reg1 & reg2.
196  */
197 
198 .macro BTCBNZ	reg1, reg2, bit, label
199 	BTC	\reg1, \reg2, \bit
200 	bne	\reg1, r0, \label
201 .endm
202 
203 /*
204  * Tests the bit in reg2 and then sets the bit in reg2.
205  * The result of the bit test is stored in reg1.  If the
206  * original bit was zero it branches to label.
207  *
208  * It is NOT safe to use the same register for reg1 & reg2.
209  */
210 
211 .macro BTSBZ	reg1, reg2, bit, label
212 	BTS	\reg1, \reg2, \bit
213 	beq	\reg1, r0, \label
214 .endm
215 
216 /*
217  * Tests the bit in reg2 and then sets the bit in reg2.
218  * The result of the bit test is stored in reg1.  If the
219  * original bit was non-zero it branches to label.
220  *
221  * It is NOT safe to use the same register for reg1 & reg2.
222  */
223 
224 .macro BTSBNZ	reg1, reg2, bit, label
225 	BTS	\reg1, \reg2, \bit
226 	bne	\reg1, r0, \label
227 .endm
228 
229 /*
230  * Tests the bit in reg2 and then resets the bit in reg2.
231  * The result of the bit test is stored in reg1.  If the
232  * original bit was zero it branches to label.
233  *
234  * It is NOT safe to use the same register for reg1 & reg2.
235  */
236 
237 .macro BTRBZ	reg1, reg2, bit, label
238 	BTR	\reg1, \reg2, \bit
239 	bne	\reg1, r0, \label
240 .endm
241 
242 /*
243  * Tests the bit in reg2 and then resets the bit in reg2.
244  * The result of the bit test is stored in reg1.  If the
245  * original bit was non-zero it branches to label.
246  *
247  * It is NOT safe to use the same register for reg1 & reg2.
248  */
249 
250 .macro BTRBNZ	reg1, reg2, bit, label
251 	BTR	\reg1, \reg2, \bit
252 	bne	\reg1, r0, \label
253 .endm
254 
255 /*
256  * Tests the bits in mask against reg2 stores the result in reg1.
257  * If the all the bits in the mask are zero it branches to label.
258  *
259  * It is safe to use the same register for reg1 & reg2.
260  */
261 
262 .macro TSTBZ	reg1, reg2, mask, label
263 	ANDI32	\reg1, \reg2, \mask
264 	beq	\reg1, r0, \label
265 .endm
266 
267 /*
268  * Tests the bits in mask against reg2 stores the result in reg1.
269  * If the any of the bits in the mask are 1 it branches to label.
270  *
271  * It is safe to use the same register for reg1 & reg2.
272  */
273 
274 .macro TSTBNZ	reg1, reg2, mask, label
275 	ANDI32	\reg1, \reg2, \mask
276 	bne	\reg1, r0, \label
277 .endm
278 
279 /*
280  * Pushes reg onto the stack.
281  */
282 
283 .macro PUSH	reg
284 	addi	sp, sp, -4
285 	stw	\reg, 0(sp)
286 .endm
287 
288 /*
289  * Pops the top of the stack into reg.
290  */
291 
292 .macro POP	reg
293 	ldw	\reg, 0(sp)
294 	addi	sp, sp, 4
295 .endm
296 
297 
298 #endif /* _ASM_NIOS2_ASMMACROS_H */
299