1  /* Intrinsics for LoongArch BASE operations.
       2     Copyright (C) 2021-2023 Free Software Foundation, Inc.
       3     Contributed by Loongson Ltd.
       4  
       5  This file is part of GCC.
       6  
       7  GCC is free software; you can redistribute it and/or modify it
       8  under the terms of the GNU General Public License as published
       9  by the Free Software Foundation; either version 3, or (at your
      10  option) any later version.
      11  
      12  GCC is distributed in the hope that it will be useful, but WITHOUT
      13  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      14  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
      15  License for more details.
      16  
      17  Under Section 7 of GPL version 3, you are granted additional
      18  permissions described in the GCC Runtime Library Exception, version
      19  3.1, as published by the Free Software Foundation.
      20  
      21  You should have received a copy of the GNU General Public License and
      22  a copy of the GCC Runtime Library Exception along with this program;
      23  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      24  <http://www.gnu.org/licenses/>.  */
      25  
      26  #ifndef _GCC_LOONGARCH_BASE_INTRIN_H
      27  #define _GCC_LOONGARCH_BASE_INTRIN_H
      28  
      29  #ifdef __cplusplus
      30  extern "C" {
      31  #endif
      32  
      33  typedef struct drdtime
      34  {
      35    unsigned long dvalue;
      36    unsigned long dtimeid;
      37  } __drdtime_t;
      38  
      39  typedef struct rdtime
      40  {
      41    unsigned int value;
      42    unsigned int timeid;
      43  } __rdtime_t;
      44  
      45  #ifdef __loongarch64
      46  extern __inline __drdtime_t
      47  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
      48  __rdtime_d (void)
      49  {
      50    __drdtime_t __drdtime;
      51    __asm__ volatile (
      52      "rdtime.d\t%[val],%[tid]\n\t"
      53      : [val]"=&r"(__drdtime.dvalue),[tid]"=&r"(__drdtime.dtimeid)
      54      :);
      55    return __drdtime;
      56  }
      57  #endif
      58  
      59  extern __inline __rdtime_t
      60  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
      61  __rdtimeh_w (void)
      62  {
      63    __rdtime_t __rdtime;
      64    __asm__ volatile (
      65      "rdtimeh.w\t%[val],%[tid]\n\t"
      66      : [val]"=&r"(__rdtime.value),[tid]"=&r"(__rdtime.timeid)
      67      :);
      68    return __rdtime;
      69  }
      70  
      71  extern __inline __rdtime_t
      72  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
      73  __rdtimel_w (void)
      74  {
      75    __rdtime_t __rdtime;
      76    __asm__ volatile (
      77      "rdtimel.w\t%[val],%[tid]\n\t"
      78      : [val]"=&r"(__rdtime.value),[tid]"=&r"(__rdtime.timeid)
      79      :);
      80    return __rdtime;
      81  }
      82  
      83  /* Assembly instruction format:	rj, fcsr.  */
      84  /* Data types in instruction templates:  USI, UQI.  */
      85  #define __movfcsr2gr(/*ui5*/ _1) __builtin_loongarch_movfcsr2gr ((_1));
      86  
      87  /* Assembly instruction format:	fcsr, rj.  */
      88  /* Data types in instruction templates:  VOID, UQI, USI.  */
      89  #define __movgr2fcsr(/*ui5*/ _1, _2) \
      90    __builtin_loongarch_movgr2fcsr ((_1), (unsigned int) _2);
      91  
      92  #if defined __loongarch64
      93  /* Assembly instruction format:	ui5, rj, si12.  */
      94  /* Data types in instruction templates:  VOID, USI, UDI, SI.  */
      95  #define __cacop_d(/*ui5*/ _1, /*unsigned long int*/ _2, /*si12*/ _3) \
      96    ((void) __builtin_loongarch_cacop_d ((_1), (unsigned long int) (_2), (_3)))
      97  #else
      98  #error "Unsupported ABI."
      99  #endif
     100  
     101  /* Assembly instruction format:	rd, rj.  */
     102  /* Data types in instruction templates:  USI, USI.  */
     103  extern __inline unsigned int
     104  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     105  __cpucfg (unsigned int _1)
     106  {
     107    return (unsigned int) __builtin_loongarch_cpucfg ((unsigned int) _1);
     108  }
     109  
     110  #ifdef __loongarch64
     111  /* Assembly instruction format:	rj, rk.  */
     112  /* Data types in instruction templates:  DI, DI.  */
     113  extern __inline void
     114  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     115  __asrtle_d (long int _1, long int _2)
     116  {
     117    __builtin_loongarch_asrtle_d ((long int) _1, (long int) _2);
     118  }
     119  
     120  /* Assembly instruction format:	rj, rk.  */
     121  /* Data types in instruction templates:  DI, DI.  */
     122  extern __inline void
     123  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     124  __asrtgt_d (long int _1, long int _2)
     125  {
     126    __builtin_loongarch_asrtgt_d ((long int) _1, (long int) _2);
     127  }
     128  #endif
     129  
     130  #if defined __loongarch64
     131  /* Assembly instruction format:	rd, rj, ui5.  */
     132  /* Data types in instruction templates:  DI, DI, UQI.  */
     133  #define __lddir_d(/*long int*/ _1, /*ui5*/ _2) \
     134    ((long int) __builtin_loongarch_lddir_d ((long int) (_1), (_2)))
     135  #else
     136  #error "Unsupported ABI."
     137  #endif
     138  
     139  #if defined __loongarch64
     140  /* Assembly instruction format:	rj, ui5.  */
     141  /* Data types in instruction templates:  VOID, DI, UQI.  */
     142  #define __ldpte_d(/*long int*/ _1, /*ui5*/ _2) \
     143    ((void) __builtin_loongarch_ldpte_d ((long int) (_1), (_2)))
     144  #else
     145  #error "Unsupported ABI."
     146  #endif
     147  
     148  /* Assembly instruction format:	rd, rj, rk.  */
     149  /* Data types in instruction templates:  SI, QI, SI.  */
     150  extern __inline int
     151  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     152  __crc_w_b_w (char _1, int _2)
     153  {
     154    return (int) __builtin_loongarch_crc_w_b_w ((char) _1, (int) _2);
     155  }
     156  
     157  /* Assembly instruction format:	rd, rj, rk.  */
     158  /* Data types in instruction templates:  SI, HI, SI.  */
     159  extern __inline int
     160  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     161  __crc_w_h_w (short _1, int _2)
     162  {
     163    return (int) __builtin_loongarch_crc_w_h_w ((short) _1, (int) _2);
     164  }
     165  
     166  /* Assembly instruction format:	rd, rj, rk.  */
     167  /* Data types in instruction templates:  SI, SI, SI.  */
     168  extern __inline int
     169  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     170  __crc_w_w_w (int _1, int _2)
     171  {
     172    return (int) __builtin_loongarch_crc_w_w_w ((int) _1, (int) _2);
     173  }
     174  
     175  #ifdef __loongarch64
     176  /* Assembly instruction format:	rd, rj, rk.  */
     177  /* Data types in instruction templates:  SI, DI, SI.  */
     178  extern __inline int
     179  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     180  __crc_w_d_w (long int _1, int _2)
     181  {
     182    return (int) __builtin_loongarch_crc_w_d_w ((long int) _1, (int) _2);
     183  }
     184  #endif
     185  
     186  /* Assembly instruction format:	rd, rj, rk.  */
     187  /* Data types in instruction templates:  SI, QI, SI.  */
     188  extern __inline int
     189  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     190  __crcc_w_b_w (char _1, int _2)
     191  {
     192    return (int) __builtin_loongarch_crcc_w_b_w ((char) _1, (int) _2);
     193  }
     194  
     195  /* Assembly instruction format:	rd, rj, rk.  */
     196  /* Data types in instruction templates:  SI, HI, SI.  */
     197  extern __inline int
     198  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     199  __crcc_w_h_w (short _1, int _2)
     200  {
     201    return (int) __builtin_loongarch_crcc_w_h_w ((short) _1, (int) _2);
     202  }
     203  
     204  /* Assembly instruction format:	rd, rj, rk.  */
     205  /* Data types in instruction templates:  SI, SI, SI.  */
     206  extern __inline int
     207  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     208  __crcc_w_w_w (int _1, int _2)
     209  {
     210    return (int) __builtin_loongarch_crcc_w_w_w ((int) _1, (int) _2);
     211  }
     212  
     213  #ifdef __loongarch64
     214  /* Assembly instruction format:	rd, rj, rk.  */
     215  /* Data types in instruction templates:  SI, DI, SI.  */
     216  extern __inline int
     217  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     218  __crcc_w_d_w (long int _1, int _2)
     219  {
     220    return (int) __builtin_loongarch_crcc_w_d_w ((long int) _1, (int) _2);
     221  }
     222  #endif
     223  
     224  /* Assembly instruction format:	rd, ui14.  */
     225  /* Data types in instruction templates:  USI, USI.  */
     226  #define __csrrd_w(/*ui14*/ _1) \
     227    ((unsigned int) __builtin_loongarch_csrrd_w ((_1)))
     228  
     229  /* Assembly instruction format:	rd, ui14.  */
     230  /* Data types in instruction templates:  USI, USI, USI.  */
     231  #define __csrwr_w(/*unsigned int*/ _1, /*ui14*/ _2) \
     232    ((unsigned int) __builtin_loongarch_csrwr_w ((unsigned int) (_1), (_2)))
     233  
     234  /* Assembly instruction format:	rd, rj, ui14.  */
     235  /* Data types in instruction templates:  USI, USI, USI, USI.  */
     236  #define __csrxchg_w(/*unsigned int*/ _1, /*unsigned int*/ _2, /*ui14*/ _3) \
     237    ((unsigned int) __builtin_loongarch_csrxchg_w ((unsigned int) (_1), \
     238  					       (unsigned int) (_2), (_3)))
     239  
     240  #ifdef __loongarch64
     241  /* Assembly instruction format:	rd, ui14.  */
     242  /* Data types in instruction templates:  UDI, USI.  */
     243  #define __csrrd_d(/*ui14*/ _1) \
     244    ((unsigned long int) __builtin_loongarch_csrrd_d ((_1)))
     245  
     246  /* Assembly instruction format:	rd, ui14.  */
     247  /* Data types in instruction templates:  UDI, UDI, USI.  */
     248  #define __csrwr_d(/*unsigned long int*/ _1, /*ui14*/ _2) \
     249    ((unsigned long int) __builtin_loongarch_csrwr_d ((unsigned long int) (_1), \
     250  						   (_2)))
     251  
     252  /* Assembly instruction format:	rd, rj, ui14.  */
     253  /* Data types in instruction templates:  UDI, UDI, UDI, USI.  */
     254  #define __csrxchg_d(/*unsigned long int*/ _1, /*unsigned long int*/ _2, \
     255  		   /*ui14*/ _3) \
     256    ((unsigned long int) __builtin_loongarch_csrxchg_d ( \
     257      (unsigned long int) (_1), (unsigned long int) (_2), (_3)))
     258  #endif
     259  
     260  /* Assembly instruction format:	rd, rj.  */
     261  /* Data types in instruction templates:  UQI, USI.  */
     262  extern __inline unsigned char
     263  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     264  __iocsrrd_b (unsigned int _1)
     265  {
     266    return (unsigned char) __builtin_loongarch_iocsrrd_b ((unsigned int) _1);
     267  }
     268  
     269  /* Assembly instruction format:	rd, rj.  */
     270  /* Data types in instruction templates:  UHI, USI.  */
     271  extern __inline unsigned char
     272  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     273  __iocsrrd_h (unsigned int _1)
     274  {
     275    return (unsigned short) __builtin_loongarch_iocsrrd_h ((unsigned int) _1);
     276  }
     277  
     278  /* Assembly instruction format:	rd, rj.  */
     279  /* Data types in instruction templates:  USI, USI.  */
     280  extern __inline unsigned int
     281  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     282  __iocsrrd_w (unsigned int _1)
     283  {
     284    return (unsigned int) __builtin_loongarch_iocsrrd_w ((unsigned int) _1);
     285  }
     286  
     287  #ifdef __loongarch64
     288  /* Assembly instruction format:	rd, rj.  */
     289  /* Data types in instruction templates:  UDI, USI.  */
     290  extern __inline unsigned long int
     291  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     292  __iocsrrd_d (unsigned int _1)
     293  {
     294    return (unsigned long int) __builtin_loongarch_iocsrrd_d ((unsigned int) _1);
     295  }
     296  #endif
     297  
     298  /* Assembly instruction format:	rd, rj.  */
     299  /* Data types in instruction templates:  VOID, UQI, USI.  */
     300  extern __inline void
     301  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     302  __iocsrwr_b (unsigned char _1, unsigned int _2)
     303  {
     304    __builtin_loongarch_iocsrwr_b ((unsigned char) _1, (unsigned int) _2);
     305  }
     306  
     307  /* Assembly instruction format:	rd, rj.  */
     308  /* Data types in instruction templates:  VOID, UHI, USI.  */
     309  extern __inline void
     310  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     311  __iocsrwr_h (unsigned short _1, unsigned int _2)
     312  {
     313    __builtin_loongarch_iocsrwr_h ((unsigned short) _1, (unsigned int) _2);
     314  }
     315  
     316  /* Assembly instruction format:	rd, rj.  */
     317  /* Data types in instruction templates:  VOID, USI, USI.  */
     318  extern __inline void
     319  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     320  __iocsrwr_w (unsigned int _1, unsigned int _2)
     321  {
     322    __builtin_loongarch_iocsrwr_w ((unsigned int) _1, (unsigned int) _2);
     323  }
     324  
     325  #ifdef __loongarch64
     326  /* Assembly instruction format:	rd, rj.  */
     327  /* Data types in instruction templates:  VOID, UDI, USI.  */
     328  extern __inline void
     329  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
     330  __iocsrwr_d (unsigned long int _1, unsigned int _2)
     331  {
     332    __builtin_loongarch_iocsrwr_d ((unsigned long int) _1, (unsigned int) _2);
     333  }
     334  #endif
     335  
     336  /* Assembly instruction format:	ui15.  */
     337  /* Data types in instruction templates:  USI.  */
     338  #define __dbar(/*ui15*/ _1) __builtin_loongarch_dbar ((_1))
     339  
     340  /* Assembly instruction format:	ui15.  */
     341  /* Data types in instruction templates:  USI.  */
     342  #define __ibar(/*ui15*/ _1) __builtin_loongarch_ibar ((_1))
     343  
     344  /* Assembly instruction format:	ui15.  */
     345  /* Data types in instruction templates:  USI.  */
     346  #define __syscall(/*ui15*/ _1) __builtin_loongarch_syscall ((_1))
     347  
     348  /* Assembly instruction format:	ui15.  */
     349  /* Data types in instruction templates:  USI.  */
     350  #define __break(/*ui15*/ _1) __builtin_loongarch_break ((_1))
     351  
     352  #ifdef __cplusplus
     353  }
     354  #endif
     355  #endif /* _GCC_LOONGARCH_BASE_INTRIN_H */