Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1883,6 +1883,22 @@ 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: @@ -1974,6 +1990,22 @@ 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); @@ -2667,14 +2699,84 @@ bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &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: @@ -2845,7 +2947,8 @@ 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 Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -1809,6 +1809,27 @@ def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6; def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6; +class CondBranchImmPseudo : + 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. Index: test/MC/Mips/macro-bcc-imm-bad.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-bcc-imm-bad.s @@ -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 Index: test/MC/Mips/macro-bcc-imm.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-bcc-imm.s @@ -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