extzstd 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/contrib/zstd/CHANGELOG +188 -1
  4. data/contrib/zstd/CONTRIBUTING.md +157 -74
  5. data/contrib/zstd/LICENSE +4 -4
  6. data/contrib/zstd/Makefile +81 -58
  7. data/contrib/zstd/Package.swift +36 -0
  8. data/contrib/zstd/README.md +59 -35
  9. data/contrib/zstd/TESTING.md +2 -3
  10. data/contrib/zstd/appveyor.yml +49 -136
  11. data/contrib/zstd/lib/BUCK +5 -7
  12. data/contrib/zstd/lib/Makefile +87 -181
  13. data/contrib/zstd/lib/README.md +23 -6
  14. data/contrib/zstd/lib/common/allocations.h +55 -0
  15. data/contrib/zstd/lib/common/bits.h +200 -0
  16. data/contrib/zstd/lib/common/bitstream.h +33 -59
  17. data/contrib/zstd/lib/common/compiler.h +115 -45
  18. data/contrib/zstd/lib/common/cpu.h +1 -1
  19. data/contrib/zstd/lib/common/debug.c +1 -1
  20. data/contrib/zstd/lib/common/debug.h +1 -1
  21. data/contrib/zstd/lib/common/entropy_common.c +15 -37
  22. data/contrib/zstd/lib/common/error_private.c +9 -2
  23. data/contrib/zstd/lib/common/error_private.h +82 -3
  24. data/contrib/zstd/lib/common/fse.h +9 -85
  25. data/contrib/zstd/lib/common/fse_decompress.c +29 -111
  26. data/contrib/zstd/lib/common/huf.h +84 -172
  27. data/contrib/zstd/lib/common/mem.h +58 -49
  28. data/contrib/zstd/lib/common/pool.c +37 -16
  29. data/contrib/zstd/lib/common/pool.h +9 -3
  30. data/contrib/zstd/lib/common/portability_macros.h +156 -0
  31. data/contrib/zstd/lib/common/threading.c +68 -14
  32. data/contrib/zstd/lib/common/threading.h +5 -10
  33. data/contrib/zstd/lib/common/xxhash.c +7 -809
  34. data/contrib/zstd/lib/common/xxhash.h +5568 -167
  35. data/contrib/zstd/lib/common/zstd_common.c +1 -36
  36. data/contrib/zstd/lib/common/zstd_deps.h +1 -1
  37. data/contrib/zstd/lib/common/zstd_internal.h +64 -150
  38. data/contrib/zstd/lib/common/zstd_trace.h +163 -0
  39. data/contrib/zstd/lib/compress/clevels.h +134 -0
  40. data/contrib/zstd/lib/compress/fse_compress.c +69 -150
  41. data/contrib/zstd/lib/compress/hist.c +1 -1
  42. data/contrib/zstd/lib/compress/hist.h +1 -1
  43. data/contrib/zstd/lib/compress/huf_compress.c +773 -251
  44. data/contrib/zstd/lib/compress/zstd_compress.c +2650 -826
  45. data/contrib/zstd/lib/compress/zstd_compress_internal.h +509 -180
  46. data/contrib/zstd/lib/compress/zstd_compress_literals.c +117 -40
  47. data/contrib/zstd/lib/compress/zstd_compress_literals.h +16 -6
  48. data/contrib/zstd/lib/compress/zstd_compress_sequences.c +28 -19
  49. data/contrib/zstd/lib/compress/zstd_compress_sequences.h +1 -1
  50. data/contrib/zstd/lib/compress/zstd_compress_superblock.c +33 -305
  51. data/contrib/zstd/lib/compress/zstd_compress_superblock.h +1 -1
  52. data/contrib/zstd/lib/compress/zstd_cwksp.h +266 -85
  53. data/contrib/zstd/lib/compress/zstd_double_fast.c +369 -132
  54. data/contrib/zstd/lib/compress/zstd_double_fast.h +3 -2
  55. data/contrib/zstd/lib/compress/zstd_fast.c +722 -258
  56. data/contrib/zstd/lib/compress/zstd_fast.h +3 -2
  57. data/contrib/zstd/lib/compress/zstd_lazy.c +1105 -360
  58. data/contrib/zstd/lib/compress/zstd_lazy.h +41 -1
  59. data/contrib/zstd/lib/compress/zstd_ldm.c +272 -208
  60. data/contrib/zstd/lib/compress/zstd_ldm.h +3 -2
  61. data/contrib/zstd/lib/compress/zstd_ldm_geartab.h +106 -0
  62. data/contrib/zstd/lib/compress/zstd_opt.c +324 -197
  63. data/contrib/zstd/lib/compress/zstd_opt.h +1 -1
  64. data/contrib/zstd/lib/compress/zstdmt_compress.c +109 -53
  65. data/contrib/zstd/lib/compress/zstdmt_compress.h +9 -6
  66. data/contrib/zstd/lib/decompress/huf_decompress.c +1071 -539
  67. data/contrib/zstd/lib/decompress/huf_decompress_amd64.S +576 -0
  68. data/contrib/zstd/lib/decompress/zstd_ddict.c +4 -4
  69. data/contrib/zstd/lib/decompress/zstd_ddict.h +1 -1
  70. data/contrib/zstd/lib/decompress/zstd_decompress.c +507 -82
  71. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +962 -310
  72. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +14 -3
  73. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +54 -6
  74. data/contrib/zstd/lib/deprecated/zbuff.h +1 -1
  75. data/contrib/zstd/lib/deprecated/zbuff_common.c +1 -1
  76. data/contrib/zstd/lib/deprecated/zbuff_compress.c +24 -4
  77. data/contrib/zstd/lib/deprecated/zbuff_decompress.c +3 -1
  78. data/contrib/zstd/lib/dictBuilder/cover.c +44 -32
  79. data/contrib/zstd/lib/dictBuilder/cover.h +6 -5
  80. data/contrib/zstd/lib/dictBuilder/divsufsort.c +1 -1
  81. data/contrib/zstd/lib/dictBuilder/fastcover.c +24 -16
  82. data/contrib/zstd/lib/dictBuilder/zdict.c +88 -95
  83. data/contrib/zstd/lib/legacy/zstd_legacy.h +8 -1
  84. data/contrib/zstd/lib/legacy/zstd_v01.c +16 -53
  85. data/contrib/zstd/lib/legacy/zstd_v01.h +1 -1
  86. data/contrib/zstd/lib/legacy/zstd_v02.c +24 -69
  87. data/contrib/zstd/lib/legacy/zstd_v02.h +1 -1
  88. data/contrib/zstd/lib/legacy/zstd_v03.c +25 -72
  89. data/contrib/zstd/lib/legacy/zstd_v03.h +1 -1
  90. data/contrib/zstd/lib/legacy/zstd_v04.c +23 -69
  91. data/contrib/zstd/lib/legacy/zstd_v04.h +1 -1
  92. data/contrib/zstd/lib/legacy/zstd_v05.c +35 -85
  93. data/contrib/zstd/lib/legacy/zstd_v05.h +1 -1
  94. data/contrib/zstd/lib/legacy/zstd_v06.c +42 -87
  95. data/contrib/zstd/lib/legacy/zstd_v06.h +1 -1
  96. data/contrib/zstd/lib/legacy/zstd_v07.c +35 -82
  97. data/contrib/zstd/lib/legacy/zstd_v07.h +1 -1
  98. data/contrib/zstd/lib/libzstd.mk +214 -0
  99. data/contrib/zstd/lib/libzstd.pc.in +4 -3
  100. data/contrib/zstd/lib/module.modulemap +35 -0
  101. data/contrib/zstd/lib/{dictBuilder/zdict.h → zdict.h} +202 -33
  102. data/contrib/zstd/lib/zstd.h +922 -293
  103. data/contrib/zstd/lib/{common/zstd_errors.h → zstd_errors.h} +27 -8
  104. data/ext/extconf.rb +7 -6
  105. data/ext/extzstd.c +13 -10
  106. data/ext/libzstd_conf.h +0 -1
  107. data/ext/zstd_decompress_asm.S +1 -0
  108. metadata +16 -5
@@ -0,0 +1,200 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ #ifndef ZSTD_BITS_H
12
+ #define ZSTD_BITS_H
13
+
14
+ #include "mem.h"
15
+
16
+ MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val)
17
+ {
18
+ assert(val != 0);
19
+ {
20
+ static const U32 DeBruijnBytePos[32] = {0, 1, 28, 2, 29, 14, 24, 3,
21
+ 30, 22, 20, 15, 25, 17, 4, 8,
22
+ 31, 27, 13, 23, 21, 19, 16, 7,
23
+ 26, 12, 18, 6, 11, 5, 10, 9};
24
+ return DeBruijnBytePos[((U32) ((val & -(S32) val) * 0x077CB531U)) >> 27];
25
+ }
26
+ }
27
+
28
+ MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val)
29
+ {
30
+ assert(val != 0);
31
+ # if defined(_MSC_VER)
32
+ # if STATIC_BMI2 == 1
33
+ return (unsigned)_tzcnt_u32(val);
34
+ # else
35
+ if (val != 0) {
36
+ unsigned long r;
37
+ _BitScanForward(&r, val);
38
+ return (unsigned)r;
39
+ } else {
40
+ /* Should not reach this code path */
41
+ __assume(0);
42
+ }
43
+ # endif
44
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
45
+ return (unsigned)__builtin_ctz(val);
46
+ # else
47
+ return ZSTD_countTrailingZeros32_fallback(val);
48
+ # endif
49
+ }
50
+
51
+ MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val) {
52
+ assert(val != 0);
53
+ {
54
+ static const U32 DeBruijnClz[32] = {0, 9, 1, 10, 13, 21, 2, 29,
55
+ 11, 14, 16, 18, 22, 25, 3, 30,
56
+ 8, 12, 20, 28, 15, 17, 24, 7,
57
+ 19, 27, 23, 6, 26, 5, 4, 31};
58
+ val |= val >> 1;
59
+ val |= val >> 2;
60
+ val |= val >> 4;
61
+ val |= val >> 8;
62
+ val |= val >> 16;
63
+ return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27];
64
+ }
65
+ }
66
+
67
+ MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val)
68
+ {
69
+ assert(val != 0);
70
+ # if defined(_MSC_VER)
71
+ # if STATIC_BMI2 == 1
72
+ return (unsigned)_lzcnt_u32(val);
73
+ # else
74
+ if (val != 0) {
75
+ unsigned long r;
76
+ _BitScanReverse(&r, val);
77
+ return (unsigned)(31 - r);
78
+ } else {
79
+ /* Should not reach this code path */
80
+ __assume(0);
81
+ }
82
+ # endif
83
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
84
+ return (unsigned)__builtin_clz(val);
85
+ # else
86
+ return ZSTD_countLeadingZeros32_fallback(val);
87
+ # endif
88
+ }
89
+
90
+ MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val)
91
+ {
92
+ assert(val != 0);
93
+ # if defined(_MSC_VER) && defined(_WIN64)
94
+ # if STATIC_BMI2 == 1
95
+ return (unsigned)_tzcnt_u64(val);
96
+ # else
97
+ if (val != 0) {
98
+ unsigned long r;
99
+ _BitScanForward64(&r, val);
100
+ return (unsigned)r;
101
+ } else {
102
+ /* Should not reach this code path */
103
+ __assume(0);
104
+ }
105
+ # endif
106
+ # elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(__LP64__)
107
+ return (unsigned)__builtin_ctzll(val);
108
+ # else
109
+ {
110
+ U32 mostSignificantWord = (U32)(val >> 32);
111
+ U32 leastSignificantWord = (U32)val;
112
+ if (leastSignificantWord == 0) {
113
+ return 32 + ZSTD_countTrailingZeros32(mostSignificantWord);
114
+ } else {
115
+ return ZSTD_countTrailingZeros32(leastSignificantWord);
116
+ }
117
+ }
118
+ # endif
119
+ }
120
+
121
+ MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val)
122
+ {
123
+ assert(val != 0);
124
+ # if defined(_MSC_VER) && defined(_WIN64)
125
+ # if STATIC_BMI2 == 1
126
+ return (unsigned)_lzcnt_u64(val);
127
+ # else
128
+ if (val != 0) {
129
+ unsigned long r;
130
+ _BitScanReverse64(&r, val);
131
+ return (unsigned)(63 - r);
132
+ } else {
133
+ /* Should not reach this code path */
134
+ __assume(0);
135
+ }
136
+ # endif
137
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
138
+ return (unsigned)(__builtin_clzll(val));
139
+ # else
140
+ {
141
+ U32 mostSignificantWord = (U32)(val >> 32);
142
+ U32 leastSignificantWord = (U32)val;
143
+ if (mostSignificantWord == 0) {
144
+ return 32 + ZSTD_countLeadingZeros32(leastSignificantWord);
145
+ } else {
146
+ return ZSTD_countLeadingZeros32(mostSignificantWord);
147
+ }
148
+ }
149
+ # endif
150
+ }
151
+
152
+ MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val)
153
+ {
154
+ if (MEM_isLittleEndian()) {
155
+ if (MEM_64bits()) {
156
+ return ZSTD_countTrailingZeros64((U64)val) >> 3;
157
+ } else {
158
+ return ZSTD_countTrailingZeros32((U32)val) >> 3;
159
+ }
160
+ } else { /* Big Endian CPU */
161
+ if (MEM_64bits()) {
162
+ return ZSTD_countLeadingZeros64((U64)val) >> 3;
163
+ } else {
164
+ return ZSTD_countLeadingZeros32((U32)val) >> 3;
165
+ }
166
+ }
167
+ }
168
+
169
+ MEM_STATIC unsigned ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
170
+ {
171
+ assert(val != 0);
172
+ return 31 - ZSTD_countLeadingZeros32(val);
173
+ }
174
+
175
+ /* ZSTD_rotateRight_*():
176
+ * Rotates a bitfield to the right by "count" bits.
177
+ * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts
178
+ */
179
+ MEM_STATIC
180
+ U64 ZSTD_rotateRight_U64(U64 const value, U32 count) {
181
+ assert(count < 64);
182
+ count &= 0x3F; /* for fickle pattern recognition */
183
+ return (value >> count) | (U64)(value << ((0U - count) & 0x3F));
184
+ }
185
+
186
+ MEM_STATIC
187
+ U32 ZSTD_rotateRight_U32(U32 const value, U32 count) {
188
+ assert(count < 32);
189
+ count &= 0x1F; /* for fickle pattern recognition */
190
+ return (value >> count) | (U32)(value << ((0U - count) & 0x1F));
191
+ }
192
+
193
+ MEM_STATIC
194
+ U16 ZSTD_rotateRight_U16(U16 const value, U32 count) {
195
+ assert(count < 16);
196
+ count &= 0x0F; /* for fickle pattern recognition */
197
+ return (value >> count) | (U16)(value << ((0U - count) & 0x0F));
198
+ }
199
+
200
+ #endif /* ZSTD_BITS_H */
@@ -1,7 +1,7 @@
1
1
  /* ******************************************************************
2
2
  * bitstream
3
3
  * Part of FSE library
4
- * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
6
6
  * You can contact the author at :
7
7
  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -30,14 +30,15 @@ extern "C" {
30
30
  #include "compiler.h" /* UNLIKELY() */
31
31
  #include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */
32
32
  #include "error_private.h" /* error codes and messages */
33
+ #include "bits.h" /* ZSTD_highbit32 */
33
34
 
34
35
 
35
36
  /*=========================================
36
37
  * Target specific
37
38
  =========================================*/
38
39
  #ifndef ZSTD_NO_INTRINSICS
39
- # if defined(__BMI__) && defined(__GNUC__)
40
- # include <immintrin.h> /* support for bextr (experimental) */
40
+ # if (defined(__BMI__) || defined(__BMI2__)) && defined(__GNUC__)
41
+ # include <immintrin.h> /* support for bextr (experimental)/bzhi */
41
42
  # elif defined(__ICCARM__)
42
43
  # include <intrinsics.h>
43
44
  # endif
@@ -132,42 +133,6 @@ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);
132
133
  MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
133
134
  /* faster, but works only if nbBits >= 1 */
134
135
 
135
-
136
-
137
- /*-**************************************************************
138
- * Internal functions
139
- ****************************************************************/
140
- MEM_STATIC unsigned BIT_highbit32 (U32 val)
141
- {
142
- assert(val != 0);
143
- {
144
- # if defined(_MSC_VER) /* Visual */
145
- # if STATIC_BMI2 == 1
146
- return _lzcnt_u32(val) ^ 31;
147
- # else
148
- unsigned long r = 0;
149
- return _BitScanReverse(&r, val) ? (unsigned)r : 0;
150
- # endif
151
- # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
152
- return __builtin_clz (val) ^ 31;
153
- # elif defined(__ICCARM__) /* IAR Intrinsic */
154
- return 31 - __CLZ(val);
155
- # else /* Software version */
156
- static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
157
- 11, 14, 16, 18, 22, 25, 3, 30,
158
- 8, 12, 20, 28, 15, 17, 24, 7,
159
- 19, 27, 23, 6, 26, 5, 4, 31 };
160
- U32 v = val;
161
- v |= v >> 1;
162
- v |= v >> 2;
163
- v |= v >> 4;
164
- v |= v >> 8;
165
- v |= v >> 16;
166
- return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
167
- # endif
168
- }
169
- }
170
-
171
136
  /*===== Local Constants =====*/
172
137
  static const unsigned BIT_mask[] = {
173
138
  0, 1, 3, 7, 0xF, 0x1F,
@@ -197,6 +162,16 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
197
162
  return 0;
198
163
  }
199
164
 
165
+ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
166
+ {
167
+ #if defined(STATIC_BMI2) && STATIC_BMI2 == 1 && !defined(ZSTD_NO_INTRINSICS)
168
+ return _bzhi_u64(bitContainer, nbBits);
169
+ #else
170
+ assert(nbBits < BIT_MASK_SIZE);
171
+ return bitContainer & BIT_mask[nbBits];
172
+ #endif
173
+ }
174
+
200
175
  /*! BIT_addBits() :
201
176
  * can add up to 31 bits into `bitC`.
202
177
  * Note : does not check for register overflow ! */
@@ -206,7 +181,7 @@ MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
206
181
  DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32);
207
182
  assert(nbBits < BIT_MASK_SIZE);
208
183
  assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
209
- bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
184
+ bitC->bitContainer |= BIT_getLowerBits(value, nbBits) << bitC->bitPos;
210
185
  bitC->bitPos += nbBits;
211
186
  }
212
187
 
@@ -285,7 +260,7 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
285
260
  bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
286
261
  bitD->bitContainer = MEM_readLEST(bitD->ptr);
287
262
  { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
288
- bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
263
+ bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
289
264
  if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
290
265
  } else {
291
266
  bitD->ptr = bitD->start;
@@ -293,27 +268,27 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
293
268
  switch(srcSize)
294
269
  {
295
270
  case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
296
- /* fall-through */
271
+ ZSTD_FALLTHROUGH;
297
272
 
298
273
  case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
299
- /* fall-through */
274
+ ZSTD_FALLTHROUGH;
300
275
 
301
276
  case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
302
- /* fall-through */
277
+ ZSTD_FALLTHROUGH;
303
278
 
304
279
  case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
305
- /* fall-through */
280
+ ZSTD_FALLTHROUGH;
306
281
 
307
282
  case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
308
- /* fall-through */
283
+ ZSTD_FALLTHROUGH;
309
284
 
310
285
  case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
311
- /* fall-through */
286
+ ZSTD_FALLTHROUGH;
312
287
 
313
288
  default: break;
314
289
  }
315
290
  { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
316
- bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
291
+ bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0;
317
292
  if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */
318
293
  }
319
294
  bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
@@ -332,16 +307,15 @@ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 c
332
307
  U32 const regMask = sizeof(bitContainer)*8 - 1;
333
308
  /* if start > regMask, bitstream is corrupted, and result is undefined */
334
309
  assert(nbBits < BIT_MASK_SIZE);
335
- return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
336
- }
337
-
338
- MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
339
- {
340
- #if defined(STATIC_BMI2) && STATIC_BMI2 == 1
341
- return _bzhi_u64(bitContainer, nbBits);
310
+ /* x86 transform & ((1 << nbBits) - 1) to bzhi instruction, it is better
311
+ * than accessing memory. When bmi2 instruction is not present, we consider
312
+ * such cpus old (pre-Haswell, 2013) and their performance is not of that
313
+ * importance.
314
+ */
315
+ #if defined(__x86_64__) || defined(_M_X86)
316
+ return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1);
342
317
  #else
343
- assert(nbBits < BIT_MASK_SIZE);
344
- return bitContainer & BIT_mask[nbBits];
318
+ return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
345
319
  #endif
346
320
  }
347
321
 
@@ -391,7 +365,7 @@ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_readBits(BIT_DStream_t* bitD, unsigned n
391
365
  }
392
366
 
393
367
  /*! BIT_readBitsFast() :
394
- * unsafe version; only works only if nbBits >= 1 */
368
+ * unsafe version; only works if nbBits >= 1 */
395
369
  MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
396
370
  {
397
371
  size_t const value = BIT_lookBitsFast(bitD, nbBits);
@@ -422,7 +396,7 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD)
422
396
  * This function is safe, it guarantees it will not read beyond src buffer.
423
397
  * @return : status of `BIT_DStream_t` internal register.
424
398
  * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */
425
- MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
399
+ MEM_STATIC FORCE_INLINE_ATTR BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
426
400
  {
427
401
  if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */
428
402
  return BIT_DStream_overflow;
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -11,6 +11,8 @@
11
11
  #ifndef ZSTD_COMPILER_H
12
12
  #define ZSTD_COMPILER_H
13
13
 
14
+ #include "portability_macros.h"
15
+
14
16
  /*-*******************************************************
15
17
  * Compiler specifics
16
18
  *********************************************************/
@@ -40,7 +42,7 @@
40
42
 
41
43
  /**
42
44
  On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC).
43
- This explictly marks such functions as __cdecl so that the code will still compile
45
+ This explicitly marks such functions as __cdecl so that the code will still compile
44
46
  if a CC other than __cdecl has been made the default.
45
47
  */
46
48
  #if defined(_MSC_VER)
@@ -90,30 +92,19 @@
90
92
  # endif
91
93
  #endif
92
94
 
95
+
93
96
  /* target attribute */
94
- #ifndef __has_attribute
95
- #define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
96
- #endif
97
97
  #if defined(__GNUC__) || defined(__ICCARM__)
98
98
  # define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
99
99
  #else
100
100
  # define TARGET_ATTRIBUTE(target)
101
101
  #endif
102
102
 
103
- /* Enable runtime BMI2 dispatch based on the CPU.
104
- * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.
103
+ /* Target attribute for BMI2 dynamic dispatch.
104
+ * Enable lzcnt, bmi, and bmi2.
105
+ * We test for bmi1 & bmi2. lzcnt is included in bmi1.
105
106
  */
106
- #ifndef DYNAMIC_BMI2
107
- #if ((defined(__clang__) && __has_attribute(__target__)) \
108
- || (defined(__GNUC__) \
109
- && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \
110
- && (defined(__x86_64__) || defined(_M_X86)) \
111
- && !defined(__BMI2__)
112
- # define DYNAMIC_BMI2 1
113
- #else
114
- # define DYNAMIC_BMI2 0
115
- #endif
116
- #endif
107
+ #define BMI2_TARGET_ATTRIBUTE TARGET_ATTRIBUTE("lzcnt,bmi,bmi2")
117
108
 
118
109
  /* prefetch
119
110
  * can be disabled, by declaring NO_PREFETCH build macro */
@@ -149,8 +140,9 @@
149
140
  }
150
141
 
151
142
  /* vectorization
152
- * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax */
153
- #if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__)
143
+ * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax,
144
+ * and some compilers, like Intel ICC and MCST LCC, do not support it at all. */
145
+ #if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && !defined(__LCC__)
154
146
  # if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5)
155
147
  # define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
156
148
  # else
@@ -173,6 +165,12 @@
173
165
  #define UNLIKELY(x) (x)
174
166
  #endif
175
167
 
168
+ #if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)))
169
+ # define ZSTD_UNREACHABLE { assert(0), __builtin_unreachable(); }
170
+ #else
171
+ # define ZSTD_UNREACHABLE { assert(0); }
172
+ #endif
173
+
176
174
  /* disable warnings */
177
175
  #ifdef _MSC_VER /* Visual Studio */
178
176
  # include <intrin.h> /* For Visual 2005 */
@@ -189,6 +187,8 @@
189
187
  # ifdef __AVX2__ //MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2
190
188
  # define STATIC_BMI2 1
191
189
  # endif
190
+ # elif defined(__BMI2__) && defined(__x86_64__) && defined(__GNUC__)
191
+ # define STATIC_BMI2 1
192
192
  # endif
193
193
  #endif
194
194
 
@@ -196,26 +196,103 @@
196
196
  #define STATIC_BMI2 0
197
197
  #endif
198
198
 
199
- /* compat. with non-clang compilers */
200
- #ifndef __has_builtin
201
- # define __has_builtin(x) 0
199
+ /* compile time determination of SIMD support */
200
+ #if !defined(ZSTD_NO_INTRINSICS)
201
+ # if defined(__SSE2__) || defined(_M_AMD64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
202
+ # define ZSTD_ARCH_X86_SSE2
203
+ # endif
204
+ # if defined(__ARM_NEON) || defined(_M_ARM64)
205
+ # define ZSTD_ARCH_ARM_NEON
206
+ # endif
207
+ #
208
+ # if defined(ZSTD_ARCH_X86_SSE2)
209
+ # include <emmintrin.h>
210
+ # elif defined(ZSTD_ARCH_ARM_NEON)
211
+ # include <arm_neon.h>
212
+ # endif
202
213
  #endif
203
214
 
204
- /* compat. with non-clang compilers */
205
- #ifndef __has_feature
206
- # define __has_feature(x) 0
215
+ /* C-language Attributes are added in C23. */
216
+ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
217
+ # define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
218
+ #else
219
+ # define ZSTD_HAS_C_ATTRIBUTE(x) 0
207
220
  #endif
208
221
 
209
- /* detects whether we are being compiled under msan */
210
- #ifndef ZSTD_MEMORY_SANITIZER
211
- # if __has_feature(memory_sanitizer)
212
- # define ZSTD_MEMORY_SANITIZER 1
213
- # else
214
- # define ZSTD_MEMORY_SANITIZER 0
215
- # endif
222
+ /* Only use C++ attributes in C++. Some compilers report support for C++
223
+ * attributes when compiling with C.
224
+ */
225
+ #if defined(__cplusplus) && defined(__has_cpp_attribute)
226
+ # define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
227
+ #else
228
+ # define ZSTD_HAS_CPP_ATTRIBUTE(x) 0
216
229
  #endif
217
230
 
218
- #if ZSTD_MEMORY_SANITIZER
231
+ /* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute.
232
+ * - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough
233
+ * - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough
234
+ * - Else: __attribute__((__fallthrough__))
235
+ */
236
+ #ifndef ZSTD_FALLTHROUGH
237
+ # if ZSTD_HAS_C_ATTRIBUTE(fallthrough)
238
+ # define ZSTD_FALLTHROUGH [[fallthrough]]
239
+ # elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough)
240
+ # define ZSTD_FALLTHROUGH [[fallthrough]]
241
+ # elif __has_attribute(__fallthrough__)
242
+ /* Leading semicolon is to satisfy gcc-11 with -pedantic. Without the semicolon
243
+ * gcc complains about: a label can only be part of a statement and a declaration is not a statement.
244
+ */
245
+ # define ZSTD_FALLTHROUGH ; __attribute__((__fallthrough__))
246
+ # else
247
+ # define ZSTD_FALLTHROUGH
248
+ # endif
249
+ #endif
250
+
251
+ /*-**************************************************************
252
+ * Alignment check
253
+ *****************************************************************/
254
+
255
+ /* this test was initially positioned in mem.h,
256
+ * but this file is removed (or replaced) for linux kernel
257
+ * so it's now hosted in compiler.h,
258
+ * which remains valid for both user & kernel spaces.
259
+ */
260
+
261
+ #ifndef ZSTD_ALIGNOF
262
+ # if defined(__GNUC__) || defined(_MSC_VER)
263
+ /* covers gcc, clang & MSVC */
264
+ /* note : this section must come first, before C11,
265
+ * due to a limitation in the kernel source generator */
266
+ # define ZSTD_ALIGNOF(T) __alignof(T)
267
+
268
+ # elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
269
+ /* C11 support */
270
+ # include <stdalign.h>
271
+ # define ZSTD_ALIGNOF(T) alignof(T)
272
+
273
+ # else
274
+ /* No known support for alignof() - imperfect backup */
275
+ # define ZSTD_ALIGNOF(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T))
276
+
277
+ # endif
278
+ #endif /* ZSTD_ALIGNOF */
279
+
280
+ /*-**************************************************************
281
+ * Sanitizer
282
+ *****************************************************************/
283
+
284
+ /* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an
285
+ * abundance of caution, disable our custom poisoning on mingw. */
286
+ #ifdef __MINGW32__
287
+ #ifndef ZSTD_ASAN_DONT_POISON_WORKSPACE
288
+ #define ZSTD_ASAN_DONT_POISON_WORKSPACE 1
289
+ #endif
290
+ #ifndef ZSTD_MSAN_DONT_POISON_WORKSPACE
291
+ #define ZSTD_MSAN_DONT_POISON_WORKSPACE 1
292
+ #endif
293
+ #endif
294
+
295
+ #if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE)
219
296
  /* Not all platforms that support msan provide sanitizers/msan_interface.h.
220
297
  * We therefore declare the functions we need ourselves, rather than trying to
221
298
  * include the header file... */
@@ -234,20 +311,13 @@ void __msan_poison(const volatile void *a, size_t size);
234
311
  /* Returns the offset of the first (at least partially) poisoned byte in the
235
312
  memory range, or -1 if the whole range is good. */
236
313
  intptr_t __msan_test_shadow(const volatile void *x, size_t size);
237
- #endif
238
314
 
239
- /* detects whether we are being compiled under asan */
240
- #ifndef ZSTD_ADDRESS_SANITIZER
241
- # if __has_feature(address_sanitizer)
242
- # define ZSTD_ADDRESS_SANITIZER 1
243
- # elif defined(__SANITIZE_ADDRESS__)
244
- # define ZSTD_ADDRESS_SANITIZER 1
245
- # else
246
- # define ZSTD_ADDRESS_SANITIZER 0
247
- # endif
315
+ /* Print shadow and origin for the memory range to stderr in a human-readable
316
+ format. */
317
+ void __msan_print_shadow(const volatile void *x, size_t size);
248
318
  #endif
249
319
 
250
- #if ZSTD_ADDRESS_SANITIZER
320
+ #if ZSTD_ADDRESS_SANITIZER && !defined(ZSTD_ASAN_DONT_POISON_WORKSPACE)
251
321
  /* Not all platforms that support asan provide sanitizers/asan_interface.h.
252
322
  * We therefore declare the functions we need ourselves, rather than trying to
253
323
  * include the header file... */
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2018-2020, Facebook, Inc.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -1,7 +1,7 @@
1
1
  /* ******************************************************************
2
2
  * debug
3
3
  * Part of FSE library
4
- * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
6
6
  * You can contact the author at :
7
7
  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -1,7 +1,7 @@
1
1
  /* ******************************************************************
2
2
  * debug
3
3
  * Part of FSE library
4
- * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
6
6
  * You can contact the author at :
7
7
  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy