Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1993,6 +1993,8 @@ : MER_Success; case Mips::BneImm: case Mips::BeqImm: + case Mips::BEQLImmMacro: + case Mips::BNELImmMacro: return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success; case Mips::BLT: case Mips::BLE: @@ -2529,7 +2531,10 @@ assert(ImmOp.isImm() && "expected immediate operand kind"); const MCOperand &MemOffsetOp = Inst.getOperand(2); - assert(MemOffsetOp.isImm() && "expected immediate operand kind"); + assert((MemOffsetOp.isImm() && "expected immediate operand kind") || + (MemOffsetOp.isExpr() && "expected expression operand kind")); + + bool IsLikely = false; unsigned OpCode = 0; switch(Inst.getOpcode()) { @@ -2539,16 +2544,29 @@ 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) - emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc, - Instructions); - else { + if (ImmValue == 0) { + if (IsLikely) { + emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, + MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, Instructions); + createNop(false, IDLoc, Instructions); + } else + emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc, + Instructions); + } else { warnIfNoMacro(IDLoc); unsigned ATReg = getATReg(IDLoc); @@ -2559,7 +2577,13 @@ IDLoc, Instructions)) return true; - emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions); + if (IsLikely) { + emitRRX(OpCode, DstRegOp.getReg(), ATReg, MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, + Instructions); + createNop(false, IDLoc, Instructions); + } else + emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, + Instructions); } return false; } Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -1988,6 +1988,9 @@ 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">; Index: test/MC/Mips/branch-pseudos-bad.s =================================================================== --- test/MC/Mips/branch-pseudos-bad.s +++ test/MC/Mips/branch-pseudos-bad.s @@ -20,6 +20,10 @@ 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 Index: test/MC/Mips/macro-bcc-imm.s =================================================================== --- test/MC/Mips/macro-bcc-imm.s +++ test/MC/Mips/macro-bcc-imm.s @@ -2,7 +2,39 @@ # RUN: FileCheck %s --check-prefix=ALL .text -foo: # ALL-LABEL: foo: +foo: + 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 + beql $a2, 16, bar # ALL: addiu $1, $zero, 16 + # ALL: beql $6, $1, bar + # ALL: # fixup A - offset: 0, value: bar-4, kind: fixup_Mips_PC16 + # ALL: nop + 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 + bnel $a2, 16, bar # ALL: addiu $1, $zero, 16 + # ALL: bnel $6, $1, bar + # ALL: # fixup A - offset: 0, value: bar-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 + beql $a2, 32767, bar # ALL: addiu $1, $zero, 32767 + # ALL: beql $6, $1, bar + # ALL: # fixup A - offset: 0, value: bar-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 + bnel $a2, 32768, bar # ALL: ori $1, $zero, 32768 + # ALL: bnel $6, $1, bar + # ALL: # fixup A - offset: 0, value: bar-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 Index: test/MC/Mips/set-nomacro.s =================================================================== --- test/MC/Mips/set-nomacro.s +++ test/MC/Mips/set-nomacro.s @@ -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