From: chenxiaolong Date: Tue, 24 Oct 2023 06:40:14 +0000 (+0800) Subject: LoongArch: Implement __builtin_thread_pointer for TLS. X-Git-Tag: releases/gcc-12.4.0~621 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41aab8301d79b35b60f9ba95913b484988ed08e1;p=thirdparty%2Fgcc.git LoongArch: Implement __builtin_thread_pointer for TLS. gcc/ChangeLog: * config/loongarch/loongarch.md (get_thread_pointer):Adds the instruction template corresponding to the __builtin_thread_pointer function. * doc/extend.texi:Add the __builtin_thread_pointer function support description to the documentation. gcc/testsuite/ChangeLog: * gcc.target/loongarch/builtin_thread_pointer.c: New test. (cherry picked from commit 1b30ef7cea773e0af527dbf821e0be42b6a264f8) --- diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index a64142c7a780..b49e058407c7 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -93,6 +93,7 @@ (define_constants [(RETURN_ADDR_REGNUM 1) + (TP_REGNUM 2) (T0_REGNUM 12) (T1_REGNUM 13) (S0_REGNUM 23) @@ -3295,6 +3296,12 @@ [(set_attr "length" "0") (set_attr "type" "ghost")]) +;; Named pattern for expanding thread pointer reference. +(define_expand "get_thread_pointer" + [(set (match_operand:P 0 "register_operand" "=r") + (reg:P TP_REGNUM))] + "HAVE_AS_TLS" + {}) (define_split [(match_operand 0 "small_data_pattern")] diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 33a776a7978c..0eb9bdcfac51 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -14618,6 +14618,7 @@ instructions, but allow the compiler to schedule those calls. * Blackfin Built-in Functions:: * BPF Built-in Functions:: * FR-V Built-in Functions:: +* LoongArch Base Built-in Functions:: * MIPS DSP Built-in Functions:: * MIPS Paired-Single Support:: * MIPS Loongson Built-in Functions:: @@ -16068,6 +16069,139 @@ Use the @code{nldub} instruction to load the contents of address @var{x} into the data cache. The instruction is issued in slot I1@. @end table +@node LoongArch Base Built-in Functions +@subsection LoongArch Base Built-in Functions + +These built-in functions are available for LoongArch. + +Data Type Description: +@itemize +@item @code{imm0_31}, a compile-time constant in range 0 to 31; +@item @code{imm0_16383}, a compile-time constant in range 0 to 16383; +@item @code{imm0_32767}, a compile-time constant in range 0 to 32767; +@item @code{imm_n2048_2047}, a compile-time constant in range -2048 to 2047; +@end itemize + +The intrinsics provided are listed below: +@smallexample + unsigned int __builtin_loongarch_movfcsr2gr (imm0_31) + void __builtin_loongarch_movgr2fcsr (imm0_31, unsigned int) + void __builtin_loongarch_cacop_d (imm0_31, unsigned long int, imm_n2048_2047) + unsigned int __builtin_loongarch_cpucfg (unsigned int) + void __builtin_loongarch_asrtle_d (long int, long int) + void __builtin_loongarch_asrtgt_d (long int, long int) + long int __builtin_loongarch_lddir_d (long int, imm0_31) + void __builtin_loongarch_ldpte_d (long int, imm0_31) + + int __builtin_loongarch_crc_w_b_w (char, int) + int __builtin_loongarch_crc_w_h_w (short, int) + int __builtin_loongarch_crc_w_w_w (int, int) + int __builtin_loongarch_crc_w_d_w (long int, int) + int __builtin_loongarch_crcc_w_b_w (char, int) + int __builtin_loongarch_crcc_w_h_w (short, int) + int __builtin_loongarch_crcc_w_w_w (int, int) + int __builtin_loongarch_crcc_w_d_w (long int, int) + + unsigned int __builtin_loongarch_csrrd_w (imm0_16383) + unsigned int __builtin_loongarch_csrwr_w (unsigned int, imm0_16383) + unsigned int __builtin_loongarch_csrxchg_w (unsigned int, unsigned int, imm0_16383) + unsigned long int __builtin_loongarch_csrrd_d (imm0_16383) + unsigned long int __builtin_loongarch_csrwr_d (unsigned long int, imm0_16383) + unsigned long int __builtin_loongarch_csrxchg_d (unsigned long int, unsigned long int, imm0_16383) + + unsigned char __builtin_loongarch_iocsrrd_b (unsigned int) + unsigned short __builtin_loongarch_iocsrrd_h (unsigned int) + unsigned int __builtin_loongarch_iocsrrd_w (unsigned int) + unsigned long int __builtin_loongarch_iocsrrd_d (unsigned int) + void __builtin_loongarch_iocsrwr_b (unsigned char, unsigned int) + void __builtin_loongarch_iocsrwr_h (unsigned short, unsigned int) + void __builtin_loongarch_iocsrwr_w (unsigned int, unsigned int) + void __builtin_loongarch_iocsrwr_d (unsigned long int, unsigned int) + + void __builtin_loongarch_dbar (imm0_32767) + void __builtin_loongarch_ibar (imm0_32767) + + void __builtin_loongarch_syscall (imm0_32767) + void __builtin_loongarch_break (imm0_32767) +@end smallexample + +@emph{Note:}Since the control register is divided into 32-bit and 64-bit, +but the access instruction is not distinguished. So GCC renames the control +instructions when implementing intrinsics. + +Take the csrrd instruction as an example, built-in functions are implemented as follows: +@smallexample + __builtin_loongarch_csrrd_w // When reading the 32-bit control register use. + __builtin_loongarch_csrrd_d // When reading the 64-bit control register use. +@end smallexample + +For the convenience of use, the built-in functions are encapsulated, +the encapsulated functions and @code{__drdtime_t, __rdtime_t} are +defined in the @code{larchintrin.h}. So if you call the following +function you need to include @code{larchintrin.h}. + +@smallexample + typedef struct drdtime@{ + unsigned long dvalue; + unsigned long dtimeid; + @} __drdtime_t; + + typedef struct rdtime@{ + unsigned int value; + unsigned int timeid; + @} __rdtime_t; +@end smallexample + +@smallexample + __drdtime_t __rdtime_d (void) + __rdtime_t __rdtimel_w (void) + __rdtime_t __rdtimeh_w (void) + unsigned int __movfcsr2gr (imm0_31) + void __movgr2fcsr (imm0_31, unsigned int) + void __cacop_d (imm0_31, unsigned long, imm_n2048_2047) + unsigned int __cpucfg (unsigned int) + void __asrtle_d (long int, long int) + void __asrtgt_d (long int, long int) + long int __lddir_d (long int, imm0_31) + void __ldpte_d (long int, imm0_31) + + int __crc_w_b_w (char, int) + int __crc_w_h_w (short, int) + int __crc_w_w_w (int, int) + int __crc_w_d_w (long int, int) + int __crcc_w_b_w (char, int) + int __crcc_w_h_w (short, int) + int __crcc_w_w_w (int, int) + int __crcc_w_d_w (long int, int) + + unsigned int __csrrd_w (imm0_16383) + unsigned int __csrwr_w (unsigned int, imm0_16383) + unsigned int __csrxchg_w (unsigned int, unsigned int, imm0_16383) + unsigned long __csrrd_d (imm0_16383) + unsigned long __csrwr_d (unsigned long, imm0_16383) + unsigned long __csrxchg_d (unsigned long, unsigned long, imm0_16383) + + unsigned char __iocsrrd_b (unsigned int) + unsigned short __iocsrrd_h (unsigned int) + unsigned int __iocsrrd_w (unsigned int) + unsigned long __iocsrrd_d (unsigned int) + void __iocsrwr_b (unsigned char, unsigned int) + void __iocsrwr_h (unsigned short, unsigned int) + void __iocsrwr_w (unsigned int, unsigned int) + void __iocsrwr_d (unsigned long, unsigned int) + + void __dbar (imm0_32767) + void __ibar (imm0_32767) + + void __syscall (imm0_32767) + void __break (imm0_32767) +@end smallexample + +Returns the value that is currently set in the @samp{tp} register. +@smallexample + void * __builtin_thread_pointer (void) +@end smallexample + @node MIPS DSP Built-in Functions @subsection MIPS DSP Built-in Functions diff --git a/gcc/testsuite/gcc.target/loongarch/builtin_thread_pointer.c b/gcc/testsuite/gcc.target/loongarch/builtin_thread_pointer.c new file mode 100644 index 000000000000..541e3b143bd2 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/builtin_thread_pointer.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target tls_native } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "or\t\\\$r4,\\\$r2,\\\$r0" } } */ + +void * +get_tp () +{ + return __builtin_thread_pointer (); +}