GNU Linux-libre 6.7.9-gnu
[releases.git] / arch / nios2 / include / asm / asm-macros.h
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 */