From ad341d48f0fc131d1c31a0c824736e70c34e0476 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Tue, 20 Aug 2013 23:38:40 +0000 Subject: [PATCH] [mips] Add support for calling convention CC_MipsO32_FP64, which is used when the size of floating point registers is 64-bit. Test case will be added when support for mfhc1 and mthc1 is added. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188847 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsCallingConv.td | 20 +++++++++++++--- lib/Target/Mips/MipsISelLowering.cpp | 42 +++++++++++++++++++++++----------- lib/Target/Mips/MipsISelLowering.h | 7 +++--- lib/Target/Mips/MipsRegisterInfo.cpp | 30 +++++++++++++++--------- lib/Target/Mips/MipsSEISelLowering.cpp | 2 +- lib/Target/Mips/MipsSubtarget.h | 1 + 6 files changed, 70 insertions(+), 32 deletions(-) diff --git a/lib/Target/Mips/MipsCallingConv.td b/lib/Target/Mips/MipsCallingConv.td index ed515ef0c96..66391cb9cb1 100644 --- a/lib/Target/Mips/MipsCallingConv.td +++ b/lib/Target/Mips/MipsCallingConv.td @@ -26,8 +26,10 @@ def RetCC_MipsO32 : CallingConv<[ // f32 are returned in registers F0, F2 CCIfType<[f32], CCAssignToReg<[F0, F2]>>, - // f64 are returned in register D0, D1 - CCIfType<[f64], CCAssignToReg<[D0, D1]>> + // f64 arguments are returned in D0_64 and D1_64 in FP64bit mode or + // in D0 and D1 in FP32bit mode. + CCIfType<[f64], CCIfSubtarget<"isFP64bit()", CCAssignToReg<[D0_64, D1_64]>>>, + CCIfType<[f64], CCIfSubtarget<"isNotFP64bit()", CCAssignToReg<[D0, D1]>>> ]>; //===----------------------------------------------------------------------===// @@ -149,7 +151,16 @@ def RetCC_MipsEABI : CallingConv<[ //===----------------------------------------------------------------------===// def CC_MipsO32_FastCC : CallingConv<[ // f64 arguments are passed in double-precision floating pointer registers. - CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7, D8, D9]>>, + CCIfType<[f64], CCIfSubtarget<"isNotFP64bit()", + CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7, + D8, D9]>>>, + CCIfType<[f64], CCIfSubtarget<"isFP64bit()", + CCAssignToReg<[D0_64, D1_64, D2_64, D3_64, + D4_64, D5_64, D6_64, D7_64, + D8_64, D9_64, D10_64, D11_64, + D12_64, D13_64, D14_64, D15_64, + D16_64, D17_64, D18_64, + D19_64]>>>, // Stack parameter slots for f64 are 64-bit doublewords and 8-byte aligned. CCIfType<[f64], CCAssignToStack<8, 8>> @@ -224,6 +235,9 @@ def CSR_SingleFloatOnly : CalleeSavedRegs<(add (sequence "F%u", 31, 20), RA, FP, def CSR_O32 : CalleeSavedRegs<(add (sequence "D%u", 15, 10), RA, FP, (sequence "S%u", 7, 0))>; +def CSR_O32_FP64 : CalleeSavedRegs<(add (sequence "D%u_64", 31, 20), RA, FP, + (sequence "S%u", 7, 0))>; + def CSR_N32 : CalleeSavedRegs<(add D31_64, D29_64, D27_64, D25_64, D24_64, D23_64, D22_64, D21_64, RA_64, FP_64, GP_64, (sequence "S%u_64", 7, 0))>; diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 3601a13bd51..c13f53a3ebe 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -2119,7 +2119,8 @@ SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op, static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, - ISD::ArgFlagsTy ArgFlags, CCState &State) { + ISD::ArgFlagsTy ArgFlags, CCState &State, + const uint16_t *F64Regs) { static const unsigned IntRegsSize=4, FloatRegsSize=2; @@ -2129,9 +2130,6 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, static const uint16_t F32Regs[] = { Mips::F12, Mips::F14 }; - static const uint16_t F64Regs[] = { - Mips::D6, Mips::D7 - }; // Do not process byval args here. if (ArgFlags.isByVal()) @@ -2200,6 +2198,22 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, return false; } +static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, + MVT LocVT, CCValAssign::LocInfo LocInfo, + ISD::ArgFlagsTy ArgFlags, CCState &State) { + static const uint16_t F64Regs[] = { Mips::D6, Mips::D7 }; + + return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State, F64Regs); +} + +static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, + MVT LocVT, CCValAssign::LocInfo LocInfo, + ISD::ArgFlagsTy ArgFlags, CCState &State) { + static const uint16_t F64Regs[] = { Mips::D12_64, Mips::D12_64 }; + + return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State, F64Regs); +} + #include "MipsGenCallingConv.inc" //===----------------------------------------------------------------------===// @@ -2312,7 +2326,8 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, getTargetMachine(), ArgLocs, *DAG.getContext()); MipsCC::SpecialCallingConvType SpecialCallingConv = getSpecialCallingConv(Callee); - MipsCC MipsCCInfo(CallConv, IsO32, CCInfo, SpecialCallingConv); + MipsCC MipsCCInfo(CallConv, IsO32, Subtarget->isFP64bit(), CCInfo, + SpecialCallingConv); MipsCCInfo.analyzeCallOperands(Outs, IsVarArg, getTargetMachine().Options.UseSoftFloat, @@ -2499,7 +2514,7 @@ MipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), getTargetMachine(), RVLocs, *DAG.getContext()); - MipsCC MipsCCInfo(CallConv, IsO32, CCInfo); + MipsCC MipsCCInfo(CallConv, IsO32, Subtarget->isFP64bit(), CCInfo); MipsCCInfo.analyzeCallResult(Ins, getTargetMachine().Options.UseSoftFloat, CallNode, RetTy); @@ -2546,7 +2561,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, SmallVector ArgLocs; CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), getTargetMachine(), ArgLocs, *DAG.getContext()); - MipsCC MipsCCInfo(CallConv, IsO32, CCInfo); + MipsCC MipsCCInfo(CallConv, IsO32, Subtarget->isFP64bit(), CCInfo); Function::const_arg_iterator FuncArg = DAG.getMachineFunction().getFunction()->arg_begin(); bool UseSoftFloat = getTargetMachine().Options.UseSoftFloat; @@ -2590,7 +2605,8 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, else if (RegVT == MVT::f32) RC = &Mips::FGR32RegClass; else if (RegVT == MVT::f64) - RC = HasMips64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass; + RC = Subtarget->isFP64bit() ? &Mips::FGR64RegClass : + &Mips::AFGR64RegClass; else llvm_unreachable("RegVT not supported by FormalArguments Lowering"); @@ -2705,7 +2721,7 @@ MipsTargetLowering::LowerReturn(SDValue Chain, // CCState - Info about the registers and stack slot. CCState CCInfo(CallConv, IsVarArg, MF, getTargetMachine(), RVLocs, *DAG.getContext()); - MipsCC MipsCCInfo(CallConv, IsO32, CCInfo); + MipsCC MipsCCInfo(CallConv, IsO32, Subtarget->isFP64bit(), CCInfo); // Analyze return values. MipsCCInfo.analyzeReturn(Outs, getTargetMachine().Options.UseSoftFloat, @@ -3178,9 +3194,9 @@ MipsTargetLowering::MipsCC::SpecialCallingConvType } MipsTargetLowering::MipsCC::MipsCC( - CallingConv::ID CC, bool IsO32_, CCState &Info, + CallingConv::ID CC, bool IsO32_, bool IsFP64_, CCState &Info, MipsCC::SpecialCallingConvType SpecialCallingConv_) - : CCInfo(Info), CallConv(CC), IsO32(IsO32_), + : CCInfo(Info), CallConv(CC), IsO32(IsO32_), IsFP64(IsFP64_), SpecialCallingConv(SpecialCallingConv_){ // Pre-allocate reserved argument area. CCInfo.AllocateStack(reservedArgArea(), 1); @@ -3336,11 +3352,11 @@ llvm::CCAssignFn *MipsTargetLowering::MipsCC::fixedArgFn() const { if (SpecialCallingConv == Mips16RetHelperConv) return CC_Mips16RetHelper; - return IsO32 ? CC_MipsO32 : CC_MipsN; + return IsO32 ? (IsFP64 ? CC_MipsO32_FP64 : CC_MipsO32_FP32) : CC_MipsN; } llvm::CCAssignFn *MipsTargetLowering::MipsCC::varArgFn() const { - return IsO32 ? CC_MipsO32 : CC_MipsN_VarArg; + return IsO32 ? (IsFP64 ? CC_MipsO32_FP64 : CC_MipsO32_FP32) : CC_MipsN_VarArg; } const uint16_t *MipsTargetLowering::MipsCC::shadowRegs() const { diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 686a38292b5..29671b0cf3a 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -244,9 +244,8 @@ namespace llvm { Mips16RetHelperConv, NoSpecialCallingConv }; - MipsCC( - CallingConv::ID CallConv, bool IsO32, CCState &Info, - SpecialCallingConvType SpecialCallingConv = NoSpecialCallingConv); + MipsCC(CallingConv::ID CallConv, bool IsO32, bool IsFP64, CCState &Info, + SpecialCallingConvType SpecialCallingConv = NoSpecialCallingConv); void analyzeCallOperands(const SmallVectorImpl &Outs, @@ -319,7 +318,7 @@ namespace llvm { CCState &CCInfo; CallingConv::ID CallConv; - bool IsO32; + bool IsO32, IsFP64; SpecialCallingConvType SpecialCallingConv; SmallVector ByValArgs; }; diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index 26891ef8ee8..03d09a6315e 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -83,26 +83,34 @@ const uint16_t* MipsRegisterInfo:: getCalleeSavedRegs(const MachineFunction *MF) const { if (Subtarget.isSingleFloat()) return CSR_SingleFloatOnly_SaveList; - else if (!Subtarget.hasMips64()) - return CSR_O32_SaveList; - else if (Subtarget.isABI_N32()) + + if (Subtarget.isABI_N64()) + return CSR_N64_SaveList; + + if (Subtarget.isABI_N32()) return CSR_N32_SaveList; - assert(Subtarget.isABI_N64()); - return CSR_N64_SaveList; + if (Subtarget.isFP64bit()) + return CSR_O32_FP64_SaveList; + + return CSR_O32_SaveList; } const uint32_t* MipsRegisterInfo::getCallPreservedMask(CallingConv::ID) const { if (Subtarget.isSingleFloat()) return CSR_SingleFloatOnly_RegMask; - else if (!Subtarget.hasMips64()) - return CSR_O32_RegMask; - else if (Subtarget.isABI_N32()) + + if (Subtarget.isABI_N64()) + return CSR_N64_RegMask; + + if (Subtarget.isABI_N32()) return CSR_N32_RegMask; - assert(Subtarget.isABI_N64()); - return CSR_N64_RegMask; + if (Subtarget.isFP64bit()) + return CSR_O32_FP64_RegMask; + + return CSR_O32_RegMask; } const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() { @@ -128,7 +136,7 @@ getReservedRegs(const MachineFunction &MF) const { for (unsigned I = 0; I < array_lengthof(ReservedGPR64); ++I) Reserved.set(ReservedGPR64[I]); - if (Subtarget.hasMips64()) { + if (Subtarget.isFP64bit()) { // Reserve all registers in AFGR64. for (RegIter Reg = Mips::AFGR64RegClass.begin(), EReg = Mips::AFGR64RegClass.end(); Reg != EReg; ++Reg) diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp index 750ec0e0d33..fb722515c87 100644 --- a/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/lib/Target/Mips/MipsSEISelLowering.cpp @@ -92,7 +92,7 @@ MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM) // When dealing with single precision only, use libcalls if (!Subtarget->isSingleFloat()) { - if (HasMips64) + if (Subtarget->isFP64bit()) addRegisterClass(MVT::f64, &Mips::FGR64RegClass); else addRegisterClass(MVT::f64, &Mips::AFGR64RegClass); diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index 21d6938adac..03bef69fb5e 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -160,6 +160,7 @@ public: bool isLittle() const { return IsLittle; } bool isFP64bit() const { return IsFP64bit; } + bool isNotFP64bit() const { return !IsFP64bit; } bool isGP64bit() const { return IsGP64bit; } bool isGP32bit() const { return !IsGP64bit; } bool isSingleFloat() const { return IsSingleFloat; } -- 2.11.0