@@ -625,10 +625,12 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
625
625
if (Subtarget.is64Bit())
626
626
setOperationAction(ISD::Constant, MVT::i64, Custom);
627
627
628
- // TODO: On M-mode only targets, the cycle[h] CSR may not be present.
628
+ // TODO: On M-mode only targets, the cycle[h]/time[h] CSR may not be present.
629
629
// Unfortunately this can't be determined just from the ISA naming string.
630
630
setOperationAction(ISD::READCYCLECOUNTER, MVT::i64,
631
631
Subtarget.is64Bit() ? Legal : Custom);
632
+ setOperationAction(ISD::READSTEADYCOUNTER, MVT::i64,
633
+ Subtarget.is64Bit() ? Legal : Custom);
632
634
633
635
setOperationAction({ISD::TRAP, ISD::DEBUGTRAP}, MVT::Other, Legal);
634
636
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
@@ -11724,13 +11726,27 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
11724
11726
Results.push_back(Result);
11725
11727
break;
11726
11728
}
11727
- case ISD::READCYCLECOUNTER: {
11728
- assert(!Subtarget.is64Bit() &&
11729
- "READCYCLECOUNTER only has custom type legalization on riscv32");
11729
+ case ISD::READCYCLECOUNTER:
11730
+ case ISD::READSTEADYCOUNTER: {
11731
+ assert(!Subtarget.is64Bit() && "READCYCLECOUNTER/READSTEADYCOUNTER only "
11732
+ "has custom type legalization on riscv32");
11730
11733
11734
+ SDValue LoCounter, HiCounter;
11735
+ MVT XLenVT = Subtarget.getXLenVT();
11736
+ if (N->getOpcode() == ISD::READCYCLECOUNTER) {
11737
+ LoCounter = DAG.getConstant(
11738
+ RISCVSysReg::lookupSysRegByName("CYCLE")->Encoding, DL, XLenVT);
11739
+ HiCounter = DAG.getConstant(
11740
+ RISCVSysReg::lookupSysRegByName("CYCLEH")->Encoding, DL, XLenVT);
11741
+ } else {
11742
+ LoCounter = DAG.getConstant(
11743
+ RISCVSysReg::lookupSysRegByName("TIME")->Encoding, DL, XLenVT);
11744
+ HiCounter = DAG.getConstant(
11745
+ RISCVSysReg::lookupSysRegByName("TIMEH")->Encoding, DL, XLenVT);
11746
+ }
11731
11747
SDVTList VTs = DAG.getVTList(MVT::i32, MVT::i32, MVT::Other);
11732
- SDValue RCW =
11733
- DAG.getNode(RISCVISD::READ_CYCLE_WIDE, DL, VTs, N->getOperand(0));
11748
+ SDValue RCW = DAG.getNode(RISCVISD::READ_COUNTER_WIDE, DL, VTs,
11749
+ N->getOperand(0), LoCounter, HiCounter );
11734
11750
11735
11751
Results.push_back(
11736
11752
DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, RCW, RCW.getValue(1)));
@@ -16902,29 +16918,30 @@ RISCVTargetLowering::getTargetConstantFromLoad(LoadSDNode *Ld) const {
16902
16918
return CNodeLo->getConstVal();
16903
16919
}
16904
16920
16905
- static MachineBasicBlock *emitReadCycleWidePseudo (MachineInstr &MI,
16906
- MachineBasicBlock *BB) {
16907
- assert(MI.getOpcode() == RISCV::ReadCycleWide && "Unexpected instruction");
16921
+ static MachineBasicBlock *emitReadCounterWidePseudo (MachineInstr &MI,
16922
+ MachineBasicBlock *BB) {
16923
+ assert(MI.getOpcode() == RISCV::ReadCounterWide && "Unexpected instruction");
16908
16924
16909
- // To read the 64-bit cycle CSR on a 32-bit target, we read the two halves.
16925
+ // To read a 64-bit counter CSR on a 32-bit target, we read the two halves.
16910
16926
// Should the count have wrapped while it was being read, we need to try
16911
16927
// again.
16912
- // ...
16928
+ // For example:
16929
+ // ```
16913
16930
// read:
16914
- // rdcycleh x3 # load high word of cycle
16915
- // rdcycle x2 # load low word of cycle
16916
- // rdcycleh x4 # load high word of cycle
16917
- // bne x3, x4, read # check if high word reads match, otherwise try again
16918
- // ...
16931
+ // csrrs x3, counterh # load high word of counter
16932
+ // csrrs x2, counter # load low word of counter
16933
+ // csrrs x4, counterh # load high word of counter
16934
+ // bne x3, x4, read # check if high word reads match, otherwise try again
16935
+ // ```
16919
16936
16920
16937
MachineFunction &MF = *BB->getParent();
16921
- const BasicBlock *LLVM_BB = BB->getBasicBlock();
16938
+ const BasicBlock *LLVMBB = BB->getBasicBlock();
16922
16939
MachineFunction::iterator It = ++BB->getIterator();
16923
16940
16924
- MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(LLVM_BB );
16941
+ MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(LLVMBB );
16925
16942
MF.insert(It, LoopMBB);
16926
16943
16927
- MachineBasicBlock *DoneMBB = MF.CreateMachineBasicBlock(LLVM_BB );
16944
+ MachineBasicBlock *DoneMBB = MF.CreateMachineBasicBlock(LLVMBB );
16928
16945
MF.insert(It, DoneMBB);
16929
16946
16930
16947
// Transfer the remainder of BB and its successor edges to DoneMBB.
@@ -16938,17 +16955,19 @@ static MachineBasicBlock *emitReadCycleWidePseudo(MachineInstr &MI,
16938
16955
Register ReadAgainReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
16939
16956
Register LoReg = MI.getOperand(0).getReg();
16940
16957
Register HiReg = MI.getOperand(1).getReg();
16958
+ int64_t LoCounter = MI.getOperand(2).getImm();
16959
+ int64_t HiCounter = MI.getOperand(3).getImm();
16941
16960
DebugLoc DL = MI.getDebugLoc();
16942
16961
16943
16962
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
16944
16963
BuildMI(LoopMBB, DL, TII->get(RISCV::CSRRS), HiReg)
16945
- .addImm(RISCVSysReg::lookupSysRegByName("CYCLEH")->Encoding )
16964
+ .addImm(HiCounter )
16946
16965
.addReg(RISCV::X0);
16947
16966
BuildMI(LoopMBB, DL, TII->get(RISCV::CSRRS), LoReg)
16948
- .addImm(RISCVSysReg::lookupSysRegByName("CYCLE")->Encoding )
16967
+ .addImm(LoCounter )
16949
16968
.addReg(RISCV::X0);
16950
16969
BuildMI(LoopMBB, DL, TII->get(RISCV::CSRRS), ReadAgainReg)
16951
- .addImm(RISCVSysReg::lookupSysRegByName("CYCLEH")->Encoding )
16970
+ .addImm(HiCounter )
16952
16971
.addReg(RISCV::X0);
16953
16972
16954
16973
BuildMI(LoopMBB, DL, TII->get(RISCV::BNE))
@@ -17527,10 +17546,10 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
17527
17546
switch (MI.getOpcode()) {
17528
17547
default:
17529
17548
llvm_unreachable("Unexpected instr type to insert");
17530
- case RISCV::ReadCycleWide :
17549
+ case RISCV::ReadCounterWide :
17531
17550
assert(!Subtarget.is64Bit() &&
17532
- "ReadCycleWrite is only to be used on riscv32");
17533
- return emitReadCycleWidePseudo (MI, BB);
17551
+ "ReadCounterWide is only to be used on riscv32");
17552
+ return emitReadCounterWidePseudo (MI, BB);
17534
17553
case RISCV::Select_GPR_Using_CC_GPR:
17535
17554
case RISCV::Select_FPR16_Using_CC_GPR:
17536
17555
case RISCV::Select_FPR16INX_Using_CC_GPR:
@@ -19202,7 +19221,7 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
19202
19221
NODE_NAME_CASE(FCLASS)
19203
19222
NODE_NAME_CASE(FMAX)
19204
19223
NODE_NAME_CASE(FMIN)
19205
- NODE_NAME_CASE(READ_CYCLE_WIDE )
19224
+ NODE_NAME_CASE(READ_COUNTER_WIDE )
19206
19225
NODE_NAME_CASE(BREV8)
19207
19226
NODE_NAME_CASE(ORC_B)
19208
19227
NODE_NAME_CASE(ZIP)
0 commit comments