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