162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Macro used to simplify coding multi-line assembler. 462306a36Sopenharmony_ci * Some of the bit test macro can simplify down to one line 562306a36Sopenharmony_ci * depending on the mask value. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 2004 Microtronix Datacom Ltd. 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * All rights reserved. 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci#ifndef _ASM_NIOS2_ASMMACROS_H 1262306a36Sopenharmony_ci#define _ASM_NIOS2_ASMMACROS_H 1362306a36Sopenharmony_ci/* 1462306a36Sopenharmony_ci * ANDs reg2 with mask and places the result in reg1. 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * You cannnot use the same register for reg1 & reg2. 1762306a36Sopenharmony_ci */ 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci.macro ANDI32 reg1, reg2, mask 2062306a36Sopenharmony_ci.if \mask & 0xffff 2162306a36Sopenharmony_ci .if \mask & 0xffff0000 2262306a36Sopenharmony_ci movhi \reg1, %hi(\mask) 2362306a36Sopenharmony_ci movui \reg1, %lo(\mask) 2462306a36Sopenharmony_ci and \reg1, \reg1, \reg2 2562306a36Sopenharmony_ci .else 2662306a36Sopenharmony_ci andi \reg1, \reg2, %lo(\mask) 2762306a36Sopenharmony_ci .endif 2862306a36Sopenharmony_ci.else 2962306a36Sopenharmony_ci andhi \reg1, \reg2, %hi(\mask) 3062306a36Sopenharmony_ci.endif 3162306a36Sopenharmony_ci.endm 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* 3462306a36Sopenharmony_ci * ORs reg2 with mask and places the result in reg1. 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * It is safe to use the same register for reg1 & reg2. 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci.macro ORI32 reg1, reg2, mask 4062306a36Sopenharmony_ci.if \mask & 0xffff 4162306a36Sopenharmony_ci .if \mask & 0xffff0000 4262306a36Sopenharmony_ci orhi \reg1, \reg2, %hi(\mask) 4362306a36Sopenharmony_ci ori \reg1, \reg2, %lo(\mask) 4462306a36Sopenharmony_ci .else 4562306a36Sopenharmony_ci ori \reg1, \reg2, %lo(\mask) 4662306a36Sopenharmony_ci .endif 4762306a36Sopenharmony_ci.else 4862306a36Sopenharmony_ci orhi \reg1, \reg2, %hi(\mask) 4962306a36Sopenharmony_ci.endif 5062306a36Sopenharmony_ci.endm 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/* 5362306a36Sopenharmony_ci * XORs reg2 with mask and places the result in reg1. 5462306a36Sopenharmony_ci * 5562306a36Sopenharmony_ci * It is safe to use the same register for reg1 & reg2. 5662306a36Sopenharmony_ci */ 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci.macro XORI32 reg1, reg2, mask 5962306a36Sopenharmony_ci.if \mask & 0xffff 6062306a36Sopenharmony_ci .if \mask & 0xffff0000 6162306a36Sopenharmony_ci xorhi \reg1, \reg2, %hi(\mask) 6262306a36Sopenharmony_ci xori \reg1, \reg1, %lo(\mask) 6362306a36Sopenharmony_ci .else 6462306a36Sopenharmony_ci xori \reg1, \reg2, %lo(\mask) 6562306a36Sopenharmony_ci .endif 6662306a36Sopenharmony_ci.else 6762306a36Sopenharmony_ci xorhi \reg1, \reg2, %hi(\mask) 6862306a36Sopenharmony_ci.endif 6962306a36Sopenharmony_ci.endm 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* 7262306a36Sopenharmony_ci * This is a support macro for BTBZ & BTBNZ. It checks 7362306a36Sopenharmony_ci * the bit to make sure it is valid 32 value. 7462306a36Sopenharmony_ci * 7562306a36Sopenharmony_ci * It is safe to use the same register for reg1 & reg2. 7662306a36Sopenharmony_ci */ 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci.macro BT reg1, reg2, bit 7962306a36Sopenharmony_ci.if \bit > 31 8062306a36Sopenharmony_ci .err 8162306a36Sopenharmony_ci.else 8262306a36Sopenharmony_ci .if \bit < 16 8362306a36Sopenharmony_ci andi \reg1, \reg2, (1 << \bit) 8462306a36Sopenharmony_ci .else 8562306a36Sopenharmony_ci andhi \reg1, \reg2, (1 << (\bit - 16)) 8662306a36Sopenharmony_ci .endif 8762306a36Sopenharmony_ci.endif 8862306a36Sopenharmony_ci.endm 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/* 9162306a36Sopenharmony_ci * Tests the bit in reg2 and branches to label if the 9262306a36Sopenharmony_ci * bit is zero. The result of the bit test is stored in reg1. 9362306a36Sopenharmony_ci * 9462306a36Sopenharmony_ci * It is safe to use the same register for reg1 & reg2. 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci.macro BTBZ reg1, reg2, bit, label 9862306a36Sopenharmony_ci BT \reg1, \reg2, \bit 9962306a36Sopenharmony_ci beq \reg1, r0, \label 10062306a36Sopenharmony_ci.endm 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci/* 10362306a36Sopenharmony_ci * Tests the bit in reg2 and branches to label if the 10462306a36Sopenharmony_ci * bit is non-zero. The result of the bit test is stored in reg1. 10562306a36Sopenharmony_ci * 10662306a36Sopenharmony_ci * It is safe to use the same register for reg1 & reg2. 10762306a36Sopenharmony_ci */ 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci.macro BTBNZ reg1, reg2, bit, label 11062306a36Sopenharmony_ci BT \reg1, \reg2, \bit 11162306a36Sopenharmony_ci bne \reg1, r0, \label 11262306a36Sopenharmony_ci.endm 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci/* 11562306a36Sopenharmony_ci * Tests the bit in reg2 and then compliments the bit in reg2. 11662306a36Sopenharmony_ci * The result of the bit test is stored in reg1. 11762306a36Sopenharmony_ci * 11862306a36Sopenharmony_ci * It is NOT safe to use the same register for reg1 & reg2. 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci.macro BTC reg1, reg2, bit 12262306a36Sopenharmony_ci.if \bit > 31 12362306a36Sopenharmony_ci .err 12462306a36Sopenharmony_ci.else 12562306a36Sopenharmony_ci .if \bit < 16 12662306a36Sopenharmony_ci andi \reg1, \reg2, (1 << \bit) 12762306a36Sopenharmony_ci xori \reg2, \reg2, (1 << \bit) 12862306a36Sopenharmony_ci .else 12962306a36Sopenharmony_ci andhi \reg1, \reg2, (1 << (\bit - 16)) 13062306a36Sopenharmony_ci xorhi \reg2, \reg2, (1 << (\bit - 16)) 13162306a36Sopenharmony_ci .endif 13262306a36Sopenharmony_ci.endif 13362306a36Sopenharmony_ci.endm 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci/* 13662306a36Sopenharmony_ci * Tests the bit in reg2 and then sets the bit in reg2. 13762306a36Sopenharmony_ci * The result of the bit test is stored in reg1. 13862306a36Sopenharmony_ci * 13962306a36Sopenharmony_ci * It is NOT safe to use the same register for reg1 & reg2. 14062306a36Sopenharmony_ci */ 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci.macro BTS reg1, reg2, bit 14362306a36Sopenharmony_ci.if \bit > 31 14462306a36Sopenharmony_ci .err 14562306a36Sopenharmony_ci.else 14662306a36Sopenharmony_ci .if \bit < 16 14762306a36Sopenharmony_ci andi \reg1, \reg2, (1 << \bit) 14862306a36Sopenharmony_ci ori \reg2, \reg2, (1 << \bit) 14962306a36Sopenharmony_ci .else 15062306a36Sopenharmony_ci andhi \reg1, \reg2, (1 << (\bit - 16)) 15162306a36Sopenharmony_ci orhi \reg2, \reg2, (1 << (\bit - 16)) 15262306a36Sopenharmony_ci .endif 15362306a36Sopenharmony_ci.endif 15462306a36Sopenharmony_ci.endm 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci/* 15762306a36Sopenharmony_ci * Tests the bit in reg2 and then resets the bit in reg2. 15862306a36Sopenharmony_ci * The result of the bit test is stored in reg1. 15962306a36Sopenharmony_ci * 16062306a36Sopenharmony_ci * It is NOT safe to use the same register for reg1 & reg2. 16162306a36Sopenharmony_ci */ 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci.macro BTR reg1, reg2, bit 16462306a36Sopenharmony_ci.if \bit > 31 16562306a36Sopenharmony_ci .err 16662306a36Sopenharmony_ci.else 16762306a36Sopenharmony_ci .if \bit < 16 16862306a36Sopenharmony_ci andi \reg1, \reg2, (1 << \bit) 16962306a36Sopenharmony_ci andi \reg2, \reg2, %lo(~(1 << \bit)) 17062306a36Sopenharmony_ci .else 17162306a36Sopenharmony_ci andhi \reg1, \reg2, (1 << (\bit - 16)) 17262306a36Sopenharmony_ci andhi \reg2, \reg2, %lo(~(1 << (\bit - 16))) 17362306a36Sopenharmony_ci .endif 17462306a36Sopenharmony_ci.endif 17562306a36Sopenharmony_ci.endm 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci/* 17862306a36Sopenharmony_ci * Tests the bit in reg2 and then compliments the bit in reg2. 17962306a36Sopenharmony_ci * The result of the bit test is stored in reg1. If the 18062306a36Sopenharmony_ci * original bit was zero it branches to label. 18162306a36Sopenharmony_ci * 18262306a36Sopenharmony_ci * It is NOT safe to use the same register for reg1 & reg2. 18362306a36Sopenharmony_ci */ 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci.macro BTCBZ reg1, reg2, bit, label 18662306a36Sopenharmony_ci BTC \reg1, \reg2, \bit 18762306a36Sopenharmony_ci beq \reg1, r0, \label 18862306a36Sopenharmony_ci.endm 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci/* 19162306a36Sopenharmony_ci * Tests the bit in reg2 and then compliments the bit in reg2. 19262306a36Sopenharmony_ci * The result of the bit test is stored in reg1. If the 19362306a36Sopenharmony_ci * original bit was non-zero it branches to label. 19462306a36Sopenharmony_ci * 19562306a36Sopenharmony_ci * It is NOT safe to use the same register for reg1 & reg2. 19662306a36Sopenharmony_ci */ 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci.macro BTCBNZ reg1, reg2, bit, label 19962306a36Sopenharmony_ci BTC \reg1, \reg2, \bit 20062306a36Sopenharmony_ci bne \reg1, r0, \label 20162306a36Sopenharmony_ci.endm 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci/* 20462306a36Sopenharmony_ci * Tests the bit in reg2 and then sets the bit in reg2. 20562306a36Sopenharmony_ci * The result of the bit test is stored in reg1. If the 20662306a36Sopenharmony_ci * original bit was zero it branches to label. 20762306a36Sopenharmony_ci * 20862306a36Sopenharmony_ci * It is NOT safe to use the same register for reg1 & reg2. 20962306a36Sopenharmony_ci */ 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci.macro BTSBZ reg1, reg2, bit, label 21262306a36Sopenharmony_ci BTS \reg1, \reg2, \bit 21362306a36Sopenharmony_ci beq \reg1, r0, \label 21462306a36Sopenharmony_ci.endm 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci/* 21762306a36Sopenharmony_ci * Tests the bit in reg2 and then sets the bit in reg2. 21862306a36Sopenharmony_ci * The result of the bit test is stored in reg1. If the 21962306a36Sopenharmony_ci * original bit was non-zero it branches to label. 22062306a36Sopenharmony_ci * 22162306a36Sopenharmony_ci * It is NOT safe to use the same register for reg1 & reg2. 22262306a36Sopenharmony_ci */ 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci.macro BTSBNZ reg1, reg2, bit, label 22562306a36Sopenharmony_ci BTS \reg1, \reg2, \bit 22662306a36Sopenharmony_ci bne \reg1, r0, \label 22762306a36Sopenharmony_ci.endm 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci/* 23062306a36Sopenharmony_ci * Tests the bit in reg2 and then resets the bit in reg2. 23162306a36Sopenharmony_ci * The result of the bit test is stored in reg1. If the 23262306a36Sopenharmony_ci * original bit was zero it branches to label. 23362306a36Sopenharmony_ci * 23462306a36Sopenharmony_ci * It is NOT safe to use the same register for reg1 & reg2. 23562306a36Sopenharmony_ci */ 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci.macro BTRBZ reg1, reg2, bit, label 23862306a36Sopenharmony_ci BTR \reg1, \reg2, \bit 23962306a36Sopenharmony_ci bne \reg1, r0, \label 24062306a36Sopenharmony_ci.endm 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci/* 24362306a36Sopenharmony_ci * Tests the bit in reg2 and then resets the bit in reg2. 24462306a36Sopenharmony_ci * The result of the bit test is stored in reg1. If the 24562306a36Sopenharmony_ci * original bit was non-zero it branches to label. 24662306a36Sopenharmony_ci * 24762306a36Sopenharmony_ci * It is NOT safe to use the same register for reg1 & reg2. 24862306a36Sopenharmony_ci */ 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci.macro BTRBNZ reg1, reg2, bit, label 25162306a36Sopenharmony_ci BTR \reg1, \reg2, \bit 25262306a36Sopenharmony_ci bne \reg1, r0, \label 25362306a36Sopenharmony_ci.endm 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci/* 25662306a36Sopenharmony_ci * Tests the bits in mask against reg2 stores the result in reg1. 25762306a36Sopenharmony_ci * If the all the bits in the mask are zero it branches to label. 25862306a36Sopenharmony_ci * 25962306a36Sopenharmony_ci * It is safe to use the same register for reg1 & reg2. 26062306a36Sopenharmony_ci */ 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci.macro TSTBZ reg1, reg2, mask, label 26362306a36Sopenharmony_ci ANDI32 \reg1, \reg2, \mask 26462306a36Sopenharmony_ci beq \reg1, r0, \label 26562306a36Sopenharmony_ci.endm 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci/* 26862306a36Sopenharmony_ci * Tests the bits in mask against reg2 stores the result in reg1. 26962306a36Sopenharmony_ci * If the any of the bits in the mask are 1 it branches to label. 27062306a36Sopenharmony_ci * 27162306a36Sopenharmony_ci * It is safe to use the same register for reg1 & reg2. 27262306a36Sopenharmony_ci */ 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci.macro TSTBNZ reg1, reg2, mask, label 27562306a36Sopenharmony_ci ANDI32 \reg1, \reg2, \mask 27662306a36Sopenharmony_ci bne \reg1, r0, \label 27762306a36Sopenharmony_ci.endm 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci/* 28062306a36Sopenharmony_ci * Pushes reg onto the stack. 28162306a36Sopenharmony_ci */ 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci.macro PUSH reg 28462306a36Sopenharmony_ci addi sp, sp, -4 28562306a36Sopenharmony_ci stw \reg, 0(sp) 28662306a36Sopenharmony_ci.endm 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci/* 28962306a36Sopenharmony_ci * Pops the top of the stack into reg. 29062306a36Sopenharmony_ci */ 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci.macro POP reg 29362306a36Sopenharmony_ci ldw \reg, 0(sp) 29462306a36Sopenharmony_ci addi sp, sp, 4 29562306a36Sopenharmony_ci.endm 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci#endif /* _ASM_NIOS2_ASMMACROS_H */ 299