diff --git a/c/common/platform.h b/c/common/platform.h index 84c448c..853fa83 100755 --- a/c/common/platform.h +++ b/c/common/platform.h @@ -223,12 +223,21 @@ OR: #define BROTLI_TARGET_RISCV64 #endif +#if defined(__s390x__) +#define BROTLI_TARGET_S390X +#endif + +#if defined(__mips64) +#define BROTLI_TARGET_MIPS64 +#endif + #if defined(BROTLI_BUILD_64_BIT) #define BROTLI_64_BITS 1 #elif defined(BROTLI_BUILD_32_BIT) #define BROTLI_64_BITS 0 #elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \ - defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64) + defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64) || \ + defined(BROTLI_TARGET_S390X) || defined(BROTLI_TARGET_MIPS64) #define BROTLI_64_BITS 1 #else #define BROTLI_64_BITS 0 @@ -279,7 +288,7 @@ OR: #define BROTLI_ALIGNED_READ (!!1) #elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \ defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \ - defined(BROTLI_TARGET_RISCV64) + defined(BROTLI_TARGET_RISCV64) || defined(BROTLI_TARGET_S390X) /* Allow unaligned read only for white-listed CPUs. */ #define BROTLI_ALIGNED_READ (!!0) #else @@ -289,22 +298,42 @@ OR: #if BROTLI_ALIGNED_READ /* Portable unaligned memory access: read / write values via memcpy. */ static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) { +#if defined(__mips__) && (!defined(__mips_isa_rev) || __mips_isa_rev < 6) + const struct { uint16_t x; } __attribute__((__packed__)) *t = p; + return t->x; +#else uint16_t t; memcpy(&t, p, sizeof t); return t; +#endif } static BROTLI_INLINE uint32_t BrotliUnalignedRead32(const void* p) { +#if defined(__mips__) && (!defined(__mips_isa_rev) || __mips_isa_rev < 6) + const struct { uint32_t x; } __attribute__((__packed__)) *t = p; + return t->x; +#else uint32_t t; memcpy(&t, p, sizeof t); return t; +#endif } static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) { +#if defined(__mips__) && (!defined(__mips_isa_rev) || __mips_isa_rev < 6) + const struct { uint64_t x; } __attribute__((__packed__)) *t = p; + return t->x; +#else uint64_t t; memcpy(&t, p, sizeof t); return t; +#endif } static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) { +#if defined(__mips__) && (!defined(__mips_isa_rev) || __mips_isa_rev < 6) + struct { uint64_t x; } __attribute__((__packed__)) *t = p; + t->x = v; +#else memcpy(p, &v, sizeof v); +#endif } #else /* BROTLI_ALIGNED_READ */ /* Unaligned memory access is allowed: just cast pointer to requested type. */ @@ -385,31 +414,20 @@ static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) { #define BROTLI_UNALIGNED_STORE64LE BrotliUnalignedWrite64 #elif BROTLI_BIG_ENDIAN /* BROTLI_LITTLE_ENDIAN */ /* Explain compiler to byte-swap values. */ -#define BROTLI_BSWAP16_(V) ((uint16_t)( \ - (((V) & 0xFFU) << 8) | \ - (((V) >> 8) & 0xFFU))) static BROTLI_INLINE uint16_t BROTLI_UNALIGNED_LOAD16LE(const void* p) { uint16_t value = BrotliUnalignedRead16(p); - return BROTLI_BSWAP16_(value); + return __builtin_bswap16(value); } -#define BROTLI_BSWAP32_(V) ( \ - (((V) & 0xFFU) << 24) | (((V) & 0xFF00U) << 8) | \ - (((V) >> 8) & 0xFF00U) | (((V) >> 24) & 0xFFU)) static BROTLI_INLINE uint32_t BROTLI_UNALIGNED_LOAD32LE(const void* p) { uint32_t value = BrotliUnalignedRead32(p); - return BROTLI_BSWAP32_(value); + return __builtin_bswap32(value); } -#define BROTLI_BSWAP64_(V) ( \ - (((V) & 0xFFU) << 56) | (((V) & 0xFF00U) << 40) | \ - (((V) & 0xFF0000U) << 24) | (((V) & 0xFF000000U) << 8) | \ - (((V) >> 8) & 0xFF000000U) | (((V) >> 24) & 0xFF0000U) | \ - (((V) >> 40) & 0xFF00U) | (((V) >> 56) & 0xFFU)) static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void* p) { uint64_t value = BrotliUnalignedRead64(p); - return BROTLI_BSWAP64_(value); + return __builtin_bswap64(value); } static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) { - uint64_t value = BROTLI_BSWAP64_(v); + uint64_t value = __builtin_bswap64(v); BrotliUnalignedWrite64(p, value); } #else /* BROTLI_LITTLE_ENDIAN */