PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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:540
size_t Size
Definition: c.h:614
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:539

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().