https://github.com/wzssyqa created https://github.com/llvm/llvm-project/pull/76894
On MIPS pre-R6, instruction b can only work within 64KiB, which is not enough now. We need the help of GOT. For __mips64, we can get GOT by: lui $t8, %hi(%neg(%gp_rel(SANITIZER_STRINGIFY(TRAMPOLINE(func))))) daddu $t8, $t8, $t9 daddiu $t8, $t8, %hi(%neg(%gp_rel(SANITIZER_STRINGIFY(TRAMPOLINE(func))))) And then get the address of __interceptor_func, and jump to it ld $t9, %got_disp(__interceptor_" SANITIZER_STRINGIFY(func) ")($t8) jr $t9 MIPS/O32 has .cpload, which can help to generate 3 instructions to get GOT. MIPSr6 has instruction bc, which can jump long enough. >From 4e1b075a26db2831d981bad61ae883ede890bd58 Mon Sep 17 00:00:00 2001 From: YunQiang Su <yunqiang...@cipunited.com> Date: Fri, 3 Nov 2023 03:30:52 -0400 Subject: [PATCH 1/2] Clang/MIPS: Use -mnan value for -mabs if not specified On most hardware, FCSR.ABS2008 is set the value same with FCSR.NAN2008. Let's use this behaivor by default. With this commit, `clang -target mips -mnan=2008 -c fabs.c` will imply `-mabs=2008`. And of course, `clang -mnan=2008 -mabs=legacy` can continue workable like previous. --- clang/lib/Driver/ToolChains/Arch/Mips.cpp | 8 ++++++-- clang/test/Driver/mips-features.c | 8 +++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Arch/Mips.cpp b/clang/lib/Driver/ToolChains/Arch/Mips.cpp index f9f14c01b2b9f0..fe9d112b8800b1 100644 --- a/clang/lib/Driver/ToolChains/Arch/Mips.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Mips.cpp @@ -221,6 +221,7 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, bool IsN64 = ABIName == "64"; bool IsPIC = false; bool NonPIC = false; + bool HasNaN2008Opt = false; Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, options::OPT_fpic, options::OPT_fno_pic, @@ -285,9 +286,10 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { StringRef Val = StringRef(A->getValue()); if (Val == "2008") { - if (mips::getIEEE754Standard(CPUName) & mips::Std2008) + if (mips::getIEEE754Standard(CPUName) & mips::Std2008) { Features.push_back("+nan2008"); - else { + HasNaN2008Opt = true; + } else { Features.push_back("-nan2008"); D.Diag(diag::warn_target_unsupported_nan2008) << CPUName; } @@ -323,6 +325,8 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, D.Diag(diag::err_drv_unsupported_option_argument) << A->getSpelling() << Val; } + } else if (HasNaN2008Opt) { + Features.push_back("+abs2008"); } AddTargetFeature(Args, Features, options::OPT_msingle_float, diff --git a/clang/test/Driver/mips-features.c b/clang/test/Driver/mips-features.c index 5ae566774959f1..fad6009ffb89ba 100644 --- a/clang/test/Driver/mips-features.c +++ b/clang/test/Driver/mips-features.c @@ -213,7 +213,13 @@ // RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \ // RUN: -mnan=legacy -mnan=2008 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NAN2008 %s -// CHECK-NAN2008: "-target-feature" "+nan2008" +// CHECK-NAN2008: "-target-feature" "+nan2008" "-target-feature" "+abs2008" +// +// -mnan=2008 -mabs=legacy +// RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \ +// RUN: -mabs=legacy -mnan=2008 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-ABSLEGACYNAN2008 %s +// CHECK-ABSLEGACYNAN2008: "-target-feature" "+nan2008" "-target-feature" "-abs2008" // // -mnan=legacy // RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \ >From 9893b37053f02f679fcef2961b1e6872d8cf20b3 Mon Sep 17 00:00:00 2001 From: YunQiang Su <s...@gcc.gnu.org> Date: Thu, 4 Jan 2024 13:07:41 +0800 Subject: [PATCH 2/2] Sanitizer/MIPS: fix build fail on pre-R6 On MIPS pre-R6, instruction b can only work within 64KiB, which is not enough now. We need the help of GOT. For __mips64, we can get GOT by: lui $t8, %hi(%neg(%gp_rel(SANITIZER_STRINGIFY(TRAMPOLINE(func))))) daddu $t8, $t8, $t9 daddiu $t8, $t8, %hi(%neg(%gp_rel(SANITIZER_STRINGIFY(TRAMPOLINE(func))))) And then get the address of __interceptor_func, and jump to it ld $t9, %got_disp(__interceptor_" SANITIZER_STRINGIFY(func) ")($t8) jr $t9 MIPS/O32 has .cpload, which can help to generate 3 instructions to get GOT. MIPSr6 has instruction bc, which can jump long enough. --- compiler-rt/lib/interception/interception.h | 5 +++-- .../lib/sanitizer_common/sanitizer_asm.h | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h index 9d8b60b2eef58c..58e969378a9082 100644 --- a/compiler-rt/lib/interception/interception.h +++ b/compiler-rt/lib/interception/interception.h @@ -205,8 +205,9 @@ const interpose_substitution substitution_##func_name[] \ ASM_TYPE_FUNCTION_STR "\n" \ SANITIZER_STRINGIFY(TRAMPOLINE(func)) ":\n" \ SANITIZER_STRINGIFY(CFI_STARTPROC) "\n" \ - SANITIZER_STRINGIFY(ASM_TAIL_CALL) " __interceptor_" \ - SANITIZER_STRINGIFY(ASM_PREEMPTIBLE_SYM(func)) "\n" \ + C_ASM_TAIL_CALL(SANITIZER_STRINGIFY(TRAMPOLINE(func)), \ + "__interceptor_" \ + SANITIZER_STRINGIFY(ASM_PREEMPTIBLE_SYM(func))) "\n" \ SANITIZER_STRINGIFY(CFI_ENDPROC) "\n" \ ".size " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", " \ ".-" SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n" \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h index bbb18cfbdf15fe..37fa77b2d6759e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h @@ -44,6 +44,8 @@ #if defined(__x86_64__) || defined(__i386__) || defined(__sparc__) # define ASM_TAIL_CALL jmp +#elif defined(__mips__) && __mips_isa_rev >= 6 +# define ASM_TAIL_CALL bc #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \ defined(__powerpc__) || defined(__loongarch_lp64) # define ASM_TAIL_CALL b @@ -53,6 +55,25 @@ # define ASM_TAIL_CALL tail #endif +#if defined(__mips64) && __mips_isa_rev < 6 +# define C_ASM_TAIL_CALL(tfunc, ifunc) \ + "lui $t8, %hi(%neg(%gp_rel(" tfunc ")))\n" \ + "daddu $t8, $t8, $t9\n" \ + "daddu $t8, $t8, %lo(%neg(%gp_rel(" tfunc ")))\n" \ + "ld $t9, %got_disp(" ifunc ")($t8)\n" \ + "jr $t9\n" +#elif defined(__mips__) && __mips_isa_rev < 6 +# define C_ASM_TAIL_CALL(tfunc, ifunc) \ + ".set noreorder\n" \ + ".cpload $t9\n" \ + ".set reorder\n" \ + "lw $t9, %got(" ifunc ")($gp)\n" \ + "jr $t9\n" +#elif defined(ASM_TAIL_CALL) +# define C_ASM_TAIL_CALL(tfunc, ifunc) \ + SANITIZER_STRINGIFY(ASM_TAIL_CALL) " " ifunc +#endif + #if defined(__ELF__) && defined(__x86_64__) || defined(__i386__) || \ defined(__riscv) # define ASM_PREEMPTIBLE_SYM(sym) sym@plt _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits