[mips] Expansion of BEQL and BNEL with immediate operands

Adds support for BEQL and BNEL macros with immediate operands.

Patch by: Srdjan Obucina

Reviewers: dsanders, zoran.jovanovic, vkalintiris, sdardis, obucina, seanbruno

Differential Revision: https://reviews.llvm.org/D17040

llvm-svn: 293905
This commit is contained in:
Simon Dardis 2017-02-02 16:13:49 +00:00
parent 5b7a09aca4
commit 08ce5fb66b
5 changed files with 82 additions and 6 deletions

View File

@ -2217,6 +2217,8 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::BneImm:
case Mips::BeqImm:
case Mips::BEQLImmMacro:
case Mips::BNELImmMacro:
return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::BLT:
case Mips::BLE:
@ -2855,6 +2857,8 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
"expected immediate or expression operand");
bool IsLikely = false;
unsigned OpCode = 0;
switch(Inst.getOpcode()) {
case Mips::BneImm:
@ -2863,16 +2867,29 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
case Mips::BeqImm:
OpCode = Mips::BEQ;
break;
case Mips::BEQLImmMacro:
OpCode = Mips::BEQL;
IsLikely = true;
break;
case Mips::BNELImmMacro:
OpCode = Mips::BNEL;
IsLikely = true;
break;
default:
llvm_unreachable("Unknown immediate branch pseudo-instruction.");
break;
}
int64_t ImmValue = ImmOp.getImm();
if (ImmValue == 0)
TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
STI);
else {
if (ImmValue == 0) {
if (IsLikely) {
TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
} else
TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
STI);
} else {
warnIfNoMacro(IDLoc);
unsigned ATReg = getATReg(IDLoc);
@ -2883,7 +2900,12 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
IDLoc, Out, STI))
return true;
TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
if (IsLikely) {
TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
} else
TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
}
return false;
}

View File

@ -2534,6 +2534,9 @@ class CondBranchImmPseudo<string instr_asm> :
MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
!strconcat(instr_asm, "\t$rs, $imm, $offset")>;
def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
def BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
def BLTImmMacro : CondBranchImmPseudo<"blt">;
def BLEImmMacro : CondBranchImmPseudo<"ble">;
def BGEImmMacro : CondBranchImmPseudo<"bge">;

View File

@ -20,6 +20,10 @@ local_label:
bgtu $7, $8, local_label
# CHECK: :[[@LINE-1]]:3: error: pseudo-instruction requires $at, which is not available
beql $7, 256, local_label
# CHECK: :[[@LINE-1]]:3: error: pseudo-instruction requires $at, which is not available
bnel $7, 256, local_label
# CHECK: :[[@LINE-1]]:3: error: pseudo-instruction requires $at, which is not available
bltl $7, $8, local_label
# CHECK: :[[@LINE-1]]:3: error: pseudo-instruction requires $at, which is not available
bltul $7, $8, local_label

View File

@ -2,7 +2,45 @@
# RUN: FileCheck %s --check-prefix=ALL
.text
foo: # ALL-LABEL: foo:
foo:
beql $a2, 0x1ffff, foo # ALL: lui $1, 1
# ALL: ori $1, $1, 65535
# ALL: beql $6, $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
# ALL: nop
beql $a2, -4096, foo # ALL: addiu $1, $zero, -4096
# ALL: beql $6, $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
beql $a2, -0x10000, foo # ALL: lui $1, 65535
# ALL: beql $6, $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
beql $a2, 16, foo # ALL: addiu $1, $zero, 16
# ALL: beql $6, $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
# ALL: nop
bnel $a2, 0x1ffff, foo # ALL: lui $1, 1
# ALL: ori $1, $1, 65535
# ALL: bnel $6, $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
# ALL: nop
bnel $a2, -4096, foo # ALL: addiu $1, $zero, -4096
# ALL: bnel $6, $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bnel $a2, -0x10000, foo # ALL: lui $1, 65535
# ALL: bnel $6, $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bnel $a2, 16, foo # ALL: addiu $1, $zero, 16
# ALL: bnel $6, $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
# ALL: nop
beql $a2, 32767, foo # ALL: addiu $1, $zero, 32767
# ALL: beql $6, $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
# ALL: nop
bnel $a2, 32768, foo # ALL: ori $1, $zero, 32768
# ALL: bnel $6, $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
# ALL: nop
blt $a2, 16, foo # ALL: addiu $1, $zero, 16
# ALL: slt $1, $6, $1
# ALL: bnez $1, foo

View File

@ -181,6 +181,15 @@
bgtu $0, $0, local_label
# CHECK-NOT: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions
bnel $2, 0, local_label
# CHECK-NOT: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions
bnel $2, 1, local_label
# CHECK: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions
beql $2, 0, local_label
# CHECK-NOT: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions
beql $2, 1, local_label
# CHECK: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions
ulh $5, 0
# CHECK: [[@LINE-1]]:3: warning: macro instruction expanded into multiple instructions
ulhu $5, 0