1  /* PowerPC AltiVec include file.
       2     Copyright (C) 2002-2023 Free Software Foundation, Inc.
       3     Contributed by Aldy Hernandez (aldyh@redhat.com).
       4     Rewritten by Paolo Bonzini (bonzini@gnu.org).
       5  
       6     This file is part of GCC.
       7  
       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
      10     by the Free Software Foundation; either version 3, or (at your
      11     option) any later version.
      12  
      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.
      17  
      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/>.  */
      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  
      33  #if !defined(__VEC__) || !defined(__ALTIVEC__)
      34  #error Use the "-maltivec" flag to enable PowerPC AltiVec support
      35  #endif
      36  
      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,
      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.  */
      43  
      44  #if !defined(__APPLE_ALTIVEC__) \
      45      && (!defined(__STRICT_ANSI__) || !defined(__cplusplus))
      46  #define vector __vector
      47  #define pixel __pixel
      48  #define bool __bool
      49  #endif
      50  
      51  /* Condition register codes for AltiVec predicates. */
      52  
      53  #define __CR6_EQ		0
      54  #define __CR6_EQ_REV		1
      55  #define __CR6_LT		2
      56  #define __CR6_LT_REV		3
      57  
      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
      65  #define vec_vaddcuw vec_addc
      66  #define vec_vand vec_and
      67  #define vec_vandc vec_andc
      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
      73  #define vec_vlogefp vec_loge
      74  #define vec_vmaddfp vec_madd
      75  #define vec_vmhaddshs vec_madds
      76  #define vec_vmhraddshs vec_mradds
      77  #define vec_vmladduhm vec_mladd
      78  #define vec_vnmsubfp vec_nmsub
      79  #define vec_vnor vec_nor
      80  #define vec_vor vec_or
      81  #define vec_vperm vec_perm
      82  #define vec_vpkpx vec_packpx
      83  #define vec_vrefp vec_re
      84  #define vec_vrfim vec_floor
      85  #define vec_vrfin vec_round
      86  #define vec_vrfip vec_ceil
      87  #define vec_vrfiz vec_trunc
      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
      98  #define vec_vsubcuw vec_subc
      99  #define vec_vsum2sws vec_sum2s
     100  #define vec_vsumsws vec_sums
     101  #define vec_vxor vec_xor
     102  
     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.  */
     120  /* Functions that are resolved by the backend to one of the
     121     typed builtins.  */
     122  #define vec_cpsgn(x,y) __builtin_vec_copysign(y,x)
     123  #define vec_rlnm(a,b,c) (__builtin_vec_rlnm((a),((c)<<8)|(b)))
     124  
     125  #ifdef __VSX__
     126  /* VSX additions */
     127  #define vec_vsx_ld __builtin_vec_vsx_ld
     128  #define vec_vsx_st __builtin_vec_vsx_st
     129  #define __builtin_vec_xl __builtin_vec_vsx_ld
     130  #define __builtin_vec_xst __builtin_vec_vsx_st
     131  
     132  #define __builtin_bcdadd_ofl __builtin_vec_bcdadd_ov
     133  #define __builtin_bcdsub_ofl __builtin_vec_bcdsub_ov
     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)
     139  #endif
     140  
     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
     146  
     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;
     166  };
     167  template <> class __altivec_bool_ret <8> {
     168    typedef __vector __bool short __ret;
     169  };
     170  template <> class __altivec_bool_ret <16> {
     171    typedef __vector __bool char __ret;
     172  };
     173  
     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,
     189    __builtin_vec_cmpge (a2, a1))
     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,
     197    __builtin_altivec_vcmpeq_p (__CR6_EQ, a1, a1))
     198  __altivec_unary_pred(vec_any_nan,
     199    __builtin_altivec_vcmpeq_p (__CR6_LT_REV, a1, a1))
     200  
     201  __altivec_unary_pred(vec_all_numeric,
     202    __builtin_altivec_vcmpeq_p (__CR6_LT, a1, a1))
     203  __altivec_unary_pred(vec_any_numeric,
     204    __builtin_altivec_vcmpeq_p (__CR6_EQ_REV, a1, a1))
     205  
     206  __altivec_scalar_pred(vec_all_eq,
     207    __builtin_vec_vcmpeq_p (__CR6_LT, a1, a2))
     208  
     209  #ifndef __POWER9_VECTOR__
     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))
     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,
     220    __builtin_vec_vcmpne_p (a1, a2))
     221  __altivec_scalar_pred(vec_any_eq,
     222    __builtin_vec_vcmpae_p (a1, a2))
     223  #endif
     224  
     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,
     238    __builtin_altivec_vcmpgt_p (__CR6_EQ, a1, a2))
     239  __altivec_scalar_pred(vec_all_nlt,
     240    __builtin_altivec_vcmpgt_p (__CR6_EQ, a2, a1))
     241  __altivec_scalar_pred(vec_any_ngt,
     242    __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a1, a2))
     243  __altivec_scalar_pred(vec_any_nlt,
     244    __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a2, a1))
     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,
     259    __builtin_altivec_vcmpge_p (__CR6_EQ, a1, a2))
     260  __altivec_scalar_pred(vec_all_nle,
     261    __builtin_altivec_vcmpge_p (__CR6_EQ, a2, a1))
     262  __altivec_scalar_pred(vec_any_nge,
     263    __builtin_altivec_vcmpge_p (__CR6_LT_REV, a1, a2))
     264  __altivec_scalar_pred(vec_any_nle,
     265    __builtin_altivec_vcmpge_p (__CR6_LT_REV, a2, a1))
     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))
     272  #define vec_cmple(a1, a2) __builtin_vec_cmpge ((a2), (a1))
     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  
     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))
     279  
     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))
     282  
     283  #define vec_all_eq(a1, a2) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a2))
     284  
     285  #ifdef __POWER9_VECTOR__
     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))
     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))
     290  #else
     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))
     293  #endif
     294  
     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  
     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))
     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  
     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))
     319  #endif
     320  
     321  /* Miscellaneous definitions.  */
     322  #define vec_dss(x) __builtin_altivec_dss((x))
     323  #define vec_dssall() __builtin_altivec_dssall ()
     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)
     331  
     332  #endif /* _ALTIVEC_H */