llvm.org GIT mirror llvm / ce7bf1c
Initial bits of ARMv4-only support. Patch by John Tytgat! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97886 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 10 years ago
6 changed file(s) with 106 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
331331
332332 static inline
333333 bool isIndirectBranchOpcode(int Opc) {
334 return Opc == ARM::BRIND || Opc == ARM::tBRIND;
334 return Opc == ARM::BRIND || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND;
335335 }
336336
337337 /// getInstrPredicate - If instruction is predicated, returns its predicate
11371137 // Set the conditional execution predicate
11381138 Binary |= II->getPredicate(&MI) << ARMII::CondShift;
11391139
1140 if (TID.Opcode == ARM::BX_RET)
1140 if (TID.Opcode == ARM::BX_RET || TID.Opcode == ARM::MOVPCLR)
11411141 // The return register is LR.
11421142 Binary |= ARMRegisterInfo::getRegisterNumbering(ARM::LR);
11431143 else
112112 //===----------------------------------------------------------------------===//
113113 // ARM Instruction Predicate Definitions.
114114 //
115 def HasV4T : Predicate<"Subtarget->hasV4TOps()">;
116 def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
115117 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
116118 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
117119 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
850852 // Control Flow Instructions.
851853 //
852854
853 let isReturn = 1, isTerminator = 1, isBarrier = 1 in
855 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
856 // ARMV4T and above
854857 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
855 "bx", "\tlr", [(ARMretflag)]> {
856 let Inst{3-0} = 0b1110;
857 let Inst{7-4} = 0b0001;
858 let Inst{19-8} = 0b111111111111;
859 let Inst{27-20} = 0b00010010;
860 }
861
862 // Indirect branches
863 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
864 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
865 [(brind GPR:$dst)]> {
858 "bx", "\tlr", [(ARMretflag)]>,
859 Requires<[IsARM, HasV4T]> {
860 let Inst{3-0} = 0b1110;
866861 let Inst{7-4} = 0b0001;
867862 let Inst{19-8} = 0b111111111111;
868863 let Inst{27-20} = 0b00010010;
864 }
865
866 // ARMV4 only
867 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
868 "mov", "\tpc, lr", [(ARMretflag)]>,
869 Requires<[IsARM, NoV4T]> {
870 let Inst{11-0} = 0b000000001110;
871 let Inst{15-12} = 0b1111;
872 let Inst{19-16} = 0b0000;
873 let Inst{27-20} = 0b00011010;
874 }
875 }
876
877 // Indirect branches
878 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
879 // ARMV4T and above
880 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
881 [(brind GPR:$dst)]>,
882 Requires<[IsARM, HasV4T]> {
883 let Inst{7-4} = 0b0001;
884 let Inst{19-8} = 0b111111111111;
885 let Inst{27-20} = 0b00010010;
886 let Inst{31-28} = 0b1110;
887 }
888
889 // ARMV4 only
890 def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
891 [(brind GPR:$dst)]>,
892 Requires<[IsARM, NoV4T]> {
893 let Inst{11-4} = 0b00000000;
894 let Inst{15-12} = 0b1111;
895 let Inst{19-16} = 0b0000;
896 let Inst{27-20} = 0b00011010;
869897 let Inst{31-28} = 0b1110;
870898 }
871899 }
912940 def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
913941 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
914942 [(ARMcall_nolink tGPR:$func)]>,
915 Requires<[IsARM, IsNotDarwin]> {
943 Requires<[IsARM, HasV4T, IsNotDarwin]> {
916944 let Inst{7-4} = 0b0001;
917945 let Inst{19-8} = 0b111111111111;
918946 let Inst{27-20} = 0b00010010;
947 }
948
949 // ARMv4
950 def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
951 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
952 [(ARMcall_nolink tGPR:$func)]>,
953 Requires<[IsARM, NoV4T, IsNotDarwin]> {
954 let Inst{11-4} = 0b00000000;
955 let Inst{15-12} = 0b1111;
956 let Inst{19-16} = 0b0000;
957 let Inst{27-20} = 0b00011010;
919958 }
920959 }
921960
949988 // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
950989 def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
951990 IIC_Br, "mov\tlr, pc\n\tbx\t$func",
952 [(ARMcall_nolink tGPR:$func)]>, Requires<[IsARM, IsDarwin]> {
991 [(ARMcall_nolink tGPR:$func)]>,
992 Requires<[IsARM, HasV4T, IsDarwin]> {
953993 let Inst{7-4} = 0b0001;
954994 let Inst{19-8} = 0b111111111111;
955995 let Inst{27-20} = 0b00010010;
996 }
997
998 // ARMv4
999 def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
1000 IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
1001 [(ARMcall_nolink tGPR:$func)]>,
1002 Requires<[IsARM, NoV4T, IsDarwin]> {
1003 let Inst{11-4} = 0b00000000;
1004 let Inst{15-12} = 0b1111;
1005 let Inst{19-16} = 0b0000;
1006 let Inst{27-20} = 0b00011010;
9561007 }
9571008 }
9581009
3232
3333 ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
3434 bool isT)
35 : ARMArchVersion(V4T)
35 : ARMArchVersion(V4)
3636 , ARMFPUType(None)
3737 , UseNEONForSinglePrecisionFP(UseNEONFP)
3838 , IsThumb(isT)
5353 // Parse features string.
5454 CPUString = ParseSubtargetFeatures(FS, CPUString);
5555
56 // When no arch is specified either by CPU or by attributes, make the default
57 // ARMv4T.
58 if (CPUString == "generic" && (FS.empty() || FS == "generic"))
59 ARMArchVersion = V4T;
60
5661 // Set the boolean corresponding to the current target triple, or the default
5762 // if one cannot be determined, to true.
5863 unsigned Len = TT.length();
6772 }
6873 if (Idx) {
6974 unsigned SubVer = TT[Idx];
70 if (SubVer > '4' && SubVer <= '9') {
71 if (SubVer >= '7') {
72 ARMArchVersion = V7A;
73 } else if (SubVer == '6') {
74 ARMArchVersion = V6;
75 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
76 ARMArchVersion = V6T2;
77 } else if (SubVer == '5') {
78 ARMArchVersion = V5T;
79 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
80 ARMArchVersion = V5TE;
81 }
82 if (ARMArchVersion >= V6T2)
83 ThumbMode = Thumb2;
75 if (SubVer >= '7' && SubVer <= '9') {
76 ARMArchVersion = V7A;
77 } else if (SubVer == '6') {
78 ARMArchVersion = V6;
79 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
80 ARMArchVersion = V6T2;
81 } else if (SubVer == '5') {
82 ARMArchVersion = V5T;
83 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
84 ARMArchVersion = V5TE;
85 } else if (SubVer == '4') {
86 if (Len >= Idx+2 && TT[Idx+1] == 't')
87 ARMArchVersion = V4T;
88 else
89 ARMArchVersion = V4;
8490 }
8591 }
8692
8793 // Thumb2 implies at least V6T2.
88 if (ARMArchVersion < V6T2 && ThumbMode >= Thumb2)
94 if (ARMArchVersion >= V6T2)
95 ThumbMode = Thumb2;
96 else if (ThumbMode >= Thumb2)
8997 ARMArchVersion = V6T2;
9098
9199 if (Len >= 10) {
2525 class ARMSubtarget : public TargetSubtarget {
2626 protected:
2727 enum ARMArchEnum {
28 V4T, V5T, V5TE, V6, V6T2, V7A
28 V4, V4T, V5T, V5TE, V6, V6T2, V7A
2929 };
3030
3131 enum ARMFPEnum {
3737 Thumb2
3838 };
3939
40 /// ARMArchVersion - ARM architecture version: V4T (base), V5T, V5TE,
40 /// ARMArchVersion - ARM architecture version: V4, V4T (base), V5T, V5TE,
4141 /// V6, V6T2, V7A.
4242 ARMArchEnum ARMArchVersion;
4343
0 ; RUN: llc < %s -mtriple=arm-unknown-eabi | FileCheck %s -check-prefix=THUMB
1 ; RUN: llc < %s -mtriple=arm-unknown-eabi -mcpu=strongarm | FileCheck %s -check-prefix=ARM
2 ; RUN: llc < %s -mtriple=arm-unknown-eabi -mcpu=cortex-a8 | FileCheck %s -check-prefix=THUMB
3 ; RUN: llc < %s -mtriple=arm-unknown-eabi -mattr=+v6 | FileCheck %s -check-prefix=THUMB
4 ; RUN: llc < %s -mtriple=armv4-unknown-eabi | FileCheck %s -check-prefix=ARM
5 ; RUN: llc < %s -mtriple=armv4t-unknown-eabi | FileCheck %s -check-prefix=THUMB
6
7 define arm_aapcscc i32 @test(i32 %a) nounwind readnone {
8 entry:
9 ; ARM: mov pc
10 ; THUMB: bx
11 ret i32 %a
12 }