x86-64: Use R10 for profiling large model
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 7 Jan 2021 22:27:49 +0000 (14:27 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 8 Jan 2021 12:51:57 +0000 (04:51 -0800)
R10 is caller-saved.  Although it can be used as a static chain register,
it is preserved when calling mcount for nested functions.  Use R10 as a
scratch register to call mcount in large model.

gcc/

PR target/98482
* config/i386/i386.c (x86_function_profiler): Use R10 to call
mcount in large model.  Sorry for large model with PIC.

gcc/testsuite/

PR target/98482
* gcc.target/i386/pr98482-1.c: New test.
* gcc.target/i386/pr98482-1.c: Likewise.

gcc/config/i386/i386.c
gcc/testsuite/gcc.target/i386/pr98482-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr98482-2.c [new file with mode: 0644]

index fad50e7..d306846 100644 (file)
@@ -20794,8 +20794,30 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
       fprintf (file, "\tleaq\t%sP%d(%%rip),%%r11\n", LPREFIX, labelno);
 #endif
 
-      if (!TARGET_PECOFF && flag_pic)
-       fprintf (file, "1:\tcall\t*%s@GOTPCREL(%%rip)\n", mcount_name);
+      if (!TARGET_PECOFF)
+       {
+         switch (ix86_cmodel)
+           {
+           case CM_LARGE:
+             /* NB: R10 is caller-saved.  Although it can be used as a
+                static chain register, it is preserved when calling
+                mcount for nested functions.  */
+             fprintf (file, "1:\tmovabsq\t$%s, %%r10\n\tcall\t*%%r10\n",
+                      mcount_name);
+             break;
+           case CM_LARGE_PIC:
+             sorry ("profiling %<-mcmodel=large%> with PIC is not supported");
+             break;
+           case CM_SMALL_PIC:
+           case CM_MEDIUM_PIC:
+             fprintf (file, "1:\tcall\t*%s@GOTPCREL(%%rip)\n",
+                      mcount_name);
+             break;
+           default:
+             x86_print_call_or_nop (file, mcount_name);
+             break;
+           }
+       }
       else
        x86_print_call_or_nop (file, mcount_name);
     }
diff --git a/gcc/testsuite/gcc.target/i386/pr98482-1.c b/gcc/testsuite/gcc.target/i386/pr98482-1.c
new file mode 100644 (file)
index 0000000..72d5ccb
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-require-effective-target mfentry } */
+/* { dg-options "-fprofile -mfentry -O2 -mcmodel=large" } */
+/* { dg-final { scan-assembler "movabsq\t\\\$__fentry__, %r10\n\tcall\t\\*%r10" } } */
+
+void
+func (void)
+{
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr98482-2.c b/gcc/testsuite/gcc.target/i386/pr98482-2.c
new file mode 100644 (file)
index 0000000..aed3ca4
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-require-effective-target mfentry } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-fpic -fprofile -mfentry -O2 -mcmodel=large" } */
+
+void
+func (void)
+{
+} /* { dg-message "sorry, unimplemented: profiling '-mcmodel=large' with PIC is not supported" } */