Index: llvm/trunk/lib/Target/Sparc/LeonFeatures.td =================================================================== --- llvm/trunk/lib/Target/Sparc/LeonFeatures.td +++ llvm/trunk/lib/Target/Sparc/LeonFeatures.td @@ -58,3 +58,7 @@ "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: llvm/trunk/lib/Target/Sparc/Sparc.td =================================================================== --- llvm/trunk/lib/Target/Sparc/Sparc.td +++ llvm/trunk/lib/Target/Sparc/Sparc.td @@ -159,7 +159,7 @@ // 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: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp +++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp @@ -1841,6 +1841,9 @@ 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 @@ 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: llvm/trunk/lib/Target/Sparc/SparcSubtarget.h =================================================================== --- llvm/trunk/lib/Target/Sparc/SparcSubtarget.h +++ llvm/trunk/lib/Target/Sparc/SparcSubtarget.h @@ -50,6 +50,7 @@ bool InsertNOPLoad; bool FixAllFDIVSQRT; bool DetectRoundChange; + bool HasLeonCycleCounter; SparcInstrInfo InstrInfo; SparcTargetLowering TLInfo; @@ -95,6 +96,7 @@ 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. Index: llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp =================================================================== --- llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp +++ llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp @@ -47,6 +47,7 @@ InsertNOPLoad = false; FixAllFDIVSQRT = false; DetectRoundChange = false; + HasLeonCycleCounter = false; // Determine default and user specified characteristics std::string CPUName = CPU; Index: llvm/trunk/test/CodeGen/SPARC/readcycle.ll =================================================================== --- llvm/trunk/test/CodeGen/SPARC/readcycle.ll +++ llvm/trunk/test/CodeGen/SPARC/readcycle.ll @@ -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()