aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-07-28 21:57:55 +0000
committerJim Grosbach <grosbach@apple.com>2011-07-28 21:57:55 +0000
commitcf121c35c484ee17210fde1cecbd896348cd654a (patch)
treee885f8a9ea5516b79628c16b0fb51d63145e5654
parentd1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bf (diff)
ARM assembly parsing and encoding for BLX (immediate).
Add parsing support for BLX (immediate). Since the register operand version is predicated and the label operand version is not, we have to use some special handling to get the operand list right for matching. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136406 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td4
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp11
-rw-r--r--test/MC/ARM/basic-arm-instructions.s4
3 files changed, 16 insertions, 3 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index fec5f72bcf..1a23651d8d 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 a528572349..42e2f7f8f5 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<ARMOperand*>(Operands[2])->isImm()) {
+ ARMOperand *Op = static_cast<ARMOperand*>(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 10ffc975b8..352a050f90 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)