From e1e460dbc561cdd87be5f3d67a22ab59f73ec066 Mon Sep 17 00:00:00 2001 From: Toma Tabacu Date: Thu, 11 Jun 2015 10:36:10 +0000 Subject: [PATCH] Recommit "[mips] [IAS] Add support for BNE and BEQ with an immediate operand." (r239396). Apparently, Arcanist didn't include some of my local changes in my previous commit attempt. llvm-svn: 239523 --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 61 ++++++++++++++++++ llvm/lib/Target/Mips/Mips64InstrInfo.td | 2 - llvm/lib/Target/Mips/MipsInstrInfo.td | 11 ++++ llvm/test/MC/Mips/mips-expansions-bad.s | 4 ++ llvm/test/MC/Mips/mips-expansions.s | 62 +++++++++++++++++++ llvm/test/MC/Mips/mips64-expansions.s | 78 ++++++++++++++++++++++++ llvm/test/MC/Mips/set-nomacro.s | 14 +++++ 7 files changed, 230 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 7002566..8028e6d 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -208,6 +208,9 @@ class MipsAsmParser : public MCTargetAsmParser { bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions); + bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions); + void createNop(bool hasShortDelaySlot, SMLoc IDLoc, SmallVectorImpl &Instructions); @@ -1619,6 +1622,8 @@ bool MipsAsmParser::needsExpansion(MCInst &Inst) { case Mips::SWM_MM: case Mips::JalOneReg: case Mips::JalTwoReg: + case Mips::BneImm: + case Mips::BeqImm: return true; default: return false; @@ -1645,6 +1650,9 @@ bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, case Mips::JalOneReg: case Mips::JalTwoReg: return expandJalWithRegs(Inst, IDLoc, Instructions); + case Mips::BneImm: + case Mips::BeqImm: + return expandBranchImm(Inst, IDLoc, Instructions); } } @@ -2035,6 +2043,59 @@ bool MipsAsmParser::expandUncondBranchMMPseudo( return false; } +bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions) { + const MCOperand &DstRegOp = Inst.getOperand(0); + assert(DstRegOp.isReg() && "expected register operand kind"); + + const MCOperand &ImmOp = Inst.getOperand(1); + assert(ImmOp.isImm() && "expected immediate operand kind"); + + const MCOperand &MemOffsetOp = Inst.getOperand(2); + assert(MemOffsetOp.isImm() && "expected immediate operand kind"); + + unsigned OpCode = 0; + switch(Inst.getOpcode()) { + case Mips::BneImm: + OpCode = Mips::BNE; + break; + case Mips::BeqImm: + OpCode = Mips::BEQ; + break; + default: + llvm_unreachable("Unknown immediate branch pseudo-instruction."); + break; + } + + int64_t ImmValue = ImmOp.getImm(); + if (ImmValue == 0) { + MCInst BranchInst; + BranchInst.setOpcode(OpCode); + BranchInst.addOperand(DstRegOp); + BranchInst.addOperand(MCOperand::createReg(Mips::ZERO)); + BranchInst.addOperand(MemOffsetOp); + Instructions.push_back(BranchInst); + } else { + warnIfNoMacro(IDLoc); + + unsigned ATReg = getATReg(IDLoc); + if (!ATReg) + return true; + + if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc, + Instructions)) + return true; + + MCInst BranchInst; + BranchInst.setOpcode(OpCode); + BranchInst.addOperand(DstRegOp); + BranchInst.addOperand(MCOperand::createReg(ATReg)); + BranchInst.addOperand(MemOffsetOp); + Instructions.push_back(BranchInst); + } + return false; +} + void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions, bool isLoad, bool isImmOpnd) { diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index 8a27874..83781ff 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -27,8 +27,6 @@ def uimm16_64 : Operand { // Signed Operand def simm10_64 : Operand; -def imm64: Operand; - // Transformation Function - get Imm - 32. def Subtract32 : SDNodeXFormgetZExtValue() - 32); diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 0c154fd..73c1fb5 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -358,6 +358,8 @@ def calltarget : Operand { let ParserMatchClass = MipsJumpTargetAsmOperand; } +def imm64: Operand; + def simm9 : Operand; def simm10 : Operand; def simm11 : Operand; @@ -1682,6 +1684,15 @@ def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs), def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs), "jal\t$rs"> ; +let hasDelaySlot = 1 in { +def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), + (ins imm64:$imm64, brtarget:$offset), + "bne\t$rt, $imm64, $offset">; +def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), + (ins imm64:$imm64, brtarget:$offset), + "beq\t$rt, $imm64, $offset">; +} + //===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/Mips/mips-expansions-bad.s b/llvm/test/MC/Mips/mips-expansions-bad.s index 6bbde26..6e747c3 100644 --- a/llvm/test/MC/Mips/mips-expansions-bad.s +++ b/llvm/test/MC/Mips/mips-expansions-bad.s @@ -22,3 +22,7 @@ # 64-BIT: ori $5, $5, %lo(symbol) dli $5, 1 # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 64-bit architecture + bne $2, 0x100010001, 1332 + # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate + beq $2, 0x100010001, 1332 + # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate diff --git a/llvm/test/MC/Mips/mips-expansions.s b/llvm/test/MC/Mips/mips-expansions.s index d3fdf39..0491c31 100644 --- a/llvm/test/MC/Mips/mips-expansions.s +++ b/llvm/test/MC/Mips/mips-expansions.s @@ -83,3 +83,65 @@ sdc1 $f0, symbol # CHECK: lui $1, %hi(symbol) # CHECK: sdc1 $f0, %lo(symbol)($1) + +# Test BNE with an immediate as the 2nd operand. + bne $2, 0, 1332 +# CHECK: bnez $2, 1332 # encoding: [0x4d,0x01,0x40,0x14] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + bne $2, 123, 1332 +# CHECK: ori $1, $zero, 123 # encoding: [0x7b,0x00,0x01,0x34] +# CHECK: bne $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x14] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + bne $2, -2345, 1332 +# CHECK: addiu $1, $zero, -2345 # encoding: [0xd7,0xf6,0x01,0x24] +# CHECK: bne $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x14] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + bne $2, 65538, 1332 +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 2 # encoding: [0x02,0x00,0x21,0x34] +# CHECK: bne $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x14] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + bne $2, ~7, 1332 +# CHECK: addiu $1, $zero, -8 # encoding: [0xf8,0xff,0x01,0x24] +# CHECK: bne $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x14] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + bne $2, 0x10000, 1332 +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: bne $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x14] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + +# Test BEQ with an immediate as the 2nd operand. + beq $2, 0, 1332 +# CHECK: beqz $2, 1332 # encoding: [0x4d,0x01,0x40,0x10] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + beq $2, 123, 1332 +# CHECK: ori $1, $zero, 123 # encoding: [0x7b,0x00,0x01,0x34] +# CHECK: beq $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x10] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + beq $2, -2345, 1332 +# CHECK: addiu $1, $zero, -2345 # encoding: [0xd7,0xf6,0x01,0x24] +# CHECK: beq $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x10] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + beq $2, 65538, 1332 +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 2 # encoding: [0x02,0x00,0x21,0x34] +# CHECK: beq $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x10] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + beq $2, ~7, 1332 +# CHECK: addiu $1, $zero, -8 # encoding: [0xf8,0xff,0x01,0x24] +# CHECK: beq $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x10] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + beq $2, 0x10000, 1332 +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: beq $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x10] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] diff --git a/llvm/test/MC/Mips/mips64-expansions.s b/llvm/test/MC/Mips/mips64-expansions.s index 62a9520..620793a 100644 --- a/llvm/test/MC/Mips/mips64-expansions.s +++ b/llvm/test/MC/Mips/mips64-expansions.s @@ -193,3 +193,81 @@ dli $9, 0x80000000 # CHECK: ori $9, $zero, 32768 # encoding: [0x00,0x80,0x09,0x34] # CHECK: dsll $9, $9, 16 # encoding: [0x38,0x4c,0x09,0x00] + +# Test bne with an immediate as the 2nd operand. + bne $2, 0x100010001, 1332 +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: bne $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x14] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + bne $2, 0x1000100010001, 1332 +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: bne $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x14] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + bne $2, -0x100010001, 1332 +# CHECK: lui $1, 65535 # encoding: [0xff,0xff,0x01,0x3c] +# CHECK: ori $1, $1, 65534 # encoding: [0xfe,0xff,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 65534 # encoding: [0xfe,0xff,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 65535 # encoding: [0xff,0xff,0x21,0x34] +# CHECK: bne $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x14] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + bne $2, -0x1000100010001, 1332 +# CHECK: lui $1, 65534 # encoding: [0xfe,0xff,0x01,0x3c] +# CHECK: ori $1, $1, 65534 # encoding: [0xfe,0xff,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 65534 # encoding: [0xfe,0xff,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 65535 # encoding: [0xff,0xff,0x21,0x34] +# CHECK: bne $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x14] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + +# Test beq with an immediate as the 2nd operand. + beq $2, 0x100010001, 1332 +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: beq $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x10] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + beq $2, 0x1000100010001, 1332 +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: beq $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x10] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + beq $2, -0x100010001, 1332 +# CHECK: lui $1, 65535 # encoding: [0xff,0xff,0x01,0x3c] +# CHECK: ori $1, $1, 65534 # encoding: [0xfe,0xff,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 65534 # encoding: [0xfe,0xff,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 65535 # encoding: [0xff,0xff,0x21,0x34] +# CHECK: beq $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x10] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + + beq $2, -0x1000100010001, 1332 +# CHECK: lui $1, 65534 # encoding: [0xfe,0xff,0x01,0x3c] +# CHECK: ori $1, $1, 65534 # encoding: [0xfe,0xff,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 65534 # encoding: [0xfe,0xff,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 65535 # encoding: [0xff,0xff,0x21,0x34] +# CHECK: beq $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x10] +# CHECK: nop # encoding: [0x00,0x00,0x00,0x00] diff --git a/llvm/test/MC/Mips/set-nomacro.s b/llvm/test/MC/Mips/set-nomacro.s index d81048f..0f66bce 100644 --- a/llvm/test/MC/Mips/set-nomacro.s +++ b/llvm/test/MC/Mips/set-nomacro.s @@ -15,6 +15,11 @@ jal $25 jal $4, $25 + bne $2, 0, 1332 + bne $2, 1, 1332 + beq $2, 0, 1332 + beq $2, 1, 1332 + add $4, $5, $6 .set noreorder @@ -42,5 +47,14 @@ jal $4, $25 # CHECK-NOT: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions + bne $2, 0, 1332 +# CHECK-NOT: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions + bne $2, 1, 1332 +# CHECK: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions + beq $2, 0, 1332 +# CHECK-NOT: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions + beq $2, 1, 1332 +# CHECK: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions + add $4, $5, $6 # CHECK-NOT: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions -- 2.7.4