10#ifndef __RISCV_PACKED_SIMD_H
11#define __RISCV_PACKED_SIMD_H
15#if defined(__cplusplus)
33#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
35#define __packed_splat2(ty, x) ((ty){(x), (x)})
36#define __packed_splat4(ty, x) ((ty){(x), (x), (x), (x)})
37#define __packed_splat8(ty, x) ((ty){(x), (x), (x), (x), (x), (x), (x), (x)})
39#define __packed_splat(name, ty, scalar_ty, splat) \
40 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(scalar_ty __x) { \
41 return splat(ty, __x); \
44#define __packed_shift(name, ty, op, mask) \
45 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
47 return __rs1 op(__rs2 & (mask)); \
49#define __packed_shift8(name, ty, op) __packed_shift(name, ty, op, 0x7)
50#define __packed_shift16(name, ty, op) __packed_shift(name, ty, op, 0xf)
51#define __packed_shift32(name, ty, op) __packed_shift(name, ty, op, 0x1f)
53#define __packed_scalar_binary_op(name, ty, scalar_ty, op, splat) \
54 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
56 return __rs1 op splat(ty, __rs2); \
59#define __packed_binary_op(name, ty, op) \
60 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
61 return __rs1 op __rs2; \
64#define __packed_unary_op(name, ty, op) \
65 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
69#define __packed_binary_builtin(name, ty, builtin) \
70 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
71 return builtin(__rs1, __rs2); \
74#define __packed_sh1add(name, ty) \
75 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
76 return (__rs1 << 1) + __rs2; \
83#define __packed_sh1sadd(name, ty) \
84 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
85 return __builtin_elementwise_add_sat( \
86 __builtin_elementwise_add_sat(__rs1, __rs1), __rs2); \
89#define __packed_cmp(name, ty, rty, op) \
90 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
92 return (rty)(__rs1 op __rs2); \
95#define __packed_pabs(name, ty, rty) \
96 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
97 return (rty)__builtin_elementwise_abs(__rs1); \
100#define __packed_binary_builtin_cast(name, ty, rty, builtin) \
101 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
103 return (rty)builtin(__rs1, __rs2); \
106#define __packed_reduction(name, rty, ty, builtin) \
107 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
109 return builtin(__rs1, __rs2); \
112#define __packed_merge_builtin(name, ty, mask_ty, builtin) \
113 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2, \
115 return (ty)builtin(__rs1, __rs2, __rd); \
118#define __packed_psabs(name, ty, builtin) \
119 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
120 return builtin(__rs1); \
123#define __packed_widen_convert(name, rty, ty) \
124 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
125 return __builtin_convertvector(__rs1, rty); \
127#define __packed_widen_high2(name, rty, ty) \
128 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
129 return (rty)__builtin_shufflevector((ty){0}, __rs1, 0, 2, 1, 3); \
131#define __packed_widen_high4(name, rty, ty) \
132 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
133 return (rty)__builtin_shufflevector((ty){0}, __rs1, 0, 4, 1, 5, 2, 6, 3, \
137#if __riscv_xlen == 64
138#define __packed_narrow_even2(name, rty, ty, sty) \
139 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
140 return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 0, 2); \
142#define __packed_narrow_even4(name, rty, ty, sty) \
143 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
144 return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 0, 2, 4, 6); \
146#define __packed_narrow_odd2(name, rty, ty, sty, uty) \
147 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
148 return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 1, 3); \
150#define __packed_narrow_odd4(name, rty, ty, sty, uty) \
151 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
152 return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 1, 3, 5, 7); \
155#define __packed_narrow_even2(name, rty, ty, sty) \
156 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
157 return __builtin_convertvector(__rs1, rty); \
159#define __packed_narrow_even4(name, rty, ty, sty) \
160 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
161 return __builtin_convertvector(__rs1, rty); \
163#define __packed_narrow_odd2(name, rty, ty, sty, uty) \
164 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
165 return __builtin_convertvector(((uty)__rs1) >> 16, rty); \
167#define __packed_narrow_odd4(name, rty, ty, sty, uty) \
168 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
169 return __builtin_convertvector(((uty)__rs1) >> 8, rty); \
175#define __packed_reverse2(name, ty) \
176 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
177 return __builtin_shufflevector(__rs1, __rs1, 1, 0); \
179#define __packed_reverse4(name, ty) \
180 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
181 return __builtin_shufflevector(__rs1, __rs1, 3, 2, 1, 0); \
183#define __packed_reverse8(name, ty) \
184 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
185 return __builtin_shufflevector(__rs1, __rs1, 7, 6, 5, 4, 3, 2, 1, 0); \
188#define __packed_zip2(name, rty, ty) \
189 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
191 return __builtin_shufflevector(__rs1, __rs2, 0, 2, 1, 3); \
193#define __packed_zip4(name, rty, ty) \
194 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
196 return __builtin_shufflevector(__rs1, __rs2, 0, 4, 1, 5, 2, 6, 3, 7); \
198#define __packed_unzipe2(name, rty, ty) \
199 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
200 return __builtin_shufflevector(__rs1, __rs1, 0, 2); \
202#define __packed_unzipe4(name, rty, ty) \
203 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
204 return __builtin_shufflevector(__rs1, __rs1, 0, 2, 4, 6); \
206#define __packed_unzipo2(name, rty, ty) \
207 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
208 return __builtin_shufflevector(__rs1, __rs1, 1, 3); \
210#define __packed_unzipo4(name, rty, ty) \
211 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
212 return __builtin_shufflevector(__rs1, __rs1, 1, 3, 5, 7); \
215#define __packed_nzip2(name, rty, ty) \
216 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
218 return __builtin_shufflevector((rty)__rs1, (rty)__rs2, 0, 4, 2, 6); \
220#define __packed_nzip4(name, rty, ty) \
221 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
223 return __builtin_shufflevector((rty)__rs1, (rty)__rs2, 0, 8, 2, 10, 4, 12, \
226#define __packed_nziph2(name, rty, ty) \
227 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
229 return __builtin_shufflevector((rty)__rs1, (rty)__rs2, 1, 5, 3, 7); \
231#define __packed_nziph4(name, rty, ty) \
232 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
234 return __builtin_shufflevector((rty)__rs1, (rty)__rs2, 1, 9, 3, 11, 5, 13, \
238#define __packed_abdsum(name, rty, ty, builtin) \
239 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
241 return builtin(__rs1, __rs2); \
244#define __packed_abdsum_acc(name, rty, ty, builtin) \
245 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(rty __rd, ty __rs1, \
247 return builtin(__rd, __rs1, __rs2); \
250#define __packed_reinterpret(name, rty, ty) \
251 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_preinterpret_##name( \
253 return __builtin_bit_cast(rty, __x); \
785#undef __packed_splat2
786#undef __packed_splat4
787#undef __packed_splat8
790#undef __packed_shift8
791#undef __packed_shift16
792#undef __packed_shift32
793#undef __packed_scalar_binary_op
794#undef __packed_binary_op
795#undef __packed_unary_op
796#undef __packed_binary_builtin
797#undef __packed_sh1add
798#undef __packed_sh1sadd
801#undef __packed_binary_builtin_cast
802#undef __packed_reduction
803#undef __packed_merge_builtin
805#undef __packed_widen_convert
806#undef __packed_widen_high2
807#undef __packed_widen_high4
808#undef __packed_narrow_even2
809#undef __packed_narrow_even4
810#undef __packed_narrow_odd2
811#undef __packed_narrow_odd4
812#undef __packed_reverse2
813#undef __packed_reverse4
814#undef __packed_reverse8
817#undef __packed_unzipe2
818#undef __packed_unzipe4
819#undef __packed_unzipo2
820#undef __packed_unzipo4
823#undef __packed_nziph2
824#undef __packed_nziph4
825#undef __packed_abdsum
826#undef __packed_abdsum_acc
827#undef __packed_reinterpret
828#undef __DEFAULT_FN_ATTRS
830#if defined(__cplusplus)
#define __packed_cmp(name, ty, rty, op)
#define __packed_widen_convert(name, rty, ty)
#define __packed_unzipo2(name, rty, ty)
__packed_splat4 int16x2_t
#define __packed_binary_op(name, ty, op)
#define __packed_reinterpret(name, rty, ty)
#define __packed_splat2(ty, x)
int8_t int8x4_t __attribute__((__vector_size__(4)))
#define __packed_reduction(name, rty, ty, builtin)
#define __packed_shift8(name, ty, op)
#define __packed_nziph2(name, rty, ty)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint16x4_t
#define __packed_reverse2(name, ty)
#define __packed_splat8(ty, x)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
#define __packed_merge_builtin(name, ty, mask_ty, builtin)
#define __packed_scalar_binary_op(name, ty, scalar_ty, op, splat)
#define __packed_shift16(name, ty, op)
#define __packed_nzip2(name, rty, ty)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 uint16_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint32x2_t
#define __packed_reverse8(name, ty)
#define __packed_binary_builtin(name, ty, builtin)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
#define __packed_nziph4(name, rty, ty)
#define __packed_narrow_even2(name, rty, ty, sty)
#define __packed_widen_high4(name, rty, ty)
#define __packed_unary_op(name, ty, op)
#define __packed_psabs(name, ty, builtin)
#define __packed_unzipe4(name, rty, ty)
#define __packed_sh1add(name, ty)
#define __packed_pabs(name, ty, rty)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint16x2_t
#define __packed_sh1sadd(name, ty)
#define __packed_unzipe2(name, rty, ty)
#define __packed_unzipo4(name, rty, ty)
#define __packed_widen_high2(name, rty, ty)
#define __packed_abdsum_acc(name, rty, ty, builtin)
#define __packed_shift32(name, ty, op)
#define __packed_nzip4(name, rty, ty)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32x2_t
#define __packed_zip4(name, rty, ty)
#define __packed_splat(name, ty, scalar_ty, splat)
#define __packed_narrow_odd2(name, rty, ty, sty, uty)
__packed_splat4 __packed_splat2 int8x8_t
#define __packed_abdsum(name, rty, ty, builtin)
#define __packed_binary_builtin_cast(name, ty, rty, builtin)
#define __packed_narrow_even4(name, rty, ty, sty)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8x4_t
#define __packed_narrow_odd4(name, rty, ty, sty, uty)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8x8_t
#define __packed_zip2(name, rty, ty)
#define __packed_splat4(ty, x)
__packed_splat4 __packed_splat2 __packed_splat8 int16x4_t
#define __packed_reverse4(name, ty)