1263320SdimPull in r200131 from upstream llvm trunk (by Jakob Stoklund Olesen):
2263320Sdim
3263320Sdim  Only generate the popc instruction for SPARC CPUs that implement it.
4263320Sdim
5263320Sdim  The popc instruction is defined in the SPARCv9 instruction set
6263320Sdim  architecture, but it was emulated on CPUs older than Niagara 2.
7263320Sdim
8269012SemasteIntroduced here: http://svnweb.freebsd.org/changeset/base/262261
9263320Sdim
10263320SdimIndex: lib/Target/Sparc/SparcISelLowering.cpp
11263320Sdim===================================================================
12263320Sdim--- lib/Target/Sparc/SparcISelLowering.cpp
13263320Sdim+++ lib/Target/Sparc/SparcISelLowering.cpp
14263320Sdim@@ -1461,7 +1461,8 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
15263320Sdim     setOperationAction(ISD::BR_CC, MVT::i64, Custom);
16263320Sdim     setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
17263320Sdim 
18263320Sdim-    setOperationAction(ISD::CTPOP, MVT::i64, Legal);
19263320Sdim+    if (Subtarget->usePopc())
20263320Sdim+      setOperationAction(ISD::CTPOP, MVT::i64, Legal);
21263320Sdim     setOperationAction(ISD::CTTZ , MVT::i64, Expand);
22263320Sdim     setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Expand);
23263320Sdim     setOperationAction(ISD::CTLZ , MVT::i64, Expand);
24263320Sdim@@ -1567,7 +1568,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
25263320Sdim 
26263320Sdim   setStackPointerRegisterToSaveRestore(SP::O6);
27263320Sdim 
28263320Sdim-  if (Subtarget->isV9())
29263320Sdim+  if (Subtarget->isV9() && Subtarget->usePopc())
30263320Sdim     setOperationAction(ISD::CTPOP, MVT::i32, Legal);
31263320Sdim 
32263320Sdim   if (Subtarget->isV9() && Subtarget->hasHardQuad()) {
33263320SdimIndex: lib/Target/Sparc/Sparc.td
34263320Sdim===================================================================
35263320Sdim--- lib/Target/Sparc/Sparc.td
36263320Sdim+++ lib/Target/Sparc/Sparc.td
37263320Sdim@@ -34,6 +34,9 @@ def FeatureHardQuad
38263320Sdim   : SubtargetFeature<"hard-quad-float", "HasHardQuad", "true",
39263320Sdim                      "Enable quad-word floating point instructions">;
40263320Sdim 
41263320Sdim+def UsePopc : SubtargetFeature<"popc", "UsePopc", "true",
42263320Sdim+                               "Use the popc (population count) instruction">;
43263320Sdim+
44263320Sdim //===----------------------------------------------------------------------===//
45263320Sdim // Register File, Calling Conv, Instruction Descriptions
46263320Sdim //===----------------------------------------------------------------------===//
47263320Sdim@@ -69,9 +72,9 @@ def : Proc<"v9",              [FeatureV9]>;
48263320Sdim def : Proc<"ultrasparc",      [FeatureV9, FeatureV8Deprecated]>;
49263320Sdim def : Proc<"ultrasparc3",     [FeatureV9, FeatureV8Deprecated]>;
50263320Sdim def : Proc<"niagara",         [FeatureV9, FeatureV8Deprecated]>;
51263320Sdim-def : Proc<"niagara2",        [FeatureV9, FeatureV8Deprecated]>;
52263320Sdim-def : Proc<"niagara3",        [FeatureV9, FeatureV8Deprecated]>;
53263320Sdim-def : Proc<"niagara4",        [FeatureV9, FeatureV8Deprecated]>;
54263320Sdim+def : Proc<"niagara2",        [FeatureV9, FeatureV8Deprecated, UsePopc]>;
55263320Sdim+def : Proc<"niagara3",        [FeatureV9, FeatureV8Deprecated, UsePopc]>;
56263320Sdim+def : Proc<"niagara4",        [FeatureV9, FeatureV8Deprecated, UsePopc]>;
57263320Sdim 
58263320Sdim def SparcAsmWriter : AsmWriter {
59263320Sdim   string AsmWriterClassName  = "InstPrinter";
60263320SdimIndex: lib/Target/Sparc/SparcSubtarget.h
61263320Sdim===================================================================
62263320Sdim--- lib/Target/Sparc/SparcSubtarget.h
63263320Sdim+++ lib/Target/Sparc/SparcSubtarget.h
64263320Sdim@@ -30,6 +30,7 @@ class SparcSubtarget : public SparcGenSubtargetInf
65263320Sdim   bool IsVIS;
66263320Sdim   bool Is64Bit;
67263320Sdim   bool HasHardQuad;
68263320Sdim+  bool UsePopc;
69263320Sdim 
70263320Sdim public:
71263320Sdim   SparcSubtarget(const std::string &TT, const std::string &CPU,
72263320Sdim@@ -39,6 +40,7 @@ class SparcSubtarget : public SparcGenSubtargetInf
73263320Sdim   bool isVIS() const { return IsVIS; }
74263320Sdim   bool useDeprecatedV8Instructions() const { return V8DeprecatedInsts; }
75263320Sdim   bool hasHardQuad() const { return HasHardQuad; }
76263320Sdim+  bool usePopc() const { return UsePopc; }
77263320Sdim 
78263320Sdim   /// ParseSubtargetFeatures - Parses features string setting specified
79263320Sdim   /// subtarget options.  Definition of function is auto generated by tblgen.
80263320SdimIndex: lib/Target/Sparc/SparcSubtarget.cpp
81263320Sdim===================================================================
82263320Sdim--- lib/Target/Sparc/SparcSubtarget.cpp
83263320Sdim+++ lib/Target/Sparc/SparcSubtarget.cpp
84263320Sdim@@ -31,7 +31,8 @@ SparcSubtarget::SparcSubtarget(const std::string &
85263320Sdim   V8DeprecatedInsts(false),
86263320Sdim   IsVIS(false),
87263320Sdim   Is64Bit(is64Bit),
88263320Sdim-  HasHardQuad(false) {
89263320Sdim+  HasHardQuad(false),
90263320Sdim+  UsePopc(false) {
91263320Sdim 
92263320Sdim   // Determine default and user specified characteristics
93263320Sdim   std::string CPUName = CPU;
94263320SdimIndex: test/CodeGen/SPARC/ctpop.ll
95263320Sdim===================================================================
96263320Sdim--- test/CodeGen/SPARC/ctpop.ll
97263320Sdim+++ test/CodeGen/SPARC/ctpop.ll
98263320Sdim@@ -1,13 +1,13 @@
99263320Sdim ; RUN: llc < %s -march=sparc -mattr=-v9 | FileCheck %s -check-prefix=V8
100263320Sdim-; RUN: llc < %s -march=sparc -mattr=+v9 | FileCheck %s -check-prefix=V9
101263320Sdim-; RUN: llc < %s -march=sparc -mcpu=v9 | FileCheck %s -check-prefix=V9
102263320Sdim-; RUN: llc < %s -march=sparc -mcpu=ultrasparc  | FileCheck %s -check-prefix=V9
103263320Sdim-; RUN: llc < %s -march=sparc -mcpu=ultrasparc3 | FileCheck %s -check-prefix=V9
104263320Sdim-; RUN: llc < %s -march=sparc -mcpu=niagara     | FileCheck %s -check-prefix=V9
105263320Sdim+; RUN: llc < %s -march=sparc -mattr=+v9,+popc | FileCheck %s -check-prefix=V9
106263320Sdim+; RUN: llc < %s -march=sparc -mcpu=v9 | FileCheck %s -check-prefix=V8
107263320Sdim+; RUN: llc < %s -march=sparc -mcpu=ultrasparc  | FileCheck %s -check-prefix=V8
108263320Sdim+; RUN: llc < %s -march=sparc -mcpu=ultrasparc3 | FileCheck %s -check-prefix=V8
109263320Sdim+; RUN: llc < %s -march=sparc -mcpu=niagara     | FileCheck %s -check-prefix=V8
110263320Sdim ; RUN: llc < %s -march=sparc -mcpu=niagara2    | FileCheck %s -check-prefix=V9
111263320Sdim ; RUN: llc < %s -march=sparc -mcpu=niagara3    | FileCheck %s -check-prefix=V9
112263320Sdim ; RUN: llc < %s -march=sparc -mcpu=niagara4    | FileCheck %s -check-prefix=V9
113263320Sdim-; RUN: llc < %s -march=sparcv9  | FileCheck %s -check-prefix=SPARC64
114263320Sdim+; RUN: llc < %s -march=sparcv9 -mattr=+popc | FileCheck %s -check-prefix=SPARC64
115263320Sdim 
116263320Sdim declare i32 @llvm.ctpop.i32(i32)
117263320Sdim 
118