1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Macro used to simplify coding multi-line assembler. 4*4882a593Smuzhiyun * Some of the bit test macro can simplify down to one line 5*4882a593Smuzhiyun * depending on the mask value. 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Copyright (C) 2004 Microtronix Datacom Ltd. 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * All rights reserved. 10*4882a593Smuzhiyun */ 11*4882a593Smuzhiyun #ifndef _ASM_NIOS2_ASMMACROS_H 12*4882a593Smuzhiyun #define _ASM_NIOS2_ASMMACROS_H 13*4882a593Smuzhiyun /* 14*4882a593Smuzhiyun * ANDs reg2 with mask and places the result in reg1. 15*4882a593Smuzhiyun * 16*4882a593Smuzhiyun * You cannnot use the same register for reg1 & reg2. 17*4882a593Smuzhiyun */ 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun .macro ANDI32 reg1, reg2, mask 20*4882a593Smuzhiyun .if \mask & 0xffff 21*4882a593Smuzhiyun .if \mask & 0xffff0000 22*4882a593Smuzhiyun movhi \reg1, %hi(\mask) 23*4882a593Smuzhiyun movui \reg1, %lo(\mask) 24*4882a593Smuzhiyun and \reg1, \reg1, \reg2 25*4882a593Smuzhiyun .else 26*4882a593Smuzhiyun andi \reg1, \reg2, %lo(\mask) 27*4882a593Smuzhiyun .endif 28*4882a593Smuzhiyun .else 29*4882a593Smuzhiyun andhi \reg1, \reg2, %hi(\mask) 30*4882a593Smuzhiyun .endif 31*4882a593Smuzhiyun .endm 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun /* 34*4882a593Smuzhiyun * ORs reg2 with mask and places the result in reg1. 35*4882a593Smuzhiyun * 36*4882a593Smuzhiyun * It is safe to use the same register for reg1 & reg2. 37*4882a593Smuzhiyun */ 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun .macro ORI32 reg1, reg2, mask 40*4882a593Smuzhiyun .if \mask & 0xffff 41*4882a593Smuzhiyun .if \mask & 0xffff0000 42*4882a593Smuzhiyun orhi \reg1, \reg2, %hi(\mask) 43*4882a593Smuzhiyun ori \reg1, \reg2, %lo(\mask) 44*4882a593Smuzhiyun .else 45*4882a593Smuzhiyun ori \reg1, \reg2, %lo(\mask) 46*4882a593Smuzhiyun .endif 47*4882a593Smuzhiyun .else 48*4882a593Smuzhiyun orhi \reg1, \reg2, %hi(\mask) 49*4882a593Smuzhiyun .endif 50*4882a593Smuzhiyun .endm 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun /* 53*4882a593Smuzhiyun * XORs reg2 with mask and places the result in reg1. 54*4882a593Smuzhiyun * 55*4882a593Smuzhiyun * It is safe to use the same register for reg1 & reg2. 56*4882a593Smuzhiyun */ 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun .macro XORI32 reg1, reg2, mask 59*4882a593Smuzhiyun .if \mask & 0xffff 60*4882a593Smuzhiyun .if \mask & 0xffff0000 61*4882a593Smuzhiyun xorhi \reg1, \reg2, %hi(\mask) 62*4882a593Smuzhiyun xori \reg1, \reg1, %lo(\mask) 63*4882a593Smuzhiyun .else 64*4882a593Smuzhiyun xori \reg1, \reg2, %lo(\mask) 65*4882a593Smuzhiyun .endif 66*4882a593Smuzhiyun .else 67*4882a593Smuzhiyun xorhi \reg1, \reg2, %hi(\mask) 68*4882a593Smuzhiyun .endif 69*4882a593Smuzhiyun .endm 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun /* 72*4882a593Smuzhiyun * This is a support macro for BTBZ & BTBNZ. It checks 73*4882a593Smuzhiyun * the bit to make sure it is valid 32 value. 74*4882a593Smuzhiyun * 75*4882a593Smuzhiyun * It is safe to use the same register for reg1 & reg2. 76*4882a593Smuzhiyun */ 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun .macro BT reg1, reg2, bit 79*4882a593Smuzhiyun .if \bit > 31 80*4882a593Smuzhiyun .err 81*4882a593Smuzhiyun .else 82*4882a593Smuzhiyun .if \bit < 16 83*4882a593Smuzhiyun andi \reg1, \reg2, (1 << \bit) 84*4882a593Smuzhiyun .else 85*4882a593Smuzhiyun andhi \reg1, \reg2, (1 << (\bit - 16)) 86*4882a593Smuzhiyun .endif 87*4882a593Smuzhiyun .endif 88*4882a593Smuzhiyun .endm 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun /* 91*4882a593Smuzhiyun * Tests the bit in reg2 and branches to label if the 92*4882a593Smuzhiyun * bit is zero. The result of the bit test is stored in reg1. 93*4882a593Smuzhiyun * 94*4882a593Smuzhiyun * It is safe to use the same register for reg1 & reg2. 95*4882a593Smuzhiyun */ 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun .macro BTBZ reg1, reg2, bit, label 98*4882a593Smuzhiyun BT \reg1, \reg2, \bit 99*4882a593Smuzhiyun beq \reg1, r0, \label 100*4882a593Smuzhiyun .endm 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun /* 103*4882a593Smuzhiyun * Tests the bit in reg2 and branches to label if the 104*4882a593Smuzhiyun * bit is non-zero. The result of the bit test is stored in reg1. 105*4882a593Smuzhiyun * 106*4882a593Smuzhiyun * It is safe to use the same register for reg1 & reg2. 107*4882a593Smuzhiyun */ 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun .macro BTBNZ reg1, reg2, bit, label 110*4882a593Smuzhiyun BT \reg1, \reg2, \bit 111*4882a593Smuzhiyun bne \reg1, r0, \label 112*4882a593Smuzhiyun .endm 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun /* 115*4882a593Smuzhiyun * Tests the bit in reg2 and then compliments the bit in reg2. 116*4882a593Smuzhiyun * The result of the bit test is stored in reg1. 117*4882a593Smuzhiyun * 118*4882a593Smuzhiyun * It is NOT safe to use the same register for reg1 & reg2. 119*4882a593Smuzhiyun */ 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun .macro BTC reg1, reg2, bit 122*4882a593Smuzhiyun .if \bit > 31 123*4882a593Smuzhiyun .err 124*4882a593Smuzhiyun .else 125*4882a593Smuzhiyun .if \bit < 16 126*4882a593Smuzhiyun andi \reg1, \reg2, (1 << \bit) 127*4882a593Smuzhiyun xori \reg2, \reg2, (1 << \bit) 128*4882a593Smuzhiyun .else 129*4882a593Smuzhiyun andhi \reg1, \reg2, (1 << (\bit - 16)) 130*4882a593Smuzhiyun xorhi \reg2, \reg2, (1 << (\bit - 16)) 131*4882a593Smuzhiyun .endif 132*4882a593Smuzhiyun .endif 133*4882a593Smuzhiyun .endm 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun /* 136*4882a593Smuzhiyun * Tests the bit in reg2 and then sets the bit in reg2. 137*4882a593Smuzhiyun * The result of the bit test is stored in reg1. 138*4882a593Smuzhiyun * 139*4882a593Smuzhiyun * It is NOT safe to use the same register for reg1 & reg2. 140*4882a593Smuzhiyun */ 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun .macro BTS reg1, reg2, bit 143*4882a593Smuzhiyun .if \bit > 31 144*4882a593Smuzhiyun .err 145*4882a593Smuzhiyun .else 146*4882a593Smuzhiyun .if \bit < 16 147*4882a593Smuzhiyun andi \reg1, \reg2, (1 << \bit) 148*4882a593Smuzhiyun ori \reg2, \reg2, (1 << \bit) 149*4882a593Smuzhiyun .else 150*4882a593Smuzhiyun andhi \reg1, \reg2, (1 << (\bit - 16)) 151*4882a593Smuzhiyun orhi \reg2, \reg2, (1 << (\bit - 16)) 152*4882a593Smuzhiyun .endif 153*4882a593Smuzhiyun .endif 154*4882a593Smuzhiyun .endm 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun /* 157*4882a593Smuzhiyun * Tests the bit in reg2 and then resets the bit in reg2. 158*4882a593Smuzhiyun * The result of the bit test is stored in reg1. 159*4882a593Smuzhiyun * 160*4882a593Smuzhiyun * It is NOT safe to use the same register for reg1 & reg2. 161*4882a593Smuzhiyun */ 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun .macro BTR reg1, reg2, bit 164*4882a593Smuzhiyun .if \bit > 31 165*4882a593Smuzhiyun .err 166*4882a593Smuzhiyun .else 167*4882a593Smuzhiyun .if \bit < 16 168*4882a593Smuzhiyun andi \reg1, \reg2, (1 << \bit) 169*4882a593Smuzhiyun andi \reg2, \reg2, %lo(~(1 << \bit)) 170*4882a593Smuzhiyun .else 171*4882a593Smuzhiyun andhi \reg1, \reg2, (1 << (\bit - 16)) 172*4882a593Smuzhiyun andhi \reg2, \reg2, %lo(~(1 << (\bit - 16))) 173*4882a593Smuzhiyun .endif 174*4882a593Smuzhiyun .endif 175*4882a593Smuzhiyun .endm 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun /* 178*4882a593Smuzhiyun * Tests the bit in reg2 and then compliments the bit in reg2. 179*4882a593Smuzhiyun * The result of the bit test is stored in reg1. If the 180*4882a593Smuzhiyun * original bit was zero it branches to label. 181*4882a593Smuzhiyun * 182*4882a593Smuzhiyun * It is NOT safe to use the same register for reg1 & reg2. 183*4882a593Smuzhiyun */ 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun .macro BTCBZ reg1, reg2, bit, label 186*4882a593Smuzhiyun BTC \reg1, \reg2, \bit 187*4882a593Smuzhiyun beq \reg1, r0, \label 188*4882a593Smuzhiyun .endm 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun /* 191*4882a593Smuzhiyun * Tests the bit in reg2 and then compliments the bit in reg2. 192*4882a593Smuzhiyun * The result of the bit test is stored in reg1. If the 193*4882a593Smuzhiyun * original bit was non-zero it branches to label. 194*4882a593Smuzhiyun * 195*4882a593Smuzhiyun * It is NOT safe to use the same register for reg1 & reg2. 196*4882a593Smuzhiyun */ 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun .macro BTCBNZ reg1, reg2, bit, label 199*4882a593Smuzhiyun BTC \reg1, \reg2, \bit 200*4882a593Smuzhiyun bne \reg1, r0, \label 201*4882a593Smuzhiyun .endm 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun /* 204*4882a593Smuzhiyun * Tests the bit in reg2 and then sets the bit in reg2. 205*4882a593Smuzhiyun * The result of the bit test is stored in reg1. If the 206*4882a593Smuzhiyun * original bit was zero it branches to label. 207*4882a593Smuzhiyun * 208*4882a593Smuzhiyun * It is NOT safe to use the same register for reg1 & reg2. 209*4882a593Smuzhiyun */ 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun .macro BTSBZ reg1, reg2, bit, label 212*4882a593Smuzhiyun BTS \reg1, \reg2, \bit 213*4882a593Smuzhiyun beq \reg1, r0, \label 214*4882a593Smuzhiyun .endm 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun /* 217*4882a593Smuzhiyun * Tests the bit in reg2 and then sets the bit in reg2. 218*4882a593Smuzhiyun * The result of the bit test is stored in reg1. If the 219*4882a593Smuzhiyun * original bit was non-zero it branches to label. 220*4882a593Smuzhiyun * 221*4882a593Smuzhiyun * It is NOT safe to use the same register for reg1 & reg2. 222*4882a593Smuzhiyun */ 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun .macro BTSBNZ reg1, reg2, bit, label 225*4882a593Smuzhiyun BTS \reg1, \reg2, \bit 226*4882a593Smuzhiyun bne \reg1, r0, \label 227*4882a593Smuzhiyun .endm 228*4882a593Smuzhiyun 229*4882a593Smuzhiyun /* 230*4882a593Smuzhiyun * Tests the bit in reg2 and then resets the bit in reg2. 231*4882a593Smuzhiyun * The result of the bit test is stored in reg1. If the 232*4882a593Smuzhiyun * original bit was zero it branches to label. 233*4882a593Smuzhiyun * 234*4882a593Smuzhiyun * It is NOT safe to use the same register for reg1 & reg2. 235*4882a593Smuzhiyun */ 236*4882a593Smuzhiyun 237*4882a593Smuzhiyun .macro BTRBZ reg1, reg2, bit, label 238*4882a593Smuzhiyun BTR \reg1, \reg2, \bit 239*4882a593Smuzhiyun bne \reg1, r0, \label 240*4882a593Smuzhiyun .endm 241*4882a593Smuzhiyun 242*4882a593Smuzhiyun /* 243*4882a593Smuzhiyun * Tests the bit in reg2 and then resets the bit in reg2. 244*4882a593Smuzhiyun * The result of the bit test is stored in reg1. If the 245*4882a593Smuzhiyun * original bit was non-zero it branches to label. 246*4882a593Smuzhiyun * 247*4882a593Smuzhiyun * It is NOT safe to use the same register for reg1 & reg2. 248*4882a593Smuzhiyun */ 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun .macro BTRBNZ reg1, reg2, bit, label 251*4882a593Smuzhiyun BTR \reg1, \reg2, \bit 252*4882a593Smuzhiyun bne \reg1, r0, \label 253*4882a593Smuzhiyun .endm 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun /* 256*4882a593Smuzhiyun * Tests the bits in mask against reg2 stores the result in reg1. 257*4882a593Smuzhiyun * If the all the bits in the mask are zero it branches to label. 258*4882a593Smuzhiyun * 259*4882a593Smuzhiyun * It is safe to use the same register for reg1 & reg2. 260*4882a593Smuzhiyun */ 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun .macro TSTBZ reg1, reg2, mask, label 263*4882a593Smuzhiyun ANDI32 \reg1, \reg2, \mask 264*4882a593Smuzhiyun beq \reg1, r0, \label 265*4882a593Smuzhiyun .endm 266*4882a593Smuzhiyun 267*4882a593Smuzhiyun /* 268*4882a593Smuzhiyun * Tests the bits in mask against reg2 stores the result in reg1. 269*4882a593Smuzhiyun * If the any of the bits in the mask are 1 it branches to label. 270*4882a593Smuzhiyun * 271*4882a593Smuzhiyun * It is safe to use the same register for reg1 & reg2. 272*4882a593Smuzhiyun */ 273*4882a593Smuzhiyun 274*4882a593Smuzhiyun .macro TSTBNZ reg1, reg2, mask, label 275*4882a593Smuzhiyun ANDI32 \reg1, \reg2, \mask 276*4882a593Smuzhiyun bne \reg1, r0, \label 277*4882a593Smuzhiyun .endm 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun /* 280*4882a593Smuzhiyun * Pushes reg onto the stack. 281*4882a593Smuzhiyun */ 282*4882a593Smuzhiyun 283*4882a593Smuzhiyun .macro PUSH reg 284*4882a593Smuzhiyun addi sp, sp, -4 285*4882a593Smuzhiyun stw \reg, 0(sp) 286*4882a593Smuzhiyun .endm 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun /* 289*4882a593Smuzhiyun * Pops the top of the stack into reg. 290*4882a593Smuzhiyun */ 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun .macro POP reg 293*4882a593Smuzhiyun ldw \reg, 0(sp) 294*4882a593Smuzhiyun addi sp, sp, 4 295*4882a593Smuzhiyun .endm 296*4882a593Smuzhiyun 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun #endif /* _ASM_NIOS2_ASMMACROS_H */ 299