It's necessary for clang sparc64 support --- grub-core/kern/compiler-rt.c | 58 ++++++++++++++++++++++++++++++++++++ include/grub/compiler-rt.h | 7 +++++ 2 files changed, 65 insertions(+)
diff --git a/grub-core/kern/compiler-rt.c b/grub-core/kern/compiler-rt.c index eda689a0c..2902ed03d 100644 --- a/grub-core/kern/compiler-rt.c +++ b/grub-core/kern/compiler-rt.c @@ -452,3 +452,61 @@ __clzdi2 (grub_uint64_t val) } } #endif + +#if defined(__sparc__) && defined(__clang__) +/* Copied from multi3.c which is under MIT license. */ +typedef long long di_int; +typedef unsigned long long du_int; + +typedef union +{ + grub_clang_ti_int all; + struct + { +#ifndef GRUB_CPU_WORDS_BIGENDIAN + du_int low; + di_int high; +#else + di_int high; + du_int low; +#endif /* _YUGA_LITTLE_ENDIAN */ + }s; +} twords; + +static +grub_clang_ti_int +__mulddi3(du_int a, du_int b) +{ + twords r; + const int bits_in_dword_2 = (int)(sizeof(di_int) * 8) / 2; + const du_int lower_mask = (du_int)~0 >> bits_in_dword_2; + r.s.low = (a & lower_mask) * (b & lower_mask); + du_int t = r.s.low >> bits_in_dword_2; + r.s.low &= lower_mask; + t += (a >> bits_in_dword_2) * (b & lower_mask); + r.s.low += (t & lower_mask) << bits_in_dword_2; + r.s.high = t >> bits_in_dword_2; + t = r.s.low >> bits_in_dword_2; + r.s.low &= lower_mask; + t += (b >> bits_in_dword_2) * (a & lower_mask); + r.s.low += (t & lower_mask) << bits_in_dword_2; + r.s.high += t >> bits_in_dword_2; + r.s.high += (a >> bits_in_dword_2) * (b >> bits_in_dword_2); + return r.all; +} + +/* Returns: a * b */ + +grub_clang_ti_int +__multi3(grub_clang_ti_int a, grub_clang_ti_int b) +{ + twords x; + x.all = a; + twords y; + y.all = b; + twords r; + r.all = __mulddi3(x.s.low, y.s.low); + r.s.high += x.s.high * y.s.low + x.s.low * y.s.high; + return r.all; +} +#endif diff --git a/include/grub/compiler-rt.h b/include/grub/compiler-rt.h index 17828b322..3637db47e 100644 --- a/include/grub/compiler-rt.h +++ b/include/grub/compiler-rt.h @@ -209,5 +209,12 @@ void EXPORT_FUNC (___chkstk_ms) (void); void EXPORT_FUNC (__chkstk_ms) (void); #endif +#if defined(__sparc__) && defined(__clang__) +/* Copied from multi3.c which is under MIT license. */ +typedef int grub_clang_ti_int __attribute__ ((mode (TI))); + +grub_clang_ti_int EXPORT_FUNC(__multi3) (grub_clang_ti_int a, grub_clang_ti_int b); +#endif + #endif -- 2.39.2 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel