PostgreSQL Source Code git master
simd.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define USE_NO_SIMD
 

Typedefs

typedef uint64 Vector8
 

Functions

static void vector8_load (Vector8 *v, const uint8 *s)
 
static Vector8 vector8_broadcast (const uint8 c)
 
static bool vector8_has (const Vector8 v, const uint8 c)
 
static bool vector8_has_zero (const Vector8 v)
 
static bool vector8_has_le (const Vector8 v, const uint8 c)
 
static bool vector8_is_highbit_set (const Vector8 v)
 
static Vector8 vector8_or (const Vector8 v1, const Vector8 v2)
 

Macro Definition Documentation

◆ USE_NO_SIMD

#define USE_NO_SIMD

Definition at line 59 of file simd.h.

Typedef Documentation

◆ Vector8

typedef uint64 Vector8

Definition at line 60 of file simd.h.

Function Documentation

◆ vector8_broadcast()

static Vector8 vector8_broadcast ( const uint8  c)
inlinestatic

Definition at line 149 of file simd.h.

150{
151#if defined(USE_SSE2)
152 return _mm_set1_epi8(c);
153#elif defined(USE_NEON)
154 return vdupq_n_u8(c);
155#else
156 return ~UINT64CONST(0) / 0xFF * c;
157#endif
158}
char * c

Referenced by hex_encode(), is_valid_ascii(), RT_NODE_16_GET_INSERTPOS(), RT_NODE_16_SEARCH_EQ(), vector8_has(), vector8_has_le(), and vector8_is_highbit_set().

◆ vector8_has()

static bool vector8_has ( const Vector8  v,
const uint8  c 
)
inlinestatic

Definition at line 176 of file simd.h.

177{
178 bool result;
179
180 /* pre-compute the result for assert checking */
181#ifdef USE_ASSERT_CHECKING
182 bool assert_result = false;
183
184 for (Size i = 0; i < sizeof(Vector8); i++)
185 {
186 if (((const uint8 *) &v)[i] == c)
187 {
188 assert_result = true;
189 break;
190 }
191 }
192#endif /* USE_ASSERT_CHECKING */
193
194#if defined(USE_NO_SIMD)
195 /* any bytes in v equal to c will evaluate to zero via XOR */
196 result = vector8_has_zero(v ^ vector8_broadcast(c));
197#else
198 result = vector8_is_highbit_set(vector8_eq(v, vector8_broadcast(c)));
199#endif
200
201 Assert(assert_result == result);
202 return result;
203}
uint8_t uint8
Definition: c.h:539
size_t Size
Definition: c.h:613
Assert(PointerIsAligned(start, uint64))
int i
Definition: isn.c:77
static Vector8 vector8_broadcast(const uint8 c)
Definition: simd.h:149
static bool vector8_has_zero(const Vector8 v)
Definition: simd.h:209
uint64 Vector8
Definition: simd.h:60
static bool vector8_is_highbit_set(const Vector8 v)
Definition: simd.h:306

References Assert(), i, vector8_broadcast(), vector8_has_zero(), and vector8_is_highbit_set().

Referenced by escape_json_with_len(), pg_lfind8(), and vector8_has_zero().

◆ vector8_has_le()

static bool vector8_has_le ( const Vector8  v,
const uint8  c 
)
inlinestatic

Definition at line 227 of file simd.h.

228{
229 bool result = false;
230#ifdef USE_SSE2
231 Vector8 umin;
232 Vector8 cmpe;
233#endif
234
235 /* pre-compute the result for assert checking */
236#ifdef USE_ASSERT_CHECKING
237 bool assert_result = false;
238
239 for (Size i = 0; i < sizeof(Vector8); i++)
240 {
241 if (((const uint8 *) &v)[i] <= c)
242 {
243 assert_result = true;
244 break;
245 }
246 }
247#endif /* USE_ASSERT_CHECKING */
248
249#if defined(USE_NO_SIMD)
250
251 /*
252 * To find bytes <= c, we can use bitwise operations to find bytes < c+1,
253 * but it only works if c+1 <= 128 and if the highest bit in v is not set.
254 * Adapted from
255 * https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord
256 */
257 if ((int64) v >= 0 && c < 0x80)
258 result = (v - vector8_broadcast(c + 1)) & ~v & vector8_broadcast(0x80);
259 else
260 {
261 /* one byte at a time */
262 for (Size i = 0; i < sizeof(Vector8); i++)
263 {
264 if (((const uint8 *) &v)[i] <= c)
265 {
266 result = true;
267 break;
268 }
269 }
270 }
271#elif defined(USE_SSE2)
272 umin = vector8_min(v, vector8_broadcast(c));
273 cmpe = vector8_eq(umin, v);
274 result = vector8_is_highbit_set(cmpe);
275#elif defined(USE_NEON)
276 result = vminvq_u8(v) <= c;
277#endif
278
279 Assert(assert_result == result);
280 return result;
281}
int64_t int64
Definition: c.h:538

References Assert(), i, vector8_broadcast(), and vector8_is_highbit_set().

Referenced by escape_json_with_len(), pg_lfind8_le(), and vector8_has_zero().

◆ vector8_has_zero()

static bool vector8_has_zero ( const Vector8  v)
inlinestatic

Definition at line 209 of file simd.h.

210{
211#if defined(USE_NO_SIMD)
212 /*
213 * We cannot call vector8_has() here, because that would lead to a
214 * circular definition.
215 */
216 return vector8_has_le(v, 0);
217#else
218 return vector8_has(v, 0);
219#endif
220}
static bool vector8_has_le(const Vector8 v, const uint8 c)
Definition: simd.h:227
static bool vector8_has(const Vector8 v, const uint8 c)
Definition: simd.h:176

References vector8_has(), and vector8_has_le().

Referenced by vector8_has().

◆ vector8_is_highbit_set()

static bool vector8_is_highbit_set ( const Vector8  v)
inlinestatic

Definition at line 306 of file simd.h.

307{
308#ifdef USE_SSE2
309 return _mm_movemask_epi8(v) != 0;
310#elif defined(USE_NEON)
311 return vmaxvq_u8(v) > 0x7F;
312#else
313 return v & vector8_broadcast(0x80);
314#endif
315}

References vector8_broadcast().

Referenced by is_valid_ascii(), vector8_has(), and vector8_has_le().

◆ vector8_load()

static void vector8_load ( Vector8 v,
const uint8 s 
)
inlinestatic

Definition at line 107 of file simd.h.

108{
109#if defined(USE_SSE2)
110 *v = _mm_loadu_si128((const __m128i *) s);
111#elif defined(USE_NEON)
112 *v = vld1q_u8(s);
113#else
114 memcpy(v, s, sizeof(Vector8));
115#endif
116}

Referenced by escape_json_with_len(), hex_decode_safe(), hex_encode(), is_valid_ascii(), pg_lfind8(), pg_lfind8_le(), RT_NODE_16_GET_INSERTPOS(), and RT_NODE_16_SEARCH_EQ().

◆ vector8_or()

static Vector8 vector8_or ( const Vector8  v1,
const Vector8  v2 
)
inlinestatic

Definition at line 373 of file simd.h.

374{
375#ifdef USE_SSE2
376 return _mm_or_si128(v1, v2);
377#elif defined(USE_NEON)
378 return vorrq_u8(v1, v2);
379#else
380 return v1 | v2;
381#endif
382}

Referenced by is_valid_ascii().