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