Cleanup of ARMv7M support. Move hardware divide and Thumb2 extract/pack
authorJim Grosbach <grosbach@apple.com>
Wed, 5 May 2010 23:44:43 +0000 (23:44 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 5 May 2010 23:44:43 +0000 (23:44 +0000)
instructions to subtarget features and update tests to reflect.
PR5717.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103136 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
lib/Target/ARM/ARM.td
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/ARMSubtarget.cpp
lib/Target/ARM/ARMSubtarget.h
test/CodeGen/Thumb2/thumb2-pack.ll
test/CodeGen/Thumb2/thumb2-rev.ll
test/CodeGen/Thumb2/thumb2-shifter.ll
test/CodeGen/Thumb2/thumb2-smla.ll
test/CodeGen/Thumb2/thumb2-smul.ll
test/CodeGen/Thumb2/thumb2-sxt_rot.ll
test/CodeGen/Thumb2/thumb2-uxt_rot.ll
test/CodeGen/Thumb2/thumb2-uxtb.ll

index a7425e61e8c4082449b1c148701fe5edca09818b..f1e6a9f083e2e84f5e6472df2cb6a22940aec70a 100644 (file)
@@ -44,6 +44,10 @@ def FeatureThumb2 : SubtargetFeature<"thumb2", "ThumbMode", "Thumb2",
                                      "Enable Thumb2 instructions">;
 def FeatureFP16   : SubtargetFeature<"fp16", "HasFP16", "true",
                                      "Enable half-precision floating point">;
+def FeatureHWDiv  : SubtargetFeature<"hwdiv", "HasHardwareDivide", "true",
+                                     "Enable divide instructions">;
+def FeatureT2ExtractPack: SubtargetFeature<"t2xtpk", "HasT2ExtractPack", "true",
+                                 "Enable Thumb2 extract and pack instructions">;
 
 // Some processors have multiply-accumulate instructions that don't
 // play nicely with other VFP instructions, and it's generally better
@@ -125,10 +129,11 @@ def : Processor<"arm1156t2f-s",    ARMV6Itineraries,
 // V7 Processors.
 def : Processor<"cortex-a8",        CortexA8Itineraries,
                 [ArchV7A, FeatureThumb2, FeatureNEON, FeatureHasSlowVMLx,
-                 FeatureNEONForFP]>;
+                 FeatureNEONForFP, FeatureT2ExtractPack]>;
 def : Processor<"cortex-a9",        CortexA9Itineraries,
-                [ArchV7A, FeatureThumb2, FeatureNEON]>;
-def : ProcNoItin<"cortex-m3",       [ArchV7M, FeatureThumb2]>;
+                [ArchV7A, FeatureThumb2, FeatureNEON, FeatureT2ExtractPack]>;
+def : ProcNoItin<"cortex-m3",       [ArchV7M, FeatureThumb2, FeatureHWDiv]>;
+def : ProcNoItin<"cortex-m4",       [ArchV7M, FeatureThumb2, FeatureHWDiv]>;
 
 //===----------------------------------------------------------------------===//
 // Register File Description
index c1d2d3ac428854117600d80e326371d01787c048..f8c17b8ac2d29a089f90080d65a2b6338c95d4c2 100644 (file)
@@ -363,7 +363,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
     setOperationAction(ISD::BSWAP, MVT::i32, Expand);
 
   // These are expanded into libcalls.
-  if (!Subtarget->hasV7MOps()) {
+  if (!Subtarget->hasDivide()) {
     // v7M has a hardware divider
     setOperationAction(ISD::SDIV,  MVT::i32, Expand);
     setOperationAction(ISD::UDIV,  MVT::i32, Expand);
@@ -393,7 +393,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
   setOperationAction(ISD::MEMBARRIER,         MVT::Other, Custom);
 
-  if (!Subtarget->hasV6Ops() && !Subtarget->isThumb2() || Subtarget->hasV7MOps()) {
+  if (!Subtarget->hasV6Ops() && (!Subtarget->isThumb2()
+      || !Subtarget->hasT2ExtractPack())) {
     setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
     setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8,  Expand);
   }
index e74c85c1f0b560de076c14af73a4a28abafbfde4..6540497d1e480446b6664c0582ba78ec87661a31 100644 (file)
@@ -124,13 +124,12 @@ def HasV6     : Predicate<"Subtarget->hasV6Ops()">;
 def HasV6T2   : Predicate<"Subtarget->hasV6T2Ops()">;
 def NoV6T2    : Predicate<"!Subtarget->hasV6T2Ops()">;
 def HasV7     : Predicate<"Subtarget->hasV7Ops()">;
-def HasV7A    : Predicate<"Subtarget->hasV7AOps()">;
-def HasV7M    : Predicate<"Subtarget->hasV7MOps()">;
-def NoV7M     : Predicate<"!Subtarget->hasV7MOps()">;
 def NoVFP     : Predicate<"!Subtarget->hasVFP2()">;
 def HasVFP2   : Predicate<"Subtarget->hasVFP2()">;
 def HasVFP3   : Predicate<"Subtarget->hasVFP3()">;
 def HasNEON   : Predicate<"Subtarget->hasNEON()">;
+def HasDivide : Predicate<"Subtarget->hasDivide()">;
+def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">;
 def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
 def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
 def IsThumb   : Predicate<"Subtarget->isThumb()">;
index 07d176742f5dc333065b2a315f4f9e835c8b3261..78d1a75c086638a7bb354ea2742e2b1ca288ff3c 100644 (file)
@@ -640,7 +640,7 @@ multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
   def r     : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
                   opc, ".w\t$dst, $src",
                  [(set GPR:$dst, (opnode GPR:$src))]>,
-                 Requires<[NoV7M]> {
+                 Requires<[HasT2ExtractPack]> {
      let Inst{31-27} = 0b11111;
      let Inst{26-23} = 0b0100;
      let Inst{22-20} = opcod;
@@ -652,7 +652,7 @@ multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
   def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
                   opc, ".w\t$dst, $src, ror $rot",
                  [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
-                 Requires<[NoV7M]> {
+                 Requires<[HasT2ExtractPack]> {
      let Inst{31-27} = 0b11111;
      let Inst{26-23} = 0b0100;
      let Inst{22-20} = opcod;
@@ -668,7 +668,7 @@ multiclass T2I_unary_rrot_nw<bits<3> opcod, string opc, PatFrag opnode> {
   def r     : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
                   opc, "\t$dst, $src",
                  [(set GPR:$dst, (opnode GPR:$src))]>,
-                 Requires<[NoV7M]> {
+                 Requires<[HasT2ExtractPack]> {
      let Inst{31-27} = 0b11111;
      let Inst{26-23} = 0b0100;
      let Inst{22-20} = opcod;
@@ -680,7 +680,7 @@ multiclass T2I_unary_rrot_nw<bits<3> opcod, string opc, PatFrag opnode> {
   def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
                   opc, "\t$dst, $src, ror $rot",
                  [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>,
-                 Requires<[NoV7M]> {
+                 Requires<[HasT2ExtractPack]> {
      let Inst{31-27} = 0b11111;
      let Inst{26-23} = 0b0100;
      let Inst{22-20} = opcod;
@@ -722,7 +722,7 @@ multiclass T2I_bin_rrot<bits<3> opcod, string opc, PatFrag opnode> {
   def rr     : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr,
                   opc, "\t$dst, $LHS, $RHS",
                   [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
-                  Requires<[NoV7M]> {
+                  Requires<[HasT2ExtractPack]> {
      let Inst{31-27} = 0b11111;
      let Inst{26-23} = 0b0100;
      let Inst{22-20} = opcod;
@@ -734,7 +734,7 @@ multiclass T2I_bin_rrot<bits<3> opcod, string opc, PatFrag opnode> {
                   IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
                   [(set GPR:$dst, (opnode GPR:$LHS,
                                           (rotr GPR:$RHS, rot_imm:$rot)))]>,
-                  Requires<[NoV7M]> {
+                  Requires<[HasT2ExtractPack]> {
      let Inst{31-27} = 0b11111;
      let Inst{26-23} = 0b0100;
      let Inst{22-20} = opcod;
@@ -866,7 +866,7 @@ def t2SUBrSPs   : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
 def t2SDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi, 
                  "sdiv", "\t$dst, $a, $b",
                  [(set GPR:$dst, (sdiv GPR:$a, GPR:$b))]>,
-                 Requires<[HasV7M]> {
+                 Requires<[HasDivide]> {
   let Inst{31-27} = 0b11111;
   let Inst{26-21} = 0b011100;
   let Inst{20} = 0b1;
@@ -877,7 +877,7 @@ def t2SDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi,
 def t2UDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi, 
                  "udiv", "\t$dst, $a, $b",
                  [(set GPR:$dst, (udiv GPR:$a, GPR:$b))]>,
-                 Requires<[HasV7M]> {
+                 Requires<[HasDivide]> {
   let Inst{31-27} = 0b11111;
   let Inst{26-21} = 0b011101;
   let Inst{20} = 0b1;
@@ -2069,7 +2069,7 @@ def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
                   [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
                                       (and (shl GPR:$src2, (i32 imm:$shamt)),
                                            0xFFFF0000)))]>,
-                  Requires<[NoV7M]> {
+                  Requires<[HasT2ExtractPack]> {
   let Inst{31-27} = 0b11101;
   let Inst{26-25} = 0b01;
   let Inst{24-20} = 0b01100;
@@ -2080,17 +2080,17 @@ def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
 // Alternate cases for PKHBT where identities eliminate some nodes.
 def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
             (t2PKHBT GPR:$src1, GPR:$src2, 0)>,
-            Requires<[NoV7M]>;
+            Requires<[HasT2ExtractPack]>;
 def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
             (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>,
-            Requires<[NoV7M]>;
+            Requires<[HasT2ExtractPack]>;
 
 def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
                   IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
                   [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
                                       (and (sra GPR:$src2, imm16_31:$shamt),
                                            0xFFFF)))]>,
-                  Requires<[NoV7M]> {
+                  Requires<[HasT2ExtractPack]> {
   let Inst{31-27} = 0b11101;
   let Inst{26-25} = 0b01;
   let Inst{24-20} = 0b01100;
@@ -2102,11 +2102,11 @@ def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
 def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
             (t2PKHTB GPR:$src1, GPR:$src2, 16)>,
-            Requires<[NoV7M]>;
+            Requires<[HasT2ExtractPack]>;
 def : T2Pat<(or (and GPR:$src1, 0xFFFF0000),
                      (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
             (t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>,
-            Requires<[NoV7M]>;
+            Requires<[HasT2ExtractPack]>;
 
 //===----------------------------------------------------------------------===//
 //  Comparison Instructions...
index 0c777e2c4d96f6fc75f65f0d312a27cd6015f53a..10fd257055fb50ec2ec65abfa9dabaa52cc96fd6 100644 (file)
@@ -39,6 +39,8 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
   , IsR9Reserved(ReserveR9)
   , UseMovt(UseMOVT)
   , HasFP16(false)
+  , HasHardwareDivide(false)
+  , HasT2ExtractPack(false)
   , stackAlignment(4)
   , CPUString("generic")
   , TargetType(isELF) // Default to ELF unless otherwise specified.
index 18715087b9a53e0c6a5e444641397d7721bb5f9c..3ba0a2e941061dcb70f1a4b1e73fb38358d6a794 100644 (file)
@@ -74,6 +74,13 @@ protected:
   /// only so far)
   bool HasFP16;
 
+  /// HasHardwareDivide - True if subtarget supports [su]div
+  bool HasHardwareDivide;
+
+  /// HasT2ExtractPack - True if subtarget supports thumb2 extract/pack
+  /// instructions.
+  bool HasT2ExtractPack;
+
   /// stackAlignment - The minimum alignment known to hold of the stack frame on
   /// entry to the function and which must be maintained by every function.
   unsigned stackAlignment;
@@ -117,14 +124,14 @@ protected:
   bool hasV6Ops()   const { return ARMArchVersion >= V6;   }
   bool hasV6T2Ops() const { return ARMArchVersion >= V6T2; }
   bool hasV7Ops()   const { return ARMArchVersion >= V7A;  }
-  bool hasV7AOps()  const { return ARMArchVersion == V7A;  }
-  bool hasV7MOps()  const { return ARMArchVersion == V7M;  }
 
   bool hasVFP2() const { return ARMFPUType >= VFPv2; }
   bool hasVFP3() const { return ARMFPUType >= VFPv3; }
   bool hasNEON() const { return ARMFPUType >= NEON;  }
   bool useNEONForSinglePrecisionFP() const {
     return hasNEON() && UseNEONForSinglePrecisionFP; }
+  bool hasDivide() const { return HasHardwareDivide; };
+  bool hasT2ExtractPack() const { return HasT2ExtractPack; };
   bool useVMLx() const {return hasVFP2() && !SlowVMLx; }
 
   bool hasFP16() const { return HasFP16; }
index a9822498fe0872b352c704de5fc380e508013478..c8302df78f680d9c14143dd8e75b3d7391c3baac 100644 (file)
@@ -1,6 +1,6 @@
-; RUN: llc < %s -march=thumb -mattr=+thumb2 | \
+; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | \
 ; RUN:   grep pkhbt | count 5
-; RUN: llc < %s -march=thumb -mattr=+thumb2 | \
+; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | \
 ; RUN:   grep pkhtb | count 4
 
 define i32 @test1(i32 %X, i32 %Y) {
index 27b1672e554a020c25f454ff6a4de494afe4c7f9..2cee2e3d6fcea219300b19e6d164ff421b4b542e 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=thumb -mattr=+thumb2,+v7a | FileCheck %s
+; RUN: llc < %s -march=thumb -mattr=+thumb2,+v7a,+t2xtpk | FileCheck %s
 
 define i32 @f1(i32 %a) {
 ; CHECK: f1:
index b106cedc092af3156de9cb99d647e6eeb2ab62dc..98854a1205f830c51be9992610d344caf6b3688d 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s
+; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s
 
 define i32 @t2ADDrs_lsl(i32 %X, i32 %Y) {
 ; CHECK: t2ADDrs_lsl
index 092ec27de4cad34f71555b649d7266ecbf522c98..bd4dcbe622fa26042a06a8ec7f9c87261d8a2dd6 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s
+; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s
 
 define i32 @f3(i32 %a, i16 %x, i32 %y) {
 ; CHECK: f3
index 16ea85db69c4cc7099b98c029c6bc2d3a1f3196e..ae175355059c7d7e1cf97d7c20dde537606f5fce 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=thumb -mattr=+thumb2 |  FileCheck %s
+; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk |  FileCheck %s
 
 @x = weak global i16 0          ; <i16*> [#uses=1]
 @y = weak global i16 0          ; <i16*> [#uses=0]
index 054d5df3583a3f0d8ab3b3748a680e4529999146..4b685a86fd8eaed1d0cc19addbcc2743c0d9ca6e 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s
+; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s
 
 define i32 @test0(i8 %A) {
 ; CHECK: test0
index 75e1d70260c572d9db72ae46e4a8f46e07cf58e6..b8e43812ed991618327830aeb4b6a656897d52ff 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s
+; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s
 
 define i8 @test1(i32 %A.u) zeroext {
 ; CHECK: test1
index 91598cdc961a06d9e131c0ffa0146050cf7695d6..541191400b1cce60095861050d5ca58bc086e4e2 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s
+; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s
 
 define i32 @test1(i32 %x) {
 ; CHECK: test1