1  /* AArch64 Non-NEON ACLE intrinsics include file.
       2  
       3     Copyright (C) 2014-2023 Free Software Foundation, Inc.
       4     Contributed by ARM Ltd.
       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  #ifndef _GCC_ARM_ACLE_H
      28  #define _GCC_ARM_ACLE_H
      29  
      30  #include <stdint.h>
      31  #include <stddef.h>
      32  
      33  #pragma GCC aarch64 "arm_acle.h"
      34  
      35  #ifdef __cplusplus
      36  extern "C" {
      37  #endif
      38  
      39  #define _GCC_ARM_ACLE_ROR_FN(NAME, TYPE)				  \
      40  __extension__ extern __inline TYPE					  \
      41  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))	  \
      42  NAME (TYPE __value, uint32_t __rotate)					  \
      43  {									  \
      44    size_t __size = sizeof (TYPE) * __CHAR_BIT__;				  \
      45    __rotate = __rotate % __size;						  \
      46    return __value >> __rotate | __value << ((__size - __rotate) % __size); \
      47  }
      48  
      49  _GCC_ARM_ACLE_ROR_FN (__ror, uint32_t)
      50  _GCC_ARM_ACLE_ROR_FN (__rorl, unsigned long)
      51  _GCC_ARM_ACLE_ROR_FN (__rorll, uint64_t)
      52  
      53  #undef _GCC_ARM_ACLE_ROR_FN
      54  
      55  #define _GCC_ARM_ACLE_DATA_FN(NAME, BUILTIN, ITYPE, RTYPE)	    \
      56  __extension__ extern __inline RTYPE				    \
      57  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) \
      58  __##NAME (ITYPE __value)					    \
      59  {								    \
      60    return __builtin_##BUILTIN (__value);				    \
      61  }
      62  
      63  _GCC_ARM_ACLE_DATA_FN (clz, clz, uint32_t, unsigned int)
      64  _GCC_ARM_ACLE_DATA_FN (clzl, clzl, unsigned long, unsigned int)
      65  _GCC_ARM_ACLE_DATA_FN (clzll, clzll, uint64_t, unsigned int)
      66  _GCC_ARM_ACLE_DATA_FN (cls, clrsb, uint32_t, unsigned int)
      67  _GCC_ARM_ACLE_DATA_FN (clsl, clrsbl, unsigned long, unsigned int)
      68  _GCC_ARM_ACLE_DATA_FN (clsll, clrsbll, uint64_t, unsigned int)
      69  _GCC_ARM_ACLE_DATA_FN (rev16, aarch64_rev16, uint32_t, uint32_t)
      70  _GCC_ARM_ACLE_DATA_FN (rev16l, aarch64_rev16l, unsigned long, unsigned long)
      71  _GCC_ARM_ACLE_DATA_FN (rev16ll, aarch64_rev16ll, uint64_t, uint64_t)
      72  _GCC_ARM_ACLE_DATA_FN (rbit, aarch64_rbit, uint32_t, uint32_t)
      73  _GCC_ARM_ACLE_DATA_FN (rbitl, aarch64_rbitl, unsigned long, unsigned long)
      74  _GCC_ARM_ACLE_DATA_FN (rbitll, aarch64_rbitll, uint64_t, uint64_t)
      75  _GCC_ARM_ACLE_DATA_FN (revsh, bswap16, int16_t, int16_t)
      76  _GCC_ARM_ACLE_DATA_FN (rev, bswap32, uint32_t, uint32_t)
      77  _GCC_ARM_ACLE_DATA_FN (revll, bswap64, uint64_t, uint64_t)
      78  
      79  #undef _GCC_ARM_ACLE_DATA_FN
      80  
      81  __extension__ extern __inline unsigned long
      82  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
      83  __revl (unsigned long __value)
      84  {
      85    if (sizeof (unsigned long) == 8)
      86      return __revll (__value);
      87    else
      88      return __rev (__value);
      89  }
      90  
      91  #pragma GCC push_options
      92  #pragma GCC target ("arch=armv8.3-a")
      93  __extension__ extern __inline int32_t
      94  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
      95  __jcvt (double __a)
      96  {
      97    return __builtin_aarch64_jcvtzs (__a);
      98  }
      99  
     100  #pragma GCC pop_options
     101  
     102  #pragma GCC push_options
     103  #pragma GCC target ("arch=armv8.5-a")
     104  __extension__ extern __inline float
     105  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     106  __rint32zf (float __a)
     107  {
     108    return __builtin_aarch64_frint32zsf (__a);
     109  }
     110  
     111  __extension__ extern __inline double
     112  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     113  __rint32z (double __a)
     114  {
     115    return __builtin_aarch64_frint32zdf (__a);
     116  }
     117  
     118  __extension__ extern __inline float
     119  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     120  __rint64zf (float __a)
     121  {
     122    return __builtin_aarch64_frint64zsf (__a);
     123  }
     124  
     125  __extension__ extern __inline double
     126  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     127  __rint64z (double __a)
     128  {
     129    return __builtin_aarch64_frint64zdf (__a);
     130  }
     131  
     132  __extension__ extern __inline float
     133  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     134  __rint32xf (float __a)
     135  {
     136    return __builtin_aarch64_frint32xsf (__a);
     137  }
     138  
     139  __extension__ extern __inline double
     140  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     141  __rint32x (double __a)
     142  {
     143    return __builtin_aarch64_frint32xdf (__a);
     144  }
     145  
     146  __extension__ extern __inline float
     147  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     148  __rint64xf (float __a)
     149  {
     150    return __builtin_aarch64_frint64xsf (__a);
     151  }
     152  
     153  __extension__ extern __inline double
     154  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     155  __rint64x (double __a)
     156  {
     157    return __builtin_aarch64_frint64xdf (__a);
     158  }
     159  
     160  
     161  #pragma GCC pop_options
     162  
     163  #pragma GCC push_options
     164  
     165  #pragma GCC target ("+nothing+crc")
     166  
     167  __extension__ extern __inline uint32_t
     168  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     169  __crc32b (uint32_t __a, uint8_t __b)
     170  {
     171    return __builtin_aarch64_crc32b (__a, __b);
     172  }
     173  
     174  __extension__ extern __inline uint32_t
     175  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     176  __crc32cb (uint32_t __a, uint8_t __b)
     177  {
     178    return __builtin_aarch64_crc32cb (__a, __b);
     179  }
     180  
     181  __extension__ extern __inline uint32_t
     182  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     183  __crc32ch (uint32_t __a, uint16_t __b)
     184  {
     185    return __builtin_aarch64_crc32ch (__a, __b);
     186  }
     187  
     188  __extension__ extern __inline uint32_t
     189  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     190  __crc32cw (uint32_t __a, uint32_t __b)
     191  {
     192    return __builtin_aarch64_crc32cw (__a, __b);
     193  }
     194  
     195  __extension__ extern __inline uint32_t
     196  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     197  __crc32cd (uint32_t __a, uint64_t __b)
     198  {
     199    return __builtin_aarch64_crc32cx (__a, __b);
     200  }
     201  
     202  __extension__ extern __inline uint32_t
     203  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     204  __crc32h (uint32_t __a, uint16_t __b)
     205  {
     206    return __builtin_aarch64_crc32h (__a, __b);
     207  }
     208  
     209  __extension__ extern __inline uint32_t
     210  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     211  __crc32w (uint32_t __a, uint32_t __b)
     212  {
     213    return __builtin_aarch64_crc32w (__a, __b);
     214  }
     215  
     216  __extension__ extern __inline uint32_t
     217  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     218  __crc32d (uint32_t __a, uint64_t __b)
     219  {
     220    return __builtin_aarch64_crc32x (__a, __b);
     221  }
     222  
     223  #pragma GCC pop_options
     224  
     225  #ifdef __ARM_FEATURE_TME
     226  #pragma GCC push_options
     227  #pragma GCC target ("+nothing+tme")
     228  
     229  #define _TMFAILURE_REASON     0x00007fffu
     230  #define _TMFAILURE_RTRY       0x00008000u
     231  #define _TMFAILURE_CNCL       0x00010000u
     232  #define _TMFAILURE_MEM        0x00020000u
     233  #define _TMFAILURE_IMP        0x00040000u
     234  #define _TMFAILURE_ERR        0x00080000u
     235  #define _TMFAILURE_SIZE       0x00100000u
     236  #define _TMFAILURE_NEST       0x00200000u
     237  #define _TMFAILURE_DBG        0x00400000u
     238  #define _TMFAILURE_INT        0x00800000u
     239  #define _TMFAILURE_TRIVIAL    0x01000000u
     240  
     241  __extension__ extern __inline uint64_t
     242  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     243  __tstart (void)
     244  {
     245    return __builtin_aarch64_tstart ();
     246  }
     247  
     248  __extension__ extern __inline void
     249  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     250  __tcommit (void)
     251  {
     252    __builtin_aarch64_tcommit ();
     253  }
     254  
     255  __extension__ extern __inline void
     256  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     257  __tcancel (const uint64_t __reason)
     258  {
     259    __builtin_aarch64_tcancel (__reason);
     260  }
     261  
     262  __extension__ extern __inline uint64_t
     263  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     264  __ttest (void)
     265  {
     266    return __builtin_aarch64_ttest ();
     267  }
     268  
     269  #pragma GCC pop_options
     270  #endif
     271  
     272  #ifdef __ARM_FEATURE_LS64
     273  typedef __arm_data512_t data512_t;
     274  #endif
     275  
     276  #pragma GCC push_options
     277  #pragma GCC target ("+nothing+rng")
     278  __extension__ extern __inline int
     279  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     280  __rndr (uint64_t *__res)
     281  {
     282    return __builtin_aarch64_rndr (__res);
     283  }
     284  
     285  __extension__ extern __inline int
     286  __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
     287  __rndrrs (uint64_t *__res)
     288  {
     289    return __builtin_aarch64_rndrrs (__res);
     290  }
     291  
     292  #pragma GCC pop_options
     293  
     294  #pragma GCC push_options
     295  #pragma GCC target ("+nothing+memtag")
     296  
     297  #define __arm_mte_create_random_tag(__ptr, __u64_mask) \
     298    __builtin_aarch64_memtag_irg(__ptr, __u64_mask)
     299  
     300  #define __arm_mte_exclude_tag(__ptr, __u64_excluded) \
     301    __builtin_aarch64_memtag_gmi(__ptr, __u64_excluded)
     302  
     303  #define __arm_mte_ptrdiff(__ptr_a, __ptr_b) \
     304    __builtin_aarch64_memtag_subp(__ptr_a, __ptr_b)
     305  
     306  #define __arm_mte_increment_tag(__ptr, __u_offset) \
     307    __builtin_aarch64_memtag_inc_tag(__ptr, __u_offset)
     308  
     309  #define __arm_mte_set_tag(__tagged_address) \
     310    __builtin_aarch64_memtag_set_tag(__tagged_address)
     311  
     312  #define __arm_mte_get_tag(__address) \
     313    __builtin_aarch64_memtag_get_tag(__address)
     314  
     315  #pragma GCC pop_options
     316  
     317  #ifdef __cplusplus
     318  }
     319  #endif
     320  
     321  #endif