summaryrefslogtreecommitdiffstats
path: root/arch/nios2/include/asm/asm-macros.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/nios2/include/asm/asm-macros.h')
-rw-r--r--arch/nios2/include/asm/asm-macros.h298
1 files changed, 298 insertions, 0 deletions
diff --git a/arch/nios2/include/asm/asm-macros.h b/arch/nios2/include/asm/asm-macros.h
new file mode 100644
index 0000000000..522e50a176
--- /dev/null
+++ b/arch/nios2/include/asm/asm-macros.h
@@ -0,0 +1,298 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Macro used to simplify coding multi-line assembler.
+ * Some of the bit test macro can simplify down to one line
+ * depending on the mask value.
+ *
+ * Copyright (C) 2004 Microtronix Datacom Ltd.
+ *
+ * All rights reserved.
+ */
+#ifndef _ASM_NIOS2_ASMMACROS_H
+#define _ASM_NIOS2_ASMMACROS_H
+/*
+ * ANDs reg2 with mask and places the result in reg1.
+ *
+ * You cannnot use the same register for reg1 & reg2.
+ */
+
+.macro ANDI32 reg1, reg2, mask
+.if \mask & 0xffff
+ .if \mask & 0xffff0000
+ movhi \reg1, %hi(\mask)
+ movui \reg1, %lo(\mask)
+ and \reg1, \reg1, \reg2
+ .else
+ andi \reg1, \reg2, %lo(\mask)
+ .endif
+.else
+ andhi \reg1, \reg2, %hi(\mask)
+.endif
+.endm
+
+/*
+ * ORs reg2 with mask and places the result in reg1.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro ORI32 reg1, reg2, mask
+.if \mask & 0xffff
+ .if \mask & 0xffff0000
+ orhi \reg1, \reg2, %hi(\mask)
+ ori \reg1, \reg2, %lo(\mask)
+ .else
+ ori \reg1, \reg2, %lo(\mask)
+ .endif
+.else
+ orhi \reg1, \reg2, %hi(\mask)
+.endif
+.endm
+
+/*
+ * XORs reg2 with mask and places the result in reg1.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro XORI32 reg1, reg2, mask
+.if \mask & 0xffff
+ .if \mask & 0xffff0000
+ xorhi \reg1, \reg2, %hi(\mask)
+ xori \reg1, \reg1, %lo(\mask)
+ .else
+ xori \reg1, \reg2, %lo(\mask)
+ .endif
+.else
+ xorhi \reg1, \reg2, %hi(\mask)
+.endif
+.endm
+
+/*
+ * This is a support macro for BTBZ & BTBNZ. It checks
+ * the bit to make sure it is valid 32 value.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro BT reg1, reg2, bit
+.if \bit > 31
+ .err
+.else
+ .if \bit < 16
+ andi \reg1, \reg2, (1 << \bit)
+ .else
+ andhi \reg1, \reg2, (1 << (\bit - 16))
+ .endif
+.endif
+.endm
+
+/*
+ * Tests the bit in reg2 and branches to label if the
+ * bit is zero. The result of the bit test is stored in reg1.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTBZ reg1, reg2, bit, label
+ BT \reg1, \reg2, \bit
+ beq \reg1, r0, \label
+.endm
+
+/*
+ * Tests the bit in reg2 and branches to label if the
+ * bit is non-zero. The result of the bit test is stored in reg1.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTBNZ reg1, reg2, bit, label
+ BT \reg1, \reg2, \bit
+ bne \reg1, r0, \label
+.endm
+
+/*
+ * Tests the bit in reg2 and then compliments the bit in reg2.
+ * The result of the bit test is stored in reg1.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTC reg1, reg2, bit
+.if \bit > 31
+ .err
+.else
+ .if \bit < 16
+ andi \reg1, \reg2, (1 << \bit)
+ xori \reg2, \reg2, (1 << \bit)
+ .else
+ andhi \reg1, \reg2, (1 << (\bit - 16))
+ xorhi \reg2, \reg2, (1 << (\bit - 16))
+ .endif
+.endif
+.endm
+
+/*
+ * Tests the bit in reg2 and then sets the bit in reg2.
+ * The result of the bit test is stored in reg1.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTS reg1, reg2, bit
+.if \bit > 31
+ .err
+.else
+ .if \bit < 16
+ andi \reg1, \reg2, (1 << \bit)
+ ori \reg2, \reg2, (1 << \bit)
+ .else
+ andhi \reg1, \reg2, (1 << (\bit - 16))
+ orhi \reg2, \reg2, (1 << (\bit - 16))
+ .endif
+.endif
+.endm
+
+/*
+ * Tests the bit in reg2 and then resets the bit in reg2.
+ * The result of the bit test is stored in reg1.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTR reg1, reg2, bit
+.if \bit > 31
+ .err
+.else
+ .if \bit < 16
+ andi \reg1, \reg2, (1 << \bit)
+ andi \reg2, \reg2, %lo(~(1 << \bit))
+ .else
+ andhi \reg1, \reg2, (1 << (\bit - 16))
+ andhi \reg2, \reg2, %lo(~(1 << (\bit - 16)))
+ .endif
+.endif
+.endm
+
+/*
+ * Tests the bit in reg2 and then compliments the bit in reg2.
+ * The result of the bit test is stored in reg1. If the
+ * original bit was zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTCBZ reg1, reg2, bit, label
+ BTC \reg1, \reg2, \bit
+ beq \reg1, r0, \label
+.endm
+
+/*
+ * Tests the bit in reg2 and then compliments the bit in reg2.
+ * The result of the bit test is stored in reg1. If the
+ * original bit was non-zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTCBNZ reg1, reg2, bit, label
+ BTC \reg1, \reg2, \bit
+ bne \reg1, r0, \label
+.endm
+
+/*
+ * Tests the bit in reg2 and then sets the bit in reg2.
+ * The result of the bit test is stored in reg1. If the
+ * original bit was zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTSBZ reg1, reg2, bit, label
+ BTS \reg1, \reg2, \bit
+ beq \reg1, r0, \label
+.endm
+
+/*
+ * Tests the bit in reg2 and then sets the bit in reg2.
+ * The result of the bit test is stored in reg1. If the
+ * original bit was non-zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTSBNZ reg1, reg2, bit, label
+ BTS \reg1, \reg2, \bit
+ bne \reg1, r0, \label
+.endm
+
+/*
+ * Tests the bit in reg2 and then resets the bit in reg2.
+ * The result of the bit test is stored in reg1. If the
+ * original bit was zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTRBZ reg1, reg2, bit, label
+ BTR \reg1, \reg2, \bit
+ bne \reg1, r0, \label
+.endm
+
+/*
+ * Tests the bit in reg2 and then resets the bit in reg2.
+ * The result of the bit test is stored in reg1. If the
+ * original bit was non-zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTRBNZ reg1, reg2, bit, label
+ BTR \reg1, \reg2, \bit
+ bne \reg1, r0, \label
+.endm
+
+/*
+ * Tests the bits in mask against reg2 stores the result in reg1.
+ * If the all the bits in the mask are zero it branches to label.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro TSTBZ reg1, reg2, mask, label
+ ANDI32 \reg1, \reg2, \mask
+ beq \reg1, r0, \label
+.endm
+
+/*
+ * Tests the bits in mask against reg2 stores the result in reg1.
+ * If the any of the bits in the mask are 1 it branches to label.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro TSTBNZ reg1, reg2, mask, label
+ ANDI32 \reg1, \reg2, \mask
+ bne \reg1, r0, \label
+.endm
+
+/*
+ * Pushes reg onto the stack.
+ */
+
+.macro PUSH reg
+ addi sp, sp, -4
+ stw \reg, 0(sp)
+.endm
+
+/*
+ * Pops the top of the stack into reg.
+ */
+
+.macro POP reg
+ ldw \reg, 0(sp)
+ addi sp, sp, 4
+.endm
+
+
+#endif /* _ASM_NIOS2_ASMMACROS_H */