OpenJPH
Open-source implementation of JPEG2000 Part-15
Loading...
Searching...
No Matches
ojph_simd_vsx.h
Go to the documentation of this file.
1//***************************************************************************/
2// This software is released under the 2-Clause BSD license, included
3// below.
4//
5// Copyright (c) 2026, Aous Naman
6// Copyright (c) 2026, Kakadu Software Pty Ltd, Australia
7// Copyright (c) 2026, The University of New South Wales, Australia
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are
11// met:
12//
13// 1. Redistributions of source code must retain the above copyright
14// notice, this list of conditions and the following disclaimer.
15//
16// 2. Redistributions in binary form must reproduce the above copyright
17// notice, this list of conditions and the following disclaimer in the
18// documentation and/or other materials provided with the distribution.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31//***************************************************************************/
32// This file is part of the OpenJPH software implementation.
33// File: ojph_simd_vsx.h
34//
35// 128-bit SIMD helpers for POWER VSX, used by the ojph_*_vsx.cpp
36// kernels. Lane numbering and operation semantics follow the same
37// conventions as the other 128-bit kernels in this codebase (lane 0
38// is the lowest memory address). Supported targets are POWER8
39// (ISA 2.07) and newer, little-endian only (ppc64le). Everything
40// here is expressible at the ISA 2.07 baseline; the one newer
41// instruction used, vec_extractm (ISA 3.1), is guarded and has an
42// ISA 2.07 fallback.
43//***************************************************************************/
44
45#ifndef OJPH_SIMD_VSX_H
46#define OJPH_SIMD_VSX_H
47
48#if !defined(__powerpc64__) && !defined(__PPC64__)
49 #error "this header is for 64-bit POWER targets only"
50#endif
51#if !defined(__LITTLE_ENDIAN__) && \
52 !(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
53 #error "this header assumes a little-endian target (ppc64le)"
54#endif
55
56#include <altivec.h>
57#include <cstring>
58
59#include "ojph_defs.h"
60
61// altivec.h leaks these context-sensitive keywords as macros under GNU C;
62// they break standard headers and the codebase (e.g. std::vector)
63#undef vector
64#undef pixel
65#undef bool
66
67typedef __vector unsigned char v128_t;
68
69typedef __vector signed char vsx_v_i8;
70typedef __vector unsigned char vsx_v_u8;
71typedef __vector signed short vsx_v_i16;
72typedef __vector unsigned short vsx_v_u16;
73typedef __vector signed int vsx_v_i32;
74typedef __vector unsigned int vsx_v_u32;
75typedef __vector signed long long vsx_v_i64;
76typedef __vector unsigned long long vsx_v_u64;
77typedef __vector float vsx_v_f32;
78
79//---------------------------------------------------------------------------
80// load/store (alignment-agnostic; lxv/stxv handle unaligned addresses)
81//---------------------------------------------------------------------------
82static inline v128_t vsx_v128_load(const void *p)
83{ return vec_xl(0, (const unsigned char *)p); }
84
85static inline void vsx_v128_store(void *p, v128_t a)
86{ vec_xst(a, 0, (unsigned char *)p); }
87
88#define vsx_v128_store32_lane(p, a, i) \
89 do { vsx_v_i32 t_ = (vsx_v_i32)(a); int v_ = t_[(i)]; \
90 std::memcpy((p), &v_, 4); } while (0)
91
92//---------------------------------------------------------------------------
93// constants, splats, makes
94//---------------------------------------------------------------------------
95// functions, not macros, so that an argument that is itself a macro
96// expanding to an argument list (e.g. OJPH_REPEAT4) works
97static inline v128_t vsx_i8x16_const(
98 signed char c0, signed char c1, signed char c2, signed char c3,
99 signed char c4, signed char c5, signed char c6, signed char c7,
100 signed char c8, signed char c9, signed char c10, signed char c11,
101 signed char c12, signed char c13, signed char c14, signed char c15)
102{ vsx_v_i8 v = {c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15};
103 return (v128_t)v; }
104static inline v128_t vsx_i16x8_const(short c0, short c1, short c2,
105 short c3, short c4, short c5,
106 short c6, short c7)
107{ vsx_v_i16 v = {c0,c1,c2,c3,c4,c5,c6,c7}; return (v128_t)v; }
108static inline v128_t vsx_u16x8_const(unsigned short c0, unsigned short c1,
109 unsigned short c2, unsigned short c3,
110 unsigned short c4, unsigned short c5,
111 unsigned short c6, unsigned short c7)
112{ vsx_v_u16 v = {c0,c1,c2,c3,c4,c5,c6,c7}; return (v128_t)v; }
113static inline v128_t vsx_i32x4_const(int c0, int c1, int c2, int c3)
114{ vsx_v_i32 v = {c0,c1,c2,c3}; return (v128_t)v; }
115static inline v128_t vsx_u32x4_const(unsigned int c0, unsigned int c1,
116 unsigned int c2, unsigned int c3)
117{ vsx_v_u32 v = {c0,c1,c2,c3}; return (v128_t)v; }
118static inline v128_t vsx_i64x2_const(long long c0, long long c1)
119{ vsx_v_i64 v = {c0,c1}; return (v128_t)v; }
120static inline v128_t vsx_u64x2_const(unsigned long long c0,
121 unsigned long long c1)
122{ vsx_v_u64 v = {c0,c1}; return (v128_t)v; }
123
124static inline v128_t vsx_i8x16_splat(signed char x)
125{ ojph_unused(x); return (v128_t)vec_splats(x); }
126static inline v128_t vsx_i16x8_splat(short x)
127{ ojph_unused(x); return (v128_t)vec_splats(x); }
128static inline v128_t vsx_i32x4_splat(int x)
129{ ojph_unused(x); return (v128_t)vec_splats(x); }
130static inline v128_t vsx_u32x4_splat(unsigned int x)
131{ ojph_unused(x); return (v128_t)vec_splats(x); }
132static inline v128_t vsx_i64x2_splat(long long x)
133{ ojph_unused(x); return (v128_t)vec_splats((signed long long)x); }
134static inline v128_t vsx_f32x4_splat(float x)
135{ ojph_unused(x); return (v128_t)vec_splats(x); }
136
137static inline v128_t vsx_i32x4_make(int a, int b, int c, int d)
138{ return (v128_t)(vsx_v_i32){a, b, c, d}; }
139
140//---------------------------------------------------------------------------
141// lane extraction (subscript is little-endian lane order)
142//---------------------------------------------------------------------------
143#define vsx_u8x16_extract_lane(a, i) (((vsx_v_u8)(a))[(i)])
144#define vsx_u16x8_extract_lane(a, i) (((vsx_v_u16)(a))[(i)])
145#define vsx_i32x4_extract_lane(a, i) (((vsx_v_i32)(a))[(i)])
146#define vsx_u32x4_extract_lane(a, i) (((vsx_v_u32)(a))[(i)])
147#define vsx_i64x2_extract_lane(a, i) (((vsx_v_i64)(a))[(i)])
148
149//---------------------------------------------------------------------------
150// bitwise
151//---------------------------------------------------------------------------
152static inline v128_t vsx_v128_and(v128_t a, v128_t b)
153{ return vec_and(a, b); }
154static inline v128_t vsx_v128_or(v128_t a, v128_t b)
155{ return vec_or(a, b); }
156static inline v128_t vsx_v128_xor(v128_t a, v128_t b)
157{ return vec_xor(a, b); }
158// a & ~b (same operand order as vec_andc)
160{ return vec_andc(a, b); }
161
162//---------------------------------------------------------------------------
163// integer arithmetic
164//---------------------------------------------------------------------------
166{ return (v128_t)vec_add((vsx_v_i8)a, (vsx_v_i8)b); }
168{ return (v128_t)vec_add((vsx_v_i16)a, (vsx_v_i16)b); }
170{ return (v128_t)vec_add((vsx_v_i32)a, (vsx_v_i32)b); }
172{ return (v128_t)vec_add((vsx_v_i64)a, (vsx_v_i64)b); }
173
175{ return (v128_t)vec_sub((vsx_v_i16)a, (vsx_v_i16)b); }
177{ return (v128_t)vec_sub((vsx_v_i32)a, (vsx_v_i32)b); }
179{ return (v128_t)vec_sub((vsx_v_i64)a, (vsx_v_i64)b); }
180
181// low half of products; vmladduhm / vmuluwm; i64x2 is lowered by the
182// compiler (mulld on ISA 3.0, vmulld on ISA 3.1)
184{ return (v128_t)((vsx_v_i16)a * (vsx_v_i16)b); }
186{ return (v128_t)((vsx_v_i32)a * (vsx_v_i32)b); }
188{ return (v128_t)((vsx_v_i64)a * (vsx_v_i64)b); }
189
191{ return (v128_t)vec_abs((vsx_v_i8)a); }
193{ return (v128_t)vec_min((vsx_v_u8)a, (vsx_v_u8)b); }
195{ return (v128_t)vec_max((vsx_v_i16)a, (vsx_v_i16)b); }
196
197//---------------------------------------------------------------------------
198// shifts (scalar count, modulo lane width)
199//---------------------------------------------------------------------------
200static inline v128_t vsx_i16x8_shl(v128_t a, int n)
201{ return (v128_t)vec_sl((vsx_v_i16)a, vec_splats((unsigned short)n)); }
202static inline v128_t vsx_i32x4_shl(v128_t a, int n)
203{ return (v128_t)vec_sl((vsx_v_i32)a, vec_splats((unsigned int)n)); }
204static inline v128_t vsx_i64x2_shl(v128_t a, int n)
205{ return (v128_t)vec_sl((vsx_v_i64)a,
206 vec_splats((unsigned long long)n)); }
207
208static inline v128_t vsx_i32x4_shr(v128_t a, int n) // arithmetic
209{ return (v128_t)vec_sra((vsx_v_i32)a, vec_splats((unsigned int)n)); }
210static inline v128_t vsx_i64x2_shr(v128_t a, int n) // arithmetic
211{ return (v128_t)vec_sra((vsx_v_i64)a,
212 vec_splats((unsigned long long)n)); }
213
214static inline v128_t vsx_u16x8_shr(v128_t a, int n) // logical
215{ return (v128_t)vec_sr((vsx_v_u16)a, vec_splats((unsigned short)n)); }
216static inline v128_t vsx_u32x4_shr(v128_t a, int n) // logical
217{ return (v128_t)vec_sr((vsx_v_u32)a, vec_splats((unsigned int)n)); }
218static inline v128_t vsx_u64x2_shr(v128_t a, int n) // logical
219{ return (v128_t)vec_sr((vsx_v_u64)a,
220 vec_splats((unsigned long long)n)); }
221
222//---------------------------------------------------------------------------
223// comparisons (true lanes -> all-ones, false lanes -> all-zeros)
224//---------------------------------------------------------------------------
225static inline v128_t vsx_i8x16_eq(v128_t a, v128_t b)
226{ return (v128_t)vec_cmpeq((vsx_v_i8)a, (vsx_v_i8)b); }
227static inline v128_t vsx_i16x8_eq(v128_t a, v128_t b)
228{ return (v128_t)vec_cmpeq((vsx_v_i16)a, (vsx_v_i16)b); }
229static inline v128_t vsx_i32x4_eq(v128_t a, v128_t b)
230{ return (v128_t)vec_cmpeq((vsx_v_i32)a, (vsx_v_i32)b); }
231
232static inline v128_t vsx_i8x16_gt(v128_t a, v128_t b)
233{ return (v128_t)vec_cmpgt((vsx_v_i8)a, (vsx_v_i8)b); }
234static inline v128_t vsx_i32x4_gt(v128_t a, v128_t b)
235{ return (v128_t)vec_cmpgt((vsx_v_i32)a, (vsx_v_i32)b); }
236static inline v128_t vsx_i32x4_lt(v128_t a, v128_t b)
237{ return (v128_t)vec_cmplt((vsx_v_i32)a, (vsx_v_i32)b); }
238static inline v128_t vsx_i64x2_lt(v128_t a, v128_t b)
239{ return (v128_t)vec_cmplt((vsx_v_i64)a, (vsx_v_i64)b); }
240
241static inline v128_t vsx_f32x4_ge(v128_t a, v128_t b)
242{ return (v128_t)vec_cmpge((vsx_v_f32)a, (vsx_v_f32)b); }
243static inline v128_t vsx_f32x4_lt(v128_t a, v128_t b)
244{ return (v128_t)vec_cmplt((vsx_v_f32)a, (vsx_v_f32)b); }
245
246//---------------------------------------------------------------------------
247// float arithmetic and conversions
248//---------------------------------------------------------------------------
250{ return (v128_t)vec_add((vsx_v_f32)a, (vsx_v_f32)b); }
252{ return (v128_t)vec_sub((vsx_v_f32)a, (vsx_v_f32)b); }
254{ return (v128_t)vec_mul((vsx_v_f32)a, (vsx_v_f32)b); }
255
256// xvcvspsxws: truncating, saturating (NaN gives 0x80000000; the
257// callers never pass NaN)
259{ return (v128_t)vec_cts((vsx_v_f32)a, 0); }
261{ return (v128_t)vec_ctf((vsx_v_i32)a, 0); }
262
263//---------------------------------------------------------------------------
264// widening
265//---------------------------------------------------------------------------
267{
268 // vsx_v_i32 v = (vsx_v_i32)a;
269 // return (v128_t)__builtin_convertvector(
270 // __builtin_shufflevector(v, v, 0, 1), vsx_v_i64);
271
272 // vec_unpackh's "high" half is the one holding elements 0 and 1; the
273 // compiler keeps that mapping on both endiannesses, so this sign-extends
274 // elements 0 and 1.
275 return (v128_t)vec_unpackh((vsx_v_i32)a);
276}
278{
279 // vsx_v_i32 v = (vsx_v_i32)a;
280 // return (v128_t)__builtin_convertvector(
281 // __builtin_shufflevector(v, v, 2, 3), vsx_v_i64);
282
283 // vec_unpackl's "low" half is the one holding elements 2 and 3; the
284 // compiler keeps that mapping on both endiannesses, so this sign-extends
285 // elements 2 and 3.
286 return (v128_t)vec_unpackl((vsx_v_i32)a);
287}
288
289//---------------------------------------------------------------------------
290// shuffles (immediate lane indices; 0..N-1 from a, N..2N-1 from b)
291//---------------------------------------------------------------------------
292// #define vsx_i8x16_shuffle(a, b, c0,c1,c2,c3,c4,c5,c6,c7,
293// c8,c9,c10,c11,c12,c13,c14,c15)
294// ((v128_t)__builtin_shufflevector((vsx_v_u8)(a), (vsx_v_u8)(b),
295// c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15))
296// #define vsx_i16x8_shuffle(a, b, c0,c1,c2,c3,c4,c5,c6,c7)
297// ((v128_t)__builtin_shufflevector((vsx_v_i16)(a), (vsx_v_i16)(b),
298// c0,c1,c2,c3,c4,c5,c6,c7))
299// #define vsx_i32x4_shuffle(a, b, c0,c1,c2,c3)
300// ((v128_t)__builtin_shufflevector((vsx_v_i32)(a), (vsx_v_i32)(b),
301// c0,c1,c2,c3))
302// #define vsx_i64x2_shuffle(a, b, c0,c1)
303// ((v128_t)__builtin_shufflevector((vsx_v_i64)(a), (vsx_v_i64)(b), c0,c1))
304
305// 8-bit Shuffle (Maps direct element indices to raw byte indices)
306#define vsx_i8x16_shuffle(a, b, c0,c1,c2,c3,c4,c5,c6,c7, \
307 c8,c9,c10,c11,c12,c13,c14,c15) \
308 ((v128_t)vec_perm((vsx_v_u8)(a), (vsx_v_u8)(b), (vsx_v_u8){ \
309 (c0), (c1), (c2), (c3), (c4), (c5), (c6), (c7), \
310 (c8), (c9), (c10),(c11),(c12),(c13),(c14),(c15) \
311 }))
312
313// 16-bit Shuffle (Multiplies element index by 2 to get byte offsets)
314#define vsx_i16x8_shuffle(a, b, c0,c1,c2,c3,c4,c5,c6,c7) \
315 ((v128_t)vec_perm((vsx_v_u8)(a), (vsx_v_u8)(b), (vsx_v_u8){ \
316 (c0)*2, (c0)*2+1, (c1)*2, (c1)*2+1, \
317 (c2)*2, (c2)*2+1, (c3)*2, (c3)*2+1, \
318 (c4)*2, (c4)*2+1, (c5)*2, (c5)*2+1, \
319 (c6)*2, (c6)*2+1, (c7)*2, (c7)*2+1 \
320 }))
321
322// 32-bit Shuffle (Multiplies element index by 4 to get byte offsets)
323#define vsx_i32x4_shuffle(a, b, c0,c1,c2,c3) \
324 ((v128_t)vec_perm((vsx_v_u8)(a), (vsx_v_u8)(b), (vsx_v_u8){ \
325 (c0)*4, (c0)*4+1, (c0)*4+2, (c0)*4+3, \
326 (c1)*4, (c1)*4+1, (c1)*4+2, (c1)*4+3, \
327 (c2)*4, (c2)*4+1, (c2)*4+2, (c2)*4+3, \
328 (c3)*4, (c3)*4+1, (c3)*4+2, (c3)*4+3 \
329 }))
330
331// 64-bit Shuffle (Multiplies element index by 8 to get byte offsets)
332#define vsx_i64x2_shuffle(a, b, c0,c1) \
333 ((v128_t)vec_perm((vsx_v_u8)(a), (vsx_v_u8)(b), (vsx_v_u8){ \
334 (c0)*8, (c0)*8+1, (c0)*8+2, (c0)*8+3, \
335 (c0)*8+4, (c0)*8+5, (c0)*8+6, (c0)*8+7, \
336 (c1)*8, (c1)*8+1, (c1)*8+2, (c1)*8+3, \
337 (c1)*8+4, (c1)*8+5, (c1)*8+6, (c1)*8+7 \
338 }))
339
340//---------------------------------------------------------------------------
341// swizzle: runtime byte-table lookup; lanes with index > 15 give 0
342//---------------------------------------------------------------------------
344{
345 v128_t r = vec_perm(a, a, idx);
346 v128_t oob = (v128_t)vec_cmpgt((vsx_v_u8)idx,
347 vec_splats((unsigned char)15));
348 return vec_andc(r, oob);
349}
350
351//---------------------------------------------------------------------------
352// bitmask: MSB of each byte lane -> bit of result, lane 0 -> bit 0
353// (vbpermq gathers the 16 selected bits into bits 48..63 of the
354// big-endian first doubleword, which is doubleword 1 on ppc64le)
355//---------------------------------------------------------------------------
356static inline int vsx_i8x16_bitmask(v128_t a)
357{
358#if defined(__POWER10_VECTOR__)
359 return (int)vec_extractm(a); // ISA 3.1 native movemask
360#else
361 const vsx_v_u8 perm = { 120, 112, 104, 96, 88, 80, 72, 64,
362 56, 48, 40, 32, 24, 16, 8, 0 };
363 vsx_v_u64 r = (vsx_v_u64)vec_bperm(a, perm);
364 return (int)r[1];
365#endif
366}
367
368#endif // OJPH_SIMD_VSX_H
#define ojph_unused(x)
Definition ojph_defs.h:78
static v128_t vsx_i8x16_splat(signed char x)
__vector unsigned int vsx_v_u32
static v128_t vsx_i32x4_sub(v128_t a, v128_t b)
static v128_t vsx_i32x4_make(int a, int b, int c, int d)
static v128_t vsx_i16x8_sub(v128_t a, v128_t b)
static v128_t vsx_u16x8_shr(v128_t a, int n)
static v128_t vsx_f32x4_mul(v128_t a, v128_t b)
static int vsx_i8x16_bitmask(v128_t a)
__vector signed int vsx_v_i32
static v128_t vsx_i8x16_swizzle(v128_t a, v128_t idx)
static v128_t vsx_f32x4_sub(v128_t a, v128_t b)
static v128_t vsx_i8x16_const(signed char c0, signed char c1, signed char c2, signed char c3, signed char c4, signed char c5, signed char c6, signed char c7, signed char c8, signed char c9, signed char c10, signed char c11, signed char c12, signed char c13, signed char c14, signed char c15)
static v128_t vsx_i64x2_lt(v128_t a, v128_t b)
static v128_t vsx_f32x4_convert_i32x4(v128_t a)
static v128_t vsx_f32x4_add(v128_t a, v128_t b)
__vector float vsx_v_f32
static v128_t vsx_v128_xor(v128_t a, v128_t b)
__vector signed char vsx_v_i8
static v128_t vsx_i16x8_mul(v128_t a, v128_t b)
static v128_t vsx_u32x4_shr(v128_t a, int n)
__vector signed long long vsx_v_i64
static v128_t vsx_i16x8_splat(short x)
static v128_t vsx_u32x4_const(unsigned int c0, unsigned int c1, unsigned int c2, unsigned int c3)
static v128_t vsx_i32x4_const(int c0, int c1, int c2, int c3)
static v128_t vsx_u8x16_min(v128_t a, v128_t b)
static v128_t vsx_f32x4_ge(v128_t a, v128_t b)
static v128_t vsx_i64x2_extend_high_i32x4(v128_t a)
static v128_t vsx_f32x4_splat(float x)
__vector signed short vsx_v_i16
static v128_t vsx_u64x2_const(unsigned long long c0, unsigned long long c1)
static v128_t vsx_i32x4_shl(v128_t a, int n)
static v128_t vsx_i16x8_max(v128_t a, v128_t b)
static v128_t vsx_i64x2_const(long long c0, long long c1)
static v128_t vsx_i8x16_abs(v128_t a)
static v128_t vsx_i32x4_add(v128_t a, v128_t b)
static v128_t vsx_f32x4_lt(v128_t a, v128_t b)
static v128_t vsx_i64x2_extend_low_i32x4(v128_t a)
__vector unsigned char v128_t
__vector unsigned char vsx_v_u8
static v128_t vsx_i8x16_add(v128_t a, v128_t b)
static v128_t vsx_u16x8_const(unsigned short c0, unsigned short c1, unsigned short c2, unsigned short c3, unsigned short c4, unsigned short c5, unsigned short c6, unsigned short c7)
static v128_t vsx_i16x8_add(v128_t a, v128_t b)
static v128_t vsx_v128_andnot(v128_t a, v128_t b)
static void vsx_v128_store(void *p, v128_t a)
static v128_t vsx_u64x2_shr(v128_t a, int n)
static v128_t vsx_v128_and(v128_t a, v128_t b)
static v128_t vsx_i64x2_shl(v128_t a, int n)
static v128_t vsx_i32x4_mul(v128_t a, v128_t b)
static v128_t vsx_i16x8_eq(v128_t a, v128_t b)
static v128_t vsx_v128_or(v128_t a, v128_t b)
static v128_t vsx_i32x4_lt(v128_t a, v128_t b)
__vector unsigned short vsx_v_u16
static v128_t vsx_i8x16_eq(v128_t a, v128_t b)
static v128_t vsx_i64x2_mul(v128_t a, v128_t b)
static v128_t vsx_i64x2_splat(long long x)
__vector unsigned long long vsx_v_u64
static v128_t vsx_i64x2_shr(v128_t a, int n)
static v128_t vsx_i64x2_add(v128_t a, v128_t b)
static v128_t vsx_i64x2_sub(v128_t a, v128_t b)
static v128_t vsx_i32x4_splat(int x)
static v128_t vsx_v128_load(const void *p)
static v128_t vsx_i16x8_const(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
static v128_t vsx_i32x4_shr(v128_t a, int n)
static v128_t vsx_i16x8_shl(v128_t a, int n)
static v128_t vsx_u32x4_splat(unsigned int x)
static v128_t vsx_i32x4_trunc_sat_f32x4(v128_t a)
static v128_t vsx_i8x16_gt(v128_t a, v128_t b)
static v128_t vsx_i32x4_eq(v128_t a, v128_t b)
static v128_t vsx_i32x4_gt(v128_t a, v128_t b)