123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- /*
- * 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.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- */
- #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 */
|