Abstract and cleanup ugly byte swapping code

These macros don't assume alignment and may be somewhat inefficient with
all that copying. I'm hoping GCC is able to optimize that crap somewhat.

Also the pg type receive functions can not, in fact, assume that their
input buffers are properly aligned. That won't necessarily be the case
for array elements.
This commit is contained in:
Yorhel 2025-02-10 07:34:08 +01:00
parent 7d71e446d0
commit d5f593387a
4 changed files with 55 additions and 77 deletions

View file

@ -151,3 +151,22 @@ static SV *fustr_done_(pTHX_ fustr *s) {
#define fustr_write_ch(a,b) fustr_write_ch_(aTHX_ a,b)
#define fustr_write_buf(a,b) fustr_write_buf_(aTHX_ a,b)
#define fustr_done(a) fustr_done_(aTHX_ a)
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define fu_bswap(bits, out, in) ({ U##bits tmpswap; memcpy(&tmpswap, in, bits>>3); tmpswap = __builtin_bswap##bits(tmpswap); memcpy(out, &tmpswap, bits>>3); })
#else
#define fu_bswap(bits, out, in) memcpy(out, in, bits>>3)
#endif
#define fu_frombeT(T, bits, buf) ({ T tmpval; fu_bswap(bits, &tmpval, buf); tmpval; })
#define fu_frombeI(bits, buf) fu_frombeT(I##bits, bits, buf)
#define fu_frombeU(bits, buf) fu_frombeT(U##bits, bits, buf)
#define fu_tobeT(T, bits, out, in) ({ T tmpval = in; fu_bswap(bits, out, &tmpval); })
#define fu_tobeI(bits, out, in) fu_tobeT(I##bits, bits, out, in)
#define fu_tobeU(bits, out, in) fu_tobeT(U##bits, bits, out, in)
#define fustr_writebeT(T, bits, s, in) fu_tobeT(T, bits, fustr_write_buf(s, bits>>3), in)
#define fustr_writebeI(bits, s, in) fustr_writebeT(I##bits, bits, s, in)
#define fustr_writebeU(bits, s, in) fustr_writebeT(U##bits, bits, s, in)