xref: /linux/arch/nios2/include/asm/asm-macros.h (revision 58e16d792a6a8c6b750f637a4649967fcac853dc)
1*4359375cSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
239b505cbSLey Foon Tan /*
339b505cbSLey Foon Tan  * Macro used to simplify coding multi-line assembler.
439b505cbSLey Foon Tan  * Some of the bit test macro can simplify down to one line
539b505cbSLey Foon Tan  * depending on the mask value.
639b505cbSLey Foon Tan  *
739b505cbSLey Foon Tan  * Copyright (C) 2004 Microtronix Datacom Ltd.
839b505cbSLey Foon Tan  *
939b505cbSLey Foon Tan  * All rights reserved.
1039b505cbSLey Foon Tan  */
1139b505cbSLey Foon Tan #ifndef _ASM_NIOS2_ASMMACROS_H
1239b505cbSLey Foon Tan #define _ASM_NIOS2_ASMMACROS_H
1339b505cbSLey Foon Tan /*
1439b505cbSLey Foon Tan  * ANDs reg2 with mask and places the result in reg1.
1539b505cbSLey Foon Tan  *
1639b505cbSLey Foon Tan  * You cannnot use the same register for reg1 & reg2.
1739b505cbSLey Foon Tan  */
1839b505cbSLey Foon Tan 
1939b505cbSLey Foon Tan .macro ANDI32	reg1, reg2, mask
2039b505cbSLey Foon Tan .if \mask & 0xffff
2139b505cbSLey Foon Tan 	.if \mask & 0xffff0000
2239b505cbSLey Foon Tan 		movhi	\reg1, %hi(\mask)
2339b505cbSLey Foon Tan 		movui	\reg1, %lo(\mask)
2439b505cbSLey Foon Tan 		and	\reg1, \reg1, \reg2
2539b505cbSLey Foon Tan 	.else
2639b505cbSLey Foon Tan 		andi	\reg1, \reg2, %lo(\mask)
2739b505cbSLey Foon Tan 	.endif
2839b505cbSLey Foon Tan .else
2939b505cbSLey Foon Tan 	andhi	\reg1, \reg2, %hi(\mask)
3039b505cbSLey Foon Tan .endif
3139b505cbSLey Foon Tan .endm
3239b505cbSLey Foon Tan 
3339b505cbSLey Foon Tan /*
3439b505cbSLey Foon Tan  * ORs reg2 with mask and places the result in reg1.
3539b505cbSLey Foon Tan  *
3639b505cbSLey Foon Tan  * It is safe to use the same register for reg1 & reg2.
3739b505cbSLey Foon Tan  */
3839b505cbSLey Foon Tan 
3939b505cbSLey Foon Tan .macro ORI32	reg1, reg2, mask
4039b505cbSLey Foon Tan .if \mask & 0xffff
4139b505cbSLey Foon Tan 	.if \mask & 0xffff0000
4239b505cbSLey Foon Tan 		orhi	\reg1, \reg2, %hi(\mask)
4339b505cbSLey Foon Tan 		ori	\reg1, \reg2, %lo(\mask)
4439b505cbSLey Foon Tan 	.else
4539b505cbSLey Foon Tan 		ori	\reg1, \reg2, %lo(\mask)
4639b505cbSLey Foon Tan 	.endif
4739b505cbSLey Foon Tan .else
4839b505cbSLey Foon Tan 	orhi	\reg1, \reg2, %hi(\mask)
4939b505cbSLey Foon Tan .endif
5039b505cbSLey Foon Tan .endm
5139b505cbSLey Foon Tan 
5239b505cbSLey Foon Tan /*
5339b505cbSLey Foon Tan  * XORs reg2 with mask and places the result in reg1.
5439b505cbSLey Foon Tan  *
5539b505cbSLey Foon Tan  * It is safe to use the same register for reg1 & reg2.
5639b505cbSLey Foon Tan  */
5739b505cbSLey Foon Tan 
5839b505cbSLey Foon Tan .macro XORI32	reg1, reg2, mask
5939b505cbSLey Foon Tan .if \mask & 0xffff
6039b505cbSLey Foon Tan 	.if \mask & 0xffff0000
6139b505cbSLey Foon Tan 		xorhi	\reg1, \reg2, %hi(\mask)
6239b505cbSLey Foon Tan 		xori	\reg1, \reg1, %lo(\mask)
6339b505cbSLey Foon Tan 	.else
6439b505cbSLey Foon Tan 		xori	\reg1, \reg2, %lo(\mask)
6539b505cbSLey Foon Tan 	.endif
6639b505cbSLey Foon Tan .else
6739b505cbSLey Foon Tan 	xorhi	\reg1, \reg2, %hi(\mask)
6839b505cbSLey Foon Tan .endif
6939b505cbSLey Foon Tan .endm
7039b505cbSLey Foon Tan 
7139b505cbSLey Foon Tan /*
7239b505cbSLey Foon Tan  * This is a support macro for BTBZ & BTBNZ.  It checks
7339b505cbSLey Foon Tan  * the bit to make sure it is valid 32 value.
7439b505cbSLey Foon Tan  *
7539b505cbSLey Foon Tan  * It is safe to use the same register for reg1 & reg2.
7639b505cbSLey Foon Tan  */
7739b505cbSLey Foon Tan 
7839b505cbSLey Foon Tan .macro BT	reg1, reg2, bit
7939b505cbSLey Foon Tan .if \bit > 31
8039b505cbSLey Foon Tan 	.err
8139b505cbSLey Foon Tan .else
8239b505cbSLey Foon Tan 	.if \bit < 16
8339b505cbSLey Foon Tan 		andi	\reg1, \reg2, (1 << \bit)
8439b505cbSLey Foon Tan 	.else
8539b505cbSLey Foon Tan 		andhi	\reg1, \reg2, (1 << (\bit - 16))
8639b505cbSLey Foon Tan 	.endif
8739b505cbSLey Foon Tan .endif
8839b505cbSLey Foon Tan .endm
8939b505cbSLey Foon Tan 
9039b505cbSLey Foon Tan /*
9139b505cbSLey Foon Tan  * Tests the bit in reg2 and branches to label if the
9239b505cbSLey Foon Tan  * bit is zero.  The result of the bit test is stored in reg1.
9339b505cbSLey Foon Tan  *
9439b505cbSLey Foon Tan  * It is safe to use the same register for reg1 & reg2.
9539b505cbSLey Foon Tan  */
9639b505cbSLey Foon Tan 
9739b505cbSLey Foon Tan .macro BTBZ	reg1, reg2, bit, label
9839b505cbSLey Foon Tan 	BT	\reg1, \reg2, \bit
9939b505cbSLey Foon Tan 	beq	\reg1, r0, \label
10039b505cbSLey Foon Tan .endm
10139b505cbSLey Foon Tan 
10239b505cbSLey Foon Tan /*
10339b505cbSLey Foon Tan  * Tests the bit in reg2 and branches to label if the
10439b505cbSLey Foon Tan  * bit is non-zero.  The result of the bit test is stored in reg1.
10539b505cbSLey Foon Tan  *
10639b505cbSLey Foon Tan  * It is safe to use the same register for reg1 & reg2.
10739b505cbSLey Foon Tan  */
10839b505cbSLey Foon Tan 
10939b505cbSLey Foon Tan .macro BTBNZ	reg1, reg2, bit, label
11039b505cbSLey Foon Tan 	BT	\reg1, \reg2, \bit
11139b505cbSLey Foon Tan 	bne	\reg1, r0, \label
11239b505cbSLey Foon Tan .endm
11339b505cbSLey Foon Tan 
11439b505cbSLey Foon Tan /*
11539b505cbSLey Foon Tan  * Tests the bit in reg2 and then compliments the bit in reg2.
11639b505cbSLey Foon Tan  * The result of the bit test is stored in reg1.
11739b505cbSLey Foon Tan  *
11839b505cbSLey Foon Tan  * It is NOT safe to use the same register for reg1 & reg2.
11939b505cbSLey Foon Tan  */
12039b505cbSLey Foon Tan 
12139b505cbSLey Foon Tan .macro BTC	reg1, reg2, bit
12239b505cbSLey Foon Tan .if \bit > 31
12339b505cbSLey Foon Tan 	.err
12439b505cbSLey Foon Tan .else
12539b505cbSLey Foon Tan 	.if \bit < 16
12639b505cbSLey Foon Tan 		andi	\reg1, \reg2, (1 << \bit)
12739b505cbSLey Foon Tan 		xori	\reg2, \reg2, (1 << \bit)
12839b505cbSLey Foon Tan 	.else
12939b505cbSLey Foon Tan 		andhi	\reg1, \reg2, (1 << (\bit - 16))
13039b505cbSLey Foon Tan 		xorhi	\reg2, \reg2, (1 << (\bit - 16))
13139b505cbSLey Foon Tan 	.endif
13239b505cbSLey Foon Tan .endif
13339b505cbSLey Foon Tan .endm
13439b505cbSLey Foon Tan 
13539b505cbSLey Foon Tan /*
13639b505cbSLey Foon Tan  * Tests the bit in reg2 and then sets the bit in reg2.
13739b505cbSLey Foon Tan  * The result of the bit test is stored in reg1.
13839b505cbSLey Foon Tan  *
13939b505cbSLey Foon Tan  * It is NOT safe to use the same register for reg1 & reg2.
14039b505cbSLey Foon Tan  */
14139b505cbSLey Foon Tan 
14239b505cbSLey Foon Tan .macro BTS	reg1, reg2, bit
14339b505cbSLey Foon Tan .if \bit > 31
14439b505cbSLey Foon Tan 	.err
14539b505cbSLey Foon Tan .else
14639b505cbSLey Foon Tan 	.if \bit < 16
14739b505cbSLey Foon Tan 		andi	\reg1, \reg2, (1 << \bit)
14839b505cbSLey Foon Tan 		ori	\reg2, \reg2, (1 << \bit)
14939b505cbSLey Foon Tan 	.else
15039b505cbSLey Foon Tan 		andhi	\reg1, \reg2, (1 << (\bit - 16))
15139b505cbSLey Foon Tan 		orhi	\reg2, \reg2, (1 << (\bit - 16))
15239b505cbSLey Foon Tan 	.endif
15339b505cbSLey Foon Tan .endif
15439b505cbSLey Foon Tan .endm
15539b505cbSLey Foon Tan 
15639b505cbSLey Foon Tan /*
15739b505cbSLey Foon Tan  * Tests the bit in reg2 and then resets the bit in reg2.
15839b505cbSLey Foon Tan  * The result of the bit test is stored in reg1.
15939b505cbSLey Foon Tan  *
16039b505cbSLey Foon Tan  * It is NOT safe to use the same register for reg1 & reg2.
16139b505cbSLey Foon Tan  */
16239b505cbSLey Foon Tan 
16339b505cbSLey Foon Tan .macro BTR	reg1, reg2, bit
16439b505cbSLey Foon Tan .if \bit > 31
16539b505cbSLey Foon Tan 	.err
16639b505cbSLey Foon Tan .else
16739b505cbSLey Foon Tan 	.if \bit < 16
16839b505cbSLey Foon Tan 		andi	\reg1, \reg2, (1 << \bit)
16939b505cbSLey Foon Tan 		andi	\reg2, \reg2, %lo(~(1 << \bit))
17039b505cbSLey Foon Tan 	.else
17139b505cbSLey Foon Tan 		andhi	\reg1, \reg2, (1 << (\bit - 16))
17239b505cbSLey Foon Tan 		andhi	\reg2, \reg2, %lo(~(1 << (\bit - 16)))
17339b505cbSLey Foon Tan 	.endif
17439b505cbSLey Foon Tan .endif
17539b505cbSLey Foon Tan .endm
17639b505cbSLey Foon Tan 
17739b505cbSLey Foon Tan /*
17839b505cbSLey Foon Tan  * Tests the bit in reg2 and then compliments the bit in reg2.
17939b505cbSLey Foon Tan  * The result of the bit test is stored in reg1.  If the
18039b505cbSLey Foon Tan  * original bit was zero it branches to label.
18139b505cbSLey Foon Tan  *
18239b505cbSLey Foon Tan  * It is NOT safe to use the same register for reg1 & reg2.
18339b505cbSLey Foon Tan  */
18439b505cbSLey Foon Tan 
18539b505cbSLey Foon Tan .macro BTCBZ	reg1, reg2, bit, label
18639b505cbSLey Foon Tan 	BTC	\reg1, \reg2, \bit
18739b505cbSLey Foon Tan 	beq	\reg1, r0, \label
18839b505cbSLey Foon Tan .endm
18939b505cbSLey Foon Tan 
19039b505cbSLey Foon Tan /*
19139b505cbSLey Foon Tan  * Tests the bit in reg2 and then compliments the bit in reg2.
19239b505cbSLey Foon Tan  * The result of the bit test is stored in reg1.  If the
19339b505cbSLey Foon Tan  * original bit was non-zero it branches to label.
19439b505cbSLey Foon Tan  *
19539b505cbSLey Foon Tan  * It is NOT safe to use the same register for reg1 & reg2.
19639b505cbSLey Foon Tan  */
19739b505cbSLey Foon Tan 
19839b505cbSLey Foon Tan .macro BTCBNZ	reg1, reg2, bit, label
19939b505cbSLey Foon Tan 	BTC	\reg1, \reg2, \bit
20039b505cbSLey Foon Tan 	bne	\reg1, r0, \label
20139b505cbSLey Foon Tan .endm
20239b505cbSLey Foon Tan 
20339b505cbSLey Foon Tan /*
20439b505cbSLey Foon Tan  * Tests the bit in reg2 and then sets the bit in reg2.
20539b505cbSLey Foon Tan  * The result of the bit test is stored in reg1.  If the
20639b505cbSLey Foon Tan  * original bit was zero it branches to label.
20739b505cbSLey Foon Tan  *
20839b505cbSLey Foon Tan  * It is NOT safe to use the same register for reg1 & reg2.
20939b505cbSLey Foon Tan  */
21039b505cbSLey Foon Tan 
21139b505cbSLey Foon Tan .macro BTSBZ	reg1, reg2, bit, label
21239b505cbSLey Foon Tan 	BTS	\reg1, \reg2, \bit
21339b505cbSLey Foon Tan 	beq	\reg1, r0, \label
21439b505cbSLey Foon Tan .endm
21539b505cbSLey Foon Tan 
21639b505cbSLey Foon Tan /*
21739b505cbSLey Foon Tan  * Tests the bit in reg2 and then sets the bit in reg2.
21839b505cbSLey Foon Tan  * The result of the bit test is stored in reg1.  If the
21939b505cbSLey Foon Tan  * original bit was non-zero it branches to label.
22039b505cbSLey Foon Tan  *
22139b505cbSLey Foon Tan  * It is NOT safe to use the same register for reg1 & reg2.
22239b505cbSLey Foon Tan  */
22339b505cbSLey Foon Tan 
22439b505cbSLey Foon Tan .macro BTSBNZ	reg1, reg2, bit, label
22539b505cbSLey Foon Tan 	BTS	\reg1, \reg2, \bit
22639b505cbSLey Foon Tan 	bne	\reg1, r0, \label
22739b505cbSLey Foon Tan .endm
22839b505cbSLey Foon Tan 
22939b505cbSLey Foon Tan /*
23039b505cbSLey Foon Tan  * Tests the bit in reg2 and then resets the bit in reg2.
23139b505cbSLey Foon Tan  * The result of the bit test is stored in reg1.  If the
23239b505cbSLey Foon Tan  * original bit was zero it branches to label.
23339b505cbSLey Foon Tan  *
23439b505cbSLey Foon Tan  * It is NOT safe to use the same register for reg1 & reg2.
23539b505cbSLey Foon Tan  */
23639b505cbSLey Foon Tan 
23739b505cbSLey Foon Tan .macro BTRBZ	reg1, reg2, bit, label
23839b505cbSLey Foon Tan 	BTR	\reg1, \reg2, \bit
23939b505cbSLey Foon Tan 	bne	\reg1, r0, \label
24039b505cbSLey Foon Tan .endm
24139b505cbSLey Foon Tan 
24239b505cbSLey Foon Tan /*
24339b505cbSLey Foon Tan  * Tests the bit in reg2 and then resets the bit in reg2.
24439b505cbSLey Foon Tan  * The result of the bit test is stored in reg1.  If the
24539b505cbSLey Foon Tan  * original bit was non-zero it branches to label.
24639b505cbSLey Foon Tan  *
24739b505cbSLey Foon Tan  * It is NOT safe to use the same register for reg1 & reg2.
24839b505cbSLey Foon Tan  */
24939b505cbSLey Foon Tan 
25039b505cbSLey Foon Tan .macro BTRBNZ	reg1, reg2, bit, label
25139b505cbSLey Foon Tan 	BTR	\reg1, \reg2, \bit
25239b505cbSLey Foon Tan 	bne	\reg1, r0, \label
25339b505cbSLey Foon Tan .endm
25439b505cbSLey Foon Tan 
25539b505cbSLey Foon Tan /*
25639b505cbSLey Foon Tan  * Tests the bits in mask against reg2 stores the result in reg1.
25739b505cbSLey Foon Tan  * If the all the bits in the mask are zero it branches to label.
25839b505cbSLey Foon Tan  *
25939b505cbSLey Foon Tan  * It is safe to use the same register for reg1 & reg2.
26039b505cbSLey Foon Tan  */
26139b505cbSLey Foon Tan 
26239b505cbSLey Foon Tan .macro TSTBZ	reg1, reg2, mask, label
26339b505cbSLey Foon Tan 	ANDI32	\reg1, \reg2, \mask
26439b505cbSLey Foon Tan 	beq	\reg1, r0, \label
26539b505cbSLey Foon Tan .endm
26639b505cbSLey Foon Tan 
26739b505cbSLey Foon Tan /*
26839b505cbSLey Foon Tan  * Tests the bits in mask against reg2 stores the result in reg1.
26939b505cbSLey Foon Tan  * If the any of the bits in the mask are 1 it branches to label.
27039b505cbSLey Foon Tan  *
27139b505cbSLey Foon Tan  * It is safe to use the same register for reg1 & reg2.
27239b505cbSLey Foon Tan  */
27339b505cbSLey Foon Tan 
27439b505cbSLey Foon Tan .macro TSTBNZ	reg1, reg2, mask, label
27539b505cbSLey Foon Tan 	ANDI32	\reg1, \reg2, \mask
27639b505cbSLey Foon Tan 	bne	\reg1, r0, \label
27739b505cbSLey Foon Tan .endm
27839b505cbSLey Foon Tan 
27939b505cbSLey Foon Tan /*
28039b505cbSLey Foon Tan  * Pushes reg onto the stack.
28139b505cbSLey Foon Tan  */
28239b505cbSLey Foon Tan 
28339b505cbSLey Foon Tan .macro PUSH	reg
28439b505cbSLey Foon Tan 	addi	sp, sp, -4
28539b505cbSLey Foon Tan 	stw	\reg, 0(sp)
28639b505cbSLey Foon Tan .endm
28739b505cbSLey Foon Tan 
28839b505cbSLey Foon Tan /*
28939b505cbSLey Foon Tan  * Pops the top of the stack into reg.
29039b505cbSLey Foon Tan  */
29139b505cbSLey Foon Tan 
29239b505cbSLey Foon Tan .macro POP	reg
29339b505cbSLey Foon Tan 	ldw	\reg, 0(sp)
29439b505cbSLey Foon Tan 	addi	sp, sp, 4
29539b505cbSLey Foon Tan .endm
29639b505cbSLey Foon Tan 
29739b505cbSLey Foon Tan 
29839b505cbSLey Foon Tan #endif /* _ASM_NIOS2_ASMMACROS_H */
299