aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorYunQiang Su <syq@gcc.gnu.org>2024-01-15 09:28:51 +0800
committerYunQiang Su <syq@gcc.gnu.org>2024-01-17 10:38:04 +0800
commitb503c8787503943c2738058828c3d0037d024fea (patch)
tree92267127e89b8e0b5f4d32507f4350a150a6b5ba /gcc
parentfce3f51f9c252c2650b2bf90401c72cda0eae088 (diff)
downloadgcc-b503c8787503943c2738058828c3d0037d024fea.zip
gcc-b503c8787503943c2738058828c3d0037d024fea.tar.gz
gcc-b503c8787503943c2738058828c3d0037d024fea.tar.bz2
MIPS: avoid $gp store if global_pointer is not $gp
$GP is used for expanding GOT load, but in the afterward passes, a temporary register is tried to replace $gp. If sucess, we have no need to store and reload $gp. The example of failure is that the function calls a preemtive function. We shouldn't use $GP for any other purpose in the code we generate. If a user's inline asm code clobbers $GP, it's their duty to save and restore $GP. gcc * config/mips/mips.cc (mips_compute_frame_info): If another register is used as global_pointer, mark $GP live false. gcc/testsuite * gcc.target/mips/mips.exp (mips_option_groups): Add -mxgot/-mno-xgot options. * gcc.target/mips/xgot-n32-avoid-gp.c: New test. * gcc.target/mips/xgot-n32-need-gp.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/mips/mips.cc2
-rw-r--r--gcc/testsuite/gcc.target/mips/mips.exp1
-rw-r--r--gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c11
-rw-r--r--gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c11
4 files changed, 25 insertions, 0 deletions
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index e752019..30e9981 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -11353,6 +11353,8 @@ mips_compute_frame_info (void)
in, which is why the global_pointer field is initialised here and not
earlier. */
cfun->machine->global_pointer = mips_global_pointer ();
+ if (cfun->machine->global_pointer != GLOBAL_POINTER_REGNUM)
+ df_set_regs_ever_live (GLOBAL_POINTER_REGNUM, false);
offset = frame->args_size + frame->cprestore_size;
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index 9f8d533..e028bc9 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -266,6 +266,7 @@ set mips_option_groups {
stack-protector "-fstack-protector"
stdlib "REQUIRES_STDLIB"
unaligned-access "-m(no-|)unaligned-access"
+ xgot "-m(no-|)xgot"
}
for { set option 0 } { $option < 32 } { incr option } {
diff --git a/gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c b/gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c
new file mode 100644
index 0000000..3f52fc5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c
@@ -0,0 +1,11 @@
+/* Check if we skip store and load gp if there is no stub function call. */
+/* { dg-options "-mips64r2 -mxgot -mabi=n32 -fPIC" } */
+
+extern int a;
+int
+foo ()
+{
+ return a;
+}
+/* { dg-final { scan-assembler-not "\tsd\t\\\$28," } } */
+/* { dg-final { scan-assembler-not "\tld\t\\\$28," } } */
diff --git a/gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c b/gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c
new file mode 100644
index 0000000..631409c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c
@@ -0,0 +1,11 @@
+/* We cannot skip store and load gp if there is stub function call. */
+/* { dg-options "-mips64r2 -mxgot -mabi=n32 -fPIC" } */
+
+extern int f();
+int
+foo ()
+{
+ return f();
+}
+/* { dg-final { scan-assembler "\tsd\t\\\$28," } } */
+/* { dg-final { scan-assembler "\tld\t\\\$28," } } */