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