diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index fec5f72bcfe..1a23651d8d3 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1639,9 +1639,9 @@ let isBranch = 1, isTerminator = 1 in { } -// BLX (immediate) -- for disassembly only +// BLX (immediate) def BLXi : AXI<(outs), (ins br_target:$target), BrMiscFrm, NoItinerary, - "blx\t$target", [/* pattern left blank */]>, + "blx\t$target", []>, Requires<[IsARM, HasV5T]> { let Inst{31-25} = 0b1111101; bits<25> target; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index a528572349b..42e2f7f8f54 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -2675,6 +2675,17 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, delete Op; } + // ARM mode 'blx' need special handling, as the register operand version + // is predicable, but the label operand version is not. So, we can't rely + // on the Mnemonic based checking to correctly figure out when to put + // a CondCode operand in the list. If we're trying to match the label + // version, remove the CondCode operand here. + if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && + static_cast(Operands[2])->isImm()) { + ARMOperand *Op = static_cast(Operands[1]); + Operands.erase(Operands.begin() + 1); + delete Op; + } return false; } diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index 10ffc975b89..352a050f902 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -358,10 +358,12 @@ Lforward: @------------------------------------------------------------------------------ bl _bar - @ FIXME: blx _bar + blx _bar @ CHECK: bl _bar @ encoding: [A,A,A,0xeb] @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbranch +@ CHECK: blx _bar @ encoding: [A,A,A,0xfa] + @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbranch @------------------------------------------------------------------------------ @ BLX (register)