diff --git a/cutypes.h b/cutypes.h index a8e7277..6c23bb6 100644 --- a/cutypes.h +++ b/cutypes.h @@ -4,29 +4,27 @@ #include #include -enum cu_arch_e { - ARCH_UNKNOWN = 0, - x86_64, - x86_32, - ARM2, - ARM3, - ARM4T, - ARM5, - ARM6T2, - ARM6, - ARM7, - ARM7A, - ARM7R, - ARM7M, - ARM7S, - AARCH64, - MIPS, - SUPERH, - POWERPC, - POWERPC64, - SPARC, - M68K, -}; +#define ARCH_UNKNOWN 0 +#define x86_64 1 +#define x86_32 2 +#define ARM2 3 +#define ARM3 4 +#define ARM4T 5 +#define ARM5 6 +#define ARM6T2 7 +#define ARM6 8 +#define ARM7 9 +#define ARM7A 10 +#define ARM7R 11 +#define ARM7M 12 +#define ARM7S 13 +#define AARCH64 14 +#define MIPS 15 +#define SUPERH 16 +#define POWERPC 17 +#define POWERPC64 18 +#define SPARC 19 +#define M68K 20 #if defined(__x86_64__) || defined(_M_X64) # define CU_ARCH x86_64 @@ -72,6 +70,25 @@ enum cu_arch_e { # define CU_ARCH ARCH_UNKNOWN; #endif +#if (CU_ARCH == x86_64 || CU_ARCH == x86_32) +# define CU_ARCH_X86 +#elif (CU_ARCH >= ARM2 && CU_ARCH <= AARCH64) +# define CU_ARCH_ARM +# define CU_ARCH_ARM_ARCH __ARM_ARCH +#elif (CU_ARCH == MIPS) +# define CU_ARCH_MIPS +#elif (CU_ARCH == SUPERH) +# define CU_ARCH_SUPERH +#elif (CU_ARCH == POWERPC || CU_ARCH == POWERPC64) +# define CU_ARCH_POWERPC +#elif (CU_ARCH == SPARC) +# define CU_ARCH_SPARC +#elif (CU_ARCH == M68K) +# define CU_ARCH_M68K +#else +# warning "unknown architecture" +#endif + #if (CU_ARCH == x86_64 || CU_ARCH == AARCH64 || CU_ARCH == POWERPC64) # define CU_64BIT #else diff --git a/endian.c b/endian.c index ef83c48..b9b011f 100644 --- a/endian.c +++ b/endian.c @@ -46,11 +46,39 @@ static uint64_t sw_bswap64(uint64_t val) | (val & 0x00000000000000FFUL) << 56; } -#include +#if (CU_ARCH == x86_32) +static uint32_t hw_bswap32(uint32_t val) +{ + __asm__ ("bswap %0" : "=r" (val) : "r" (val)); + return val; +} + +bswap16_t cu_bswap16 = sw_bswap16; +bswap32_t cu_bswap32 = hw_bswap32; +bswap64_t cu_bswap64 = sw_bswap64; +#elif (CU_ARCH == x86_64) +static uint32_t hw_bswap32(uint32_t val) +{ + __asm__ ("bswap %0" : "=r" (val) : "r" (val)); + return val; +} + +static uint64_t hw_bswap64(uint64_t val) +{ + __asm__ ("bswap %0" : "=r" (val) : "r" (val)); + return val; +} + +bswap16_t cu_bswap16 = sw_bswap16; +bswap32_t cu_bswap32 = hw_bswap32; +bswap64_t cu_bswap64 = hw_bswap64; +#else +bswap16_t cu_bswap16 = sw_bswap16; +bswap32_t cu_bswap32 = sw_bswap32; +bswap64_t cu_bswap64 = sw_bswap64; +#endif void cu_endian_init() { cu_endian = endian_detect(); - printf("%x\t%x\n", 0x12345678, sw_bswap32(0x12345678)); - printf("%lx\t%lx\n", 0x12345678abcd8765, sw_bswap64(0x12345678abcd8765)); } diff --git a/endian.h b/endian.h index 6d32640..9c5132b 100644 --- a/endian.h +++ b/endian.h @@ -11,6 +11,14 @@ enum cu_endian_e { extern enum cu_endian_e cu_endian; +typedef uint16_t (*bswap16_t)(uint16_t); +typedef uint32_t (*bswap32_t)(uint32_t); +typedef uint64_t (*bswap64_t)(uint64_t); + +extern bswap16_t cu_bswap16; +extern bswap32_t cu_bswap32; +extern bswap64_t cu_bswap64; + void cu_endian_init(); #endif \ No newline at end of file diff --git a/test.c b/test.c index 9a28daf..4047433 100644 --- a/test.c +++ b/test.c @@ -77,7 +77,11 @@ int main() printf("[cutil]\n"); printf("cutil_arch\t%u\n", CU_ARCH); + + printf("[endian]\n"); printf("cutil_endian\t%u\n", cu_endian); + printf("%x\t%x\n", 0x12345678, cu_bswap32(0x12345678)); + printf("%lx\t%lx\n", 0x12345678abcd8765, cu_bswap64(0x12345678abcd8765)); cutil_exit(); return 0;