diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index e33bf956860..aa221fbda3d 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -101,6 +101,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) setOperationAction(ISD::CTPOP , MVT::i32 , Expand); setOperationAction(ISD::CTTZ , MVT::i32 , Expand); setOperationAction(ISD::CTLZ , MVT::i32 , Expand); + setOperationAction(ISD::READCYCLECOUNTER , MVT::i64 , Custom); setOperationAction(ISD::READIO , MVT::i1 , Expand); setOperationAction(ISD::READIO , MVT::i8 , Expand); @@ -912,5 +913,11 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return DAG.getLoad(Op.getValueType(), FIST, StackSlot, DAG.getSrcValue(NULL)); } + case ISD::READCYCLECOUNTER: { + SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, MVT::Other, Op.getOperand(0)); + SDOperand Lo = DAG.getCopyFromReg(rd, X86::EAX, MVT::i32); + SDOperand Hi = DAG.getCopyFromReg(rd, X86::EDX, MVT::i32); + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); + } } } diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index b4468ac8a33..ccec6ea23f7 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -62,6 +62,10 @@ namespace llvm { /// LLVM. CALL, TAILCALL, + + /// RDTSC_DAG - This operation implements the lowering for + /// readcyclecounter + RDTSC_DAG, }; } diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp index 58c60692b9d..5c4594aa9ec 100644 --- a/lib/Target/X86/X86ISelPattern.cpp +++ b/lib/Target/X86/X86ISelPattern.cpp @@ -3090,6 +3090,11 @@ void ISel::Select(SDOperand N) { default: Node->dump(); std::cerr << "\n"; assert(0 && "Node not handled yet!"); + case X86ISD::RDTSC_DAG: + Select(Node->getOperand(0)); //Chain + BuildMI(BB, X86::RDTSC, 0); + return; + case ISD::EntryToken: return; // Noop case ISD::TokenFactor: if (Node->getNumOperands() == 2) { diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 40b2481ab4a..0eaf337fd4f 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -167,6 +167,10 @@ class Ii32 o, Format f, dag ops, string asm, list pattern> def PHI : I<0, Pseudo, (ops variable_ops), "PHINODE">; // PHI node. def NOOP : I<0x90, RawFrm, (ops), "nop">; // nop +//FIXME: encode this correctly +let Defs = [EAX, EDX] in + def RDTSC : I<0, Pseudo, (ops ), "rdtsc">; //in binary, this inst is 0x0f 0x31 + def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN">; def ADJCALLSTACKUP : I<0, Pseudo, (ops i32imm:$amt1, i32imm:$amt2), "#ADJCALLSTACKUP">;