@@ -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
@@ -363,6 +365,9 @@ def MIPS16_RET_DF : RuntimeLibcall;
363
365
def MIPS16_RET_SC : RuntimeLibcall;
364
366
def MIPS16_RET_SF : RuntimeLibcall;
365
367
368
+ // Create libcall impls for `long double` and `_Float128`. See also `_ld128`
369
+ // impls defined at `LibmF128AsLongDoubleLibcalls`.
370
+
366
371
// Produce libcall impls for all float types. If provided, `rtbasename` should
367
372
// contain an `X` that will be replaced with the `f`/`l`/`fX` suffix (if not
368
373
// provided, it is appended to the def name).
@@ -376,7 +381,7 @@ multiclass LibmLibcallImpls<string libcall_basename = !toupper(NAME),
376
381
!subst("X", "", rtbasename)>;
377
382
def NAME#"_f128"
378
383
: RuntimeLibcallImpl<!cast<RuntimeLibcall>(libcall_basename#"_F128"),
379
- !subst("X", "l ", rtbasename)>;
384
+ !subst("X", "f128 ", rtbasename)>;
380
385
def NAME#"_ppcf128"
381
386
: RuntimeLibcallImpl<!cast<RuntimeLibcall>(libcall_basename#"_PPCF128"),
382
387
!subst("X", "l", rtbasename)>;
@@ -385,6 +390,13 @@ multiclass LibmLibcallImpls<string libcall_basename = !toupper(NAME),
385
390
!subst("X", "l", rtbasename)>;
386
391
}
387
392
393
+ multiclass LibmF128AsLongDoubleImpls<string libcall_basename = !toupper(NAME),
394
+ string rtbasename = !strconcat(NAME, "X")> {
395
+ def NAME#"_ld128"
396
+ : RuntimeLibcallImpl<!cast<RuntimeLibcall>(libcall_basename#"_F128"),
397
+ !subst("X", "l", rtbasename)>;
398
+ }
399
+
388
400
// AArch64 calls
389
401
def SC_MEMCPY : RuntimeLibcall;
390
402
def SC_MEMMOVE : RuntimeLibcall;
@@ -806,60 +818,61 @@ def __riscv_flush_icache : RuntimeLibcallImpl<RISCV_FLUSH_ICACHE>;
806
818
// F128 libm Runtime Libcalls
807
819
//===----------------------------------------------------------------------===//
808
820
809
- defset list<RuntimeLibcallImpl> LibmF128Libcalls = {
810
- def logf128 : RuntimeLibcallImpl<LOG_F128>;
811
- def log2f128 : RuntimeLibcallImpl<LOG2_F128>;
812
- def log10f128 : RuntimeLibcallImpl<LOG10_F128>;
813
- def expf128 : RuntimeLibcallImpl<EXP_F128>;
814
- def exp2f128 : RuntimeLibcallImpl<EXP2_F128>;
815
- def exp10f128 : RuntimeLibcallImpl<EXP10_F128>;
816
- def sinf128 : RuntimeLibcallImpl<SIN_F128>;
817
- def cosf128 : RuntimeLibcallImpl<COS_F128>;
818
- def tanf128 : RuntimeLibcallImpl<TAN_F128>;
819
- def tanhf128 : RuntimeLibcallImpl<TANH_F128>;
820
- def sincosf128 : RuntimeLibcallImpl<SINCOS_F128>;
821
- def powf128 : RuntimeLibcallImpl<POW_F128>;
822
- def fminf128 : RuntimeLibcallImpl<FMIN_F128>;
823
- def fmaxf128 : RuntimeLibcallImpl<FMAX_F128>;
824
- def fmodf128 : RuntimeLibcallImpl<REM_F128>;
825
- def sqrtf128 : RuntimeLibcallImpl<SQRT_F128>;
826
- def ceilf128 : RuntimeLibcallImpl<CEIL_F128>;
827
- def floorf128 : RuntimeLibcallImpl<FLOOR_F128>;
828
- def truncf128 : RuntimeLibcallImpl<TRUNC_F128>;
829
- def roundf128 : RuntimeLibcallImpl<ROUND_F128>;
830
- def lroundf128 : RuntimeLibcallImpl<LROUND_F128>;
831
- def llroundf128 : RuntimeLibcallImpl<LLROUND_F128>;
832
- def rintf128 : RuntimeLibcallImpl<RINT_F128>;
833
- def lrintf128 : RuntimeLibcallImpl<LRINT_F128>;
834
- def llrintf128 : RuntimeLibcallImpl<LLRINT_F128>;
835
- def nearbyintf128 : RuntimeLibcallImpl<NEARBYINT_F128>;
836
- def fmaf128 : RuntimeLibcallImpl<FMA_F128>;
837
- def frexpf128 : RuntimeLibcallImpl<FREXP_F128>;
838
- def cbrtf128 : RuntimeLibcallImpl<CBRT_F128>;
839
- def fminimumf128 : RuntimeLibcallImpl<FMINIMUM_F128>;
840
- def fmaximumf128 : RuntimeLibcallImpl<FMAXIMUM_F128>;
841
- def fminimum_numf128 : RuntimeLibcallImpl<FMINIMUM_NUM_F128>;
842
- def fmaximum_numf128 : RuntimeLibcallImpl<FMAXIMUM_NUM_F128>;
843
- def asinf128 : RuntimeLibcallImpl<ASIN_F128>;
844
- def acosf128 : RuntimeLibcallImpl<ACOS_F128>;
845
- def atanf128 : RuntimeLibcallImpl<ATAN_F128>;
846
- def atan2f128 : RuntimeLibcallImpl<ATAN2_F128>;
847
- def ldexpf128 : RuntimeLibcallImpl<LDEXP_F128>;
848
- def roundevenf128 : RuntimeLibcallImpl<ROUNDEVEN_F128>;
849
- def modff128 : RuntimeLibcallImpl<MODF_F128>;
850
- def sinhf128 : RuntimeLibcallImpl<SINH_F128>;
851
- def coshf128 : RuntimeLibcallImpl<COSH_F128>;
852
- def copysignf128 : RuntimeLibcallImpl<COPYSIGN_F128>;
821
+ // Impls for treating `fp128` as `long double`
822
+ defset list<RuntimeLibcallImpl> LibmF128AsLongDoubleLibcalls = {
823
+ defm log : LibmF128AsLongDoubleImpls;
824
+ defm log2 : LibmF128AsLongDoubleImpls;
825
+ defm log10 : LibmF128AsLongDoubleImpls;
826
+ defm exp : LibmF128AsLongDoubleImpls;
827
+ defm exp2 : LibmF128AsLongDoubleImpls;
828
+ defm exp10 : LibmF128AsLongDoubleImpls;
829
+ defm sin : LibmF128AsLongDoubleImpls;
830
+ defm cos : LibmF128AsLongDoubleImpls;
831
+ defm tan : LibmF128AsLongDoubleImpls;
832
+ defm tanh : LibmF128AsLongDoubleImpls;
833
+ defm sincos : LibmF128AsLongDoubleImpls;
834
+ defm pow : LibmF128AsLongDoubleImpls;
835
+ defm fmin : LibmF128AsLongDoubleImpls;
836
+ defm fmax : LibmF128AsLongDoubleImpls;
837
+ defm fmod : LibmF128AsLongDoubleImpls<"REM">;
838
+ defm sqrt : LibmF128AsLongDoubleImpls;
839
+ defm ceil : LibmF128AsLongDoubleImpls;
840
+ defm floor : LibmF128AsLongDoubleImpls;
841
+ defm trunc : LibmF128AsLongDoubleImpls;
842
+ defm round : LibmF128AsLongDoubleImpls;
843
+ defm lround : LibmF128AsLongDoubleImpls;
844
+ defm llround : LibmF128AsLongDoubleImpls;
845
+ defm rint : LibmF128AsLongDoubleImpls;
846
+ defm lrint : LibmF128AsLongDoubleImpls;
847
+ defm llrint : LibmF128AsLongDoubleImpls;
848
+ defm nearbyint : LibmF128AsLongDoubleImpls;
849
+ defm fma : LibmF128AsLongDoubleImpls;
850
+ defm frexp : LibmF128AsLongDoubleImpls;
851
+ defm cbrt : LibmF128AsLongDoubleImpls;
852
+ defm fminimum : LibmF128AsLongDoubleImpls;
853
+ defm fmaximum : LibmF128AsLongDoubleImpls;
854
+ defm fminimum_num : LibmF128AsLongDoubleImpls;
855
+ defm fmaximum_num : LibmF128AsLongDoubleImpls;
856
+ defm asin : LibmF128AsLongDoubleImpls;
857
+ defm acos : LibmF128AsLongDoubleImpls;
858
+ defm atan : LibmF128AsLongDoubleImpls;
859
+ defm atan2 : LibmF128AsLongDoubleImpls;
860
+ defm ldexp : LibmF128AsLongDoubleImpls;
861
+ defm roundeven : LibmF128AsLongDoubleImpls;
862
+ defm modf : LibmF128AsLongDoubleImpls;
863
+ defm sinh : LibmF128AsLongDoubleImpls;
864
+ defm cosh : LibmF128AsLongDoubleImpls;
865
+ defm copysign : LibmF128AsLongDoubleImpls;
853
866
}
854
867
855
- defset list<RuntimeLibcallImpl> LibmF128FiniteLibcalls = {
856
- def __logf128_finite : RuntimeLibcallImpl<LOG_FINITE_F128 >;
857
- def __log2f128_finite : RuntimeLibcallImpl<LOG2_FINITE_F128 >;
858
- def __log10f128_finite : RuntimeLibcallImpl<LOG10_FINITE_F128 >;
859
- def __expf128_finite : RuntimeLibcallImpl<EXP_FINITE_F128 >;
860
- def __exp2f128_finite : RuntimeLibcallImpl<EXP2_FINITE_F128 >;
861
- def __exp10f128_finite : RuntimeLibcallImpl<EXP10_FINITE_F128 >;
862
- def __powf128_finite : RuntimeLibcallImpl<POW_FINITE_F128 >;
868
+ defset list<RuntimeLibcallImpl> LibmF128AsLongDoubleFiniteLibcalls = {
869
+ defm __log_finite : LibmF128AsLongDoubleImpls<"LOG_FINITE", "__logX_finite" >;
870
+ defm __log2_finite : LibmF128AsLongDoubleImpls<"LOG2_FINITE", "__log2X_finite" >;
871
+ defm __log10_finite : LibmF128AsLongDoubleImpls<"LOG10_FINITE", "__log10X_finite" >;
872
+ defm __exp_finite : LibmF128AsLongDoubleImpls<"EXP_FINITE", "__expX_finite" >;
873
+ defm __exp2_finite : LibmF128AsLongDoubleImpls<"EXP2_FINITE", "__exp2X_finite" >;
874
+ defm __exp10_finite : LibmF128AsLongDoubleImpls<"EXP10_FINITE", "__exp10X_finite" >;
875
+ defm __pow_finite : LibmF128AsLongDoubleImpls<"POW_FINITE", "__powX_finite" >;
863
876
}
864
877
865
878
//===----------------------------------------------------------------------===//
@@ -893,10 +906,6 @@ defvar DefaultRuntimeLibcallImpls_ppcf128 =
893
906
!filter(entry, AllDefaultRuntimeLibcallImpls,
894
907
!match(!cast<string>(entry.Provides), "PPCF128"));
895
908
896
- defvar DefaultRuntimeLibcallImpls_f128 =
897
- !filter(entry, AllDefaultRuntimeLibcallImpls,
898
- !match(!cast<string>(entry.Provides), "_F128"));
899
-
900
909
defvar DefaultRuntimeLibcallImpls =
901
910
!listremove(
902
911
!listremove(
@@ -1690,7 +1699,7 @@ def NVPTXSystemLibrary : SystemRuntimeLibrary<isNVPTX, (add)>;
1690
1699
//===----------------------------------------------------------------------===//
1691
1700
1692
1701
// For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf".
1693
- defset list<RuntimeLibcallImpl> PPCRuntimeLibcalls = {
1702
+ defset list<RuntimeLibcallImpl> PPCOverriddenRuntimeLibcalls = {
1694
1703
def __addkf3 : RuntimeLibcallImpl<ADD_F128>;
1695
1704
def __subkf3 : RuntimeLibcallImpl<SUB_F128>;
1696
1705
def __mulkf3 : RuntimeLibcallImpl<MUL_F128>;
@@ -1734,7 +1743,22 @@ defset list<RuntimeLibcallImpl> PPC32AIXCallList = {
1734
1743
def ___bzero : RuntimeLibcallImpl<BZERO>;
1735
1744
}
1736
1745
1737
- defvar PPCOverrides = !foreach(entry, PPCRuntimeLibcalls, entry.Provides);
1746
+ // List of overriden libcalls as strings, `["ADD_F128", "SUB_F128", ...]`
1747
+ defvar PPCOverriddenNames = !foreach(
1748
+ entry, PPCOverriddenRuntimeLibcalls,
1749
+ !cast<string>(entry.Provides)
1750
+ );
1751
+
1752
+ // Default libcalls except for those that appear in `PPCOverrideNames`
1753
+ defvar PPCNonOverriddenImpls = !filter(
1754
+ default_entry, DefaultRuntimeLibcallImpls,
1755
+ // `!contains` does not exist, `not->empty->filter` is a slightly hacky way
1756
+ !not(!empty(!filter(
1757
+ overridden,
1758
+ PPCOverriddenNames,
1759
+ !eq(overridden, !cast<string>(default_entry.Provides))
1760
+ )))
1761
+ );
1738
1762
1739
1763
def isPPC : RuntimeLibcallPredicate<"TT.isPPC()">;
1740
1764
def isPPC32 : RuntimeLibcallPredicate<"TT.isPPC32()">;
@@ -1747,18 +1771,22 @@ def isPPC64_AIX : RuntimeLibcallPredicate<"(TT.isPPC64() && TT.isOSAIX())">;
1747
1771
def AIX32Calls : LibcallImpls<(add PPC32AIXCallList), isPPC32_AIX>;
1748
1772
def AIX64Calls : LibcallImpls<(add PPC64AIXCallList), isPPC64_AIX>;
1749
1773
1774
+ // Replace overridden values, adjust mem* symbols, add ppc_f128<->f128
1775
+ // conversions.
1776
+ defvar PPCDefaultRuntimeLibcallImpls =
1777
+ (add (sub DefaultRuntimeLibcallImpls, PPCNonOverriddenImpls, memcpy),
1778
+ PPCOverriddenRuntimeLibcalls,
1779
+ __extendkftf2, __trunctfkf2,
1780
+ DefaultRuntimeLibcallImpls_ppcf128,
1781
+ AIX32Calls, AIX64Calls);
1782
+
1750
1783
// FIXME: Current emission behavior with multiple implementations is
1751
1784
// janky. We need to filter out the conflicting cases with different
1752
1785
// f128 names, and then add the overrides. We should switch to
1753
1786
// explicitly adding subsets of the default calls.
1754
1787
def PPCSystemLibrary
1755
1788
: SystemRuntimeLibrary<isPPC,
1756
- (add PPCRuntimeLibcalls,
1757
- (sub DefaultRuntimeLibcallImpls, memcpy,
1758
- DefaultRuntimeLibcallImpls_f128),
1759
- __extendkftf2, __trunctfkf2,
1760
- DefaultRuntimeLibcallImpls_ppcf128,
1761
- LibmF128Libcalls, AIX32Calls, AIX64Calls,
1789
+ (add PPCDefaultRuntimeLibcallImpls,
1762
1790
AvailableIf<memcpy, isNotAIX>,
1763
1791
LibcallImpls<(add Int128RTLibcalls), isPPC64>)>;
1764
1792
0 commit comments