[mips][ias] Implement macro expansion when bcc has an immediate where a register belongs.

Summary: Fixes PR24915.

Reviewers: vkalintiris

Subscribers: emaste, seanbruno, llvm-commits

Differential Revision: http://reviews.llvm.org/D13533

llvm-svn: 250042
This commit is contained in:
Daniel Sanders 2015-10-12 14:24:05 +00:00
parent 332cef6c5f
commit b1ef88c172
4 changed files with 207 additions and 2 deletions

View File

@ -1937,6 +1937,22 @@ bool MipsAsmParser::needsExpansion(MCInst &Inst) {
case Mips::BLEUL:
case Mips::BGEUL:
case Mips::BGTUL:
case Mips::BLTImmMacro:
case Mips::BLEImmMacro:
case Mips::BGEImmMacro:
case Mips::BGTImmMacro:
case Mips::BLTUImmMacro:
case Mips::BLEUImmMacro:
case Mips::BGEUImmMacro:
case Mips::BGTUImmMacro:
case Mips::BLTLImmMacro:
case Mips::BLELImmMacro:
case Mips::BGELImmMacro:
case Mips::BGTLImmMacro:
case Mips::BLTULImmMacro:
case Mips::BLEULImmMacro:
case Mips::BGEULImmMacro:
case Mips::BGTULImmMacro:
case Mips::SDivMacro:
case Mips::UDivMacro:
case Mips::DSDivMacro:
@ -2028,6 +2044,22 @@ bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
case Mips::BLEUL:
case Mips::BGEUL:
case Mips::BGTUL:
case Mips::BLTImmMacro:
case Mips::BLEImmMacro:
case Mips::BGEImmMacro:
case Mips::BGTImmMacro:
case Mips::BLTUImmMacro:
case Mips::BLEUImmMacro:
case Mips::BGEUImmMacro:
case Mips::BGTUImmMacro:
case Mips::BLTLImmMacro:
case Mips::BLELImmMacro:
case Mips::BGELImmMacro:
case Mips::BGTLImmMacro:
case Mips::BLTULImmMacro:
case Mips::BLEULImmMacro:
case Mips::BGEULImmMacro:
case Mips::BGTULImmMacro:
return expandCondBranches(Inst, IDLoc, Instructions);
case Mips::SDivMacro:
return expandDiv(Inst, IDLoc, Instructions, false, true);
@ -2614,14 +2646,84 @@ MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions) {
bool EmittedNoMacroWarning = false;
unsigned PseudoOpcode = Inst.getOpcode();
unsigned SrcReg = Inst.getOperand(0).getReg();
unsigned TrgReg = Inst.getOperand(1).getReg();
const MCOperand &TrgOp = Inst.getOperand(1);
const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
unsigned ZeroSrcOpcode, ZeroTrgOpcode;
bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
unsigned TrgReg;
if (TrgOp.isReg())
TrgReg = TrgOp.getReg();
else if (TrgOp.isImm()) {
warnIfNoMacro(IDLoc);
EmittedNoMacroWarning = true;
TrgReg = getATReg(IDLoc);
if (!TrgReg)
return true;
switch(PseudoOpcode) {
default:
llvm_unreachable("unknown opcode for branch pseudo-instruction");
case Mips::BLTImmMacro:
PseudoOpcode = Mips::BLT;
break;
case Mips::BLEImmMacro:
PseudoOpcode = Mips::BLE;
break;
case Mips::BGEImmMacro:
PseudoOpcode = Mips::BGE;
break;
case Mips::BGTImmMacro:
PseudoOpcode = Mips::BGT;
break;
case Mips::BLTUImmMacro:
PseudoOpcode = Mips::BLTU;
break;
case Mips::BLEUImmMacro:
PseudoOpcode = Mips::BLEU;
break;
case Mips::BGEUImmMacro:
PseudoOpcode = Mips::BGEU;
break;
case Mips::BGTUImmMacro:
PseudoOpcode = Mips::BGTU;
break;
case Mips::BLTLImmMacro:
PseudoOpcode = Mips::BLTL;
break;
case Mips::BLELImmMacro:
PseudoOpcode = Mips::BLEL;
break;
case Mips::BGELImmMacro:
PseudoOpcode = Mips::BGEL;
break;
case Mips::BGTLImmMacro:
PseudoOpcode = Mips::BGTL;
break;
case Mips::BLTULImmMacro:
PseudoOpcode = Mips::BLTUL;
break;
case Mips::BLEULImmMacro:
PseudoOpcode = Mips::BLEUL;
break;
case Mips::BGEULImmMacro:
PseudoOpcode = Mips::BGEUL;
break;
case Mips::BGTULImmMacro:
PseudoOpcode = Mips::BGTUL;
break;
}
if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
false, IDLoc, Instructions))
return true;
}
switch (PseudoOpcode) {
case Mips::BLT:
case Mips::BLTU:
@ -2770,7 +2872,8 @@ bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
if (!ATRegNum)
return true;
warnIfNoMacro(IDLoc);
if (!EmittedNoMacroWarning)
warnIfNoMacro(IDLoc);
// SLT fits well with 2 of our 4 pseudo-branches:
// BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and

View File

@ -1809,6 +1809,27 @@ def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
class CondBranchImmPseudo<string instr_asm> :
MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
!strconcat(instr_asm, "\t$rs, $imm, $offset")>;
def BLTImmMacro : CondBranchImmPseudo<"blt">;
def BLEImmMacro : CondBranchImmPseudo<"ble">;
def BGEImmMacro : CondBranchImmPseudo<"bge">;
def BGTImmMacro : CondBranchImmPseudo<"bgt">;
def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
// FIXME: Predicates are removed because instructions are matched regardless of
// predicates, because PredicateControl was not in the hierarchy. This was
// done to emit more precise error message from expansion function.

View File

@ -0,0 +1,12 @@
# RUN: not llvm-mc %s -arch=mips -mcpu=mips32r2 2>&1 | \
# RUN: FileCheck %s --check-prefix=ALL
.text
.set noat
foo:
blt $a2, 16, foo # ALL: :[[@LINE]]:5: error: pseudo-instruction requires $at, which is not available
.set at
.set noreorder
.set nomacro
blt $a2, 16, foo # ALL: :[[@LINE]]:5: warning: macro instruction expanded into multiple instructions
# ALL-NOT: :[[@LINE-1]]:5: warning: macro instruction expanded into multiple instructions

View File

@ -0,0 +1,69 @@
# RUN: llvm-mc %s -arch=mips -mcpu=mips32r2 -show-encoding 2>&1 | \
# RUN: FileCheck %s --check-prefix=ALL
.text
foo: # ALL-LABEL: foo:
blt $a2, 16, foo # ALL: addiu $1, $zero, 16
# ALL: slt $1, $6, $1
# ALL: bnez $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
ble $a2, 16, foo # ALL: addiu $1, $zero, 16
# ALL: slt $1, $1, $6
# ALL: beqz $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bge $a2, 32767, foo # ALL: addiu $1, $zero, 32767
# ALL: slt $1, $6, $1
# ALL: beqz $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bgt $a2, 32768, foo # ALL: ori $1, $zero, 32768
# ALL: slt $1, $1, $6
# ALL: bnez $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bltu $a2, 16, foo # ALL: addiu $1, $zero, 16
# ALL: sltu $1, $6, $1
# ALL: bnez $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bleu $a2, 16, foo # ALL: addiu $1, $zero, 16
# ALL: sltu $1, $1, $6
# ALL: beqz $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bgeu $a2, 32767, foo # ALL: addiu $1, $zero, 32767
# ALL: sltu $1, $6, $1
# ALL: beqz $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bgtu $a2, 32768, foo # ALL: ori $1, $zero, 32768
# ALL: sltu $1, $1, $6
# ALL: bnez $1, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bltl $a2, 16, foo # ALL: addiu $1, $zero, 16
# ALL: slt $1, $6, $1
# ALL: bnel $1, $zero, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
blel $a2, 16, foo # ALL: addiu $1, $zero, 16
# ALL: slt $1, $1, $6
# ALL: beql $1, $zero, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bgel $a2, 32767, foo # ALL: addiu $1, $zero, 32767
# ALL: slt $1, $6, $1
# ALL: beql $1, $zero, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bgtl $a2, 32768, foo # ALL: ori $1, $zero, 32768
# ALL: slt $1, $1, $6
# ALL: bnel $1, $zero, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bltul $a2, 16, foo # ALL: addiu $1, $zero, 16
# ALL: sltu $1, $6, $1
# ALL: bnel $1, $zero, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bleul $a2, 16, foo # ALL: addiu $1, $zero, 16
# ALL: sltu $1, $1, $6
# ALL: beql $1, $zero, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bgeul $a2, 32767, foo # ALL: addiu $1, $zero, 32767
# ALL: sltu $1, $6, $1
# ALL: beql $1, $zero, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16
bgtul $a2, 65536, foo # ALL: lui $1, 1
# ALL: sltu $1, $1, $6
# ALL: bnel $1, $zero, foo
# ALL: # fixup A - offset: 0, value: foo-4, kind: fixup_Mips_PC16