diff options
Diffstat (limited to 'llvm/lib/Target/Mips/MipsCCState.cpp')
| -rw-r--r-- | llvm/lib/Target/Mips/MipsCCState.cpp | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/llvm/lib/Target/Mips/MipsCCState.cpp b/llvm/lib/Target/Mips/MipsCCState.cpp index fe3fe82797c3..76acfa97c3b4 100644 --- a/llvm/lib/Target/Mips/MipsCCState.cpp +++ b/llvm/lib/Target/Mips/MipsCCState.cpp @@ -12,8 +12,7 @@ using namespace llvm; -/// This function returns true if CallSym is a long double emulation routine. -static bool isF128SoftLibCall(const char *CallSym) { +bool MipsCCState::isF128SoftLibCall(const char *CallSym) { const char *const LibCalls[] = { "__addtf3", "__divtf3", "__eqtf2", "__extenddftf2", "__extendsftf2", "__fixtfdi", "__fixtfsi", "__fixtfti", @@ -37,7 +36,7 @@ static bool isF128SoftLibCall(const char *CallSym) { /// This function returns true if Ty is fp128, {f128} or i128 which was /// originally a fp128. -static bool originalTypeIsF128(const Type *Ty, const char *Func) { +bool MipsCCState::originalTypeIsF128(const Type *Ty, const char *Func) { if (Ty->isFP128Ty()) return true; @@ -47,11 +46,12 @@ static bool originalTypeIsF128(const Type *Ty, const char *Func) { // If the Ty is i128 and the function being called is a long double emulation // routine, then the original type is f128. + // FIXME: This is unsound because these functions could be indirectly called return (Func && Ty->isIntegerTy(128) && isF128SoftLibCall(Func)); } /// Return true if the original type was vXfXX. -static bool originalEVTTypeIsVectorFloat(EVT Ty) { +bool MipsCCState::originalEVTTypeIsVectorFloat(EVT Ty) { if (Ty.isVector() && Ty.getVectorElementType().isFloatingPoint()) return true; @@ -59,7 +59,7 @@ static bool originalEVTTypeIsVectorFloat(EVT Ty) { } /// Return true if the original type was vXfXX / vXfXX. -static bool originalTypeIsVectorFloat(const Type * Ty) { +bool MipsCCState::originalTypeIsVectorFloat(const Type *Ty) { if (Ty->isVectorTy() && Ty->isFPOrFPVectorTy()) return true; @@ -126,6 +126,18 @@ void MipsCCState::PreAnalyzeReturnForVectorFloat( } } +void MipsCCState::PreAnalyzeReturnValue(EVT ArgVT) { + OriginalRetWasFloatVector.push_back(originalEVTTypeIsVectorFloat(ArgVT)); +} + +void MipsCCState::PreAnalyzeCallOperand(const Type *ArgTy, bool IsFixed, + const char *Func) { + OriginalArgWasF128.push_back(originalTypeIsF128(ArgTy, Func)); + OriginalArgWasFloat.push_back(ArgTy->isFloatingPointTy()); + OriginalArgWasFloatVector.push_back(ArgTy->isVectorTy()); + CallOperandIsFixed.push_back(IsFixed); +} + /// Identify lowered values that originated from f128, float and sret to vXfXX /// arguments and record this. void MipsCCState::PreAnalyzeCallOperands( @@ -142,6 +154,27 @@ void MipsCCState::PreAnalyzeCallOperands( } } +void MipsCCState::PreAnalyzeFormalArgument(const Type *ArgTy, + ISD::ArgFlagsTy Flags) { + // SRet arguments cannot originate from f128 or {f128} returns so we just + // push false. We have to handle this specially since SRet arguments + // aren't mapped to an original argument. + if (Flags.isSRet()) { + OriginalArgWasF128.push_back(false); + OriginalArgWasFloat.push_back(false); + OriginalArgWasFloatVector.push_back(false); + return; + } + + OriginalArgWasF128.push_back(originalTypeIsF128(ArgTy, nullptr)); + OriginalArgWasFloat.push_back(ArgTy->isFloatingPointTy()); + + // The MIPS vector ABI exhibits a corner case of sorts or quirk; if the + // first argument is actually an SRet pointer to a vector, then the next + // argument slot is $a2. + OriginalArgWasFloatVector.push_back(ArgTy->isVectorTy()); +} + /// Identify lowered values that originated from f128, float and vXfXX arguments /// and record this. void MipsCCState::PreAnalyzeFormalArgumentsForF128( |
