#pragma once #include "antcc.h" extern bool targ_bigendian; /*** Macros and functions for endian specific memory access ***/ /** byte-swapping functions **/ #if HAS_BUILTIN(bswap16) #define bswap16 __builtin_bswap16 #else static inline ushort bswap16(ushort x) { return x >> 8 | x << 8; } #endif #if HAS_BUILTIN(bswap32) #define bswap32 __builtin_bswap32 #else static inline uint bswap32(uint x) { return x >> 24 & 0x000000FF | x >> 8 & 0x0000FF00 | x << 8 & 0x00FF0000 | x << 24 & 0xFF000000; } #endif #if HAS_BUILTIN(bswap64) #define bswap64 __builtin_bswap64 #else static inline u64int bswap64(u64int x) { return (u64int) bswap32(x) << 32 | bswap32(x >> 32); } #endif #if (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \ defined __hppa__ || defined __m68k__ || defined mc68000 || defined _M_M68K || \ (defined __MIPS__ && defined __MIPSEB__) || \ defined __ppc__ || defined __POWERPC__ || defined __powerpc__ || defined __PPC__ || \ defined __sparc__ #define HOST_BIG_ENDIAN #define hostntarg_sameendian() (targ_bigendian) #else #define HOST_LIL_ENDIAN #define hostntarg_sameendian() (!targ_bigendian) #endif /** little-endian memory writes **/ static inline void wr16le(uchar *p, ushort x) { #ifndef HOST_LIL_ENDIAN x = bswap16(x); #endif memcpy(p, &x, sizeof x); } static inline void wr32le(uchar *p, uint x) { #ifndef HOST_LIL_ENDIAN x = bswap32(x); #endif memcpy(p, &x, sizeof x); } static inline void wr64le(uchar *p, u64int x) { #ifndef HOST_LIL_ENDIAN x = bswap64(x); #endif memcpy(p, &x, sizeof x); } /** big-endian memory writes **/ static inline void wr16be(uchar *p, ushort x) { #ifndef HOST_BIG_ENDIAN x = bswap16(x); #endif memcpy(p, &x, sizeof x); } static inline void wr32be(uchar *p, uint x) { #ifndef HOST_BIG_ENDIAN x = bswap32(x); #endif memcpy(p, &x, sizeof x); } static inline void wr64be(uchar *p, u64int x) { #ifndef HOST_BIG_ENDIAN x = bswap64(x); #endif memcpy(p, &x, sizeof x); } /** target-endian memory read/write **/ static inline ushort rd16targ(uchar *p) { ushort x; memcpy(&x, p, sizeof x); if (!hostntarg_sameendian()) x = bswap16(x); return x; } static inline uint rd32targ(uchar *p) { uint x; memcpy(&x, p, sizeof x); if (!hostntarg_sameendian()) x = bswap32(x); return x; } static inline u64int rd64targ(uchar *p) { u64int x; memcpy(&x, p, sizeof x); if (!hostntarg_sameendian()) x = bswap64(x); return x; } static inline float rdf32targ(uchar *p) { union { uint i; float f; } u = { rd32targ(p) }; return u.f; } static inline double rdf64targ(uchar *p) { union { u64int i; double f; } u = { rd64targ(p) }; return u.f; } static inline void wr16targ(uchar *p, ushort x) { if (!hostntarg_sameendian()) x = bswap16(x); memcpy(p, &x, sizeof x); } static inline void wr32targ(uchar *p, uint x) { if (!hostntarg_sameendian()) x = bswap32(x); memcpy(p, &x, sizeof x); } static inline void wr64targ(uchar *p, u64int x) { if (!hostntarg_sameendian()) x = bswap64(x); memcpy(p, &x, sizeof x); } static inline void wrf32targ(uchar *p, float x) { union { float f; uint i; } u = { x }; wr32targ(p, u.i); } static inline void wrf64targ(uchar *p, double x) { union { double f; u64int i; } u = { x }; wr64targ(p, u.i); } /* vim:set ts=3 sw=3 expandtab: */