aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp6
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td2
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td60
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td40
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp4
5 files changed, 40 insertions, 72 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 23e1037baa..97134ee3d1 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -263,7 +263,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
} else {
setOperationAction(ISD::MUL, MVT::i64, Expand);
setOperationAction(ISD::MULHU, MVT::i32, Expand);
- if (!Subtarget->isThumb1Only() && !Subtarget->hasV6Ops())
+ if (!Subtarget->hasV6Ops())
setOperationAction(ISD::MULHS, MVT::i32, Expand);
}
setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
@@ -985,8 +985,8 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
// FIXME: handle tail calls differently.
unsigned CallOpc;
- if (Subtarget->isThumb1Only()) {
- if (!Subtarget->hasV5TOps() && (!isDirect || isARMFunc))
+ if (Subtarget->isThumb()) {
+ if ((!isDirect || isARMFunc) && !Subtarget->hasV5TOps())
CallOpc = ARMISD::CALL_NOLINK;
else
CallOpc = isARMFunc ? ARMISD::CALL : ARMISD::tCALL;
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 3194fbc0a9..fe32c5f669 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -808,7 +808,7 @@ class ThumbI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
class TI<dag oops, dag iops, string asm, list<dag> pattern>
: ThumbI<oops, iops, AddrModeNone, Size2Bytes, asm, "", pattern>;
-// BL, BLX(1) are translated by assembler into two instructions
+// tBL, tBX instructions
class TIx2<dag oops, dag iops, string asm, list<dag> pattern>
: ThumbI<oops, iops, AddrModeNone, Size4Bytes, asm, "", pattern>;
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
index b7aa941431..9917e016dd 100644
--- a/lib/Target/ARM/ARMInstrThumb.td
+++ b/lib/Target/ARM/ARMInstrThumb.td
@@ -170,24 +170,26 @@ let isCall = 1,
D0, D1, D2, D3, D4, D5, D6, D7,
D16, D17, D18, D19, D20, D21, D22, D23,
D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in {
- def tBL : T1Ix2<(outs), (ins i32imm:$func, variable_ops),
+ // Also used for Thumb2
+ def tBL : TIx2<(outs), (ins i32imm:$func, variable_ops),
"bl ${func:call}",
[(ARMtcall tglobaladdr:$func)]>,
- Requires<[IsThumb1Only, IsNotDarwin]>;
+ Requires<[IsThumb, IsNotDarwin]>;
- // ARMv5T and above
- def tBLXi : T1Ix2<(outs), (ins i32imm:$func, variable_ops),
+ // ARMv5T and above, also used for Thumb2
+ def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops),
"blx ${func:call}",
[(ARMcall tglobaladdr:$func)]>,
- Requires<[IsThumb1Only, HasV5T, IsNotDarwin]>;
+ Requires<[IsThumb, HasV5T, IsNotDarwin]>;
- def tBLXr : T1I<(outs), (ins tGPR:$func, variable_ops),
+ // Also used for Thumb2
+ def tBLXr : TI<(outs), (ins GPR:$func, variable_ops),
"blx $func",
- [(ARMtcall tGPR:$func)]>,
- Requires<[IsThumb1Only, HasV5T, IsNotDarwin]>;
+ [(ARMtcall GPR:$func)]>,
+ Requires<[IsThumb, HasV5T, IsNotDarwin]>;
// ARMv4T
- def tBX : T1Ix2<(outs), (ins tGPR:$func, variable_ops),
+ def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops),
"mov lr, pc\n\tbx $func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsThumb1Only, IsNotDarwin]>;
@@ -199,24 +201,26 @@ let isCall = 1,
D0, D1, D2, D3, D4, D5, D6, D7,
D16, D17, D18, D19, D20, D21, D22, D23,
D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in {
- def tBLr9 : T1Ix2<(outs), (ins i32imm:$func, variable_ops),
+ // Also used for Thumb2
+ def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops),
"bl ${func:call}",
[(ARMtcall tglobaladdr:$func)]>,
- Requires<[IsThumb1Only, IsDarwin]>;
+ Requires<[IsThumb, IsDarwin]>;
- // ARMv5T and above
- def tBLXi_r9 : T1Ix2<(outs), (ins i32imm:$func, variable_ops),
+ // ARMv5T and above, also used for Thumb2
+ def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops),
"blx ${func:call}",
[(ARMcall tglobaladdr:$func)]>,
- Requires<[IsThumb1Only, HasV5T, IsDarwin]>;
+ Requires<[IsThumb, HasV5T, IsDarwin]>;
- def tBLXr_r9 : T1I<(outs), (ins tGPR:$func, variable_ops),
+ // Also used for Thumb2
+ def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops),
"blx $func",
- [(ARMtcall tGPR:$func)]>,
- Requires<[IsThumb1Only, HasV5T, IsDarwin]>;
+ [(ARMtcall GPR:$func)]>,
+ Requires<[IsThumb, HasV5T, IsDarwin]>;
// ARMv4T
- def tBXr9 : T1Ix2<(outs), (ins tGPR:$func, variable_ops),
+ def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops),
"mov lr, pc\n\tbx $func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsThumb1Only, IsDarwin]>;
@@ -229,7 +233,7 @@ let isBranch = 1, isTerminator = 1 in {
[(br bb:$target)]>;
// Far jump
- def tBfar : T1Ix2<(outs), (ins brtarget:$target),
+ def tBfar : TIx2<(outs), (ins brtarget:$target),
"bl $target\t@ far jump",[]>;
def tBR_JTr : T1JTI<(outs),
@@ -601,7 +605,7 @@ def tLEApcrelJT : T1I<(outs tGPR:$dst), (ins i32imm:$label, i32imm:$id),
// __aeabi_read_tp preserves the registers r1-r3.
let isCall = 1,
Defs = [R0, LR] in {
- def tTPsoft : T1Ix2<(outs), (ins),
+ def tTPsoft : TIx2<(outs), (ins),
"bl __aeabi_read_tp",
[(set R0, ARMthread_pointer)]>;
}
@@ -636,20 +640,20 @@ def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
// Direct calls
def : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>,
- Requires<[IsThumb1Only, IsNotDarwin]>;
+ Requires<[IsThumb, IsNotDarwin]>;
def : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>,
- Requires<[IsThumb1Only, IsDarwin]>;
+ Requires<[IsThumb, IsDarwin]>;
def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>,
- Requires<[IsThumb1Only, HasV5T, IsNotDarwin]>;
+ Requires<[IsThumb, HasV5T, IsNotDarwin]>;
def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>,
- Requires<[IsThumb1Only, HasV5T, IsDarwin]>;
+ Requires<[IsThumb, HasV5T, IsDarwin]>;
// Indirect calls to ARM routines
-def : Tv5Pat<(ARMcall tGPR:$dst), (tBLXr tGPR:$dst)>,
- Requires<[IsThumb1Only, HasV5T, IsNotDarwin]>;
-def : Tv5Pat<(ARMcall tGPR:$dst), (tBLXr_r9 tGPR:$dst)>,
- Requires<[IsThumb1Only, HasV5T, IsDarwin]>;
+def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>,
+ Requires<[IsThumb, HasV5T, IsNotDarwin]>;
+def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>,
+ Requires<[IsThumb, HasV5T, IsDarwin]>;
// zextload i1 -> zextload i8
def : T1Pat<(zextloadi1 t_addrmode_s1:$addr),
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 361afcc4f0..bb4f11a307 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -1016,40 +1016,6 @@ let isReturn = 1, isTerminator = 1, mayLoad = 1 in
"ldm${addr:submode}${p} $addr, $dst1",
[]>;
-// On non-Darwin platforms R9 is callee-saved.
-let isCall = 1,
- Defs = [R0, R1, R2, R3, R12, LR,
- D0, D1, D2, D3, D4, D5, D6, D7,
- D16, D17, D18, D19, D20, D21, D22, D23,
- D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in {
-def t2BL : T2XI<(outs), (ins i32imm:$func, variable_ops),
- "bl ${func:call}",
- [(ARMcall tglobaladdr:$func)]>,
- Requires<[IsThumb2, IsNotDarwin]>;
-
-def t2BLX : T2XI<(outs), (ins GPR:$func, variable_ops),
- "blx $func",
- [(ARMcall GPR:$func)]>,
- Requires<[IsThumb2, IsNotDarwin]>;
-}
-
-// On Darwin R9 is call-clobbered.
-let isCall = 1,
- Defs = [R0, R1, R2, R3, R9, R12, LR,
- D0, D1, D2, D3, D4, D5, D6, D7,
- D16, D17, D18, D19, D20, D21, D22, D23,
- D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in {
-def t2BLr9 : T2XI<(outs), (ins i32imm:$func, variable_ops),
- "bl ${func:call}",
- [(ARMcall tglobaladdr:$func)]>,
- Requires<[IsThumb2, IsDarwin]>;
-
-def t2BLXr9 : T2XI<(outs), (ins GPR:$func, variable_ops),
- "blx $func",
- [(ARMcall GPR:$func)]>,
- Requires<[IsThumb2, IsDarwin]>;
-}
-
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
let isPredicable = 1 in
def t2B : T2XI<(outs), (ins brtarget:$target),
@@ -1103,9 +1069,3 @@ def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
def : T2Pat<(i32 imm:$src),
(t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>;
-
-// Direct calls
-def : T2Pat<(ARMcall texternalsym:$func), (t2BL texternalsym:$func)>,
- Requires<[IsThumb2, IsNotDarwin]>;
-def : T2Pat<(ARMcall texternalsym:$func), (t2BLr9 texternalsym:$func)>,
- Requires<[IsThumb2, IsDarwin]>;
diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp
index e611088574..d30592b0f4 100644
--- a/lib/Target/ARM/ARMSubtarget.cpp
+++ b/lib/Target/ARM/ARMSubtarget.cpp
@@ -75,6 +75,10 @@ ARMSubtarget::ARMSubtarget(const Module &M, const std::string &FS,
}
}
+ // Thumb2 implies at least V6T2.
+ if (ARMArchVersion < V6T2 && ThumbMode >= Thumb2)
+ ARMArchVersion = V6T2;
+
if (Len >= 10) {
if (TT.find("-darwin") != std::string::npos)
// arm-darwin