On 11/10/20 10:59 AM, Stefan Kanthak via Gcc-patches wrote: > The implementation of the __ashlDI3(), __ashrDI3() and __lshrDI3() functions > is rather bad, it yields bad machine code at least on i386 and AMD64. > Since GCC knows how to shift integers twice the register size these functions > can be written as one-liners. > > The implementation of the __bswapsi2() function uses SIGNED instead of > unsigned mask values; cf. __bswapdi2() > > Stefan Kanthak > > libgcc2.diff > > --- -/libgcc/libgcc2.h > +++ +/libgcc/libgcc2.h > @@ -391,7 +391,7 @@ > extern DWtype __negdi2 (DWtype); > #endif > > -extern DWtype __lshrdi3 (DWtype, shift_count_type); > +extern UDWtype __lshrdi3 (UDWtype, shift_count_type); > extern DWtype __ashldi3 (DWtype, shift_count_type); > extern DWtype __ashrdi3 (DWtype, shift_count_type); > > --- -/libgcc/libgcc2.c > +++ +/libgcc/libgcc2.c > @@ -398,30 +398,10 @@ > /* Unless shift functions are defined with full ANSI prototypes, > parameter b will be promoted to int if shift_count_type is smaller than > an int. */ > #ifdef L_lshrdi3 > -DWtype > -__lshrdi3 (DWtype u, shift_count_type b) > +UDWtype > +__lshrdi3 (UDWtype u, shift_count_type b)
As has been pointed out, you can't implement these routines by doing the operation in the same mode as the argument. It's potentially self-recursive. THe whole point of these routines is to provide double-word capabilities on targets that don't have intrinsic double-word capabilities. That's why they're written in a non-obvious way using word sized operations. > > @@ -486,10 +425,10 @@ > SItype > __bswapsi2 (SItype u) > { > - return ((((u) & 0xff000000) >> 24) > - | (((u) & 0x00ff0000) >> 8) > - | (((u) & 0x0000ff00) << 8) > - | (((u) & 0x000000ff) << 24)); > + return ((((u) & 0xff000000u) >> 24) > + | (((u) & 0x00ff0000u) >> 8) > + | (((u) & 0x0000ff00u) << 8) > + | (((u) & 0x000000ffu) << 24)); What's the point of this change? I'm not sure how the signedness of the constant really matters here. jeff