[Sparc] Add support for the cycle counter available in GR740
authorDaniel Cederman <cederman@gaisler.com>
Mon, 13 Aug 2018 10:49:48 +0000 (10:49 +0000)
committerDaniel Cederman <cederman@gaisler.com>
Mon, 13 Aug 2018 10:49:48 +0000 (10:49 +0000)
Summary: The GR740 provides an up cycle counter in the
registers ASR22 and ASR23. As these registers can not be
read together atomically we only use the value of ASR23
for llvm.readcyclecounter(). The ASR23 register holds the
32 LSBs of the up-counter.

Reviewers: jyknight, venkatra

Reviewed By: jyknight

Subscribers: fedor.sergeev, jrtc27, llvm-commits

Differential Revision: https://reviews.llvm.org/D48638

llvm-svn: 339551

llvm/lib/Target/Sparc/LeonFeatures.td
llvm/lib/Target/Sparc/Sparc.td
llvm/lib/Target/Sparc/SparcISelLowering.cpp
llvm/lib/Target/Sparc/SparcSubtarget.cpp
llvm/lib/Target/Sparc/SparcSubtarget.h
llvm/test/CodeGen/SPARC/readcycle.ll [new file with mode: 0644]

index a7dea06..61e5f16 100644 (file)
@@ -58,3 +58,7 @@ def FixAllFDIVSQRT : SubtargetFeature<
   "true",
   "LEON erratum fix: Fix FDIVS/FDIVD/FSQRTS/FSQRTD instructions with NOPs and floating-point store" 
 >;
+
+def LeonCycleCounter
+  : SubtargetFeature<"leoncyclecounter", "HasLeonCycleCounter", "true",
+                     "Use the Leon cycle counter register">;
index 2f9b57f..0c69605 100644 (file)
@@ -159,7 +159,7 @@ def : Processor<"leon4", LEON4Itineraries,
 // LEON 4 FT (GR740) 
 // TO DO: Place-holder: Processor specific features will be added *very* soon here.
 def : Processor<"gr740", LEON4Itineraries, 
-                [FeatureLeon, UMACSMACSupport, LeonCASA]>;
+                [FeatureLeon, UMACSMACSupport, LeonCASA, LeonCycleCounter]>;
 
 //===----------------------------------------------------------------------===//
 // Declare the target which we are implementing
index b04c6b1..420eba3 100644 (file)
@@ -1841,6 +1841,9 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::FMUL, MVT::f32, Promote);
   }
 
+  if (Subtarget->hasLeonCycleCounter())
+    setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Custom);
+
   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
 
   setMinFunctionAlignment(2);
@@ -3587,7 +3590,16 @@ void SparcTargetLowering::ReplaceNodeResults(SDNode *N,
                                   getLibcallName(libCall),
                                   1));
     return;
-
+  case ISD::READCYCLECOUNTER: {
+    assert(Subtarget->hasLeonCycleCounter());
+    SDValue Lo = DAG.getCopyFromReg(N->getOperand(0), dl, SP::ASR23, MVT::i32);
+    SDValue Hi = DAG.getCopyFromReg(Lo, dl, SP::G0, MVT::i32);
+    SDValue Ops[] = { Lo, Hi };
+    SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Ops);
+    Results.push_back(Pair);
+    Results.push_back(N->getOperand(0));
+    return;
+  }
   case ISD::SINT_TO_FP:
   case ISD::UINT_TO_FP:
     // Custom lower only if it involves f128 or i64.
index 40c5683..f3a2049 100644 (file)
@@ -47,6 +47,7 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU,
   InsertNOPLoad = false;
   FixAllFDIVSQRT = false;
   DetectRoundChange = false;
+  HasLeonCycleCounter = false;
 
   // Determine default and user specified characteristics
   std::string CPUName = CPU;
index 588a676..65627f4 100644 (file)
@@ -50,6 +50,7 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
   bool InsertNOPLoad;
   bool FixAllFDIVSQRT;
   bool DetectRoundChange;
+  bool HasLeonCycleCounter;
 
   SparcInstrInfo InstrInfo;
   SparcTargetLowering TLInfo;
@@ -95,6 +96,7 @@ public:
   bool insertNOPLoad() const { return InsertNOPLoad; }
   bool fixAllFDIVSQRT() const { return FixAllFDIVSQRT; }
   bool detectRoundChange() const { return DetectRoundChange; }
+  bool hasLeonCycleCounter() const { return HasLeonCycleCounter; }
 
   /// ParseSubtargetFeatures - Parses features string setting specified
   /// subtarget options.  Definition of function is auto generated by tblgen.
diff --git a/llvm/test/CodeGen/SPARC/readcycle.ll b/llvm/test/CodeGen/SPARC/readcycle.ll
new file mode 100644 (file)
index 0000000..5c330ea
--- /dev/null
@@ -0,0 +1,11 @@
+; RUN: llc < %s -march=sparc -mcpu=gr740 | FileCheck %s
+; CHECK: rd %asr23, %o1
+; CHECK: mov %g0, %o0
+
+define i64 @test() {
+entry:
+  %0 = call i64 @llvm.readcyclecounter()
+  ret i64 %0
+}
+
+declare i64 @llvm.readcyclecounter()