From b1fa7d4d26533bdd021c3269d14c30eb6096fb7a Mon Sep 17 00:00:00 2001 From: Reed Kotler Date: Thu, 1 Aug 2013 21:17:53 +0000 Subject: Fix some issues with Mips16 floating when certain intrinsics are present. This is actually an LLVM bug in the way it generates signatures for these when soft float is enabled. For example, floor ends up having the signature of int64(int64). The signature part is not the same as where the actual parameter types are recorded, and those ARE of course int64(int64) when soft float is enabled. (Yes, Mips16 hard float uses soft float but with different runtime rounes but then has to interoperate with Mips32 using normal floating point). This logic will eventually be moved to the Mips16HardFloat pass so it's not worth sorting out these issues in LLVM since nobody but Mips16 cares about these signatures, as far as I know, and even I won't eventually either. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187613 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/Mips16ISelLowering.cpp | 52 ++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'lib') diff --git a/lib/Target/Mips/Mips16ISelLowering.cpp b/lib/Target/Mips/Mips16ISelLowering.cpp index 1ec0f2f..b3beb12 100644 --- a/lib/Target/Mips/Mips16ISelLowering.cpp +++ b/lib/Target/Mips/Mips16ISelLowering.cpp @@ -37,6 +37,18 @@ struct Mips16Libcall { return std::strcmp(Name, RHS.Name) < 0; } }; + +struct Mips16IntrinsicHelperType{ + const char* Name; + const char* Helper; + + bool operator<(const Mips16IntrinsicHelperType &RHS) const { + return std::strcmp(Name, RHS.Name) < 0; + } + bool operator==(const Mips16IntrinsicHelperType &RHS) const { + return std::strcmp(Name, RHS.Name) == 0; + } +}; } // Libcalls for which no helper is generated. Sorted by name for binary search. @@ -77,6 +89,31 @@ static const Mips16Libcall HardFloatLibCalls[] = { { RTLIB::UO_F32, "__mips16_unordsf2" } }; +static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = { + {"ceil", "__mips16_call_stub_df_2"}, + {"ceilf", "__mips16_call_stub_sf_1"}, + {"copysign", "__mips16_call_stub_df_10"}, + {"copysignf", "__mips16_call_stub_sf_5"}, + {"cos", "__mips16_call_stub_df_2"}, + {"cosf", "__mips16_call_stub_sf_1"}, + {"exp2", "__mips16_call_stub_df_2"}, + {"exp2f", "__mips16_call_stub_sf_1"}, + {"floor", "__mips16_call_stub_df_2"}, + {"floorf", "__mips16_call_stub_sf_1"}, + {"log2", "__mips16_call_stub_df_2"}, + {"log2f", "__mips16_call_stub_sf_1"}, + {"nearbyint", "__mips16_call_stub_df_2"}, + {"nearbyintf", "__mips16_call_stub_sf_1"}, + {"rint", "__mips16_call_stub_df_2"}, + {"rintf", "__mips16_call_stub_sf_1"}, + {"sin", "__mips16_call_stub_df_2"}, + {"sinf", "__mips16_call_stub_sf_1"}, + {"sqrt", "__mips16_call_stub_df_2"}, + {"sqrtf", "__mips16_call_stub_sf_1"}, + {"trunc", "__mips16_call_stub_df_2"}, + {"truncf", "__mips16_call_stub_sf_1"}, +}; + Mips16TargetLowering::Mips16TargetLowering(MipsTargetMachine &TM) : MipsTargetLowering(TM) { // @@ -398,6 +435,21 @@ getOpndList(SmallVectorImpl &Ops, if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls), Find)) LookupHelper = false; + else { + Mips16IntrinsicHelperType IntrinsicFind = {S->getSymbol(), ""}; + // one more look at list of intrinsics + if (std::binary_search(Mips16IntrinsicHelper, + array_endof(Mips16IntrinsicHelper), + IntrinsicFind)) { + const Mips16IntrinsicHelperType *h =(std::find(Mips16IntrinsicHelper, + array_endof(Mips16IntrinsicHelper), + IntrinsicFind)); + Mips16HelperFunction = h->Helper; + NeedMips16Helper = true; + LookupHelper = false; + } + + } } else if (GlobalAddressSDNode *G = dyn_cast(CLI.Callee)) { Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, -- cgit v1.1