]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Initialize PIC register for large PIC model C++ thunk
authorH.J. Lu <hongjiu.lu@intel.com>
Wed, 12 Nov 2014 21:16:14 +0000 (21:16 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Wed, 12 Nov 2014 21:16:14 +0000 (13:16 -0800)
gcc/

PR target/63815
* config/i386/i386.c (ix86_init_large_pic_reg): New.  Extracted
from ...
(ix86_init_pic_reg): Here.  Use ix86_init_large_pic_reg.
(x86_output_mi_thunk): Set PIC register to %r11.  Call
ix86_init_large_pic_reg to initialize PIC register.

gcc/testsuite/

PR target/63815
* g++.dg/other/pr63815.C: New test.

From-SVN: r217445

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/pr63815.C [new file with mode: 0644]

index 8b98649f226426cada2fb823bfe34de3921b849b..1fc374b69d4913175f194e08a7fd1b4ee4ec4307 100644 (file)
@@ -1,3 +1,12 @@
+2014-11-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/63815
+       * config/i386/i386.c (ix86_init_large_pic_reg): New.  Extracted
+       from ...
+       (ix86_init_pic_reg): Here.  Use ix86_init_large_pic_reg.
+       (x86_output_mi_thunk): Set PIC register to %r11.  Call
+       ix86_init_large_pic_reg to initialize PIC register.
+
 2014-11-12  Kai Tietz  <ktietz@redhat.com>
 
        * sdbout.c (sdbout_symbol): Eliminate register only
index 28669009014022afb3e1be8668fe8abc19dbe799..3d7e057e64ac317ceeca7b4150a82769720e9667 100644 (file)
@@ -6195,6 +6195,27 @@ ix86_use_pseudo_pic_reg (void)
   return true;
 }
 
+/* Initialize large model PIC register.  */
+
+static void
+ix86_init_large_pic_reg (unsigned int tmp_regno)
+{
+  rtx_code_label *label;
+  rtx tmp_reg;
+
+  gcc_assert (Pmode == DImode);
+  label = gen_label_rtx ();
+  emit_label (label);
+  LABEL_PRESERVE_P (label) = 1;
+  tmp_reg = gen_rtx_REG (Pmode, tmp_regno);
+  gcc_assert (REGNO (pic_offset_table_rtx) != tmp_regno);
+  emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
+                               label));
+  emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
+  emit_insn (ix86_gen_add3 (pic_offset_table_rtx,
+                           pic_offset_table_rtx, tmp_reg));
+}
+
 /* Create and initialize PIC register if required.  */
 static void
 ix86_init_pic_reg (void)
@@ -6210,22 +6231,7 @@ ix86_init_pic_reg (void)
   if (TARGET_64BIT)
     {
       if (ix86_cmodel == CM_LARGE_PIC)
-       {
-         rtx_code_label *label;
-         rtx tmp_reg;
-
-         gcc_assert (Pmode == DImode);
-         label = gen_label_rtx ();
-         emit_label (label);
-         LABEL_PRESERVE_P (label) = 1;
-         tmp_reg = gen_rtx_REG (Pmode, R11_REG);
-         gcc_assert (REGNO (pic_offset_table_rtx) != REGNO (tmp_reg));
-         emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
-                                       label));
-         emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
-         emit_insn (ix86_gen_add3 (pic_offset_table_rtx,
-                                   pic_offset_table_rtx, tmp_reg));
-       }
+       ix86_init_large_pic_reg (R11_REG);
       else
        emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
     }
@@ -42686,8 +42692,16 @@ x86_output_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,
   else
     {
       if (ix86_cmodel == CM_LARGE_PIC && SYMBOLIC_CONST (fnaddr))
-       fnaddr = legitimize_pic_address (fnaddr,
-                                        gen_rtx_REG (Pmode, tmp_regno));
+       {
+         // CM_LARGE_PIC always uses pseudo PIC register which is
+         // uninitialized.  Since FUNCTION is local and calling it
+         // doesn't go through PLT, we use scratch register %r11 as
+         // PIC register and initialize it here.
+         SET_REGNO (pic_offset_table_rtx, R11_REG);
+         ix86_init_large_pic_reg (tmp_regno);
+         fnaddr = legitimize_pic_address (fnaddr,
+                                          gen_rtx_REG (Pmode, tmp_regno));
+       }
 
       if (!sibcall_insn_operand (fnaddr, word_mode))
        {
index d943df62a0ff66b1725e96c6250ca4b121820bbf..93889d4d065b86907c943b8a4a66c508ee36fa8d 100644 (file)
@@ -1,3 +1,8 @@
+2014-11-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/63815
+       * g++.dg/other/pr63815.C: New test.
+
 2014-11-12  Paolo Carlini  <paolo.carlini@oracle.com>
 
        DR 1510
diff --git a/gcc/testsuite/g++.dg/other/pr63815.C b/gcc/testsuite/g++.dg/other/pr63815.C
new file mode 100644 (file)
index 0000000..fce6226
--- /dev/null
@@ -0,0 +1,50 @@
+// PR target/63815
+// { dg-do run { target { { i?86-*-linux* x86_64-*-linux* } && lp64 } } }
+// { dg-options "-mcmodel=large" }
+// { dg-additional-options "-fpic" { target fpic } }
+
+struct ICCStringClass
+{
+  virtual int CreateString (int) = 0;
+};
+
+struct AGSCCDynamicObject
+{
+  virtual void Unserialize () = 0;
+};
+
+struct ScriptString:AGSCCDynamicObject, ICCStringClass
+{
+  virtual int CreateString (int);
+  virtual void Unserialize ();
+};
+
+int
+__attribute__ ((noinline))
+CreateNewScriptString (int fromText, bool reAllocate = true)
+{
+  return fromText;
+}
+
+int
+__attribute__ ((noinline))
+ScriptString::CreateString (int fromText)
+{
+  return CreateNewScriptString (fromText);
+}
+
+void
+__attribute__ ((noinline))
+ScriptString::Unserialize ()
+{
+}
+
+int
+main ()
+{
+  ICCStringClass *x = new ScriptString;
+
+  if (x->CreateString (1) != 1)
+    __builtin_abort ();
+  return 0;
+}