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_binary_builtin_mixed(name, rty, ty1, ty2, builtin) \
75 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty1 __rs1, \
77 return builtin(__rs1, __rs2); \
80#define __packed_ternary_builtin(name, ty, builtin) \
81 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rd, ty __rs1, \
83 return builtin(__rd, __rs1, __rs2); \
86#define __packed_ternary_builtin_mixed(name, rty, ty1, ty2, builtin) \
87 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(rty __rd, ty1 __rs1, \
89 return builtin(__rd, __rs1, __rs2); \
92#define __packed_sh1add(name, ty) \
93 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
94 return (__rs1 << 1) + __rs2; \
101#define __packed_sh1sadd(name, ty) \
102 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
103 return __builtin_elementwise_add_sat( \
104 __builtin_elementwise_add_sat(__rs1, __rs1), __rs2); \
107#define __packed_cmp(name, ty, rty, op) \
108 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
110 return (rty)(__rs1 op __rs2); \
113#define __packed_pabs(name, ty, rty) \
114 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
115 return (rty)__builtin_elementwise_abs(__rs1); \
118#define __packed_binary_builtin_cast(name, ty, rty, builtin) \
119 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
121 return (rty)builtin(__rs1, __rs2); \
124#define __packed_reduction(name, rty, ty, builtin) \
125 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
127 return builtin(__rs1, __rs2); \
130#define __packed_merge_builtin(name, ty, mask_ty, builtin) \
131 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2, \
133 return (ty)builtin(__rs1, __rs2, __rd); \
136#define __packed_unary_builtin(name, ty, builtin) \
137 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
138 return builtin(__rs1); \
141#define __packed_widen_convert(name, rty, ty) \
142 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
143 return __builtin_convertvector(__rs1, rty); \
145#define __packed_widen_binary_op(name, rty, ty, op) \
146 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
148 return __builtin_convertvector(__rs1, rty) \
149 op __builtin_convertvector(__rs2, rty); \
151#define __packed_widen_mul(name, rty, ty) \
152 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
154 return __builtin_convertvector(__rs1, rty) * \
155 __builtin_convertvector(__rs2, rty); \
157#define __packed_widen_mulsu(name, rty, ty1, ty2, uty) \
158 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty1 __rs1, \
160 return __builtin_convertvector(__rs1, rty) * \
161 (rty) __builtin_convertvector(__rs2, uty); \
163#define __packed_widen_high2(name, rty, ty) \
164 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
165 return (rty)__builtin_shufflevector((ty){0}, __rs1, 0, 2, 1, 3); \
167#define __packed_widen_high4(name, rty, ty) \
168 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
169 return (rty)__builtin_shufflevector((ty){0}, __rs1, 0, 4, 1, 5, 2, 6, 3, \
173#define __packed_narrow_even2(name, rty, ty, sty) \
174 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
175 return __builtin_convertvector(__rs1, rty); \
177#define __packed_narrow_even4(name, rty, ty, sty) \
178 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
179 return __builtin_convertvector(__rs1, rty); \
181#define __packed_narrow_odd2(name, rty, ty, sty, uty) \
182 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
183 return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 1, 3); \
185#define __packed_narrow_odd4(name, rty, ty, sty, uty) \
186 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
187 return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 1, 3, 5, 7); \
192#define __packed_reverse2(name, ty) \
193 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
194 return __builtin_shufflevector(__rs1, __rs1, 1, 0); \
196#define __packed_reverse4(name, ty) \
197 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
198 return __builtin_shufflevector(__rs1, __rs1, 3, 2, 1, 0); \
200#define __packed_reverse8(name, ty) \
201 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
202 return __builtin_shufflevector(__rs1, __rs1, 7, 6, 5, 4, 3, 2, 1, 0); \
205#define __packed_zip2(name, rty, ty) \
206 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
208 return __builtin_shufflevector(__rs1, __rs2, 0, 2, 1, 3); \
210#define __packed_zip4(name, rty, ty) \
211 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
213 return __builtin_shufflevector(__rs1, __rs2, 0, 4, 1, 5, 2, 6, 3, 7); \
215#define __packed_unzipe2(name, rty, ty) \
216 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
217 return __builtin_shufflevector(__rs1, __rs1, 0, 2); \
219#define __packed_unzipe4(name, rty, ty) \
220 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
221 return __builtin_shufflevector(__rs1, __rs1, 0, 2, 4, 6); \
223#define __packed_unzipo2(name, rty, ty) \
224 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
225 return __builtin_shufflevector(__rs1, __rs1, 1, 3); \
227#define __packed_unzipo4(name, rty, ty) \
228 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \
229 return __builtin_shufflevector(__rs1, __rs1, 1, 3, 5, 7); \
232#define __packed_pair_ee4(name, ty) \
233 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
234 return __builtin_shufflevector(__rs1, __rs2, 0, 4, 2, 6); \
236#define __packed_pair_eo4(name, ty) \
237 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
238 return __builtin_shufflevector(__rs1, __rs2, 0, 5, 2, 7); \
240#define __packed_pair_oe4(name, ty) \
241 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
242 return __builtin_shufflevector(__rs1, __rs2, 1, 4, 3, 6); \
244#define __packed_pair_oo4(name, ty) \
245 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
246 return __builtin_shufflevector(__rs1, __rs2, 1, 5, 3, 7); \
248#define __packed_pair_ee8(name, ty) \
249 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
250 return __builtin_shufflevector(__rs1, __rs2, 0, 8, 2, 10, 4, 12, 6, 14); \
252#define __packed_pair_eo8(name, ty) \
253 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
254 return __builtin_shufflevector(__rs1, __rs2, 0, 9, 2, 11, 4, 13, 6, 15); \
256#define __packed_pair_oe8(name, ty) \
257 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
258 return __builtin_shufflevector(__rs1, __rs2, 1, 8, 3, 10, 5, 12, 7, 14); \
260#define __packed_pair_oo8(name, ty) \
261 static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
262 return __builtin_shufflevector(__rs1, __rs2, 1, 9, 3, 11, 5, 13, 7, 15); \
265#define __packed_nzip2(name, rty, ty) \
266 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
268 return __builtin_shufflevector((rty)__rs1, (rty)__rs2, 0, 4, 2, 6); \
270#define __packed_nzip4(name, rty, ty) \
271 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
273 return __builtin_shufflevector((rty)__rs1, (rty)__rs2, 0, 8, 2, 10, 4, 12, \
276#define __packed_nziph2(name, rty, ty) \
277 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
279 return __builtin_shufflevector((rty)__rs1, (rty)__rs2, 1, 5, 3, 7); \
281#define __packed_nziph4(name, rty, ty) \
282 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
284 return __builtin_shufflevector((rty)__rs1, (rty)__rs2, 1, 9, 3, 11, 5, 13, \
288#define __packed_abdsum(name, rty, ty, builtin) \
289 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
291 return builtin(__rs1, __rs2); \
294#define __packed_ternary_builtin_cast(name, rty, ty, builtin) \
295 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(rty __rd, ty __rs1, \
297 return builtin(__rd, __rs1, __rs2); \
300#define __packed_reinterpret(name, rty, ty) \
301 static __inline__ rty __DEFAULT_FN_ATTRS __riscv_preinterpret_##name( \
303 return __builtin_bit_cast(rty, __x); \
1043#undef __packed_splat2
1044#undef __packed_splat4
1045#undef __packed_splat8
1046#undef __packed_splat
1047#undef __packed_shift
1048#undef __packed_shift8
1049#undef __packed_shift16
1050#undef __packed_shift32
1051#undef __packed_scalar_binary_op
1052#undef __packed_binary_op
1053#undef __packed_unary_op
1054#undef __packed_binary_builtin
1055#undef __packed_binary_builtin_mixed
1056#undef __packed_ternary_builtin
1057#undef __packed_ternary_builtin_mixed
1058#undef __packed_sh1add
1059#undef __packed_sh1sadd
1062#undef __packed_binary_builtin_cast
1063#undef __packed_reduction
1064#undef __packed_merge_builtin
1065#undef __packed_unary_builtin
1066#undef __packed_widen_convert
1067#undef __packed_widen_binary_op
1068#undef __packed_widen_mul
1069#undef __packed_widen_mulsu
1070#undef __packed_widen_high2
1071#undef __packed_widen_high4
1072#undef __packed_narrow_even2
1073#undef __packed_narrow_even4
1074#undef __packed_narrow_odd2
1075#undef __packed_narrow_odd4
1076#undef __packed_reverse2
1077#undef __packed_reverse4
1078#undef __packed_reverse8
1081#undef __packed_unzipe2
1082#undef __packed_unzipe4
1083#undef __packed_unzipo2
1084#undef __packed_unzipo4
1085#undef __packed_pair_ee4
1086#undef __packed_pair_eo4
1087#undef __packed_pair_oe4
1088#undef __packed_pair_oo4
1089#undef __packed_pair_ee8
1090#undef __packed_pair_eo8
1091#undef __packed_pair_oe8
1092#undef __packed_pair_oo8
1093#undef __packed_nzip2
1094#undef __packed_nzip4
1095#undef __packed_nziph2
1096#undef __packed_nziph4
1097#undef __packed_abdsum
1098#undef __packed_ternary_builtin_cast
1099#undef __packed_reinterpret
1100#undef __DEFAULT_FN_ATTRS
1102#if defined(__cplusplus)
#define __packed_pair_oe8(name, ty)
#define __packed_cmp(name, ty, rty, op)
#define __packed_widen_convert(name, rty, ty)
#define __packed_unary_builtin(name, ty, builtin)
#define __packed_widen_mulsu(name, rty, ty1, ty2, uty)
#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_binary_builtin_mixed(name, rty, ty1, ty2, builtin)
#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_pair_ee4(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_pair_eo4(name, ty)
#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
#define __packed_pair_eo8(name, ty)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint32x2_t
#define __packed_reverse8(name, ty)
#define __packed_binary_builtin(name, ty, builtin)
#define __packed_pair_oe4(name, ty)
__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_ternary_builtin(name, ty, builtin)
#define __packed_unary_op(name, ty, op)
#define __packed_pair_oo4(name, ty)
#define __packed_pair_ee8(name, ty)
#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_ternary_builtin_mixed(name, rty, ty1, ty2, builtin)
#define __packed_pair_oo8(name, ty)
#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_widen_binary_op(name, rty, ty, op)
#define __packed_binary_builtin_cast(name, ty, rty, builtin)
#define __packed_ternary_builtin_cast(name, rty, ty, 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)
#define __packed_widen_mul(name, rty, ty)
__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)