Only generate the popc instruction for SPARC CPUs that implement it.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Sun, 26 Jan 2014 06:09:59 +0000 (06:09 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Sun, 26 Jan 2014 06:09:59 +0000 (06:09 +0000)
The popc instruction is defined in the SPARCv9 instruction set
architecture, but it was emulated on CPUs older than Niagara 2.

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

lib/Target/Sparc/Sparc.td
lib/Target/Sparc/SparcISelLowering.cpp
lib/Target/Sparc/SparcSubtarget.cpp
lib/Target/Sparc/SparcSubtarget.h
test/CodeGen/SPARC/ctpop.ll

index 9f6992de2f132a8aa282a59b44a141dc93fc7c59..ab86dc9c311e98e39006947eb29f6cec1eb4ca8c 100644 (file)
@@ -34,6 +34,9 @@ def FeatureHardQuad
   : SubtargetFeature<"hard-quad-float", "HasHardQuad", "true",
                      "Enable quad-word floating point instructions">;
 
   : SubtargetFeature<"hard-quad-float", "HasHardQuad", "true",
                      "Enable quad-word floating point instructions">;
 
+def UsePopc : SubtargetFeature<"popc", "UsePopc", "true",
+                               "Use the popc (population count) instruction">;
+
 //===----------------------------------------------------------------------===//
 // Register File, Calling Conv, Instruction Descriptions
 //===----------------------------------------------------------------------===//
 //===----------------------------------------------------------------------===//
 // Register File, Calling Conv, Instruction Descriptions
 //===----------------------------------------------------------------------===//
@@ -69,9 +72,9 @@ def : Proc<"v9",              [FeatureV9]>;
 def : Proc<"ultrasparc",      [FeatureV9, FeatureV8Deprecated]>;
 def : Proc<"ultrasparc3",     [FeatureV9, FeatureV8Deprecated]>;
 def : Proc<"niagara",         [FeatureV9, FeatureV8Deprecated]>;
 def : Proc<"ultrasparc",      [FeatureV9, FeatureV8Deprecated]>;
 def : Proc<"ultrasparc3",     [FeatureV9, FeatureV8Deprecated]>;
 def : Proc<"niagara",         [FeatureV9, FeatureV8Deprecated]>;
-def : Proc<"niagara2",        [FeatureV9, FeatureV8Deprecated]>;
-def : Proc<"niagara3",        [FeatureV9, FeatureV8Deprecated]>;
-def : Proc<"niagara4",        [FeatureV9, FeatureV8Deprecated]>;
+def : Proc<"niagara2",        [FeatureV9, FeatureV8Deprecated, UsePopc]>;
+def : Proc<"niagara3",        [FeatureV9, FeatureV8Deprecated, UsePopc]>;
+def : Proc<"niagara4",        [FeatureV9, FeatureV8Deprecated, UsePopc]>;
 
 
 //===----------------------------------------------------------------------===//
 
 
 //===----------------------------------------------------------------------===//
index b5550496662920bd48d96c6ba36dedd2ebcbb153..9bec9113b5639a6404e7067abdaba645879b2963 100644 (file)
@@ -1463,7 +1463,8 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
     setOperationAction(ISD::BR_CC, MVT::i64, Custom);
     setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
 
     setOperationAction(ISD::BR_CC, MVT::i64, Custom);
     setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
 
-    setOperationAction(ISD::CTPOP, MVT::i64, Legal);
+    if (Subtarget->usePopc())
+      setOperationAction(ISD::CTPOP, MVT::i64, Legal);
     setOperationAction(ISD::CTTZ , MVT::i64, Expand);
     setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Expand);
     setOperationAction(ISD::CTLZ , MVT::i64, Expand);
     setOperationAction(ISD::CTTZ , MVT::i64, Expand);
     setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Expand);
     setOperationAction(ISD::CTLZ , MVT::i64, Expand);
@@ -1569,7 +1570,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
 
   setStackPointerRegisterToSaveRestore(SP::O6);
 
 
   setStackPointerRegisterToSaveRestore(SP::O6);
 
-  if (Subtarget->isV9())
+  if (Subtarget->isV9() && Subtarget->usePopc())
     setOperationAction(ISD::CTPOP, MVT::i32, Legal);
 
   if (Subtarget->isV9() && Subtarget->hasHardQuad()) {
     setOperationAction(ISD::CTPOP, MVT::i32, Legal);
 
   if (Subtarget->isV9() && Subtarget->hasHardQuad()) {
index 7032d7f3fb0919bcaee377b7b2441d30cb89bb67..7373613eb2696fe65b6bf558b76171c6945562e3 100644 (file)
@@ -31,7 +31,8 @@ SparcSubtarget::SparcSubtarget(const std::string &TT, const std::string &CPU,
   V8DeprecatedInsts(false),
   IsVIS(false),
   Is64Bit(is64Bit),
   V8DeprecatedInsts(false),
   IsVIS(false),
   Is64Bit(is64Bit),
-  HasHardQuad(false) {
+  HasHardQuad(false),
+  UsePopc(false) {
 
   // Determine default and user specified characteristics
   std::string CPUName = CPU;
 
   // Determine default and user specified characteristics
   std::string CPUName = CPU;
index 012aca7d923fb34a6ee44ac123a8fb5e22890f90..154afb55f8082b999b5d16a72ff0ee5140b6b6c2 100644 (file)
@@ -30,6 +30,7 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
   bool IsVIS;
   bool Is64Bit;
   bool HasHardQuad;
   bool IsVIS;
   bool Is64Bit;
   bool HasHardQuad;
+  bool UsePopc;
 
 public:
   SparcSubtarget(const std::string &TT, const std::string &CPU,
 
 public:
   SparcSubtarget(const std::string &TT, const std::string &CPU,
@@ -39,6 +40,7 @@ public:
   bool isVIS() const { return IsVIS; }
   bool useDeprecatedV8Instructions() const { return V8DeprecatedInsts; }
   bool hasHardQuad() const { return HasHardQuad; }
   bool isVIS() const { return IsVIS; }
   bool useDeprecatedV8Instructions() const { return V8DeprecatedInsts; }
   bool hasHardQuad() const { return HasHardQuad; }
+  bool usePopc() const { return UsePopc; }
 
   /// ParseSubtargetFeatures - Parses features string setting specified
   /// subtarget options.  Definition of function is auto generated by tblgen.
 
   /// ParseSubtargetFeatures - Parses features string setting specified
   /// subtarget options.  Definition of function is auto generated by tblgen.
index 665b44b8f674d271151dfc378d4352c2c385e69c..3a373404b9915801c462b34a3484a5bbd6adf087 100644 (file)
@@ -1,13 +1,13 @@
 ; RUN: llc < %s -march=sparc -mattr=-v9 | FileCheck %s -check-prefix=V8
 ; RUN: llc < %s -march=sparc -mattr=-v9 | FileCheck %s -check-prefix=V8
-; RUN: llc < %s -march=sparc -mattr=+v9 | FileCheck %s -check-prefix=V9
-; RUN: llc < %s -march=sparc -mcpu=v9 | FileCheck %s -check-prefix=V9
-; RUN: llc < %s -march=sparc -mcpu=ultrasparc  | FileCheck %s -check-prefix=V9
-; RUN: llc < %s -march=sparc -mcpu=ultrasparc3 | FileCheck %s -check-prefix=V9
-; RUN: llc < %s -march=sparc -mcpu=niagara     | FileCheck %s -check-prefix=V9
+; RUN: llc < %s -march=sparc -mattr=+v9,+popc | FileCheck %s -check-prefix=V9
+; RUN: llc < %s -march=sparc -mcpu=v9 | FileCheck %s -check-prefix=V8
+; RUN: llc < %s -march=sparc -mcpu=ultrasparc  | FileCheck %s -check-prefix=V8
+; RUN: llc < %s -march=sparc -mcpu=ultrasparc3 | FileCheck %s -check-prefix=V8
+; RUN: llc < %s -march=sparc -mcpu=niagara     | FileCheck %s -check-prefix=V8
 ; RUN: llc < %s -march=sparc -mcpu=niagara2    | FileCheck %s -check-prefix=V9
 ; RUN: llc < %s -march=sparc -mcpu=niagara3    | FileCheck %s -check-prefix=V9
 ; RUN: llc < %s -march=sparc -mcpu=niagara4    | FileCheck %s -check-prefix=V9
 ; RUN: llc < %s -march=sparc -mcpu=niagara2    | FileCheck %s -check-prefix=V9
 ; RUN: llc < %s -march=sparc -mcpu=niagara3    | FileCheck %s -check-prefix=V9
 ; RUN: llc < %s -march=sparc -mcpu=niagara4    | FileCheck %s -check-prefix=V9
-; RUN: llc < %s -march=sparcv9  | FileCheck %s -check-prefix=SPARC64
+; RUN: llc < %s -march=sparcv9 -mattr=+popc | FileCheck %s -check-prefix=SPARC64
 
 declare i32 @llvm.ctpop.i32(i32)
 
 
 declare i32 @llvm.ctpop.i32(i32)