summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-03-12 00:45:26 +0000
committerJim Grosbach <grosbach@apple.com>2011-03-12 00:45:26 +0000
commitf859a545de30bbc848d1b0896b7ef8fa84fd631b (patch)
tree1f5b279c0e39b2f84084e46e48a36b7331195e1f
parentcea5afc98558b24bafee28a02ec21a6d42d2d8e7 (diff)
Pseudo-ize the ARM Darwin *r9 call instruction definitions. They're the same
actual instruction as the non-Darwin defs, but have different call-clobber semantics and so need separate patterns. They don't need to duplicate the encoding information, however. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127515 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp20
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td40
2 files changed, 33 insertions, 27 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
index b48fbf6740..4c9ab3c146 100644
--- a/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -1035,6 +1035,26 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OutStreamer.EmitInstruction(TmpInst);
return;
}
+ // Darwin call instructions are just normal call instructions with different
+ // clobber semantics (they clobber R9).
+ case ARM::BLr9:
+ case ARM::BLr9_pred:
+ case ARM::BLXr9:
+ case ARM::BLXr9_pred: {
+ unsigned newOpc;
+ switch (Opc) {
+ default: assert(0);
+ case ARM::BLr9: newOpc = ARM::BL; break;
+ case ARM::BLr9_pred: newOpc = ARM::BL_pred; break;
+ case ARM::BLXr9: newOpc = ARM::BLX; break;
+ case ARM::BLXr9_pred: newOpc = ARM::BLX_pred; break;
+ }
+ MCInst TmpInst;
+ LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
+ TmpInst.setOpcode(newOpc);
+ OutStreamer.EmitInstruction(TmpInst);
+ return;
+ }
case ARM::BXr9_CALL:
case ARM::BX_CALL: {
{
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 05fbc40d1c..98b211ddd9 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -1371,39 +1371,25 @@ let isCall = 1,
D16, D17, D18, D19, D20, D21, D22, D23,
D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
Uses = [R7, SP] in {
- def BLr9 : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
- IIC_Br, "bl\t$func",
- [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> {
- let Inst{31-28} = 0b1110;
- bits<24> func;
- let Inst{23-0} = func;
- }
+ def BLr9 : ARMPseudoInst<(outs), (ins bltarget:$func, variable_ops),
+ Size4Bytes, IIC_Br,
+ [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]>;
- def BLr9_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
- IIC_Br, "bl", "\t$func",
+ def BLr9_pred : ARMPseudoInst<(outs),
+ (ins bltarget:$func, pred:$p, variable_ops),
+ Size4Bytes, IIC_Br,
[(ARMcall_pred tglobaladdr:$func)]>,
- Requires<[IsARM, IsDarwin]> {
- bits<24> func;
- let Inst{23-0} = func;
- }
+ Requires<[IsARM, IsDarwin]>;
// ARMv5T and above
- def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
- IIC_Br, "blx\t$func",
- [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
- bits<4> func;
- let Inst{31-4} = 0b1110000100101111111111110011;
- let Inst{3-0} = func;
- }
+ def BLXr9 : ARMPseudoInst<(outs), (ins GPR:$func, variable_ops),
+ Size4Bytes, IIC_Br,
+ [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]>;
- def BLXr9_pred : AI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
- IIC_Br, "blx", "\t$func",
+ def BLXr9_pred: ARMPseudoInst<(outs), (ins GPR:$func, pred:$p, variable_ops),
+ Size4Bytes, IIC_Br,
[(ARMcall_pred GPR:$func)]>,
- Requires<[IsARM, HasV5T, IsDarwin]> {
- bits<4> func;
- let Inst{27-4} = 0b000100101111111111110011;
- let Inst{3-0} = func;
- }
+ Requires<[IsARM, HasV5T, IsDarwin]>;
// ARMv4T
// Note: Restrict $func to the tGPR regclass to prevent it being in LR.