mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
continued readcyclecounter support
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24300 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
aeef8fc5c6
commit
51b8d54922
@ -128,6 +128,7 @@
|
||||
<li><a href="#i_frameaddress">'<tt>llvm.frameaddress</tt>' Intrinsic</a></li>
|
||||
<li><a href="#i_prefetch">'<tt>llvm.prefetch</tt>' Intrinsic</a></li>
|
||||
<li><a href="#i_pcmarker">'<tt>llvm.pcmarker</tt>' Intrinsic</a></li>
|
||||
<li><a href="#i_readcyclecounter"><tt>llvm.readcyclecounter</tt>' Intrinsic</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#int_os">Operating System Intrinsics</a>
|
||||
@ -2811,6 +2812,39 @@ support this intrinisic may ignore it.
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="i_readcyclecounter">'<tt>llvm.readcyclecounter</tt>' Intrinsic</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
declare ulong %llvm.readcyclecounter( )
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
|
||||
|
||||
<p>
|
||||
The '<tt>llvm.readcyclecounter</tt>' intrinsic provides access to the cycle
|
||||
counter register (or similar low latency, high accuracy clocks) on those targets
|
||||
that support it. On X86, it should map to RDTSC. On Alpha, it should map to RPCC.
|
||||
As the backing counters overflow quickly (on the order of 9 seconds on alpha), this
|
||||
should only be used for small timings.
|
||||
</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
|
||||
<p>
|
||||
When directly supported, reading the cycle counter should not modify any memory.
|
||||
Implementations are allowed to either return a application specific value or a
|
||||
system wide value. On backends without support, this is lowered to a constant 0.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
|
@ -709,6 +709,7 @@ static const char *DoesntAccessMemoryTable[] = {
|
||||
// LLVM intrinsics:
|
||||
"llvm.frameaddress", "llvm.returnaddress", "llvm.readport",
|
||||
"llvm.isunordered", "llvm.sqrt", "llvm.ctpop", "llvm.ctlz", "llvm.cttz",
|
||||
"llvm.readcyclecounter",
|
||||
|
||||
"abs", "labs", "llabs", "imaxabs", "fabs", "fabsf", "fabsl",
|
||||
"trunc", "truncf", "truncl", "ldexp",
|
||||
|
@ -262,6 +262,12 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
|
||||
|
||||
case Intrinsic::pcmarker:
|
||||
break; // Simply strip out pcmarker on unsupported architectures
|
||||
case Intrinsic::readcyclecounter: {
|
||||
std::cerr << "WARNING: this target does not support the llvm.readcyclecounter"
|
||||
<< " intrinsic. It is being lowered to a constant 0\n";
|
||||
CI->replaceAllUsesWith(ConstantUInt::get(Type::ULongTy, 0));
|
||||
break;
|
||||
}
|
||||
|
||||
case Intrinsic::dbg_stoppoint:
|
||||
case Intrinsic::dbg_region_start:
|
||||
|
@ -1122,6 +1122,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
if (Tmp1 != Node->getOperand(0))
|
||||
Result = DAG.getNode(ISD::PCMARKER, MVT::Other, Tmp1,Node->getOperand(1));
|
||||
break;
|
||||
case ISD::READCYCLECOUNTER:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain
|
||||
if (Tmp1 != Node->getOperand(0))
|
||||
Result = DAG.getNode(ISD::READCYCLECOUNTER, MVT::i64, Tmp1);
|
||||
break;
|
||||
case ISD::TRUNCSTORE:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||
Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the pointer.
|
||||
|
@ -1624,6 +1624,7 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
}
|
||||
|
||||
case ISD::PCMARKER: return "PCMarker";
|
||||
case ISD::READCYCLECOUNTER: return "ReadCycleCounter";
|
||||
case ISD::SRCVALUE: return "SrcValue";
|
||||
case ISD::VALUETYPE: return "ValueType";
|
||||
case ISD::EntryToken: return "EntryToken";
|
||||
|
@ -804,6 +804,9 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Tmp));
|
||||
return 0;
|
||||
}
|
||||
case Intrinsic::readcyclecounter:
|
||||
setValue(&I, DAG.getNode(ISD::READCYCLECOUNTER, MVT::i64, getRoot()));
|
||||
return 0;
|
||||
case Intrinsic::cttz:
|
||||
setValue(&I, DAG.getNode(ISD::CTTZ,
|
||||
getValue(I.getOperand(1)).getValueType(),
|
||||
|
@ -549,6 +549,11 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
|
||||
Node->dump();
|
||||
assert(0 && "Node not handled!\n");
|
||||
|
||||
case ISD::READCYCLECOUNTER:
|
||||
Select(N.getOperand(0)); //Select chain
|
||||
BuildMI(BB, Alpha::RPCC, 1, Result).addReg(Alpha::R31);
|
||||
return Result;
|
||||
|
||||
case ISD::CTPOP:
|
||||
case ISD::CTTZ:
|
||||
case ISD::CTLZ:
|
||||
|
@ -50,6 +50,15 @@ class MForm<bits<6> opcode, string asmstr>
|
||||
let Inst{20-16} = Rb;
|
||||
let Inst{15-0} = disp;
|
||||
}
|
||||
class MfcForm<bits<6> opcode, bits<16> fc, string asmstr>
|
||||
: InstAlpha<opcode, (ops GPRC:$RA, GPRC:$RB), asmstr> {
|
||||
bits<5> Ra;
|
||||
bits<5> Rb;
|
||||
|
||||
let Inst{25-21} = Ra;
|
||||
let Inst{20-16} = Rb;
|
||||
let Inst{15-0} = fc;
|
||||
}
|
||||
|
||||
class MgForm<bits<6> opcode, string asmstr>
|
||||
: InstAlpha<opcode, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB, s16imm:$NUM), asmstr> {
|
||||
|
@ -465,6 +465,8 @@ def FBLE : FBForm<0x33, "fble $RA,$DISP">; //Floating branch if <= zero
|
||||
def FBLT : FBForm<0x32, "fblt $RA,$DISP">; //Floating branch if < zero
|
||||
def FBNE : FBForm<0x35, "fbne $RA,$DISP">; //Floating branch if != zero
|
||||
|
||||
def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA">; //Read process cycle counter
|
||||
|
||||
//Basic Floating point ops
|
||||
|
||||
//Floats
|
||||
@ -558,7 +560,6 @@ def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
|
||||
//LDQ_L Mem 2B Load quadword locked
|
||||
//LDQ_U Mem 0B Load unaligned quadword
|
||||
//MB Mfc 18.4000 Memory barrier
|
||||
//RPCC Mfc 18.C000 Read process cycle counter
|
||||
//STL_C Mem 2E Store longword conditional
|
||||
//STQ_C Mem 2F Store quadword conditional
|
||||
//STQ_U Mem 0F Store unaligned quadword
|
||||
|
@ -243,9 +243,10 @@ unsigned Function::getIntrinsicID() const {
|
||||
if (getName() == "llvm.pcmarker") return Intrinsic::pcmarker;
|
||||
break;
|
||||
case 'r':
|
||||
if (getName() == "llvm.returnaddress") return Intrinsic::returnaddress;
|
||||
if (getName() == "llvm.readport") return Intrinsic::readport;
|
||||
if (getName() == "llvm.readio") return Intrinsic::readio;
|
||||
if (getName() == "llvm.returnaddress") return Intrinsic::returnaddress;
|
||||
if (getName() == "llvm.readport") return Intrinsic::readport;
|
||||
if (getName() == "llvm.readio") return Intrinsic::readio;
|
||||
if (getName() == "llvm.readcyclecounter") return Intrinsic::readcyclecounter;
|
||||
break;
|
||||
case 's':
|
||||
if (getName() == "llvm.setjmp") return Intrinsic::setjmp;
|
||||
|
@ -726,6 +726,14 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
|
||||
NumArgs = 2;
|
||||
break;
|
||||
|
||||
case Intrinsic::readcyclecounter:
|
||||
Assert1(FT->getNumParams() == 0,
|
||||
"Illegal # arguments for intrinsic function!", IF);
|
||||
Assert1(FT->getReturnType() == Type::ULongTy,
|
||||
"Return type is not ulong!", IF);
|
||||
NumArgs = 0;
|
||||
break;
|
||||
|
||||
case Intrinsic::ctpop:
|
||||
case Intrinsic::ctlz:
|
||||
case Intrinsic::cttz:
|
||||
|
10
test/CodeGen/Alpha/rpcc.ll
Normal file
10
test/CodeGen/Alpha/rpcc.ll
Normal file
@ -0,0 +1,10 @@
|
||||
; RUN: llvm-as < %s | llc -march=alpha | grep rpcc
|
||||
|
||||
declare ulong %llvm.readcyclecounter()
|
||||
|
||||
ulong %foo() {
|
||||
entry:
|
||||
%tmp.1 = call ulong %llvm.readcyclecounter ()
|
||||
ret ulong %tmp.1
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user