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 <stdint.h>
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

View file

@ -46,11 +46,39 @@ static uint64_t sw_bswap64(uint64_t val)
| (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()
{
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;
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

4
test.c
View file

@ -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;