/* Intrinsics for LoongArch BASE operations. Copyright (C) 2021-2022 Free Software Foundation, Inc. Contributed by Loongson Ltd. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ #ifndef _GCC_LOONGARCH_BASE_INTRIN_H #define _GCC_LOONGARCH_BASE_INTRIN_H #ifdef __cplusplus extern "C" { #endif typedef struct drdtime { unsigned long dvalue; unsigned long dtimeid; } __drdtime_t; typedef struct rdtime { unsigned int value; unsigned int timeid; } __rdtime_t; #ifdef __loongarch64 extern __inline __drdtime_t __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __rdtime_d (void) { __drdtime_t __drdtime; __asm__ volatile ( "rdtime.d\t%[val],%[tid]\n\t" : [val]"=&r"(__drdtime.dvalue),[tid]"=&r"(__drdtime.dtimeid) :); return __drdtime; } #endif extern __inline __rdtime_t __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __rdtimeh_w (void) { __rdtime_t __rdtime; __asm__ volatile ( "rdtimeh.w\t%[val],%[tid]\n\t" : [val]"=&r"(__rdtime.value),[tid]"=&r"(__rdtime.timeid) :); return __rdtime; } extern __inline __rdtime_t __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __rdtimel_w (void) { __rdtime_t __rdtime; __asm__ volatile ( "rdtimel.w\t%[val],%[tid]\n\t" : [val]"=&r"(__rdtime.value),[tid]"=&r"(__rdtime.timeid) :); return __rdtime; } /* Assembly instruction format: rj, fcsr. */ /* Data types in instruction templates: USI, UQI. */ #define __movfcsr2gr(/*ui5*/ _1) __builtin_loongarch_movfcsr2gr ((_1)); /* Assembly instruction format: fcsr, rj. */ /* Data types in instruction templates: VOID, UQI, USI. */ #define __movgr2fcsr(/*ui5*/ _1, _2) \ __builtin_loongarch_movgr2fcsr ((_1), (unsigned int) _2); #if defined __loongarch64 /* Assembly instruction format: ui5, rj, si12. */ /* Data types in instruction templates: VOID, USI, UDI, SI. */ #define __cacop_d(/*ui5*/ _1, /*unsigned long int*/ _2, /*si12*/ _3) \ ((void) __builtin_loongarch_cacop_d ((_1), (unsigned long int) (_2), (_3))) #else #error "Unsupported ABI." #endif /* Assembly instruction format: rd, rj. */ /* Data types in instruction templates: USI, USI. */ extern __inline unsigned int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __cpucfg (unsigned int _1) { return (unsigned int) __builtin_loongarch_cpucfg ((unsigned int) _1); } #ifdef __loongarch64 /* Assembly instruction format: rj, rk. */ /* Data types in instruction templates: DI, DI. */ extern __inline void __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __asrtle_d (long int _1, long int _2) { __builtin_loongarch_asrtle_d ((long int) _1, (long int) _2); } /* Assembly instruction format: rj, rk. */ /* Data types in instruction templates: DI, DI. */ extern __inline void __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __asrtgt_d (long int _1, long int _2) { __builtin_loongarch_asrtgt_d ((long int) _1, (long int) _2); } #endif #if defined __loongarch64 /* Assembly instruction format: rd, rj, ui5. */ /* Data types in instruction templates: DI, DI, UQI. */ #define __lddir_d(/*long int*/ _1, /*ui5*/ _2) \ ((long int) __builtin_loongarch_lddir_d ((long int) (_1), (_2))) #else #error "Unsupported ABI." #endif #if defined __loongarch64 /* Assembly instruction format: rj, ui5. */ /* Data types in instruction templates: VOID, DI, UQI. */ #define __ldpte_d(/*long int*/ _1, /*ui5*/ _2) \ ((void) __builtin_loongarch_ldpte_d ((long int) (_1), (_2))) #else #error "Unsupported ABI." #endif /* Assembly instruction format: rd, rj, rk. */ /* Data types in instruction templates: SI, QI, SI. */ extern __inline int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __crc_w_b_w (char _1, int _2) { return (int) __builtin_loongarch_crc_w_b_w ((char) _1, (int) _2); } /* Assembly instruction format: rd, rj, rk. */ /* Data types in instruction templates: SI, HI, SI. */ extern __inline int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __crc_w_h_w (short _1, int _2) { return (int) __builtin_loongarch_crc_w_h_w ((short) _1, (int) _2); } /* Assembly instruction format: rd, rj, rk. */ /* Data types in instruction templates: SI, SI, SI. */ extern __inline int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __crc_w_w_w (int _1, int _2) { return (int) __builtin_loongarch_crc_w_w_w ((int) _1, (int) _2); } #ifdef __loongarch64 /* Assembly instruction format: rd, rj, rk. */ /* Data types in instruction templates: SI, DI, SI. */ extern __inline int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __crc_w_d_w (long int _1, int _2) { return (int) __builtin_loongarch_crc_w_d_w ((long int) _1, (int) _2); } #endif /* Assembly instruction format: rd, rj, rk. */ /* Data types in instruction templates: SI, QI, SI. */ extern __inline int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __crcc_w_b_w (char _1, int _2) { return (int) __builtin_loongarch_crcc_w_b_w ((char) _1, (int) _2); } /* Assembly instruction format: rd, rj, rk. */ /* Data types in instruction templates: SI, HI, SI. */ extern __inline int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __crcc_w_h_w (short _1, int _2) { return (int) __builtin_loongarch_crcc_w_h_w ((short) _1, (int) _2); } /* Assembly instruction format: rd, rj, rk. */ /* Data types in instruction templates: SI, SI, SI. */ extern __inline int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __crcc_w_w_w (int _1, int _2) { return (int) __builtin_loongarch_crcc_w_w_w ((int) _1, (int) _2); } #ifdef __loongarch64 /* Assembly instruction format: rd, rj, rk. */ /* Data types in instruction templates: SI, DI, SI. */ extern __inline int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __crcc_w_d_w (long int _1, int _2) { return (int) __builtin_loongarch_crcc_w_d_w ((long int) _1, (int) _2); } #endif /* Assembly instruction format: rd, ui14. */ /* Data types in instruction templates: USI, USI. */ #define __csrrd_w(/*ui14*/ _1) \ ((unsigned int) __builtin_loongarch_csrrd_w ((_1))) /* Assembly instruction format: rd, ui14. */ /* Data types in instruction templates: USI, USI, USI. */ #define __csrwr_w(/*unsigned int*/ _1, /*ui14*/ _2) \ ((unsigned int) __builtin_loongarch_csrwr_w ((unsigned int) (_1), (_2))) /* Assembly instruction format: rd, rj, ui14. */ /* Data types in instruction templates: USI, USI, USI, USI. */ #define __csrxchg_w(/*unsigned int*/ _1, /*unsigned int*/ _2, /*ui14*/ _3) \ ((unsigned int) __builtin_loongarch_csrxchg_w ((unsigned int) (_1), \ (unsigned int) (_2), (_3))) #ifdef __loongarch64 /* Assembly instruction format: rd, ui14. */ /* Data types in instruction templates: UDI, USI. */ #define __csrrd_d(/*ui14*/ _1) \ ((unsigned long int) __builtin_loongarch_csrrd_d ((_1))) /* Assembly instruction format: rd, ui14. */ /* Data types in instruction templates: UDI, UDI, USI. */ #define __csrwr_d(/*unsigned long int*/ _1, /*ui14*/ _2) \ ((unsigned long int) __builtin_loongarch_csrwr_d ((unsigned long int) (_1), \ (_2))) /* Assembly instruction format: rd, rj, ui14. */ /* Data types in instruction templates: UDI, UDI, UDI, USI. */ #define __csrxchg_d(/*unsigned long int*/ _1, /*unsigned long int*/ _2, \ /*ui14*/ _3) \ ((unsigned long int) __builtin_loongarch_csrxchg_d ( \ (unsigned long int) (_1), (unsigned long int) (_2), (_3))) #endif /* Assembly instruction format: rd, rj. */ /* Data types in instruction templates: UQI, USI. */ extern __inline unsigned char __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __iocsrrd_b (unsigned int _1) { return (unsigned char) __builtin_loongarch_iocsrrd_b ((unsigned int) _1); } /* Assembly instruction format: rd, rj. */ /* Data types in instruction templates: UHI, USI. */ extern __inline unsigned char __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __iocsrrd_h (unsigned int _1) { return (unsigned short) __builtin_loongarch_iocsrrd_h ((unsigned int) _1); } /* Assembly instruction format: rd, rj. */ /* Data types in instruction templates: USI, USI. */ extern __inline unsigned int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __iocsrrd_w (unsigned int _1) { return (unsigned int) __builtin_loongarch_iocsrrd_w ((unsigned int) _1); } #ifdef __loongarch64 /* Assembly instruction format: rd, rj. */ /* Data types in instruction templates: UDI, USI. */ extern __inline unsigned long int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __iocsrrd_d (unsigned int _1) { return (unsigned long int) __builtin_loongarch_iocsrrd_d ((unsigned int) _1); } #endif /* Assembly instruction format: rd, rj. */ /* Data types in instruction templates: VOID, UQI, USI. */ extern __inline void __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __iocsrwr_b (unsigned char _1, unsigned int _2) { __builtin_loongarch_iocsrwr_b ((unsigned char) _1, (unsigned int) _2); } /* Assembly instruction format: rd, rj. */ /* Data types in instruction templates: VOID, UHI, USI. */ extern __inline void __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __iocsrwr_h (unsigned short _1, unsigned int _2) { __builtin_loongarch_iocsrwr_h ((unsigned short) _1, (unsigned int) _2); } /* Assembly instruction format: rd, rj. */ /* Data types in instruction templates: VOID, USI, USI. */ extern __inline void __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __iocsrwr_w (unsigned int _1, unsigned int _2) { __builtin_loongarch_iocsrwr_w ((unsigned int) _1, (unsigned int) _2); } #ifdef __loongarch64 /* Assembly instruction format: rd, rj. */ /* Data types in instruction templates: VOID, UDI, USI. */ extern __inline void __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __iocsrwr_d (unsigned long int _1, unsigned int _2) { __builtin_loongarch_iocsrwr_d ((unsigned long int) _1, (unsigned int) _2); } #endif /* Assembly instruction format: ui15. */ /* Data types in instruction templates: USI. */ #define __dbar(/*ui15*/ _1) __builtin_loongarch_dbar ((_1)) /* Assembly instruction format: ui15. */ /* Data types in instruction templates: USI. */ #define __ibar(/*ui15*/ _1) __builtin_loongarch_ibar ((_1)) /* Assembly instruction format: ui15. */ /* Data types in instruction templates: USI. */ #define __syscall(/*ui15*/ _1) __builtin_loongarch_syscall ((_1)) /* Assembly instruction format: ui15. */ /* Data types in instruction templates: USI. */ #define __break(/*ui15*/ _1) __builtin_loongarch_break ((_1)) #ifdef __cplusplus } #endif #endif /* _GCC_LOONGARCH_BASE_INTRIN_H */