@@ -22,6 +22,8 @@ def isOSWindows : RuntimeLibcallPredicate<"TT.isOSWindows()">;
22
22
def darwinHasSinCosStret : RuntimeLibcallPredicate<"darwinHasSinCosStret(TT)">;
23
23
def darwinHasExp10 : RuntimeLibcallPredicate<"darwinHasExp10(TT)">;
24
24
def hasSinCos : RuntimeLibcallPredicate<"hasSinCos(TT)">;
25
+ def f128LibmShouldUseLongDouble
26
+ : RuntimeLibcallPredicate<"f128LibmShouldUseLongDouble(TT)">;
25
27
26
28
//--------------------------------------------------------------------
27
29
// Declare all kinds of used libcalls
@@ -352,6 +354,9 @@ def MIPS16_RET_DF : RuntimeLibcall;
352
354
def MIPS16_RET_SC : RuntimeLibcall;
353
355
def MIPS16_RET_SF : RuntimeLibcall;
354
356
357
+ // Create libcall impls for `long double` and `_Float128`. See also `_ld128`
358
+ // impls defined at `LibmF128AsLongDoubleLibcalls`.
359
+
355
360
// Produce libcall impls for all float types. If provided, `rtbasename` should
356
361
// contain an `X` that will be replaced with the `f`/`l`/`fX` suffix (if not
357
362
// provided, it is appended to the def name).
@@ -365,7 +370,7 @@ multiclass LibmLibcallImpls<string libcall_basename = !toupper(NAME),
365
370
!subst("X", "", rtbasename)>;
366
371
def NAME#"_f128"
367
372
: RuntimeLibcallImpl<!cast<RuntimeLibcall>(libcall_basename#"_F128"),
368
- !subst("X", "l ", rtbasename)>;
373
+ !subst("X", "f128 ", rtbasename)>;
369
374
def NAME#"_ppcf128"
370
375
: RuntimeLibcallImpl<!cast<RuntimeLibcall>(libcall_basename#"_PPCF128"),
371
376
!subst("X", "l", rtbasename)>;
@@ -374,6 +379,13 @@ multiclass LibmLibcallImpls<string libcall_basename = !toupper(NAME),
374
379
!subst("X", "l", rtbasename)>;
375
380
}
376
381
382
+ multiclass LibmF128AsLongDoubleImpls<string libcall_basename = !toupper(NAME),
383
+ string rtbasename = !strconcat(NAME, "X")> {
384
+ def NAME#"_ld128"
385
+ : RuntimeLibcallImpl<!cast<RuntimeLibcall>(libcall_basename#"_F128"),
386
+ !subst("X", "l", rtbasename)>;
387
+ }
388
+
377
389
// AArch64 calls
378
390
def SC_MEMCPY : RuntimeLibcall;
379
391
def SC_MEMMOVE : RuntimeLibcall;
@@ -796,60 +808,61 @@ def _Unwind_SjLj_Resume : RuntimeLibcallImpl<UNWIND_RESUME>;
796
808
// F128 libm Runtime Libcalls
797
809
//===----------------------------------------------------------------------===//
798
810
799
- defset list<RuntimeLibcallImpl> LibmF128Libcalls = {
800
- def logf128 : RuntimeLibcallImpl<LOG_F128>;
801
- def log2f128 : RuntimeLibcallImpl<LOG2_F128>;
802
- def log10f128 : RuntimeLibcallImpl<LOG10_F128>;
803
- def expf128 : RuntimeLibcallImpl<EXP_F128>;
804
- def exp2f128 : RuntimeLibcallImpl<EXP2_F128>;
805
- def exp10f128 : RuntimeLibcallImpl<EXP10_F128>;
806
- def sinf128 : RuntimeLibcallImpl<SIN_F128>;
807
- def cosf128 : RuntimeLibcallImpl<COS_F128>;
808
- def tanf128 : RuntimeLibcallImpl<TAN_F128>;
809
- def tanhf128 : RuntimeLibcallImpl<TANH_F128>;
810
- def sincosf128 : RuntimeLibcallImpl<SINCOS_F128>;
811
- def powf128 : RuntimeLibcallImpl<POW_F128>;
812
- def fminf128 : RuntimeLibcallImpl<FMIN_F128>;
813
- def fmaxf128 : RuntimeLibcallImpl<FMAX_F128>;
814
- def fmodf128 : RuntimeLibcallImpl<REM_F128>;
815
- def sqrtf128 : RuntimeLibcallImpl<SQRT_F128>;
816
- def ceilf128 : RuntimeLibcallImpl<CEIL_F128>;
817
- def floorf128 : RuntimeLibcallImpl<FLOOR_F128>;
818
- def truncf128 : RuntimeLibcallImpl<TRUNC_F128>;
819
- def roundf128 : RuntimeLibcallImpl<ROUND_F128>;
820
- def lroundf128 : RuntimeLibcallImpl<LROUND_F128>;
821
- def llroundf128 : RuntimeLibcallImpl<LLROUND_F128>;
822
- def rintf128 : RuntimeLibcallImpl<RINT_F128>;
823
- def lrintf128 : RuntimeLibcallImpl<LRINT_F128>;
824
- def llrintf128 : RuntimeLibcallImpl<LLRINT_F128>;
825
- def nearbyintf128 : RuntimeLibcallImpl<NEARBYINT_F128>;
826
- def fmaf128 : RuntimeLibcallImpl<FMA_F128>;
827
- def frexpf128 : RuntimeLibcallImpl<FREXP_F128>;
828
- def cbrtf128 : RuntimeLibcallImpl<CBRT_F128>;
829
- def fminimumf128 : RuntimeLibcallImpl<FMINIMUM_F128>;
830
- def fmaximumf128 : RuntimeLibcallImpl<FMAXIMUM_F128>;
831
- def fminimum_numf128 : RuntimeLibcallImpl<FMINIMUM_NUM_F128>;
832
- def fmaximum_numf128 : RuntimeLibcallImpl<FMAXIMUM_NUM_F128>;
833
- def asinf128 : RuntimeLibcallImpl<ASIN_F128>;
834
- def acosf128 : RuntimeLibcallImpl<ACOS_F128>;
835
- def atanf128 : RuntimeLibcallImpl<ATAN_F128>;
836
- def atan2f128 : RuntimeLibcallImpl<ATAN2_F128>;
837
- def ldexpf128 : RuntimeLibcallImpl<LDEXP_F128>;
838
- def roundevenf128 : RuntimeLibcallImpl<ROUNDEVEN_F128>;
839
- def modff128 : RuntimeLibcallImpl<MODF_F128>;
840
- def sinhf128 : RuntimeLibcallImpl<SINH_F128>;
841
- def coshf128 : RuntimeLibcallImpl<COSH_F128>;
842
- def copysignf128 : RuntimeLibcallImpl<COPYSIGN_F128>;
811
+ // Impls for treating `fp128` as `long double`
812
+ defset list<RuntimeLibcallImpl> LibmF128AsLongDoubleLibcalls = {
813
+ defm log : LibmF128AsLongDoubleImpls;
814
+ defm log2 : LibmF128AsLongDoubleImpls;
815
+ defm log10 : LibmF128AsLongDoubleImpls;
816
+ defm exp : LibmF128AsLongDoubleImpls;
817
+ defm exp2 : LibmF128AsLongDoubleImpls;
818
+ defm exp10 : LibmF128AsLongDoubleImpls;
819
+ defm sin : LibmF128AsLongDoubleImpls;
820
+ defm cos : LibmF128AsLongDoubleImpls;
821
+ defm tan : LibmF128AsLongDoubleImpls;
822
+ defm tanh : LibmF128AsLongDoubleImpls;
823
+ defm sincos : LibmF128AsLongDoubleImpls;
824
+ defm pow : LibmF128AsLongDoubleImpls;
825
+ defm fmin : LibmF128AsLongDoubleImpls;
826
+ defm fmax : LibmF128AsLongDoubleImpls;
827
+ defm fmod : LibmF128AsLongDoubleImpls<"REM">;
828
+ defm sqrt : LibmF128AsLongDoubleImpls;
829
+ defm ceil : LibmF128AsLongDoubleImpls;
830
+ defm floor : LibmF128AsLongDoubleImpls;
831
+ defm trunc : LibmF128AsLongDoubleImpls;
832
+ defm round : LibmF128AsLongDoubleImpls;
833
+ defm lround : LibmF128AsLongDoubleImpls;
834
+ defm llround : LibmF128AsLongDoubleImpls;
835
+ defm rint : LibmF128AsLongDoubleImpls;
836
+ defm lrint : LibmF128AsLongDoubleImpls;
837
+ defm llrint : LibmF128AsLongDoubleImpls;
838
+ defm nearbyint : LibmF128AsLongDoubleImpls;
839
+ defm fma : LibmF128AsLongDoubleImpls;
840
+ defm frexp : LibmF128AsLongDoubleImpls;
841
+ defm cbrt : LibmF128AsLongDoubleImpls;
842
+ defm fminimum : LibmF128AsLongDoubleImpls;
843
+ defm fmaximum : LibmF128AsLongDoubleImpls;
844
+ defm fminimum_num : LibmF128AsLongDoubleImpls;
845
+ defm fmaximum_num : LibmF128AsLongDoubleImpls;
846
+ defm asin : LibmF128AsLongDoubleImpls;
847
+ defm acos : LibmF128AsLongDoubleImpls;
848
+ defm atan : LibmF128AsLongDoubleImpls;
849
+ defm atan2 : LibmF128AsLongDoubleImpls;
850
+ defm ldexp : LibmF128AsLongDoubleImpls;
851
+ defm roundeven : LibmF128AsLongDoubleImpls;
852
+ defm modf : LibmF128AsLongDoubleImpls;
853
+ defm sinh : LibmF128AsLongDoubleImpls;
854
+ defm cosh : LibmF128AsLongDoubleImpls;
855
+ defm copysign : LibmF128AsLongDoubleImpls;
843
856
}
844
857
845
- defset list<RuntimeLibcallImpl> LibmF128FiniteLibcalls = {
846
- def __logf128_finite : RuntimeLibcallImpl<LOG_FINITE_F128 >;
847
- def __log2f128_finite : RuntimeLibcallImpl<LOG2_FINITE_F128 >;
848
- def __log10f128_finite : RuntimeLibcallImpl<LOG10_FINITE_F128 >;
849
- def __expf128_finite : RuntimeLibcallImpl<EXP_FINITE_F128 >;
850
- def __exp2f128_finite : RuntimeLibcallImpl<EXP2_FINITE_F128 >;
851
- def __exp10f128_finite : RuntimeLibcallImpl<EXP10_FINITE_F128 >;
852
- def __powf128_finite : RuntimeLibcallImpl<POW_FINITE_F128 >;
858
+ defset list<RuntimeLibcallImpl> LibmF128AsLongDoubleFiniteLibcalls = {
859
+ defm __log_finite : LibmF128AsLongDoubleImpls<"LOG_FINITE", "__logX_finite" >;
860
+ defm __log2_finite : LibmF128AsLongDoubleImpls<"LOG2_FINITE", "__log2X_finite" >;
861
+ defm __log10_finite : LibmF128AsLongDoubleImpls<"LOG10_FINITE", "__log10X_finite" >;
862
+ defm __exp_finite : LibmF128AsLongDoubleImpls<"EXP_FINITE", "__expX_finite" >;
863
+ defm __exp2_finite : LibmF128AsLongDoubleImpls<"EXP2_FINITE", "__exp2X_finite" >;
864
+ defm __exp10_finite : LibmF128AsLongDoubleImpls<"EXP10_FINITE", "__exp10X_finite" >;
865
+ defm __pow_finite : LibmF128AsLongDoubleImpls<"POW_FINITE", "__powX_finite" >;
853
866
}
854
867
855
868
//===----------------------------------------------------------------------===//
@@ -880,10 +893,6 @@ defvar DefaultRuntimeLibcallImpls =
880
893
Int128RTLibcalls),
881
894
CompilerRTOnlyInt128Libcalls);
882
895
883
- defvar DefaultRuntimeLibcallImpls_f128 =
884
- !filter(entry, DefaultRuntimeLibcallImpls,
885
- !match(!cast<string>(entry.Provides), "_F128"));
886
-
887
896
defvar DefaultRuntimeLibcallImpls_atomic =
888
897
!filter(entry, DefaultRuntimeLibcallImpls,
889
898
!match(!cast<string>(entry.Provides), "ATOMIC"));
@@ -1658,7 +1667,7 @@ def NVPTXSystemLibrary : SystemRuntimeLibrary<isNVPTX, (add)>;
1658
1667
//===----------------------------------------------------------------------===//
1659
1668
1660
1669
// For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf".
1661
- defset list<RuntimeLibcallImpl> PPCRuntimeLibcalls = {
1670
+ defset list<RuntimeLibcallImpl> PPCOverriddenRuntimeLibcalls = {
1662
1671
def __addkf3 : RuntimeLibcallImpl<ADD_F128>;
1663
1672
def __subkf3 : RuntimeLibcallImpl<SUB_F128>;
1664
1673
def __mulkf3 : RuntimeLibcallImpl<MUL_F128>;
@@ -1702,7 +1711,22 @@ defset list<RuntimeLibcallImpl> PPC32AIXCallList = {
1702
1711
def ___bzero : RuntimeLibcallImpl<BZERO>;
1703
1712
}
1704
1713
1705
- defvar PPCOverrides = !foreach(entry, PPCRuntimeLibcalls, entry.Provides);
1714
+ // List of overriden libcalls as strings, `["ADD_F128", "SUB_F128", ...]`
1715
+ defvar PPCOverriddenNames = !foreach(
1716
+ entry, PPCOverriddenRuntimeLibcalls,
1717
+ !cast<string>(entry.Provides)
1718
+ );
1719
+
1720
+ // Default libcalls except for those that appear in `PPCOverrideNames`
1721
+ defvar PPCNonOverriddenImpls = !filter(
1722
+ default_entry, DefaultRuntimeLibcallImpls,
1723
+ // `!contains` does not exist, `not->empty->filter` is a slightly hacky way
1724
+ !not(!empty(!filter(
1725
+ overridden,
1726
+ PPCOverriddenNames,
1727
+ !eq(overridden, !cast<string>(default_entry.Provides))
1728
+ )))
1729
+ );
1706
1730
1707
1731
def isPPC : RuntimeLibcallPredicate<"TT.isPPC()">;
1708
1732
def isPPC32 : RuntimeLibcallPredicate<"TT.isPPC32()">;
@@ -1715,17 +1739,21 @@ def isPPC64_AIX : RuntimeLibcallPredicate<"(TT.isPPC64() && TT.isOSAIX())">;
1715
1739
def AIX32Calls : LibcallImpls<(add PPC32AIXCallList), isPPC32_AIX>;
1716
1740
def AIX64Calls : LibcallImpls<(add PPC64AIXCallList), isPPC64_AIX>;
1717
1741
1742
+ // Replace overridden values, adjust mem* symbols, add ppc_f128<->f128
1743
+ // conversions.
1744
+ defvar PPCDefaultRuntimeLibcallImpls =
1745
+ (add (sub DefaultRuntimeLibcallImpls, PPCNonOverriddenImpls, memcpy),
1746
+ PPCOverriddenRuntimeLibcalls ,
1747
+ __extendkftf2, __trunctfkf2,
1748
+ AIX32Calls, AIX64Calls);
1749
+
1718
1750
// FIXME: Current emission behavior with multiple implementations is
1719
1751
// janky. We need to filter out the conflicting cases with different
1720
1752
// f128 names, and then add the overrides. We should switch to
1721
1753
// explicitly adding subsets of the default calls.
1722
1754
def PPCSystemLibrary
1723
1755
: SystemRuntimeLibrary<isPPC,
1724
- (add PPCRuntimeLibcalls,
1725
- (sub DefaultRuntimeLibcallImpls, memcpy,
1726
- DefaultRuntimeLibcallImpls_f128),
1727
- __extendkftf2, __trunctfkf2,
1728
- LibmF128Libcalls, AIX32Calls, AIX64Calls,
1756
+ (add PPCDefaultRuntimeLibcallImpls,
1729
1757
AvailableIf<memcpy, isNotAIX>,
1730
1758
LibcallImpls<(add Int128RTLibcalls), isPPC64>)>;
1731
1759
0 commit comments