]>
Commit | Line | Data |
---|---|---|
5fb4cf24 | 1 | /* PowerPC AltiVec include file. |
a945c346 | 2 | Copyright (C) 2002-2024 Free Software Foundation, Inc. |
5fb4cf24 | 3 | Contributed by Aldy Hernandez (aldyh@redhat.com). |
58646b77 | 4 | Rewritten by Paolo Bonzini (bonzini@gnu.org). |
5fb4cf24 | 5 | |
5de601cf | 6 | This file is part of GCC. |
5fb4cf24 | 7 | |
5de601cf NC |
8 | GCC is free software; you can redistribute it and/or modify it |
9 | under the terms of the GNU General Public License as published | |
748086b7 | 10 | by the Free Software Foundation; either version 3, or (at your |
5de601cf | 11 | option) any later version. |
5fb4cf24 | 12 | |
5de601cf NC |
13 | GCC is distributed in the hope that it will be useful, but WITHOUT |
14 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
15 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
16 | License for more details. | |
5fb4cf24 | 17 | |
748086b7 JJ |
18 | Under Section 7 of GPL version 3, you are granted additional |
19 | permissions described in the GCC Runtime Library Exception, version | |
20 | 3.1, as published by the Free Software Foundation. | |
21 | ||
22 | You should have received a copy of the GNU General Public License and | |
23 | a copy of the GCC Runtime Library Exception along with this program; | |
24 | see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
25 | <http://www.gnu.org/licenses/>. */ | |
5fb4cf24 AH |
26 | |
27 | /* Implemented to conform to the specification included in the AltiVec | |
28 | Technology Programming Interface Manual (ALTIVECPIM/D 6/1999 Rev 0). */ | |
29 | ||
30 | #ifndef _ALTIVEC_H | |
31 | #define _ALTIVEC_H 1 | |
32 | ||
8bb418a3 ZL |
33 | #if !defined(__VEC__) || !defined(__ALTIVEC__) |
34 | #error Use the "-maltivec" flag to enable PowerPC AltiVec support | |
71a0ab0c | 35 | #endif |
5fb4cf24 | 36 | |
f95d9272 ZL |
37 | /* If __APPLE_ALTIVEC__ is defined, the compiler supports 'vector', |
38 | 'pixel' and 'bool' as context-sensitive AltiVec keywords (in | |
39 | non-AltiVec contexts, they revert to their original meanings, | |
e756e900 BS |
40 | if any), so we do not need to define them as macros. Also, |
41 | avoid defining them as macros for C++ with strict ANSI, as | |
42 | this is not compatible. */ | |
f95d9272 | 43 | |
e756e900 BS |
44 | #if !defined(__APPLE_ALTIVEC__) \ |
45 | && (!defined(__STRICT_ANSI__) || !defined(__cplusplus)) | |
5fb4cf24 | 46 | #define vector __vector |
8bb418a3 ZL |
47 | #define pixel __pixel |
48 | #define bool __bool | |
f95d9272 | 49 | #endif |
5fb4cf24 | 50 | |
8bb418a3 | 51 | /* Condition register codes for AltiVec predicates. */ |
5fb4cf24 | 52 | |
ae4b4a02 AH |
53 | #define __CR6_EQ 0 |
54 | #define __CR6_EQ_REV 1 | |
55 | #define __CR6_LT 2 | |
56 | #define __CR6_LT_REV 3 | |
57 | ||
d0823635 BS |
58 | #include "rs6000-vecdefines.h" |
59 | ||
60 | /* Deprecated interfaces. */ | |
61 | #define vec_lvx vec_ld | |
62 | #define vec_lvxl vec_ldl | |
63 | #define vec_stvx vec_st | |
64 | #define vec_stvxl vec_stl | |
4287a893 AH |
65 | #define vec_vaddcuw vec_addc |
66 | #define vec_vand vec_and | |
67 | #define vec_vandc vec_andc | |
4287a893 AH |
68 | #define vec_vcmpbfp vec_cmpb |
69 | #define vec_vcmpgefp vec_cmpge | |
70 | #define vec_vctsxs vec_cts | |
71 | #define vec_vctuxs vec_ctu | |
72 | #define vec_vexptefp vec_expte | |
4287a893 AH |
73 | #define vec_vlogefp vec_loge |
74 | #define vec_vmaddfp vec_madd | |
75 | #define vec_vmhaddshs vec_madds | |
4287a893 | 76 | #define vec_vmhraddshs vec_mradds |
d0823635 | 77 | #define vec_vmladduhm vec_mladd |
4287a893 AH |
78 | #define vec_vnmsubfp vec_nmsub |
79 | #define vec_vnor vec_nor | |
80 | #define vec_vor vec_or | |
4287a893 | 81 | #define vec_vperm vec_perm |
d0823635 | 82 | #define vec_vpkpx vec_packpx |
4287a893 | 83 | #define vec_vrefp vec_re |
d0823635 | 84 | #define vec_vrfim vec_floor |
4287a893 | 85 | #define vec_vrfin vec_round |
d0823635 BS |
86 | #define vec_vrfip vec_ceil |
87 | #define vec_vrfiz vec_trunc | |
4287a893 AH |
88 | #define vec_vrsqrtefp vec_rsqrte |
89 | #define vec_vsel vec_sel | |
90 | #define vec_vsldoi vec_sld | |
91 | #define vec_vsl vec_sll | |
92 | #define vec_vslo vec_slo | |
93 | #define vec_vspltisb vec_splat_s8 | |
94 | #define vec_vspltish vec_splat_s16 | |
95 | #define vec_vspltisw vec_splat_s32 | |
96 | #define vec_vsr vec_srl | |
97 | #define vec_vsro vec_sro | |
4287a893 AH |
98 | #define vec_vsubcuw vec_subc |
99 | #define vec_vsum2sws vec_sum2s | |
100 | #define vec_vsumsws vec_sums | |
4287a893 AH |
101 | #define vec_vxor vec_xor |
102 | ||
d0823635 BS |
103 | /* For _ARCH_PWR8. Always define to support #pragma GCC target. */ |
104 | #define vec_vclz vec_cntlz | |
105 | #define vec_vgbbd vec_gb | |
106 | #define vec_vmrgew vec_mergee | |
107 | #define vec_vmrgow vec_mergeo | |
108 | #define vec_vpopcntu vec_popcnt | |
109 | #define vec_vrld vec_rl | |
110 | #define vec_vsld vec_sl | |
111 | #define vec_vsrd vec_sr | |
112 | #define vec_vsrad vec_sra | |
113 | ||
114 | /* For _ARCH_PWR9. Always define to support #pragma GCC target. */ | |
115 | #define vec_extract_fp_from_shorth vec_extract_fp32_from_shorth | |
116 | #define vec_extract_fp_from_shortl vec_extract_fp32_from_shortl | |
117 | #define vec_vctz vec_cnttz | |
118 | ||
119 | /* Synonyms. */ | |
58646b77 PB |
120 | /* Functions that are resolved by the backend to one of the |
121 | typed builtins. */ | |
76ba473b | 122 | #define vec_cpsgn(x,y) __builtin_vec_copysign(y,x) |
e97929e2 | 123 | #define vec_rlnm(a,b,c) (__builtin_vec_rlnm((a),((c)<<8)|(b))) |
266b4890 | 124 | |
29e6733c MM |
125 | #ifdef __VSX__ |
126 | /* VSX additions */ | |
c9485473 MM |
127 | #define vec_vsx_ld __builtin_vec_vsx_ld |
128 | #define vec_vsx_st __builtin_vec_vsx_st | |
d0823635 BS |
129 | #define __builtin_vec_xl __builtin_vec_vsx_ld |
130 | #define __builtin_vec_xst __builtin_vec_vsx_st | |
05161256 | 131 | |
05161256 | 132 | #define __builtin_bcdadd_ofl __builtin_vec_bcdadd_ov |
05161256 | 133 | #define __builtin_bcdsub_ofl __builtin_vec_bcdsub_ov |
05161256 CL |
134 | #define __builtin_bcdcmpeq(a,b) __builtin_vec_bcdsub_eq(a,b,0) |
135 | #define __builtin_bcdcmpgt(a,b) __builtin_vec_bcdsub_gt(a,b,0) | |
136 | #define __builtin_bcdcmplt(a,b) __builtin_vec_bcdsub_lt(a,b,0) | |
137 | #define __builtin_bcdcmpge(a,b) __builtin_vec_bcdsub_ge(a,b,0) | |
138 | #define __builtin_bcdcmple(a,b) __builtin_vec_bcdsub_le(a,b,0) | |
d0823635 | 139 | #endif |
05161256 | 140 | |
d0823635 BS |
141 | /* For _ARCH_PWR10. Always define to support #pragma GCC target. */ |
142 | #define __builtin_vec_se_lxvrx __builtin_vec_xl_sext | |
143 | #define __builtin_vec_tr_stxvrx __builtin_vec_xst_trunc | |
144 | #define __builtin_vec_ze_lxvrx __builtin_vec_xl_zext | |
145 | #define __builtin_vsx_xxpermx __builtin_vec_xxpermx | |
05161256 | 146 | |
58646b77 PB |
147 | /* Predicates. |
148 | For C++, we use templates in order to allow non-parenthesized arguments. | |
149 | For C, instead, we use macros since non-parenthesized arguments were | |
150 | not allowed even in older GCC implementation of AltiVec. | |
151 | ||
152 | In the future, we may add more magic to the back-end, so that no | |
153 | one- or two-argument macros are used. */ | |
154 | ||
155 | #ifdef __cplusplus__ | |
156 | #define __altivec_unary_pred(NAME, CALL) \ | |
157 | template <class T> int NAME (T a1) { return CALL; } | |
158 | ||
159 | #define __altivec_scalar_pred(NAME, CALL) \ | |
160 | template <class T, class U> int NAME (T a1, U a2) { return CALL; } | |
161 | ||
162 | /* Given the vec_step of a type, return the corresponding bool type. */ | |
163 | template <int STEP> class __altivec_bool_ret { }; | |
164 | template <> class __altivec_bool_ret <4> { | |
165 | typedef __vector __bool int __ret; | |
8bb418a3 | 166 | }; |
58646b77 PB |
167 | template <> class __altivec_bool_ret <8> { |
168 | typedef __vector __bool short __ret; | |
98705d7d | 169 | }; |
58646b77 PB |
170 | template <> class __altivec_bool_ret <16> { |
171 | typedef __vector __bool char __ret; | |
8bb418a3 ZL |
172 | }; |
173 | ||
58646b77 PB |
174 | /* Be very liberal in the pairs we accept. Mistakes such as passing |
175 | a `vector char' and `vector short' will be caught by the middle-end, | |
176 | while any attempt to detect them here would produce hard to understand | |
177 | error messages involving the implementation details of AltiVec. */ | |
178 | #define __altivec_binary_pred(NAME, CALL) \ | |
179 | template <class T, class U> \ | |
180 | typename __altivec_bool_ret <vec_step (T)>::__ret \ | |
181 | NAME (T a1, U a2) \ | |
182 | { \ | |
183 | return CALL; \ | |
184 | } | |
185 | ||
186 | __altivec_binary_pred(vec_cmplt, | |
187 | __builtin_vec_cmpgt (a2, a1)) | |
188 | __altivec_binary_pred(vec_cmple, | |
00c8e9f6 | 189 | __builtin_vec_cmpge (a2, a1)) |
58646b77 PB |
190 | |
191 | __altivec_scalar_pred(vec_all_in, | |
192 | __builtin_altivec_vcmpbfp_p (__CR6_EQ, a1, a2)) | |
193 | __altivec_scalar_pred(vec_any_out, | |
194 | __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, a1, a2)) | |
195 | ||
196 | __altivec_unary_pred(vec_all_nan, | |
29e6733c | 197 | __builtin_altivec_vcmpeq_p (__CR6_EQ, a1, a1)) |
58646b77 | 198 | __altivec_unary_pred(vec_any_nan, |
29e6733c | 199 | __builtin_altivec_vcmpeq_p (__CR6_LT_REV, a1, a1)) |
58646b77 PB |
200 | |
201 | __altivec_unary_pred(vec_all_numeric, | |
29e6733c | 202 | __builtin_altivec_vcmpeq_p (__CR6_LT, a1, a1)) |
58646b77 | 203 | __altivec_unary_pred(vec_any_numeric, |
29e6733c | 204 | __builtin_altivec_vcmpeq_p (__CR6_EQ_REV, a1, a1)) |
58646b77 PB |
205 | |
206 | __altivec_scalar_pred(vec_all_eq, | |
207 | __builtin_vec_vcmpeq_p (__CR6_LT, a1, a2)) | |
902cb7b1 | 208 | |
50181506 | 209 | #ifndef __POWER9_VECTOR__ |
58646b77 PB |
210 | __altivec_scalar_pred(vec_all_ne, |
211 | __builtin_vec_vcmpeq_p (__CR6_EQ, a1, a2)) | |
212 | __altivec_scalar_pred(vec_any_eq, | |
213 | __builtin_vec_vcmpeq_p (__CR6_EQ_REV, a1, a2)) | |
902cb7b1 KN |
214 | #else |
215 | __altivec_scalar_pred(vec_all_nez, | |
216 | __builtin_vec_vcmpnez_p (__CR6_LT, a1, a2)) | |
217 | __altivec_scalar_pred(vec_any_eqz, | |
218 | __builtin_vec_vcmpnez_p (__CR6_LT_REV, a1, a2)) | |
219 | __altivec_scalar_pred(vec_all_ne, | |
b0ba96c2 | 220 | __builtin_vec_vcmpne_p (a1, a2)) |
902cb7b1 | 221 | __altivec_scalar_pred(vec_any_eq, |
b0ba96c2 | 222 | __builtin_vec_vcmpae_p (a1, a2)) |
902cb7b1 KN |
223 | #endif |
224 | ||
58646b77 PB |
225 | __altivec_scalar_pred(vec_any_ne, |
226 | __builtin_vec_vcmpeq_p (__CR6_LT_REV, a1, a2)) | |
227 | ||
228 | __altivec_scalar_pred(vec_all_gt, | |
229 | __builtin_vec_vcmpgt_p (__CR6_LT, a1, a2)) | |
230 | __altivec_scalar_pred(vec_all_lt, | |
231 | __builtin_vec_vcmpgt_p (__CR6_LT, a2, a1)) | |
232 | __altivec_scalar_pred(vec_any_gt, | |
233 | __builtin_vec_vcmpgt_p (__CR6_EQ_REV, a1, a2)) | |
234 | __altivec_scalar_pred(vec_any_lt, | |
235 | __builtin_vec_vcmpgt_p (__CR6_EQ_REV, a2, a1)) | |
236 | ||
237 | __altivec_scalar_pred(vec_all_ngt, | |
29e6733c | 238 | __builtin_altivec_vcmpgt_p (__CR6_EQ, a1, a2)) |
58646b77 | 239 | __altivec_scalar_pred(vec_all_nlt, |
29e6733c | 240 | __builtin_altivec_vcmpgt_p (__CR6_EQ, a2, a1)) |
58646b77 | 241 | __altivec_scalar_pred(vec_any_ngt, |
29e6733c | 242 | __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a1, a2)) |
58646b77 | 243 | __altivec_scalar_pred(vec_any_nlt, |
29e6733c | 244 | __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a2, a1)) |
58646b77 PB |
245 | |
246 | /* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types, | |
247 | while for integer types it is converted to __builtin_vec_vcmpgt_p, | |
248 | with inverted args and condition code. */ | |
249 | __altivec_scalar_pred(vec_all_le, | |
250 | __builtin_vec_vcmpge_p (__CR6_LT, a2, a1)) | |
251 | __altivec_scalar_pred(vec_all_ge, | |
252 | __builtin_vec_vcmpge_p (__CR6_LT, a1, a2)) | |
253 | __altivec_scalar_pred(vec_any_le, | |
254 | __builtin_vec_vcmpge_p (__CR6_EQ_REV, a2, a1)) | |
255 | __altivec_scalar_pred(vec_any_ge, | |
256 | __builtin_vec_vcmpge_p (__CR6_EQ_REV, a1, a2)) | |
257 | ||
258 | __altivec_scalar_pred(vec_all_nge, | |
29e6733c | 259 | __builtin_altivec_vcmpge_p (__CR6_EQ, a1, a2)) |
58646b77 | 260 | __altivec_scalar_pred(vec_all_nle, |
29e6733c | 261 | __builtin_altivec_vcmpge_p (__CR6_EQ, a2, a1)) |
58646b77 | 262 | __altivec_scalar_pred(vec_any_nge, |
29e6733c | 263 | __builtin_altivec_vcmpge_p (__CR6_LT_REV, a1, a2)) |
58646b77 | 264 | __altivec_scalar_pred(vec_any_nle, |
29e6733c | 265 | __builtin_altivec_vcmpge_p (__CR6_LT_REV, a2, a1)) |
58646b77 PB |
266 | |
267 | #undef __altivec_scalar_pred | |
268 | #undef __altivec_unary_pred | |
269 | #undef __altivec_binary_pred | |
270 | #else | |
271 | #define vec_cmplt(a1, a2) __builtin_vec_cmpgt ((a2), (a1)) | |
00c8e9f6 | 272 | #define vec_cmple(a1, a2) __builtin_vec_cmpge ((a2), (a1)) |
58646b77 PB |
273 | |
274 | #define vec_all_in(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ, (a1), (a2)) | |
275 | #define vec_any_out(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, (a1), (a2)) | |
276 | ||
29e6733c MM |
277 | #define vec_all_nan(a1) __builtin_vec_vcmpeq_p (__CR6_EQ, (a1), (a1)) |
278 | #define vec_any_nan(a1) __builtin_vec_vcmpeq_p (__CR6_LT_REV, (a1), (a1)) | |
58646b77 | 279 | |
29e6733c MM |
280 | #define vec_all_numeric(a1) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a1)) |
281 | #define vec_any_numeric(a1) __builtin_vec_vcmpeq_p (__CR6_EQ_REV, (a1), (a1)) | |
58646b77 PB |
282 | |
283 | #define vec_all_eq(a1, a2) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a2)) | |
902cb7b1 | 284 | |
50181506 | 285 | #ifdef __POWER9_VECTOR__ |
902cb7b1 KN |
286 | #define vec_all_nez(a1, a2) __builtin_vec_vcmpnez_p (__CR6_LT, (a1), (a2)) |
287 | #define vec_any_eqz(a1, a2) __builtin_vec_vcmpnez_p (__CR6_LT_REV, (a1), (a2)) | |
50181506 KN |
288 | #define vec_all_ne(a1, a2) __builtin_vec_vcmpne_p ((a1), (a2)) |
289 | #define vec_any_eq(a1, a2) __builtin_vec_vcmpae_p ((a1), (a2)) | |
902cb7b1 | 290 | #else |
58646b77 PB |
291 | #define vec_all_ne(a1, a2) __builtin_vec_vcmpeq_p (__CR6_EQ, (a1), (a2)) |
292 | #define vec_any_eq(a1, a2) __builtin_vec_vcmpeq_p (__CR6_EQ_REV, (a1), (a2)) | |
902cb7b1 KN |
293 | #endif |
294 | ||
58646b77 PB |
295 | #define vec_any_ne(a1, a2) __builtin_vec_vcmpeq_p (__CR6_LT_REV, (a1), (a2)) |
296 | ||
297 | #define vec_all_gt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT, (a1), (a2)) | |
298 | #define vec_all_lt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT, (a2), (a1)) | |
299 | #define vec_any_gt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a1), (a2)) | |
300 | #define vec_any_lt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a2), (a1)) | |
301 | ||
29e6733c MM |
302 | #define vec_all_ngt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ, (a1), (a2)) |
303 | #define vec_all_nlt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ, (a2), (a1)) | |
304 | #define vec_any_ngt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT_REV, (a1), (a2)) | |
305 | #define vec_any_nlt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT_REV, (a2), (a1)) | |
58646b77 PB |
306 | |
307 | /* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types, | |
308 | while for integer types it is converted to __builtin_vec_vcmpgt_p, | |
309 | with inverted args and condition code. */ | |
310 | #define vec_all_le(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT, (a2), (a1)) | |
311 | #define vec_all_ge(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT, (a1), (a2)) | |
312 | #define vec_any_le(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a2), (a1)) | |
313 | #define vec_any_ge(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a1), (a2)) | |
314 | ||
29e6733c MM |
315 | #define vec_all_nge(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ, (a1), (a2)) |
316 | #define vec_all_nle(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ, (a2), (a1)) | |
317 | #define vec_any_nge(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT_REV, (a1), (a2)) | |
318 | #define vec_any_nle(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT_REV, (a2), (a1)) | |
58646b77 | 319 | #endif |
5fb4cf24 | 320 | |
d0823635 | 321 | /* Miscellaneous definitions. */ |
58646b77 | 322 | #define vec_dss(x) __builtin_altivec_dss((x)) |
5fb4cf24 | 323 | #define vec_dssall() __builtin_altivec_dssall () |
58646b77 PB |
324 | #define vec_splat_u8(x) ((__vector unsigned char) vec_splat_s8 ((x))) |
325 | #define vec_splat_u16(x) ((__vector unsigned short) vec_splat_s16 ((x))) | |
326 | #define vec_splat_u32(x) ((__vector unsigned int) vec_splat_s32 ((x))) | |
327 | ||
328 | /* This also accepts a type for its parameter, so it is not enough | |
329 | to #define vec_step to __builtin_vec_step. */ | |
330 | #define vec_step(x) __builtin_vec_step (* (__typeof__ (x) *) 0) | |
5fb4cf24 AH |
331 | |
332 | #endif /* _ALTIVEC_H */ |