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:
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);
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:
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
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.
--- /dev/null
+# 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
--- /dev/null
+# 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