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 135 of file simd.h.

136 {
137 #if defined(USE_SSE2)
138  return _mm_set1_epi8(c);
139 #elif defined(USE_NEON)
140  return vdupq_n_u8(c);
141 #else
142  return ~UINT64CONST(0) / 0xFF * c;
143 #endif
144 }
char * c

Referenced by 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 162 of file simd.h.

163 {
164  bool result;
165 
166  /* pre-compute the result for assert checking */
167 #ifdef USE_ASSERT_CHECKING
168  bool assert_result = false;
169 
170  for (Size i = 0; i < sizeof(Vector8); i++)
171  {
172  if (((const uint8 *) &v)[i] == c)
173  {
174  assert_result = true;
175  break;
176  }
177  }
178 #endif /* USE_ASSERT_CHECKING */
179 
180 #if defined(USE_NO_SIMD)
181  /* any bytes in v equal to c will evaluate to zero via XOR */
182  result = vector8_has_zero(v ^ vector8_broadcast(c));
183 #else
184  result = vector8_is_highbit_set(vector8_eq(v, vector8_broadcast(c)));
185 #endif
186 
187  Assert(assert_result == result);
188  return result;
189 }
#define Assert(condition)
Definition: c.h:863
unsigned char uint8
Definition: c.h:516
size_t Size
Definition: c.h:610
int i
Definition: isn.c:72
static Vector8 vector8_broadcast(const uint8 c)
Definition: simd.h:135
static bool vector8_has_zero(const Vector8 v)
Definition: simd.h:195
uint64 Vector8
Definition: simd.h:60
static bool vector8_is_highbit_set(const Vector8 v)
Definition: simd.h:271

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 213 of file simd.h.

214 {
215  bool result = false;
216 
217  /* pre-compute the result for assert checking */
218 #ifdef USE_ASSERT_CHECKING
219  bool assert_result = false;
220 
221  for (Size i = 0; i < sizeof(Vector8); i++)
222  {
223  if (((const uint8 *) &v)[i] <= c)
224  {
225  assert_result = true;
226  break;
227  }
228  }
229 #endif /* USE_ASSERT_CHECKING */
230 
231 #if defined(USE_NO_SIMD)
232 
233  /*
234  * To find bytes <= c, we can use bitwise operations to find bytes < c+1,
235  * but it only works if c+1 <= 128 and if the highest bit in v is not set.
236  * Adapted from
237  * https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord
238  */
239  if ((int64) v >= 0 && c < 0x80)
240  result = (v - vector8_broadcast(c + 1)) & ~v & vector8_broadcast(0x80);
241  else
242  {
243  /* one byte at a time */
244  for (Size i = 0; i < sizeof(Vector8); i++)
245  {
246  if (((const uint8 *) &v)[i] <= c)
247  {
248  result = true;
249  break;
250  }
251  }
252  }
253 #else
254 
255  /*
256  * Use saturating subtraction to find bytes <= c, which will present as
257  * NUL bytes. This approach is a workaround for the lack of unsigned
258  * comparison instructions on some architectures.
259  */
260  result = vector8_has_zero(vector8_ssub(v, vector8_broadcast(c)));
261 #endif
262 
263  Assert(assert_result == result);
264  return result;
265 }

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

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 195 of file simd.h.

196 {
197 #if defined(USE_NO_SIMD)
198  /*
199  * We cannot call vector8_has() here, because that would lead to a
200  * circular definition.
201  */
202  return vector8_has_le(v, 0);
203 #else
204  return vector8_has(v, 0);
205 #endif
206 }
static bool vector8_has_le(const Vector8 v, const uint8 c)
Definition: simd.h:213
static bool vector8_has(const Vector8 v, const uint8 c)
Definition: simd.h:162

References vector8_has(), and vector8_has_le().

Referenced by vector8_has(), and vector8_has_le().

◆ vector8_is_highbit_set()

static bool vector8_is_highbit_set ( const Vector8  v)
inlinestatic

Definition at line 271 of file simd.h.

272 {
273 #ifdef USE_SSE2
274  return _mm_movemask_epi8(v) != 0;
275 #elif defined(USE_NEON)
276  return vmaxvq_u8(v) > 0x7F;
277 #else
278  return v & vector8_broadcast(0x80);
279 #endif
280 }

References vector8_broadcast().

Referenced by is_valid_ascii(), and vector8_has().

◆ vector8_load()

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

Definition at line 108 of file simd.h.

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

Referenced by escape_json_with_len(), 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 338 of file simd.h.

339 {
340 #ifdef USE_SSE2
341  return _mm_or_si128(v1, v2);
342 #elif defined(USE_NEON)
343  return vorrq_u8(v1, v2);
344 #else
345  return v1 | v2;
346 #endif
347 }

Referenced by is_valid_ascii().