From d3bdf19ce7a37e23a6c4d877fb681eb010be74f7 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Wed, 27 May 2009 17:23:44 +0000 Subject: [PATCH] Added support for fround, fextend and FP_TO_SINT git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72483 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/Mips.td | 8 +++--- lib/Target/Mips/MipsISelLowering.cpp | 37 ++++++++++++++++++++++++++++ lib/Target/Mips/MipsISelLowering.h | 4 +++ lib/Target/Mips/MipsInstrFPU.td | 26 ++++++++++++++----- lib/Target/Mips/MipsInstrInfo.cpp | 25 +++++++++++-------- lib/Target/Mips/MipsInstrInfo.td | 4 +-- lib/Target/Mips/MipsRegisterInfo.td | 12 ++++----- lib/Target/Mips/MipsSubtarget.cpp | 1 + lib/Target/Mips/MipsSubtarget.h | 2 +- 9 files changed, 90 insertions(+), 29 deletions(-) diff --git a/lib/Target/Mips/Mips.td b/lib/Target/Mips/Mips.td index 79ae5d2425f..79a78d86aef 100644 --- a/lib/Target/Mips/Mips.td +++ b/lib/Target/Mips/Mips.td @@ -39,6 +39,8 @@ def FeatureFP64Bit : SubtargetFeature<"fp64", "IsFP64bit", "true", "Support 64-bit FP registers.">; def FeatureSingleFloat : SubtargetFeature<"single-float", "IsSingleFloat", "true", "Only supports single precision float">; +def FeatureMips1 : SubtargetFeature<"mips1", "MipsArchVersion", "Mips1", + "Mips1 ISA Support">; def FeatureMips2 : SubtargetFeature<"mips2", "MipsArchVersion", "Mips2", "Mips2 ISA Support">; def FeatureO32 : SubtargetFeature<"o32", "MipsABI", "O32", @@ -67,9 +69,9 @@ def FeatureBitCount : SubtargetFeature<"bitcount", "HasBitCount", "true", class Proc Features> : Processor; -def : Proc<"mips1", []>; -def : Proc<"r2000", []>; -def : Proc<"r3000", []>; +def : Proc<"mips1", [FeatureMips1]>; +def : Proc<"r2000", [FeatureMips1]>; +def : Proc<"r3000", [FeatureMips1]>; def : Proc<"mips2", [FeatureMips2]>; def : Proc<"r6000", [FeatureMips2]>; diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index a0e5f30d787..9281940019a 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -48,6 +48,7 @@ getTargetNodeName(unsigned Opcode) const case MipsISD::FPSelectCC : return "MipsISD::FPSelectCC"; case MipsISD::FPBrcond : return "MipsISD::FPBrcond"; case MipsISD::FPCmp : return "MipsISD::FPCmp"; + case MipsISD::FPRound : return "MipsISD::FPRound"; default : return NULL; } } @@ -96,8 +97,10 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM) setOperationAction(ISD::SELECT, MVT::f32, Custom); setOperationAction(ISD::SELECT, MVT::i32, Custom); setOperationAction(ISD::SETCC, MVT::f32, Custom); + setOperationAction(ISD::SETCC, MVT::f64, Custom); setOperationAction(ISD::BRCOND, MVT::Other, Custom); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); // We custom lower AND/OR to handle the case where the DAG contain 'ands/ors' // with operands comming from setcc fp comparions. This is necessary since @@ -166,6 +169,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); + case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); @@ -358,6 +362,39 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, // Misc Lower Operation implementation //===----------------------------------------------------------------------===// +SDValue MipsTargetLowering:: +LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) +{ + if (!Subtarget->isMips1()) + return Op; + + MachineFunction &MF = DAG.getMachineFunction(); + unsigned CCReg = AddLiveIn(MF, Mips::FCR31, Mips::CCRRegisterClass); + + SDValue Chain = DAG.getEntryNode(); + DebugLoc dl = Op.getDebugLoc(); + SDValue Src = Op.getOperand(0); + + // Set the condition register + SDValue CondReg = DAG.getCopyFromReg(Chain, dl, CCReg, MVT::i32); + CondReg = DAG.getCopyToReg(Chain, dl, Mips::AT, CondReg); + CondReg = DAG.getCopyFromReg(CondReg, dl, Mips::AT, MVT::i32); + + SDValue Cst = DAG.getConstant(3, MVT::i32); + SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i32, CondReg, Cst); + Cst = DAG.getConstant(2, MVT::i32); + SDValue Xor = DAG.getNode(ISD::XOR, dl, MVT::i32, Or, Cst); + + SDValue InFlag(0, 0); + CondReg = DAG.getCopyToReg(Chain, dl, Mips::FCR31, Xor, InFlag); + + // Emit the round instruction and bit convert to integer + SDValue Trunc = DAG.getNode(MipsISD::FPRound, dl, MVT::f32, + Src, CondReg.getValue(1)); + SDValue BitCvt = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Trunc); + return BitCvt; +} + SDValue MipsTargetLowering:: LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) { diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 11289825e44..55cd6eadd09 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -55,6 +55,9 @@ namespace llvm { // Floating Point Compare FPCmp, + // Floating Point Rounding + FPRound, + // Return Ret }; @@ -98,6 +101,7 @@ namespace llvm { SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG); SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG); SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); + SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG); diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index b734a7ccf9b..b6a6d2f5c05 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -30,6 +30,8 @@ def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisInt<2>]>; def SDT_MipsFPSelectCC : SDTypeProfile<1, 4, [SDTCisInt<1>, SDTCisInt<4>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>]>; + +def MipsFPRound : SDNode<"MipsISD::FPRound", SDTFPRoundOp, [SDNPOptInFlag]>; def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, [SDNPHasChain]>; def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp>; @@ -66,7 +68,7 @@ multiclass FFR1_1 funct, string asmstr> def _S32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), (ins FGR32:$fs), !strconcat(asmstr, ".s $fd, $fs"), []>; - def _D32 : FFR<0x11, funct, 0x1, (outs AFGR64:$fd), (ins AFGR64:$fs), + def _D32 : FFR<0x11, funct, 0x1, (outs FGR32:$fd), (ins AFGR64:$fs), !strconcat(asmstr, ".d $fd, $fs"), []>, Requires<[In32BitMode]>; } @@ -157,12 +159,12 @@ let ft = 0 in { // regardless of register aliasing. let fd = 0 in { /// Move Control Registers From/To CPU Registers - ///def CFC1 : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins FGR32:$fs), - /// "cfc1 $rt, $fs", []>; + def CFC1 : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins CCR:$fs), + "cfc1 $rt, $fs", []>; - ///def CTC1 : FFR<0x11, 0x0, 0x6, (outs CPURegs:$rt), (ins FGR32:$fs), - /// "ctc1 $rt, $fs", []>; - /// + def CTC1 : FFR<0x11, 0x0, 0x6, (outs CCR:$rt), (ins CPURegs:$fs), + "ctc1 $fs, $rt", []>; + def MFC1 : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins FGR32:$fs), "mfc1 $rt, $fs", []>; @@ -272,6 +274,9 @@ def Select_FCC_S32 : PseudoFPSelCC; def Select_FCC_D32 : PseudoFPSelCC, Requires<[In32BitMode]>; +def MOVCCRToCCR : MipsPseudo<(outs CCR:$dst), (ins CCR:$src), + "# MOVCCRToCCR", []>; + //===----------------------------------------------------------------------===// // Floating Point Patterns //===----------------------------------------------------------------------===// @@ -288,3 +293,12 @@ def : Pat<(i32 (fp_to_sint FGR32:$src)), (MFC1 (TRUNC_W_S32 FGR32:$src))>; def : Pat<(i32 (bitconvert FGR32:$src)), (MFC1 FGR32:$src)>; def : Pat<(f32 (bitconvert CPURegs:$src)), (MTC1 CPURegs:$src)>; + +let Predicates = [In32BitMode] in { + def : Pat<(f32 (fround AFGR64:$src)), (CVTS_D32 AFGR64:$src)>; + def : Pat<(f64 (fextend FGR32:$src)), (CVTD_S32 FGR32:$src)>; +} + +// MipsFPRound is only emitted for MipsI targets. +def : Pat<(f32 (MipsFPRound AFGR64:$src)), (CVTW_D32 AFGR64:$src)>; + diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index 2ccbe898fa3..6225fa9c988 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -55,7 +55,8 @@ isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg, if (MI.getOpcode() == Mips::FMOV_S32 || MI.getOpcode() == Mips::FMOV_D32 || MI.getOpcode() == Mips::MFC1 || - MI.getOpcode() == Mips::MTC1 ) { + MI.getOpcode() == Mips::MTC1 || + MI.getOpcode() == Mips::MOVCCRToCCR) { DstReg = MI.getOperand(0).getReg(); SrcReg = MI.getOperand(1).getReg(); return true; @@ -69,6 +70,7 @@ isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg, return true; } } + return false; } @@ -132,22 +134,23 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, if (I != MBB.end()) DL = I->getDebugLoc(); if (DestRC != SrcRC) { - // Moves between coprocessors and cpu + + // Copy to/from FCR31 condition register if ((DestRC == Mips::CPURegsRegisterClass) && + (SrcRC == Mips::CCRRegisterClass)) + BuildMI(MBB, I, DL, get(Mips::CFC1), DestReg).addReg(SrcReg); + else if ((DestRC == Mips::CCRRegisterClass) && + (SrcRC == Mips::CPURegsRegisterClass)) + BuildMI(MBB, I, DL, get(Mips::CTC1), DestReg).addReg(SrcReg); + + // Moves between coprocessors and cpu + else if ((DestRC == Mips::CPURegsRegisterClass) && (SrcRC == Mips::FGR32RegisterClass)) BuildMI(MBB, I, DL, get(Mips::MFC1), DestReg).addReg(SrcReg); else if ((DestRC == Mips::FGR32RegisterClass) && (SrcRC == Mips::CPURegsRegisterClass)) BuildMI(MBB, I, DL, get(Mips::MTC1), DestReg).addReg(SrcReg); - // Condition registers - else if ((SrcRC == Mips::CCRRegisterClass) && - (SrcReg == Mips::FCR31)) - return true; // This register is used implicitly, no copy needed. - else if ((DestRC == Mips::CCRRegisterClass) && - (DestReg == Mips::FCR31)) - return true; // This register is used implicitly, no copy needed. - // Move from/to Hi/Lo registers else if ((DestRC == Mips::HILORegisterClass) && (SrcRC == Mips::CPURegsRegisterClass)) { @@ -172,6 +175,8 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, BuildMI(MBB, I, DL, get(Mips::FMOV_S32), DestReg).addReg(SrcReg); else if (DestRC == Mips::AFGR64RegisterClass) BuildMI(MBB, I, DL, get(Mips::FMOV_D32), DestReg).addReg(SrcReg); + else if (DestRC == Mips::CCRRegisterClass) + BuildMI(MBB, I, DL, get(Mips::MOVCCRToCCR), DestReg).addReg(SrcReg); else // Can't copy this register return false; diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index e30dfbf29e9..b9276fe495e 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -518,10 +518,10 @@ let Uses = [LO] in /// Sign Ext In Register Instructions. let Predicates = [HasSEInReg] in { - let shamt = 0x10, rs = 0 in + let shamt = 0x10, rs = 0 in def SEB : SignExtInReg<0x21, "seb", i8>; - let shamt = 0x18, rs = 0 in + let shamt = 0x18, rs = 0 in def SEH : SignExtInReg<0x20, "seh", i16>; } diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td index aa942696572..bbb275c6624 100644 --- a/lib/Target/Mips/MipsRegisterInfo.td +++ b/lib/Target/Mips/MipsRegisterInfo.td @@ -131,7 +131,7 @@ let Namespace = "Mips" in { def LO : Register<"lo">, DwarfRegNum<[65]>; // Status flags register - def FCR31 : Register<"FCR31">; + def FCR31 : Register<"31">; } //===----------------------------------------------------------------------===// @@ -244,11 +244,9 @@ def AFGR64 : RegisterClass<"Mips", [f64], 64, }]; } -def CCR : RegisterClass<"Mips", [i32], 32, [FCR31]> { - let CopyCost = -1; // Don't allow copying of status registers. -} +// Condition Register for floating point operations +def CCR : RegisterClass<"Mips", [i32], 32, [FCR31]>; -def HILO : RegisterClass<"Mips", [i32], 32, [HI, LO]> { - //let CopyCost = -1; // Don't allow copying of hi/lo registers. -} +// Hi/Lo Registers +def HILO : RegisterClass<"Mips", [i32], 32, [HI, LO]>; diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp index 48f58a55aad..4245f274f8f 100644 --- a/lib/Target/Mips/MipsSubtarget.cpp +++ b/lib/Target/Mips/MipsSubtarget.cpp @@ -37,6 +37,7 @@ MipsSubtarget::MipsSubtarget(const TargetMachine &TM, const Module &M, HasMulDivAdd(false), HasMinMax(false), HasSwap(false), HasBitCount(false) { std::string CPU = "mips1"; + MipsArchVersion = Mips1; // Parse features string. ParseSubtargetFeatures(FS, CPU); diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index 62d5e969ee2..61c37c1d377 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -112,7 +112,7 @@ public: std::string ParseSubtargetFeatures(const std::string &FS, const std::string &CPU); - bool hasMips2Ops() const { return MipsArchVersion >= Mips2; } + bool isMips1() const { return MipsArchVersion == Mips1; } bool isLittle() const { return IsLittle; } bool isFP64bit() const { return IsFP64bit; }; -- 2.34.1