redefine architecture list as macro so therefore it can be used in preprocessor expressions. implement hardware byte-swapping, detect compile-time hardware capabilties to do that.

This commit is contained in:
mykola2312 2022-04-29 06:36:01 +03:00
parent 20e7489866
commit 5432d8f889
4 changed files with 83 additions and 26 deletions

View file

@ -4,29 +4,27 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
enum cu_arch_e { #define ARCH_UNKNOWN 0
ARCH_UNKNOWN = 0, #define x86_64 1
x86_64, #define x86_32 2
x86_32, #define ARM2 3
ARM2, #define ARM3 4
ARM3, #define ARM4T 5
ARM4T, #define ARM5 6
ARM5, #define ARM6T2 7
ARM6T2, #define ARM6 8
ARM6, #define ARM7 9
ARM7, #define ARM7A 10
ARM7A, #define ARM7R 11
ARM7R, #define ARM7M 12
ARM7M, #define ARM7S 13
ARM7S, #define AARCH64 14
AARCH64, #define MIPS 15
MIPS, #define SUPERH 16
SUPERH, #define POWERPC 17
POWERPC, #define POWERPC64 18
POWERPC64, #define SPARC 19
SPARC, #define M68K 20
M68K,
};
#if defined(__x86_64__) || defined(_M_X64) #if defined(__x86_64__) || defined(_M_X64)
# define CU_ARCH x86_64 # define CU_ARCH x86_64
@ -72,6 +70,25 @@ enum cu_arch_e {
# define CU_ARCH ARCH_UNKNOWN; # define CU_ARCH ARCH_UNKNOWN;
#endif #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) #if (CU_ARCH == x86_64 || CU_ARCH == AARCH64 || CU_ARCH == POWERPC64)
# define CU_64BIT # define CU_64BIT
#else #else

View file

@ -46,11 +46,39 @@ static uint64_t sw_bswap64(uint64_t val)
| (val & 0x00000000000000FFUL) << 56; | (val & 0x00000000000000FFUL) << 56;
} }
#include <stdio.h> #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() void cu_endian_init()
{ {
cu_endian = endian_detect(); cu_endian = endian_detect();
printf("%x\t%x\n", 0x12345678, sw_bswap32(0x12345678));
printf("%lx\t%lx\n", 0x12345678abcd8765, sw_bswap64(0x12345678abcd8765));
} }

View file

@ -11,6 +11,14 @@ enum cu_endian_e {
extern enum cu_endian_e cu_endian; 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(); void cu_endian_init();
#endif #endif

4
test.c
View file

@ -77,7 +77,11 @@ int main()
printf("[cutil]\n"); printf("[cutil]\n");
printf("cutil_arch\t%u\n", CU_ARCH); printf("cutil_arch\t%u\n", CU_ARCH);
printf("[endian]\n");
printf("cutil_endian\t%u\n", cu_endian); 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(); cutil_exit();
return 0; return 0;