-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[Mips] Custom lowering of SET_ROUNDING, GET_ROUNDING #170047
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-backend-mips Author: Erik Enikeev (Varnike) ChangesIn order to access Full diff: https://github.com/llvm/llvm-project/pull/170047.diff 7 Files Affected:
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
index d5fc30cef695c..67d4c82a32ef4 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
@@ -445,6 +445,8 @@ def : MipsPat<(MipsTruncIntFP FGR64Opnd:$src),
FGR_64;
def : MipsPat<(MipsTruncIntFP FGR32Opnd:$src),
(TRUNC_W_S_MM FGR32Opnd:$src)>, ISA_MICROMIPS32_NOT_MIPS32R6;
+def PseudoReadFCSR_MM : ReadFCSRImpl<[FCR31]>;
+def PseudoWriteFCSR_MM : WriteFCSRImpl<[FCR31]>;
// Selects
defm : MovzPats0<GPR32, FGR32, MOVZ_I_S_MM, SLT_MM, SLTu_MM, SLTi_MM, SLTiu_MM>,
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index eec908e453724..81f7f46ed0347 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -289,6 +289,8 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
case MipsISD::PCKEV: return "MipsISD::PCKEV";
case MipsISD::PCKOD: return "MipsISD::PCKOD";
case MipsISD::INSVE: return "MipsISD::INSVE";
+ case MipsISD::ReadFCSR: return "MipsISD::ReadFCSR";
+ case MipsISD::WriteFCSR: return "MipsISD::WriteFCSR";
}
return nullptr;
}
@@ -358,6 +360,8 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
+ setOperationAction(ISD::GET_ROUNDING, MVT::i32, Custom);
+ setOperationAction(ISD::SET_ROUNDING, MVT::Other, Custom);
setOperationAction(ISD::STRICT_FSETCC, MVT::f32, Custom);
setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Custom);
@@ -1372,6 +1376,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
case ISD::STRICT_FP_TO_UINT:
return lowerSTRICT_FP_TO_INT(Op, DAG);
case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG);
+ case ISD::GET_ROUNDING: return lowerGET_ROUNDING(Op, DAG);
+ case ISD::SET_ROUNDING: return lowerSET_ROUNDING(Op, DAG);
case ISD::READCYCLECOUNTER:
return lowerREADCYCLECOUNTER(Op, DAG);
}
@@ -3011,6 +3017,68 @@ static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG,
SD->getMemOperand()->getFlags());
}
+SDValue MipsTargetLowering::lowerGET_ROUNDING(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ SDValue Chain = Op.getOperand(0);
+
+ // Use formula:
+ // ((FCSR & 0x3) ^ ((~FCSR & 0x3) >> 1))
+ // to transform Mips rounding mode value stored in bits 1:0 of FCSR
+ // (FCR31) to LLVM rounding mode format: 1->0, 0->1, 2->2, 3->3.
+ SDValue FCSR = DAG.getNode(MipsISD::ReadFCSR, DL, {MVT::i32, MVT::Other}, Chain);
+ Chain = FCSR.getValue(1);
+ FCSR = FCSR.getValue(0);
+
+ SDValue Expr1 = DAG.getNode(ISD::AND, DL, MVT::i32,
+ FCSR, DAG.getConstant(3, DL, MVT::i32));
+ SDValue Expr2 =
+ DAG.getNode(ISD::SRL, DL, MVT::i32,
+ DAG.getNode(ISD::AND, DL, MVT::i32,
+ DAG.getNode(ISD::XOR, DL, MVT::i32,
+ FCSR, DAG.getConstant(3, DL, MVT::i32)),
+ DAG.getConstant(3, DL, MVT::i32)),
+ DAG.getConstant(1, DL, MVT::i32));
+
+ SDValue RM = DAG.getNode(ISD::XOR, DL, MVT::i32, Expr1, Expr2);
+
+ return DAG.getMergeValues({RM, Chain}, DL);
+}
+
+SDValue MipsTargetLowering::lowerSET_ROUNDING(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ SDValue Chain = Op->getOperand(0);
+ SDValue RMValue = Op->getOperand(1);
+
+ // Use formula x ^ (~(x >> 1) & 1) to transform LLVM rounding mode to Mips
+ // FCSR (FCR31) format: 0->1, 1->0, 2->2, 3->3.
+ //
+ // It is expected that the argument of llvm.set.rounding is within the
+ // segment [0, 3], so NearestTiesToAway (4) is not handled here. It is
+ // responsibility of the code generated llvm.set.rounding to ensure this
+ // condition.
+ SDValue One = DAG.getConstant(1, DL, MVT::i32);
+ SDValue NewRM = DAG.getNode(
+ ISD::XOR, DL, MVT::i32, RMValue,
+ DAG.getNode(ISD::AND, DL, MVT::i32,
+ DAG.getNOT(DL,
+ DAG.getNode(ISD::SRL, DL, MVT::i32, RMValue, One),
+ MVT::i32),
+ One));
+
+ // Put calculated rounding mode into FCSR[1:0]:
+ // FCSR = (FCSR & FFFFFFFC) | NewRM
+ SDValue FCSR = DAG.getNode(MipsISD::ReadFCSR, DL, {MVT::i32, MVT::Other}, Chain);
+ Chain = FCSR.getValue(1);
+ FCSR = FCSR.getValue(0);
+
+ FCSR = DAG.getNode(ISD::AND, DL, MVT::i32, FCSR, DAG.getConstant(0xFFFFFFFC, DL, MVT::i32));
+ FCSR = DAG.getNode(ISD::OR, DL, MVT::i32, FCSR, NewRM);
+
+ return DAG.getNode(MipsISD::WriteFCSR, DL, MVT::Other, Chain, FCSR);
+}
+
SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
StoreSDNode *SD = cast<StoreSDNode>(Op);
EVT MemVT = SD->getMemoryVT();
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 7c489b3b268a4..4c396e971368a 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -106,6 +106,10 @@ class TargetRegisterClass;
// Node used to generate an MTC1 i32 to f64 instruction
MTC1_D64,
+ // Nodes used to access FCR31 (fcsr)
+ ReadFCSR,
+ WriteFCSR,
+
// Floating Point Conditional Moves
CMovFP_T,
CMovFP_F,
@@ -573,6 +577,8 @@ class TargetRegisterClass;
SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerFSETCC(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerSET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td
index c065ba6c9632e..f1f6359abc761 100644
--- a/llvm/lib/Target/Mips/MipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MipsInstrFPU.td
@@ -41,6 +41,9 @@ def SDT_MipsExtractElementF64 : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
def SDT_MipsMTC1_D64 : SDTypeProfile<1, 1, [SDTCisVT<0, f64>,
SDTCisVT<1, i32>]>;
+def SDT_MipsReadFCSR : SDTypeProfile<1, 0, [SDTCisInt<0>]>;
+def SDT_MipsWriteFCSR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
+
def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp, [SDNPOutGlue]>;
def MipsCMovFP_T : SDNode<"MipsISD::CMovFP_T", SDT_MipsCMovFP, [SDNPInGlue]>;
def MipsCMovFP_F : SDNode<"MipsISD::CMovFP_F", SDT_MipsCMovFP, [SDNPInGlue]>;
@@ -53,6 +56,10 @@ def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64",
SDT_MipsExtractElementF64>;
def MipsMTC1_D64 : SDNode<"MipsISD::MTC1_D64", SDT_MipsMTC1_D64>;
+def MipsReadFCSR : SDNode<"MipsISD::ReadFCSR", SDT_MipsReadFCSR,
+ [SDNPHasChain]>;
+def MipsWriteFCSR : SDNode<"MipsISD::WriteFCSR", SDT_MipsWriteFCSR,
+ [SDNPHasChain, SDNPSideEffect]>;
// Operand for printing out a condition code.
let PrintMethod = "printFCCOperand", DecoderMethod = "DecodeCondCode" in
@@ -787,6 +794,27 @@ class ExtractElementF64Base<RegisterOperand RO> :
def ExtractElementF64 : ExtractElementF64Base<AFGR64Opnd>, FGR_32, HARDFLOAT;
def ExtractElementF64_64 : ExtractElementF64Base<FGR64Opnd>, FGR_64, HARDFLOAT;
+class ReadFCSRImpl<list<Register> Regs> :
+ PseudoSE<(outs GPR32Opnd:$rd), (ins),
+ [(set GPR32Opnd:$rd, (MipsReadFCSR))]> {
+ let Uses = Regs;
+ let hasSideEffects = 0;
+ let hasNoSchedulingInfo = 1;
+}
+
+class WriteFCSRImpl<list<Register> Regs> :
+ PseudoSE<(outs), (ins GPR32Opnd:$val),
+ [(MipsWriteFCSR GPR32Opnd:$val)]> {
+ let Defs = Regs;
+ let hasSideEffects = 1;
+ let hasNoSchedulingInfo = 1;
+}
+
+let AdditionalPredicates = [NotInMicroMips] in {
+ def PseudoReadFCSR : ReadFCSRImpl<[FCR31]>;
+ def PseudoWriteFCSR : WriteFCSRImpl<[FCR31]>;
+}
+
def PseudoTRUNC_W_S : MipsAsmPseudoInst<(outs FGR32Opnd:$fd),
(ins FGR32Opnd:$fs, GPR32Opnd:$rs),
"trunc.w.s\t$fd, $fs, $rs">;
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
index a1d0aa089c089..a5df5201c2efd 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -444,6 +444,18 @@ bool MipsSEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
case Mips::MIPSeh_return64:
expandEhReturn(MBB, MI);
break;
+ case Mips::PseudoReadFCSR:
+ expandReadFCSR(MBB, MI, Mips::CFC1);
+ break;
+ case Mips::PseudoWriteFCSR:
+ expandWriteFCSR(MBB, MI, Mips::CTC1);
+ break;
+ case Mips::PseudoReadFCSR_MM:
+ expandReadFCSR(MBB, MI, Mips::CFC1_MM);
+ break;
+ case Mips::PseudoWriteFCSR_MM:
+ expandWriteFCSR(MBB, MI, Mips::CTC1_MM);
+ break;
}
MBB.erase(MI);
@@ -877,6 +889,23 @@ void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB,
expandRetRA(MBB, I);
}
+void MipsSEInstrInfo::expandReadFCSR(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ unsigned Opc) const {
+ Register Dst = I->getOperand(0).getReg();
+ BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst)
+ .addImm(31);
+}
+
+void MipsSEInstrInfo::expandWriteFCSR(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ unsigned Opc) const {
+ Register Src = I->getOperand(0).getReg();
+ BuildMI(MBB, I, I->getDebugLoc(), get(Opc))
+ .addImm(31)
+ .addReg(Src);
+}
+
const MipsInstrInfo *llvm::createMipsSEInstrInfo(const MipsSubtarget &STI) {
return new MipsSEInstrInfo(STI);
}
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.h b/llvm/lib/Target/Mips/MipsSEInstrInfo.h
index 5c48ccdc27f02..a9fe9bf36ac1a 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.h
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.h
@@ -120,6 +120,10 @@ class MipsSEInstrInfo : public MipsInstrInfo {
bool FP64) const;
void expandEhReturn(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
+ void expandWriteFCSR(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I, unsigned Opc) const;
+ void expandReadFCSR(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I, unsigned Opc) const;
};
}
diff --git a/llvm/test/CodeGen/Mips/frounds.ll b/llvm/test/CodeGen/Mips/frounds.ll
new file mode 100644
index 0000000000000..06e60fb3dce20
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/frounds.ll
@@ -0,0 +1,58 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=mips -mcpu=mips32r2 < %s | FileCheck %s
+; RUN: llc -mtriple=mips -mattr=+micromips < %s | FileCheck %s --check-prefix=CHECK-MM
+
+define i32 @get_rounding() {
+; CHECK-LABEL: get_rounding:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: cfc1 $1, 31
+; CHECK-NEXT: andi $2, $1, 3
+; CHECK-NEXT: not $1, $1
+; CHECK-NEXT: andi $1, $1, 2
+; CHECK-NEXT: srl $1, $1, 1
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: xor $2, $2, $1
+;
+; CHECK-MM-LABEL: get_rounding:
+; CHECK-MM: # %bb.0: # %entry
+; CHECK-MM-NEXT: cfc1 $2, 31
+; CHECK-MM-NEXT: andi16 $3, $2, 3
+; CHECK-MM-NEXT: not16 $2, $2
+; CHECK-MM-NEXT: andi16 $2, $2, 2
+; CHECK-MM-NEXT: srl16 $2, $2, 1
+; CHECK-MM-NEXT: xor16 $2, $3
+; CHECK-MM-NEXT: jrc $ra
+entry:
+ %0 = call i32 @llvm.get.rounding()
+ ret i32 %0
+}
+
+define void @set_rounding(i32 %a) {
+; CHECK-LABEL: set_rounding:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: addiu $1, $zero, -4
+; CHECK-NEXT: cfc1 $2, 31
+; CHECK-NEXT: and $1, $2, $1
+; CHECK-NEXT: andi $2, $4, 2
+; CHECK-NEXT: sltiu $2, $2, 1
+; CHECK-NEXT: xor $2, $4, $2
+; CHECK-NEXT: or $1, $1, $2
+; CHECK-NEXT: ctc1 $1, 31
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: nop
+;
+; CHECK-MM-LABEL: set_rounding:
+; CHECK-MM: # %bb.0: # %entry
+; CHECK-MM-NEXT: addiu $2, $zero, -4
+; CHECK-MM-NEXT: cfc1 $3, 31
+; CHECK-MM-NEXT: and16 $3, $2
+; CHECK-MM-NEXT: andi16 $2, $4, 2
+; CHECK-MM-NEXT: sltiu $2, $2, 1
+; CHECK-MM-NEXT: xor16 $2, $4
+; CHECK-MM-NEXT: or16 $2, $3
+; CHECK-MM-NEXT: ctc1 $2, 31
+; CHECK-MM-NEXT: jrc $ra
+entry:
+ call void @llvm.set.rounding(i32 %a)
+ ret void
+}
|
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions cpp,h -- llvm/lib/Target/Mips/MipsISelLowering.cpp llvm/lib/Target/Mips/MipsISelLowering.h llvm/lib/Target/Mips/MipsSEInstrInfo.cpp llvm/lib/Target/Mips/MipsSEInstrInfo.h --diff_from_common_commit
View the diff from clang-format here.diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 81f7f46ed..b0dfe97fd 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -289,8 +289,10 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
case MipsISD::PCKEV: return "MipsISD::PCKEV";
case MipsISD::PCKOD: return "MipsISD::PCKOD";
case MipsISD::INSVE: return "MipsISD::INSVE";
- case MipsISD::ReadFCSR: return "MipsISD::ReadFCSR";
- case MipsISD::WriteFCSR: return "MipsISD::WriteFCSR";
+ case MipsISD::ReadFCSR:
+ return "MipsISD::ReadFCSR";
+ case MipsISD::WriteFCSR:
+ return "MipsISD::WriteFCSR";
}
return nullptr;
}
@@ -360,8 +362,8 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
- setOperationAction(ISD::GET_ROUNDING, MVT::i32, Custom);
- setOperationAction(ISD::SET_ROUNDING, MVT::Other, Custom);
+ setOperationAction(ISD::GET_ROUNDING, MVT::i32, Custom);
+ setOperationAction(ISD::SET_ROUNDING, MVT::Other, Custom);
setOperationAction(ISD::STRICT_FSETCC, MVT::f32, Custom);
setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Custom);
@@ -1376,8 +1378,10 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
case ISD::STRICT_FP_TO_UINT:
return lowerSTRICT_FP_TO_INT(Op, DAG);
case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG);
- case ISD::GET_ROUNDING: return lowerGET_ROUNDING(Op, DAG);
- case ISD::SET_ROUNDING: return lowerSET_ROUNDING(Op, DAG);
+ case ISD::GET_ROUNDING:
+ return lowerGET_ROUNDING(Op, DAG);
+ case ISD::SET_ROUNDING:
+ return lowerSET_ROUNDING(Op, DAG);
case ISD::READCYCLECOUNTER:
return lowerREADCYCLECOUNTER(Op, DAG);
}
@@ -3018,27 +3022,28 @@ static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG,
}
SDValue MipsTargetLowering::lowerGET_ROUNDING(SDValue Op,
- SelectionDAG &DAG) const {
+ SelectionDAG &DAG) const {
SDLoc DL(Op);
SDValue Chain = Op.getOperand(0);
-
- // Use formula:
- // ((FCSR & 0x3) ^ ((~FCSR & 0x3) >> 1))
- // to transform Mips rounding mode value stored in bits 1:0 of FCSR
+
+ // Use formula:
+ // ((FCSR & 0x3) ^ ((~FCSR & 0x3) >> 1))
+ // to transform Mips rounding mode value stored in bits 1:0 of FCSR
// (FCR31) to LLVM rounding mode format: 1->0, 0->1, 2->2, 3->3.
- SDValue FCSR = DAG.getNode(MipsISD::ReadFCSR, DL, {MVT::i32, MVT::Other}, Chain);
+ SDValue FCSR =
+ DAG.getNode(MipsISD::ReadFCSR, DL, {MVT::i32, MVT::Other}, Chain);
Chain = FCSR.getValue(1);
FCSR = FCSR.getValue(0);
- SDValue Expr1 = DAG.getNode(ISD::AND, DL, MVT::i32,
- FCSR, DAG.getConstant(3, DL, MVT::i32));
+ SDValue Expr1 = DAG.getNode(ISD::AND, DL, MVT::i32, FCSR,
+ DAG.getConstant(3, DL, MVT::i32));
SDValue Expr2 =
- DAG.getNode(ISD::SRL, DL, MVT::i32,
- DAG.getNode(ISD::AND, DL, MVT::i32,
- DAG.getNode(ISD::XOR, DL, MVT::i32,
- FCSR, DAG.getConstant(3, DL, MVT::i32)),
- DAG.getConstant(3, DL, MVT::i32)),
- DAG.getConstant(1, DL, MVT::i32));
+ DAG.getNode(ISD::SRL, DL, MVT::i32,
+ DAG.getNode(ISD::AND, DL, MVT::i32,
+ DAG.getNode(ISD::XOR, DL, MVT::i32, FCSR,
+ DAG.getConstant(3, DL, MVT::i32)),
+ DAG.getConstant(3, DL, MVT::i32)),
+ DAG.getConstant(1, DL, MVT::i32));
SDValue RM = DAG.getNode(ISD::XOR, DL, MVT::i32, Expr1, Expr2);
@@ -3046,12 +3051,12 @@ SDValue MipsTargetLowering::lowerGET_ROUNDING(SDValue Op,
}
SDValue MipsTargetLowering::lowerSET_ROUNDING(SDValue Op,
- SelectionDAG &DAG) const {
+ SelectionDAG &DAG) const {
SDLoc DL(Op);
SDValue Chain = Op->getOperand(0);
SDValue RMValue = Op->getOperand(1);
- // Use formula x ^ (~(x >> 1) & 1) to transform LLVM rounding mode to Mips
+ // Use formula x ^ (~(x >> 1) & 1) to transform LLVM rounding mode to Mips
// FCSR (FCR31) format: 0->1, 1->0, 2->2, 3->3.
//
// It is expected that the argument of llvm.set.rounding is within the
@@ -3067,13 +3072,15 @@ SDValue MipsTargetLowering::lowerSET_ROUNDING(SDValue Op,
MVT::i32),
One));
- // Put calculated rounding mode into FCSR[1:0]:
+ // Put calculated rounding mode into FCSR[1:0]:
// FCSR = (FCSR & FFFFFFFC) | NewRM
- SDValue FCSR = DAG.getNode(MipsISD::ReadFCSR, DL, {MVT::i32, MVT::Other}, Chain);
+ SDValue FCSR =
+ DAG.getNode(MipsISD::ReadFCSR, DL, {MVT::i32, MVT::Other}, Chain);
Chain = FCSR.getValue(1);
FCSR = FCSR.getValue(0);
- FCSR = DAG.getNode(ISD::AND, DL, MVT::i32, FCSR, DAG.getConstant(0xFFFFFFFC, DL, MVT::i32));
+ FCSR = DAG.getNode(ISD::AND, DL, MVT::i32, FCSR,
+ DAG.getConstant(0xFFFFFFFC, DL, MVT::i32));
FCSR = DAG.getNode(ISD::OR, DL, MVT::i32, FCSR, NewRM);
return DAG.getNode(MipsISD::WriteFCSR, DL, MVT::Other, Chain, FCSR);
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 4c396e971..2642f4502 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -52,216 +52,216 @@ class TargetRegisterClass;
namespace MipsISD {
- enum NodeType : unsigned {
- // Start the numbering from where ISD NodeType finishes.
- FIRST_NUMBER = ISD::BUILTIN_OP_END,
+ enum NodeType : unsigned {
+ // Start the numbering from where ISD NodeType finishes.
+ FIRST_NUMBER = ISD::BUILTIN_OP_END,
- // Jump and link (call)
- JmpLink,
+ // Jump and link (call)
+ JmpLink,
- // Tail call
- TailCall,
+ // Tail call
+ TailCall,
- // Get the Highest (63-48) 16 bits from a 64-bit immediate
- Highest,
+ // Get the Highest (63-48) 16 bits from a 64-bit immediate
+ Highest,
- // Get the Higher (47-32) 16 bits from a 64-bit immediate
- Higher,
+ // Get the Higher (47-32) 16 bits from a 64-bit immediate
+ Higher,
- // Get the High 16 bits from a 32/64-bit immediate
- // No relation with Mips Hi register
- Hi,
+ // Get the High 16 bits from a 32/64-bit immediate
+ // No relation with Mips Hi register
+ Hi,
- // Get the Lower 16 bits from a 32/64-bit immediate
- // No relation with Mips Lo register
- Lo,
+ // Get the Lower 16 bits from a 32/64-bit immediate
+ // No relation with Mips Lo register
+ Lo,
- // Get the High 16 bits from a 32 bit immediate for accessing the GOT.
- GotHi,
+ // Get the High 16 bits from a 32 bit immediate for accessing the GOT.
+ GotHi,
- // Get the High 16 bits from a 32-bit immediate for accessing TLS.
- TlsHi,
+ // Get the High 16 bits from a 32-bit immediate for accessing TLS.
+ TlsHi,
- // Handle gp_rel (small data/bss sections) relocation.
- GPRel,
+ // Handle gp_rel (small data/bss sections) relocation.
+ GPRel,
- // Thread Pointer
- ThreadPointer,
+ // Thread Pointer
+ ThreadPointer,
- // Vector Floating Point Multiply and Subtract
- FMS,
+ // Vector Floating Point Multiply and Subtract
+ FMS,
- // Floating Point Branch Conditional
- FPBrcond,
-
- // Floating Point Compare
- FPCmp,
-
- // Floating point Abs
- FAbs,
-
- // Floating point select
- FSELECT,
-
- // Node used to generate an MTC1 i32 to f64 instruction
- MTC1_D64,
-
- // Nodes used to access FCR31 (fcsr)
- ReadFCSR,
- WriteFCSR,
-
- // Floating Point Conditional Moves
- CMovFP_T,
- CMovFP_F,
-
- // FP-to-int truncation node.
- TruncIntFP,
-
- // Return
- Ret,
-
- // Interrupt, exception, error trap Return
- ERet,
-
- // Software Exception Return.
- EH_RETURN,
-
- // Node used to extract integer from accumulator.
- MFHI,
- MFLO,
-
- // Node used to insert integers to accumulator.
- MTLOHI,
-
- // Mult nodes.
- Mult,
- Multu,
-
- // MAdd/Sub nodes
- MAdd,
- MAddu,
- MSub,
- MSubu,
-
- // DivRem(u)
- DivRem,
- DivRemU,
- DivRem16,
- DivRemU16,
-
- BuildPairF64,
- ExtractElementF64,
-
- Wrapper,
-
- DynAlloc,
-
- Sync,
-
- Ext,
- Ins,
- CIns,
-
- // EXTR.W intrinsic nodes.
- EXTP,
- EXTPDP,
- EXTR_S_H,
- EXTR_W,
- EXTR_R_W,
- EXTR_RS_W,
- SHILO,
- MTHLIP,
-
- // DPA.W intrinsic nodes.
- MULSAQ_S_W_PH,
- MAQ_S_W_PHL,
- MAQ_S_W_PHR,
- MAQ_SA_W_PHL,
- MAQ_SA_W_PHR,
- DPAU_H_QBL,
- DPAU_H_QBR,
- DPSU_H_QBL,
- DPSU_H_QBR,
- DPAQ_S_W_PH,
- DPSQ_S_W_PH,
- DPAQ_SA_L_W,
- DPSQ_SA_L_W,
- DPA_W_PH,
- DPS_W_PH,
- DPAQX_S_W_PH,
- DPAQX_SA_W_PH,
- DPAX_W_PH,
- DPSX_W_PH,
- DPSQX_S_W_PH,
- DPSQX_SA_W_PH,
- MULSA_W_PH,
-
- MULT,
- MULTU,
- MADD_DSP,
- MADDU_DSP,
- MSUB_DSP,
- MSUBU_DSP,
-
- // DSP shift nodes.
- SHLL_DSP,
- SHRA_DSP,
- SHRL_DSP,
-
- // DSP setcc and select_cc nodes.
- SETCC_DSP,
- SELECT_CC_DSP,
-
- // Vector comparisons.
- // These take a vector and return a boolean.
- VALL_ZERO,
- VANY_ZERO,
- VALL_NONZERO,
- VANY_NONZERO,
-
- // These take a vector and return a vector bitmask.
- VCEQ,
- VCLE_S,
- VCLE_U,
- VCLT_S,
- VCLT_U,
-
- // Vector Shuffle with mask as an operand
- VSHF, // Generic shuffle
- SHF, // 4-element set shuffle.
- ILVEV, // Interleave even elements
- ILVOD, // Interleave odd elements
- ILVL, // Interleave left elements
- ILVR, // Interleave right elements
- PCKEV, // Pack even elements
- PCKOD, // Pack odd elements
-
- // Vector Lane Copy
- INSVE, // Copy element from one vector to another
-
- // Combined (XOR (OR $a, $b), -1)
- VNOR,
-
- // Extended vector element extraction
- VEXTRACT_SEXT_ELT,
- VEXTRACT_ZEXT_ELT,
-
- // Double select nodes for machines without conditional-move.
- DOUBLE_SELECT_I,
- DOUBLE_SELECT_I64,
-
- // Load/Store Left/Right nodes.
- FIRST_MEMORY_OPCODE,
- LWL = FIRST_MEMORY_OPCODE,
- LWR,
- SWL,
- SWR,
- LDL,
- LDR,
- SDL,
- SDR,
- LAST_MEMORY_OPCODE = SDR,
- };
+ // Floating Point Branch Conditional
+ FPBrcond,
+
+ // Floating Point Compare
+ FPCmp,
+
+ // Floating point Abs
+ FAbs,
+
+ // Floating point select
+ FSELECT,
+
+ // Node used to generate an MTC1 i32 to f64 instruction
+ MTC1_D64,
+
+ // Nodes used to access FCR31 (fcsr)
+ ReadFCSR,
+ WriteFCSR,
+
+ // Floating Point Conditional Moves
+ CMovFP_T,
+ CMovFP_F,
+
+ // FP-to-int truncation node.
+ TruncIntFP,
+
+ // Return
+ Ret,
+
+ // Interrupt, exception, error trap Return
+ ERet,
+
+ // Software Exception Return.
+ EH_RETURN,
+
+ // Node used to extract integer from accumulator.
+ MFHI,
+ MFLO,
+
+ // Node used to insert integers to accumulator.
+ MTLOHI,
+
+ // Mult nodes.
+ Mult,
+ Multu,
+
+ // MAdd/Sub nodes
+ MAdd,
+ MAddu,
+ MSub,
+ MSubu,
+
+ // DivRem(u)
+ DivRem,
+ DivRemU,
+ DivRem16,
+ DivRemU16,
+
+ BuildPairF64,
+ ExtractElementF64,
+
+ Wrapper,
+
+ DynAlloc,
+
+ Sync,
+
+ Ext,
+ Ins,
+ CIns,
+
+ // EXTR.W intrinsic nodes.
+ EXTP,
+ EXTPDP,
+ EXTR_S_H,
+ EXTR_W,
+ EXTR_R_W,
+ EXTR_RS_W,
+ SHILO,
+ MTHLIP,
+
+ // DPA.W intrinsic nodes.
+ MULSAQ_S_W_PH,
+ MAQ_S_W_PHL,
+ MAQ_S_W_PHR,
+ MAQ_SA_W_PHL,
+ MAQ_SA_W_PHR,
+ DPAU_H_QBL,
+ DPAU_H_QBR,
+ DPSU_H_QBL,
+ DPSU_H_QBR,
+ DPAQ_S_W_PH,
+ DPSQ_S_W_PH,
+ DPAQ_SA_L_W,
+ DPSQ_SA_L_W,
+ DPA_W_PH,
+ DPS_W_PH,
+ DPAQX_S_W_PH,
+ DPAQX_SA_W_PH,
+ DPAX_W_PH,
+ DPSX_W_PH,
+ DPSQX_S_W_PH,
+ DPSQX_SA_W_PH,
+ MULSA_W_PH,
+
+ MULT,
+ MULTU,
+ MADD_DSP,
+ MADDU_DSP,
+ MSUB_DSP,
+ MSUBU_DSP,
+
+ // DSP shift nodes.
+ SHLL_DSP,
+ SHRA_DSP,
+ SHRL_DSP,
+
+ // DSP setcc and select_cc nodes.
+ SETCC_DSP,
+ SELECT_CC_DSP,
+
+ // Vector comparisons.
+ // These take a vector and return a boolean.
+ VALL_ZERO,
+ VANY_ZERO,
+ VALL_NONZERO,
+ VANY_NONZERO,
+
+ // These take a vector and return a vector bitmask.
+ VCEQ,
+ VCLE_S,
+ VCLE_U,
+ VCLT_S,
+ VCLT_U,
+
+ // Vector Shuffle with mask as an operand
+ VSHF, // Generic shuffle
+ SHF, // 4-element set shuffle.
+ ILVEV, // Interleave even elements
+ ILVOD, // Interleave odd elements
+ ILVL, // Interleave left elements
+ ILVR, // Interleave right elements
+ PCKEV, // Pack even elements
+ PCKOD, // Pack odd elements
+
+ // Vector Lane Copy
+ INSVE, // Copy element from one vector to another
+
+ // Combined (XOR (OR $a, $b), -1)
+ VNOR,
+
+ // Extended vector element extraction
+ VEXTRACT_SEXT_ELT,
+ VEXTRACT_ZEXT_ELT,
+
+ // Double select nodes for machines without conditional-move.
+ DOUBLE_SELECT_I,
+ DOUBLE_SELECT_I64,
+
+ // Load/Store Left/Right nodes.
+ FIRST_MEMORY_OPCODE,
+ LWL = FIRST_MEMORY_OPCODE,
+ LWR,
+ SWL,
+ SWR,
+ LDL,
+ LDR,
+ SDL,
+ SDR,
+ LAST_MEMORY_OPCODE = SDR,
+ };
} // ene namespace MipsISD
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
index a5df5201c..0d23cf68e 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -893,17 +893,14 @@ void MipsSEInstrInfo::expandReadFCSR(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned Opc) const {
Register Dst = I->getOperand(0).getReg();
- BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst)
- .addImm(31);
+ BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst).addImm(31);
}
void MipsSEInstrInfo::expandWriteFCSR(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned Opc) const {
Register Src = I->getOperand(0).getReg();
- BuildMI(MBB, I, I->getDebugLoc(), get(Opc))
- .addImm(31)
- .addReg(Src);
+ BuildMI(MBB, I, I->getDebugLoc(), get(Opc)).addImm(31).addReg(Src);
}
const MipsInstrInfo *llvm::createMipsSEInstrInfo(const MipsSubtarget &STI) {
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.h b/llvm/lib/Target/Mips/MipsSEInstrInfo.h
index a9fe9bf36..b22de630f 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.h
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.h
@@ -120,10 +120,10 @@ private:
bool FP64) const;
void expandEhReturn(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
- void expandWriteFCSR(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I, unsigned Opc) const;
- void expandReadFCSR(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I, unsigned Opc) const;
+ void expandWriteFCSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+ unsigned Opc) const;
+ void expandReadFCSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+ unsigned Opc) const;
};
}
|
|
cc @yingopq |
In order to access
FCSR(FCR31),ReadFCSRandWriteFCSRnodes were added.