From e726703c27c417ffb5917eca4760ea3c4f4a62d5 Mon Sep 17 00:00:00 2001 From: gonglingqin Date: Thu, 22 Dec 2022 19:18:22 +0800 Subject: [PATCH] [Clang][LoongArch] Add intrinsic for rdtime_d, rdtimeh_w and rdtimel_w Add these intrinsics to keep consistent with GCC [1]. [1]: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/larchintrin.h#L33 Differential Revision: https://reviews.llvm.org/D139987 --- clang/lib/Headers/larchintrin.h | 40 ++++++++++++++++++++++ .../test/CodeGen/LoongArch/intrinsic-la32-error.c | 4 +++ clang/test/CodeGen/LoongArch/intrinsic-la32.c | 11 ++++++ clang/test/CodeGen/LoongArch/intrinsic-la64.c | 20 +++++++++++ 4 files changed, 75 insertions(+) diff --git a/clang/lib/Headers/larchintrin.h b/clang/lib/Headers/larchintrin.h index 22e6d40..524c134 100644 --- a/clang/lib/Headers/larchintrin.h +++ b/clang/lib/Headers/larchintrin.h @@ -14,6 +14,46 @@ extern "C" { #endif +typedef struct rdtime { + unsigned int value; + unsigned int timeid; +} __rdtime_t; + +#if __loongarch_grlen == 64 +typedef struct drdtime { + unsigned long dvalue; + unsigned long dtimeid; +} __drdtime_t; + +extern __inline __drdtime_t + __attribute__((__gnu_inline__, __always_inline__, __artificial__)) + __rdtime_d(void) { + __drdtime_t __drdtime; + __asm__ volatile( + "rdtime.d %[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 %[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 %[val], %[tid]\n\t" + : [val] "=&r"(__rdtime.value), [tid] "=&r"(__rdtime.timeid)); + return __rdtime; +} + #if __loongarch_grlen == 64 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la32-error.c b/clang/test/CodeGen/LoongArch/intrinsic-la32-error.c index 56ac396..cca7f14 100644 --- a/clang/test/CodeGen/LoongArch/intrinsic-la32-error.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la32-error.c @@ -111,3 +111,7 @@ void lddir_d(long int a, int b) { void ldpte_d(long int a, int b) { __builtin_loongarch_ldpte_d(a, 1); // expected-error {{this builtin requires target: loongarch64}} } + +void rdtime_d() { + __rdtime_d(); // expected-error {{call to undeclared function '__rdtime_d'}} +} diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la32.c b/clang/test/CodeGen/LoongArch/intrinsic-la32.c index 529732e..dbfa554 100644 --- a/clang/test/CodeGen/LoongArch/intrinsic-la32.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la32.c @@ -166,3 +166,14 @@ unsigned int cpucfg(unsigned int a) { unsigned int c = __builtin_loongarch_cpucfg(a); return 0; } + +// LA32-LABEL: @rdtime( +// LA32-NEXT: entry: +// LA32-NEXT: [[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !2 +// LA32-NEXT: [[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !3 +// LA32-NEXT: ret void +// +void rdtime() { + __rdtimeh_w(); + __rdtimel_w(); +} diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la64.c b/clang/test/CodeGen/LoongArch/intrinsic-la64.c index 11f5408..da39d45 100644 --- a/clang/test/CodeGen/LoongArch/intrinsic-la64.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la64.c @@ -373,3 +373,23 @@ unsigned int cpucfg(unsigned int a) { unsigned int c = __builtin_loongarch_cpucfg(a); return 0; } + +// CHECK-LABEL: @rdtime_d( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { i64, i64 } asm sideeffect "rdtime.d $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !2 +// CHECK-NEXT: ret void +// +void rdtime_d() { + __rdtime_d(); +} + +// CHECK-LABEL: @rdtime( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !3 +// CHECK-NEXT: [[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !4 +// CHECK-NEXT: ret void +// +void rdtime() { + __rdtimeh_w(); + __rdtimel_w(); +} -- 2.7.4