Skip to content

Commit 5a8708f

Browse files
committed
[Mips] Support llvm.readcyclecounter intrinsic
The llvm.readcyclecounter intrinsic can be implemented via the `rdhwr $2, $hwr_cc` instruction. $hwr_cc: High-resolution cycle counter. This register provides read access to the coprocessor 0 Count Register. Fix #106318.
1 parent ba5676c commit 5a8708f

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,10 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
359359
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
360360
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
361361

362+
if (Subtarget.hasMips32r2() ||
363+
getTargetMachine().getTargetTriple().isOSLinux())
364+
setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Custom);
365+
362366
// Lower fmin/fmax/fclass operations for MIPS R6.
363367
if (Subtarget.hasMips32r6()) {
364368
setOperationAction(ISD::FMINNUM_IEEE, MVT::f32, Legal);
@@ -1311,6 +1315,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
13111315
case ISD::STORE: return lowerSTORE(Op, DAG);
13121316
case ISD::EH_DWARF_CFA: return lowerEH_DWARF_CFA(Op, DAG);
13131317
case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG);
1318+
case ISD::READCYCLECOUNTER:
1319+
return lowerREADCYCLECOUNTER(Op, DAG);
13141320
}
13151321
return SDValue();
13161322
}
@@ -2092,6 +2098,44 @@ MachineBasicBlock *MipsTargetLowering::emitAtomicCmpSwapPartword(
20922098
return exitMBB;
20932099
}
20942100

2101+
SDValue MipsTargetLowering::lowerREADCYCLECOUNTER(SDValue Op,
2102+
SelectionDAG &DAG) const {
2103+
SmallVector<SDValue, 3> Results;
2104+
SDLoc DL(Op);
2105+
MachineFunction &MF = DAG.getMachineFunction();
2106+
unsigned RdhwrOpc, DestReg;
2107+
EVT PtrVT = getPointerTy(DAG.getDataLayout());
2108+
2109+
if (PtrVT == MVT::i64) {
2110+
RdhwrOpc = Mips::RDHWR64;
2111+
DestReg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64));
2112+
SDNode *Rdhwr = DAG.getMachineNode(RdhwrOpc, DL, MVT::i64, MVT::Glue,
2113+
DAG.getRegister(Mips::HWR2, MVT::i32),
2114+
DAG.getTargetConstant(0, DL, MVT::i32));
2115+
SDValue Chain = DAG.getCopyToReg(DAG.getEntryNode(), DL, DestReg,
2116+
SDValue(Rdhwr, 0), SDValue(Rdhwr, 1));
2117+
SDValue ResNode =
2118+
DAG.getCopyFromReg(Chain, DL, DestReg, MVT::i64, Chain.getValue(1));
2119+
Results.push_back(ResNode);
2120+
Results.push_back(ResNode.getValue(1));
2121+
} else {
2122+
RdhwrOpc = Mips::RDHWR;
2123+
DestReg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i32));
2124+
SDNode *Rdhwr = DAG.getMachineNode(RdhwrOpc, DL, MVT::i32, MVT::Glue,
2125+
DAG.getRegister(Mips::HWR2, MVT::i32),
2126+
DAG.getTargetConstant(0, DL, MVT::i32));
2127+
SDValue Chain = DAG.getCopyToReg(DAG.getEntryNode(), DL, DestReg,
2128+
SDValue(Rdhwr, 0), SDValue(Rdhwr, 1));
2129+
SDValue ResNode =
2130+
DAG.getCopyFromReg(Chain, DL, DestReg, MVT::i32, Chain.getValue(1));
2131+
Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, ResNode,
2132+
DAG.getConstant(0, DL, MVT::i32)));
2133+
Results.push_back(ResNode.getValue(1));
2134+
}
2135+
2136+
return DAG.getMergeValues(Results, DL);
2137+
}
2138+
20952139
SDValue MipsTargetLowering::lowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
20962140
// The first operand is the chain, the second is the condition, the third is
20972141
// the block to branch to if the condition is true.

llvm/lib/Target/Mips/MipsISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ class TargetRegisterClass;
560560
bool IsSRA) const;
561561
SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
562562
SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
563+
SDValue lowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
563564

564565
/// isEligibleForTailCallOptimization - Check whether the call is eligible
565566
/// for tail call optimization.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
;RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips32r2 < %s | FileCheck %s --check-prefix=MIPSEL
2+
;RUN: llc -mtriple=mips64el-linux-gnuabi64 -mcpu=mips64r2 < %s | FileCheck %s --check-prefix=MIPS64EL
3+
;RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips2 < %s | FileCheck %s --check-prefix=MIPSEL
4+
;RUN: llc -mtriple=mips64el-linux-gnuabi64 -mcpu=mips3 < %s | FileCheck %s --check-prefix=MIPS64EL
5+
;RUN: llc -mtriple=mipsel -mcpu=mips32r2 < %s | FileCheck %s --check-prefix=MIPSEL
6+
;RUN: llc -mtriple=mips64el -mcpu=mips64r2 < %s | FileCheck %s --check-prefix=MIPS64EL
7+
;RUN: llc -mtriple=mipsel -mcpu=mips2 < %s | FileCheck %s --check-prefix=MIPSEL_NOT_SUPPORTED
8+
;RUN: llc -mtriple=mips64el -mcpu=mips3 < %s | FileCheck %s --check-prefix=MIPS64EL_NOT_SUPPORTED
9+
10+
define i64 @test_readcyclecounter() nounwind {
11+
; MIPSEL-LABEL: test_readcyclecounter:
12+
; MIPSEL: # %bb.0: # %entry
13+
; MIPSEL-NEXT: .set push
14+
; MIPSEL-NEXT: .set mips32r2
15+
; MIPSEL-NEXT: rdhwr $2, $hwr_cc
16+
; MIPSEL-NEXT: .set pop
17+
; MIPSEL-NEXT: jr $ra
18+
; MIPSEL-NEXT: addiu $3, $zero, 0
19+
;
20+
; MIPSEL_NOT_SUPPORTED-LABEL: test_readcyclecounter:
21+
; MIPSEL_NOT_SUPPORTED: # %bb.0: # %entry
22+
; MIPSEL_NOT_SUPPORTED-NEXT: addiu $2, $zero, 0
23+
; MIPSEL_NOT_SUPPORTED-NEXT: jr $ra
24+
; MIPSEL_NOT_SUPPORTED-NEXT: addiu $3, $zero, 0
25+
;
26+
; MIPS64EL-LABEL: test_readcyclecounter:
27+
; MIPS64EL: # %bb.0: # %entry
28+
; MIPS64EL-NEXT: .set push
29+
; MIPS64EL-NEXT: .set mips32r2
30+
; MIPS64EL-NEXT: rdhwr $2, $hwr_cc
31+
; MIPS64EL-NEXT: .set pop
32+
; MIPS64EL-NEXT: jr $ra
33+
; MIPS64EL-NEXT: nop
34+
;
35+
; MIPS64EL_NOT_SUPPORTED-LABEL: test_readcyclecounter:
36+
; MIPS64EL_NOT_SUPPORTED: # %bb.0: # %entry
37+
; MIPS64EL_NOT_SUPPORTED-NEXT: jr $ra
38+
; MIPS64EL_NOT_SUPPORTED-NEXT: daddiu $2, $zero, 0
39+
entry:
40+
%tmp0 = call i64 @llvm.readcyclecounter()
41+
ret i64 %tmp0
42+
}
43+

0 commit comments

Comments
 (0)