blob: 2833f148709c57eb8602949b6a4bc76b428c420a [file] [log] [blame]
/* 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
<http://www.gnu.org/licenses/>. */
#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 */