From ebc4cd54b2378147d7041fd05ff03bd0e1a61e48 Mon Sep 17 00:00:00 2001 From: Stefan Kanthak Date: Tue, 10 Nov 2020 08:22:28 -0700 Subject: [PATCH] Improve generated code for various libgcc2.c routines libgcc/ * libgcc2.c (__addvSI3): Use overflow builtins. (__addvsi3, __addvDI3 ,__subvSI3, __subvsi3): Likewise. (__subvDI3 __mulvSI3, __mulvsi3, __negvSI2): Likewise. (__negvsi2, __negvDI2): Likewise. (__cmpdi2, __ucmpdi2): Adjust implementation to improve generated code. * libgcc2.h (__ucmpdi2): Adjust prototype. --- libgcc/libgcc2.c | 82 +++++++++++++++++------------------------------- libgcc/libgcc2.h | 2 +- 2 files changed, 30 insertions(+), 54 deletions(-) diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c index e0a9fd712e7..4e4defb9bce 100644 --- a/libgcc/libgcc2.c +++ b/libgcc/libgcc2.c @@ -75,9 +75,9 @@ __negdi2 (DWtype u) Wtype __addvSI3 (Wtype a, Wtype b) { - const Wtype w = (UWtype) a + (UWtype) b; + Wtype w; - if (b >= 0 ? w < a : w > a) + if (__builtin_add_overflow(a, b, &w)) abort (); return w; @@ -86,9 +86,9 @@ __addvSI3 (Wtype a, Wtype b) SItype __addvsi3 (SItype a, SItype b) { - const SItype w = (USItype) a + (USItype) b; + SItype w; - if (b >= 0 ? w < a : w > a) + if (__builtin_add_overflow(a, b, &w)) abort (); return w; @@ -100,9 +100,9 @@ __addvsi3 (SItype a, SItype b) DWtype __addvDI3 (DWtype a, DWtype b) { - const DWtype w = (UDWtype) a + (UDWtype) b; + DWtype w; - if (b >= 0 ? w < a : w > a) + if (__builtin_add_overflow(a, b, &w)) abort (); return w; @@ -113,9 +113,9 @@ __addvDI3 (DWtype a, DWtype b) Wtype __subvSI3 (Wtype a, Wtype b) { - const Wtype w = (UWtype) a - (UWtype) b; + Wtype w; - if (b >= 0 ? w > a : w < a) + if (__builtin_sub_overflow(a, b, &w)) abort (); return w; @@ -124,9 +124,9 @@ __subvSI3 (Wtype a, Wtype b) SItype __subvsi3 (SItype a, SItype b) { - const SItype w = (USItype) a - (USItype) b; + SItype w; - if (b >= 0 ? w > a : w < a) + if (__builtin_sub_overflow(a, b, &w)) abort (); return w; @@ -138,9 +138,9 @@ __subvsi3 (SItype a, SItype b) DWtype __subvDI3 (DWtype a, DWtype b) { - const DWtype w = (UDWtype) a - (UDWtype) b; + DWtype w; - if (b >= 0 ? w > a : w < a) + if (__builtin_sub_overflow(a, b, &w)) abort (); return w; @@ -151,22 +151,20 @@ __subvDI3 (DWtype a, DWtype b) Wtype __mulvSI3 (Wtype a, Wtype b) { - const DWtype w = (DWtype) a * (DWtype) b; + Wtype w; - if ((Wtype) (w >> W_TYPE_SIZE) != (Wtype) w >> (W_TYPE_SIZE - 1)) + if (__builtin_mul_overflow(a, b, &w)) abort (); return w; } #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC -#undef WORD_SIZE -#define WORD_SIZE (sizeof (SItype) * __CHAR_BIT__) SItype __mulvsi3 (SItype a, SItype b) { - const DItype w = (DItype) a * (DItype) b; + SItype w; - if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1)) + if (__builtin_mul_overflow(a, b, &w)) abort (); return w; @@ -178,23 +176,23 @@ __mulvsi3 (SItype a, SItype b) Wtype __negvSI2 (Wtype a) { - const Wtype w = -(UWtype) a; + Wtype w; - if (a >= 0 ? w > 0 : w < 0) + if (__builtin_sub_overflow(0, a, &w)) abort (); - return w; + return w; } #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC SItype __negvsi2 (SItype a) { - const SItype w = -(USItype) a; + SItype w; - if (a >= 0 ? w > 0 : w < 0) + if (__builtin_sub_overflow(0, a, &w)) abort (); - return w; + return w; } #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ #endif @@ -203,9 +201,9 @@ __negvsi2 (SItype a) DWtype __negvDI2 (DWtype a) { - const DWtype w = -(UDWtype) a; + DWtype w; - if (a >= 0 ? w > 0 : w < 0) + if (__builtin_sub_overflow(0, a, &w)) abort (); return w; @@ -953,7 +951,7 @@ __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) aligns the divisor under the dividend and then perform number of test-subtract iterations which shift the dividend left. Number of iterations is k + 1 where k is the number of bit positions the - divisor must be shifted left to align it under the dividend. + divisor must be shifted left to align it under the dividend. quotient bits can be saved in the rightmost positions of the dividend as it shifts left on each test-subtract iteration. */ @@ -965,7 +963,7 @@ __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) k = lz1 - lz2; y = (y << k); - /* Dividend can exceed 2 ^ (width − 1) − 1 but still be less than the + /* Dividend can exceed 2 ^ (width - 1) - 1 but still be less than the aligned divisor. Normal iteration can drops the high order bit of the dividend. Therefore, first test-subtract iteration is a special case, saving its quotient bit in a separate location and @@ -1325,37 +1323,15 @@ __udivdi3 (UDWtype n, UDWtype d) cmp_return_type __cmpdi2 (DWtype a, DWtype b) { - const DWunion au = {.ll = a}; - const DWunion bu = {.ll = b}; - - if (au.s.high < bu.s.high) - return 0; - else if (au.s.high > bu.s.high) - return 2; - if ((UWtype) au.s.low < (UWtype) bu.s.low) - return 0; - else if ((UWtype) au.s.low > (UWtype) bu.s.low) - return 2; - return 1; + return (a > b) - (a < b) + 1; } #endif #ifdef L_ucmpdi2 cmp_return_type -__ucmpdi2 (DWtype a, DWtype b) +__ucmpdi2 (UDWtype a, UDWtype b) { - const DWunion au = {.ll = a}; - const DWunion bu = {.ll = b}; - - if ((UWtype) au.s.high < (UWtype) bu.s.high) - return 0; - else if ((UWtype) au.s.high > (UWtype) bu.s.high) - return 2; - if ((UWtype) au.s.low < (UWtype) bu.s.low) - return 0; - else if ((UWtype) au.s.low > (UWtype) bu.s.low) - return 2; - return 1; + return (a > b) - (a < b) + 1; } #endif diff --git a/libgcc/libgcc2.h b/libgcc/libgcc2.h index 1c20ffcaae3..22a27062f82 100644 --- a/libgcc/libgcc2.h +++ b/libgcc/libgcc2.h @@ -402,7 +402,7 @@ extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype); #endif extern cmp_return_type __cmpdi2 (DWtype, DWtype); -extern cmp_return_type __ucmpdi2 (DWtype, DWtype); +extern cmp_return_type __ucmpdi2 (UDWtype, UDWtype); #if MIN_UNITS_PER_WORD > 1 extern SItype __bswapsi2 (SItype); -- 2.30.2