[llvm-commits] Support for ARMv4

John Tytgat john at bass-software.com
Sat Feb 13 20:25:06 PST 2010


Hi,

I hope this is the right place to submit patches.

Attached one allows ARMv4 arch selection and avoids BX getting emited
when ARMv4 is selected.

Detail:
- lib/Target/ARM/ARMSubtarget.cpp(ARMSubtarget::ARMSubtarget): Make triple
  armv4-* switch ARMArchVersion to V4, allow CPU selection (like strongarm)
  to switch to V4 as well but keep ARMv4T still as default when no arch
  is specified.
- lib/Target/ARM/ARMSubtarget.h(V4): Defined.
- lib/Target/ARM/ARMInstrInfo.td(HasV4T,NoV4T): Define.
  (BX_RET): Add IsARM and HasV4T requirements.
  (MOVPCLR): Define, is equivalent to BX_RET but for ARMv4 only.
  (BRIND): Add IsARM and HasV4T requirements.
  (MOVPC): Define, is equivalent to BRIND but for ARMv4 only.
  (BX, BXr9): Add HasV4T requirements.
- lib/Target/ARM/ARMCodeEmitter.cpp(ARMCodeEmitter::emitMiscBranchInstruction):
  Take ARM::MOVPCLR into account.
- lib/Target/ARM/ARMBaseInstrInfo.h(isIndirectBranchOpcode): Take
  ARM::MOVPC into account.
- test/CodeGen/ARM/armv4.ll: Added test case.

No regressions for 'make TESTSUITE=CodeGen/ARM check'.

John.
-- 
John Tytgat
John at bass-software.com
-------------- next part --------------
Index: test/CodeGen/ARM/armv4.ll
===================================================================
--- test/CodeGen/ARM/armv4.ll	(revision 0)
+++ test/CodeGen/ARM/armv4.ll	(revision 0)
@@ -0,0 +1,13 @@
+; RUN: llc < %s -mtriple=arm-unknown-eabi | FileCheck %s -check-prefix=THUMB
+; RUN: llc < %s -mtriple=arm-unknown-eabi -mcpu=strongarm | FileCheck %s -check-prefix=ARM
+; RUN: llc < %s -mtriple=arm-unknown-eabi -mcpu=cortex-a8 | FileCheck %s -check-prefix=THUMB
+; RUN: llc < %s -mtriple=arm-unknown-eabi -mattr=+v6 | FileCheck %s -check-prefix=THUMB
+; RUN: llc < %s -mtriple=armv4-unknown-eabi | FileCheck %s -check-prefix=ARM
+; RUN: llc < %s -mtriple=armv4t-unknown-eabi | FileCheck %s -check-prefix=THUMB
+
+define arm_aapcscc i32 @test(i32 %a) nounwind readnone {
+entry:
+; ARM: mov pc
+; THUMB: bx
+  ret i32 %a
+}
Index: lib/Target/ARM/ARMSubtarget.cpp
===================================================================
--- lib/Target/ARM/ARMSubtarget.cpp	(revision 96101)
+++ lib/Target/ARM/ARMSubtarget.cpp	(working copy)
@@ -33,7 +33,7 @@
 
 ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
                            bool isT)
-  : ARMArchVersion(V4T)
+  : ARMArchVersion(V4)
   , ARMFPUType(None)
   , UseNEONForSinglePrecisionFP(UseNEONFP)
   , IsThumb(isT)
@@ -54,6 +54,11 @@
   // Parse features string.
   CPUString = ParseSubtargetFeatures(FS, CPUString);
 
+  // When no arch is specified either by CPU or by attributes, make the default
+  // ARMv4T.
+  if (CPUString == "generic" && (FS.empty() || FS == "generic"))
+    ARMArchVersion = V4T;
+
   // Set the boolean corresponding to the current target triple, or the default
   // if one cannot be determined, to true.
   unsigned Len = TT.length();
@@ -68,25 +73,28 @@
   }
   if (Idx) {
     unsigned SubVer = TT[Idx];
-    if (SubVer > '4' && SubVer <= '9') {
-      if (SubVer >= '7') {
-        ARMArchVersion = V7A;
-      } else if (SubVer == '6') {
-        ARMArchVersion = V6;
-        if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
-          ARMArchVersion = V6T2;
-      } else if (SubVer == '5') {
-        ARMArchVersion = V5T;
-        if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
-          ARMArchVersion = V5TE;
-      }
-      if (ARMArchVersion >= V6T2)
-        ThumbMode = Thumb2;
+    if (SubVer >= '7' && SubVer <= '9') {
+      ARMArchVersion = V7A;
+    } else if (SubVer == '6') {
+      ARMArchVersion = V6;
+      if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
+        ARMArchVersion = V6T2;
+    } else if (SubVer == '5') {
+      ARMArchVersion = V5T;
+      if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
+        ARMArchVersion = V5TE;
+    } else if (SubVer == '4') {
+      if (Len >= Idx+2 && TT[Idx+1] == 't')
+        ARMArchVersion = V4T;
+      else
+        ARMArchVersion = V4;
     }
   }
 
   // Thumb2 implies at least V6T2.
-  if (ARMArchVersion < V6T2 && ThumbMode >= Thumb2)
+  if (ARMArchVersion >= V6T2)
+    ThumbMode = Thumb2;
+  else if (ThumbMode >= Thumb2)
     ARMArchVersion = V6T2;
 
   if (Len >= 10) {
Index: lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- lib/Target/ARM/ARMInstrInfo.td	(revision 96101)
+++ lib/Target/ARM/ARMInstrInfo.td	(working copy)
@@ -113,6 +113,8 @@
 //===----------------------------------------------------------------------===//
 // ARM Instruction Predicate Definitions.
 //
+def HasV4T    : Predicate<"Subtarget->hasV4TOps()">;
+def NoV4T     : Predicate<"!Subtarget->hasV4TOps()">;
 def HasV5T    : Predicate<"Subtarget->hasV5TOps()">;
 def HasV5TE   : Predicate<"Subtarget->hasV5TEOps()">;
 def HasV6     : Predicate<"Subtarget->hasV6Ops()">;
@@ -770,24 +772,49 @@
 //  Control Flow Instructions.
 //
 
-let isReturn = 1, isTerminator = 1, isBarrier = 1 in
+let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
+  // ARMV4T and above
   def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 
-                  "bx", "\tlr", [(ARMretflag)]> {
-  let Inst{3-0}   = 0b1110;
-  let Inst{7-4}   = 0b0001;
-  let Inst{19-8}  = 0b111111111111;
-  let Inst{27-20} = 0b00010010;
+                  "bx", "\tlr", [(ARMretflag)]>,
+               Requires<[IsARM, HasV4T]> {
+    let Inst{3-0}   = 0b1110;
+    let Inst{7-4}   = 0b0001;
+    let Inst{19-8}  = 0b111111111111;
+    let Inst{27-20} = 0b00010010;
+  }
+
+  // ARMV4 only
+  def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br, 
+                  "mov", "\tpc, lr", [(ARMretflag)]>,
+               Requires<[IsARM, NoV4T]> {
+    let Inst{3-0}   = 0b1110;
+    let Inst{7-4}   = 0b0000;
+    let Inst{19-8}  = 0b000011110000;
+    let Inst{27-20} = 0b00011010;
+  }
 }
 
 // Indirect branches
 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
+  // ARMV4T and above
   def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
-                  [(brind GPR:$dst)]> {
+                  [(brind GPR:$dst)]>,
+              Requires<[IsARM, HasV4T]> {
     let Inst{7-4}   = 0b0001;
     let Inst{19-8}  = 0b111111111111;
     let Inst{27-20} = 0b00010010;
     let Inst{31-28} = 0b1110;
   }
+
+  // ARMV4 only
+  def MOVPC : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
+                  [(brind GPR:$dst)]>,
+              Requires<[IsARM, NoV4T]> {
+    let Inst{7-4}   = 0b0000;
+    let Inst{19-8}  = 0b000011110000;
+    let Inst{27-20} = 0b00011010;
+    let Inst{31-28} = 0b1110;
+  }
 }
 
 // FIXME: remove when we have a way to marking a MI with these properties.
@@ -831,7 +858,7 @@
   def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
                   IIC_Br, "mov\tlr, pc\n\tbx\t$func",
                   [(ARMcall_nolink GPR:$func)]>,
-           Requires<[IsARM, IsNotDarwin]> {
+           Requires<[IsARM, HasV4T, IsNotDarwin]> {
     let Inst{7-4}   = 0b0001;
     let Inst{19-8}  = 0b111111111111;
     let Inst{27-20} = 0b00010010;
@@ -867,7 +894,8 @@
   // ARMv4T
   def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
                   IIC_Br, "mov\tlr, pc\n\tbx\t$func",
-                  [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
+                  [(ARMcall_nolink GPR:$func)]>,
+             Requires<[IsARM, HasV4T, IsDarwin]> {
     let Inst{7-4}   = 0b0001;
     let Inst{19-8}  = 0b111111111111;
     let Inst{27-20} = 0b00010010;
Index: lib/Target/ARM/ARMCodeEmitter.cpp
===================================================================
--- lib/Target/ARM/ARMCodeEmitter.cpp	(revision 96101)
+++ lib/Target/ARM/ARMCodeEmitter.cpp	(working copy)
@@ -1138,7 +1138,7 @@
   // Set the conditional execution predicate
   Binary |= II->getPredicate(&MI) << ARMII::CondShift;
 
-  if (TID.Opcode == ARM::BX_RET)
+  if (TID.Opcode == (Subtarget->hasV4TOps() ? ARM::BX_RET : ARM::MOVPCLR))
     // The return register is LR.
     Binary |= ARMRegisterInfo::getRegisterNumbering(ARM::LR);
   else
Index: lib/Target/ARM/ARMSubtarget.h
===================================================================
--- lib/Target/ARM/ARMSubtarget.h	(revision 96101)
+++ lib/Target/ARM/ARMSubtarget.h	(working copy)
@@ -26,7 +26,7 @@
 class ARMSubtarget : public TargetSubtarget {
 protected:
   enum ARMArchEnum {
-    V4T, V5T, V5TE, V6, V6T2, V7A
+    V4, V4T, V5T, V5TE, V6, V6T2, V7A
   };
 
   enum ARMFPEnum {
@@ -38,7 +38,7 @@
     Thumb2
   };
 
-  /// ARMArchVersion - ARM architecture version: V4T (base), V5T, V5TE,
+  /// ARMArchVersion - ARM architecture version: V4, V4T (base), V5T, V5TE,
   /// V6, V6T2, V7A.
   ARMArchEnum ARMArchVersion;
 
Index: lib/Target/ARM/ARMBaseInstrInfo.h
===================================================================
--- lib/Target/ARM/ARMBaseInstrInfo.h	(revision 96101)
+++ lib/Target/ARM/ARMBaseInstrInfo.h	(working copy)
@@ -332,7 +332,7 @@
 
 static inline
 bool isIndirectBranchOpcode(int Opc) {
-  return Opc == ARM::BRIND || Opc == ARM::tBRIND;
+  return Opc == ARM::BRIND || Opc == ARM::MOVPC || Opc == ARM::tBRIND;
 }
 
 /// getInstrPredicate - If instruction is predicated, returns its predicate


More information about the llvm-commits mailing list