1212    * BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations 
1313    * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations 
1414    * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations 
15-     * BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned 
16-       read and overlapping memcpy; this reduces decompression speed by 5% 
1715    * BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs 
16+     * BROTLI_BUILD_NO_UNALIGNED_READ_FAST forces off the fast-unaligned-read 
17+       optimizations (mainly for testing purposes) 
1818    * BROTLI_DEBUG dumps file name and line number when decoder detects stream 
1919      or memory error 
2020    * BROTLI_ENABLE_LOG enables asserts and dumps various state information 
21+     * BROTLI_ENABLE_DUMP overrides default "dump" behaviour 
2122*/ 
2223
2324#ifndef  BROTLI_COMMON_PLATFORM_H_
4041#define  BROTLI_X_BIG_ENDIAN  BIG_ENDIAN
4142#endif 
4243
43- #if  BROTLI_MSVC_VERSION_CHECK(12 , 0, 0)
44+ #if  BROTLI_MSVC_VERSION_CHECK(18 , 0, 0)
4445#include  < intrin.h> 
4546#endif 
4647
@@ -156,24 +157,6 @@ To apply compiler hint, enclose the branching condition into macros, like this:
156157#define  BROTLI_NOINLINE 
157158#endif 
158159
159- /*  BROTLI_INTERNAL could be defined to override visibility, e.g. for tests. */ 
160- #if  !defined(BROTLI_INTERNAL)
161- #if  defined(_WIN32) || defined(__CYGWIN__)
162- #define  BROTLI_INTERNAL 
163- #elif  BROTLI_GNUC_VERSION_CHECK(3, 3, 0) ||                         \
164-     BROTLI_TI_VERSION_CHECK (8 , 0 , 0 ) ||                             \
165-     BROTLI_INTEL_VERSION_CHECK(16 , 0 , 0 ) ||                         \
166-     BROTLI_ARM_VERSION_CHECK(4 , 1 , 0 ) ||                            \
167-     BROTLI_IBM_VERSION_CHECK(13 , 1 , 0 ) ||                           \
168-     BROTLI_SUNPRO_VERSION_CHECK(5 , 11 , 0 ) ||                        \
169-     (BROTLI_TI_VERSION_CHECK(7 , 3 , 0 ) &&                            \
170-      defined(__TI_GNU_ATTRIBUTE_SUPPORT__) && defined(__TI_EABI__))
171- #define  BROTLI_INTERNAL  __attribute__  ((visibility (" hidden" 
172- #else 
173- #define  BROTLI_INTERNAL 
174- #endif 
175- #endif 
176- 
177160/*  <<< <<< <<< end of hedley macros. */ 
178161
179162#if  BROTLI_GNUC_HAS_ATTRIBUTE(unused, 2, 7, 0) || \
@@ -226,15 +209,24 @@ To apply compiler hint, enclose the branching condition into macros, like this:
226209#define  BROTLI_TARGET_RISCV64 
227210#endif 
228211
212+ #if  defined(__loongarch_lp64)
213+ #define  BROTLI_TARGET_LOONGARCH64 
214+ #endif 
215+ 
216+ #if  defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \
217+     defined (BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64) || \
218+     defined(BROTLI_TARGET_LOONGARCH64)
219+ #define  BROTLI_TARGET_64_BITS  1 
220+ #else 
221+ #define  BROTLI_TARGET_64_BITS  0 
222+ #endif 
223+ 
229224#if  defined(BROTLI_BUILD_64_BIT)
230225#define  BROTLI_64_BITS  1 
231226#elif  defined(BROTLI_BUILD_32_BIT)
232227#define  BROTLI_64_BITS  0 
233- #elif  defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \
234-     defined (BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64)
235- #define  BROTLI_64_BITS  1 
236228#else 
237- #define  BROTLI_64_BITS  0 
229+ #define  BROTLI_64_BITS  BROTLI_TARGET_64_BITS 
238230#endif 
239231
240232#if  (BROTLI_64_BITS)
@@ -278,18 +270,19 @@ To apply compiler hint, enclose the branching condition into macros, like this:
278270#undef  BROTLI_X_BIG_ENDIAN
279271#endif 
280272
281- #if  defined(BROTLI_BUILD_PORTABLE )
282- #define  BROTLI_ALIGNED_READ  (!!1 )
283- #elif  defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
273+ #if  defined(BROTLI_BUILD_NO_UNALIGNED_READ_FAST )
274+ #define  BROTLI_UNALIGNED_READ_FAST  (!!0 )
275+ #elif  defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) ||        \
284276    defined (BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \
285-     defined(BROTLI_TARGET_RISCV64)
286- /*  Allow unaligned read only for white-listed CPUs. */ 
287- #define  BROTLI_ALIGNED_READ  (!!0 )
277+     defined(BROTLI_TARGET_RISCV64) || defined(BROTLI_TARGET_LOONGARCH64)
278+ /*  These targets are known to generate efficient code for unaligned reads
279+  * (e.g. a single instruction, not multiple 1-byte loads, shifted and or'd 
280+  * together). */  
281+ #define  BROTLI_UNALIGNED_READ_FAST  (!!1 )
288282#else 
289- #define  BROTLI_ALIGNED_READ  (!!1 )
283+ #define  BROTLI_UNALIGNED_READ_FAST  (!!0 )
290284#endif 
291285
292- #if  BROTLI_ALIGNED_READ
293286/*  Portable unaligned memory access: read / write values via memcpy. */ 
294287static  BROTLI_INLINE uint16_t  BrotliUnalignedRead16 (const  void * p) {
295288  uint16_t  t;
@@ -309,75 +302,6 @@ static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
309302static  BROTLI_INLINE void  BrotliUnalignedWrite64 (void * p, uint64_t  v) {
310303  memcpy (p, &v, sizeof  v);
311304}
312- #else   /*  BROTLI_ALIGNED_READ */ 
313- /*  Unaligned memory access is allowed: just cast pointer to requested type. */ 
314- #if  BROTLI_SANITIZED
315- /*  Consider we have an unaligned load/store of 4 bytes from address 0x...05.
316-    AddressSanitizer will treat it as a 3-byte access to the range 05:07 and 
317-    will miss a bug if 08 is the first unaddressable byte. 
318-    ThreadSanitizer will also treat this as a 3-byte access to 05:07 and will 
319-    miss a race between this access and some other accesses to 08. 
320-    MemorySanitizer will correctly propagate the shadow on unaligned stores 
321-    and correctly report bugs on unaligned loads, but it may not properly 
322-    update and report the origin of the uninitialized memory. 
323-    For all three tools, replacing an unaligned access with a tool-specific 
324-    callback solves the problem. */  
325- #if  defined(__cplusplus)
326- extern  " C" 
327- #endif  /*  __cplusplus */ 
328-   uint16_t  __sanitizer_unaligned_load16 (const  void * p);
329-   uint32_t  __sanitizer_unaligned_load32 (const  void * p);
330-   uint64_t  __sanitizer_unaligned_load64 (const  void * p);
331-   void  __sanitizer_unaligned_store64 (void * p, uint64_t  v);
332- #if  defined(__cplusplus)
333- }  /*  extern "C" */ 
334- #endif   /*  __cplusplus */ 
335- #define  BrotliUnalignedRead16  __sanitizer_unaligned_load16
336- #define  BrotliUnalignedRead32  __sanitizer_unaligned_load32
337- #define  BrotliUnalignedRead64  __sanitizer_unaligned_load64
338- #define  BrotliUnalignedWrite64  __sanitizer_unaligned_store64
339- #else   /*  BROTLI_SANITIZED */ 
340- static  BROTLI_INLINE uint16_t  BrotliUnalignedRead16 (const  void * p) {
341-   return  *(const  uint16_t *)p;
342- }
343- static  BROTLI_INLINE uint32_t  BrotliUnalignedRead32 (const  void * p) {
344-   return  *(const  uint32_t *)p;
345- }
346- #if  (BROTLI_64_BITS)
347- static  BROTLI_INLINE uint64_t  BrotliUnalignedRead64 (const  void * p) {
348-   return  *(const  uint64_t *)p;
349- }
350- static  BROTLI_INLINE void  BrotliUnalignedWrite64 (void * p, uint64_t  v) {
351-   *(uint64_t *)p = v;
352- }
353- #else   /*  BROTLI_64_BITS */ 
354- /*  Avoid emitting LDRD / STRD, which require properly aligned address. */ 
355- /*  If __attribute__(aligned) is available, use that. Otherwise, memcpy. */ 
356- 
357- #if  BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0)
358- typedef  BROTLI_ALIGNED (1 ) uint64_t brotli_unaligned_uint64_t;
359- 
360- static  BROTLI_INLINE uint64_t  BrotliUnalignedRead64 (const  void * p) {
361-   return  (uint64_t ) ((const  brotli_unaligned_uint64_t *) p)[0 ];
362- }
363- static  BROTLI_INLINE void  BrotliUnalignedWrite64 (void * p, uint64_t  v) {
364-   brotli_unaligned_uint64_t * dwords = (brotli_unaligned_uint64_t *) p;
365-   dwords[0 ] = (brotli_unaligned_uint64_t ) v;
366- }
367- #else  /*  BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0) */ 
368- static  BROTLI_INLINE uint64_t  BrotliUnalignedRead64 (const  void * p) {
369-   uint64_t  v;
370-   memcpy (&v, p, sizeof (uint64_t ));
371-   return  v;
372- }
373- 
374- static  BROTLI_INLINE void  BrotliUnalignedWrite64 (void * p, uint64_t  v) {
375-   memcpy (p, &v, sizeof (uint64_t ));
376- }
377- #endif   /*  BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0) */ 
378- #endif   /*  BROTLI_64_BITS */ 
379- #endif  /*  BROTLI_SANITIZED */ 
380- #endif  /*  BROTLI_ALIGNED_READ */ 
381305
382306#if  BROTLI_LITTLE_ENDIAN
383307/*  Straight endianness. Just read / write values. */ 
@@ -453,6 +377,16 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
453377}
454378#endif   /*  BROTLI_LITTLE_ENDIAN */ 
455379
380+ static  BROTLI_INLINE void * BROTLI_UNALIGNED_LOAD_PTR (const  void * p) {
381+   void * v;
382+   memcpy (&v, p, sizeof (void *));
383+   return  v;
384+ }
385+ 
386+ static  BROTLI_INLINE void  BROTLI_UNALIGNED_STORE_PTR (void * p, const  void * v) {
387+   memcpy (p, &v, sizeof (void *));
388+ }
389+ 
456390/*  BROTLI_IS_CONSTANT macros returns true for compile-time constants. */ 
457391#if  BROTLI_GNUC_HAS_BUILTIN(__builtin_constant_p, 3, 0, 1) || \
458392    BROTLI_INTEL_VERSION_CHECK (16 , 0 , 0 )
@@ -474,22 +408,34 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
474408#endif 
475409
476410#if  defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
411+ #define  BROTLI_ENABLE_DUMP_DEFAULT  1 
477412#define  BROTLI_DCHECK (x ) assert (x)
413+ #else 
414+ #define  BROTLI_ENABLE_DUMP_DEFAULT  0 
415+ #define  BROTLI_DCHECK (x )
416+ #endif 
417+ 
418+ #if  !defined(BROTLI_ENABLE_DUMP)
419+ #define  BROTLI_ENABLE_DUMP  BROTLI_ENABLE_DUMP_DEFAULT
420+ #endif 
421+ 
422+ #if  BROTLI_ENABLE_DUMP
478423static  BROTLI_INLINE void  BrotliDump (const  char * f, int  l, const  char * fn) {
479424  fprintf (stderr, " %s:%d (%s)\n " 
480425  fflush (stderr);
481426}
482427#define  BROTLI_DUMP () BrotliDump(__FILE__, __LINE__, __FUNCTION__)
483428#else 
484- #define  BROTLI_DCHECK (x )
485429#define  BROTLI_DUMP () (void )(0 )
486430#endif 
487431
488- /*  TODO: add appropriate icc/sunpro/arm/ibm/ti checks. */ 
432+ /*  BrotliRBit assumes brotli_reg_t fits native CPU register type. */ 
433+ #if  (BROTLI_64_BITS == BROTLI_TARGET_64_BITS)
434+ /*  TODO(eustas): add appropriate icc/sunpro/arm/ibm/ti checks. */ 
489435#if  (BROTLI_GNUC_VERSION_CHECK(3, 0, 0) || defined(__llvm__)) && \
490436    !defined (BROTLI_BUILD_NO_RBIT)
491437#if  defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY)
492- /*  TODO: detect ARMv6T2 and enable this code for it. */ 
438+ /*  TODO(eustas) : detect ARMv6T2 and enable this code for it. */ 
493439static  BROTLI_INLINE brotli_reg_t  BrotliRBit (brotli_reg_t  input) {
494440  brotli_reg_t  output;
495441  __asm__ (" rbit %0, %1\n " " =r" " r" 
@@ -498,15 +444,14 @@ static BROTLI_INLINE brotli_reg_t BrotliRBit(brotli_reg_t input) {
498444#define  BROTLI_RBIT (x ) BrotliRBit(x)
499445#endif   /*  armv7 / armv8 */ 
500446#endif   /*  gcc || clang */ 
447+ #endif   /*  brotli_reg_t is native */ 
501448#if  !defined(BROTLI_RBIT)
502449static  BROTLI_INLINE void  BrotliRBit (void ) { /*  Should break build if used. */ 
503450#endif   /*  BROTLI_RBIT */ 
504451
505- #define  BROTLI_REPEAT (N, X ) {     \
506-   if  ((N & 1 ) != 0 ) {X;}          \
507-   if  ((N & 2 ) != 0 ) {X; X;}       \
508-   if  ((N & 4 ) != 0 ) {X; X; X; X;} \
509- }
452+ #define  BROTLI_REPEAT_4 (X ) {X; X; X; X;}
453+ #define  BROTLI_REPEAT_5 (X ) {X; X; X; X; X;}
454+ #define  BROTLI_REPEAT_6 (X ) {X; X; X; X; X; X;}
510455
511456#define  BROTLI_UNUSED (X ) (void )(X)
512457
@@ -529,7 +474,7 @@ BROTLI_MIN_MAX(size_t) BROTLI_MIN_MAX(uint32_t) BROTLI_MIN_MAX(uint8_t)
529474#if  BROTLI_GNUC_HAS_BUILTIN(__builtin_ctzll, 3, 4, 0) || \
530475    BROTLI_INTEL_VERSION_CHECK (16 , 0 , 0 )
531476#define  BROTLI_TZCNT64  __builtin_ctzll
532- #elif  BROTLI_MSVC_VERSION_CHECK(12 , 0, 0)
477+ #elif  BROTLI_MSVC_VERSION_CHECK(18 , 0, 0)
533478#if  defined(BROTLI_TARGET_X64)
534479#define  BROTLI_TZCNT64  _tzcnt_u64
535480#else  /*  BROTLI_TARGET_X64 */ 
@@ -546,7 +491,7 @@ static BROTLI_INLINE uint32_t BrotliBsf64Msvc(uint64_t x) {
546491#if  BROTLI_GNUC_HAS_BUILTIN(__builtin_clz, 3, 4, 0) || \
547492    BROTLI_INTEL_VERSION_CHECK (16 , 0 , 0 )
548493#define  BROTLI_BSR32 (x ) (31u  ^ (uint32_t )__builtin_clz(x))
549- #elif  BROTLI_MSVC_VERSION_CHECK(12 , 0, 0)
494+ #elif  BROTLI_MSVC_VERSION_CHECK(18 , 0, 0)
550495static  BROTLI_INLINE uint32_t  BrotliBsr32Msvc (uint32_t  x) {
551496  unsigned  long  msb;
552497  _BitScanReverse (&msb, x);
@@ -571,6 +516,8 @@ BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) {
571516  BROTLI_UNUSED (&BROTLI_UNALIGNED_LOAD32LE);
572517  BROTLI_UNUSED (&BROTLI_UNALIGNED_LOAD64LE);
573518  BROTLI_UNUSED (&BROTLI_UNALIGNED_STORE64LE);
519+   BROTLI_UNUSED (&BROTLI_UNALIGNED_LOAD_PTR);
520+   BROTLI_UNUSED (&BROTLI_UNALIGNED_STORE_PTR);
574521  BROTLI_UNUSED (&BrotliRBit);
575522  BROTLI_UNUSED (&brotli_min_double);
576523  BROTLI_UNUSED (&brotli_max_double);
@@ -586,7 +533,7 @@ BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) {
586533  BROTLI_UNUSED (&brotli_max_uint8_t );
587534  BROTLI_UNUSED (&BrotliDefaultAllocFunc);
588535  BROTLI_UNUSED (&BrotliDefaultFreeFunc);
589- #if  defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG) 
536+ #if  BROTLI_ENABLE_DUMP 
590537  BROTLI_UNUSED (&BrotliDump);
591538#endif 
592539}
0 commit comments