03-22-2025, 09:43 PM
This will be my last post on the subject, but just for sharing and learning purposes here is the solution I choose to follow and what I have so far. Please take it as work in progress and it "works" for me.
*** This code is Linux targeted, you're on your own for Windows! ***
Built and tested under Debian 11 (Bullseye) x86_64 and Debian 12 (Bookworm) x86.
C static library implementation using x86_64 intrinsic instructions and a x86 work around.
QB64pe test program.
*** This code is Linux targeted, you're on your own for Windows! ***
Built and tested under Debian 11 (Bullseye) x86_64 and Debian 12 (Bookworm) x86.
C static library implementation using x86_64 intrinsic instructions and a x86 work around.
Code: (Select All)
/*
* Compile:
* gcc -O3 -static endian_swap.h -o endian_swap.o
*
* Create static library:
* ar r libendian_swap.a endian_swap.o
*/
#ifndef ENDIAN_SWAP_H
#define ENDIAN_SWAP_H
#include <stdint.h>
inline void endian_swap16(uint16_t* v)
{
__asm__ volatile ("movw %[src], %%ax\n"
"xchg %%ah, %%al\n"
"movw %%ax, %[dst]"
: [dst] "=r" (*v)
: [src] "m" (*v)
);
}
#ifdef __x86_64__
inline void endian_swap32(uint32_t* v)
{
__asm__ volatile ("movbel %[src], %[dst]"
: [dst] "=r" (*v)
: [src] "m" (*v)
);
}
inline void endian_swap64(uint64_t* v)
{
__asm__ volatile ("movbeq %[src], %[dst]"
: [dst] "=r" (*v)
: [src] "m" (*v)
);
}
#else
inline void endian_swap32(uint32_t* v)
{
__asm__ volatile ("movl %[src], %%eax\n"
"bswap %%eax\n"
"movl %%eax, %[dst]"
: [dst] "=r" (*v)
: [src] "m" (*v)
);
}
#endif
#endif /* ENDIAN_SWAP_H */
QB64pe test program.
Code: (Select All)
DECLARE STATIC LIBRARY "endian_swap"
sub endian_swap16(v AS _UNSIGNED INTEGER)
sub endian_swap32(v AS _UNSIGNED LONG)
$IF 64BIT THEN
sub endian_swap64(v AS _UNSIGNED _INTEGER64)
$END IF
END DECLARE
DIM value16 AS _UNSIGNED INTEGER
DIM value32 AS _UNSIGNED LONG
DIM value64 AS _UNSIGNED _INTEGER64
value16 = &HCEFA
value32 = &HEFBEADDE
value64 = &H0DF0FECAEFBEADDE
PRINT HEX$(value16)
PRINT HEX$(value32)
PRINT HEX$(value64)
endian_swap16 value16
endian_swap32 value32
endian_swap64 value64
PRINT HEX$(value16)
PRINT HEX$(value32)
PRINT HEX$(value64)
END