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