arm.c (arm_reorg): Skip Thumb reorg pass for thunks.
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 26 Sep 2018 07:36:45 +0000 (07:36 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 26 Sep 2018 07:36:45 +0000 (07:36 +0000)
* config/arm/arm.c (arm_reorg): Skip Thumb reorg pass for thunks.
(arm32_output_mi_thunk): Deal with long calls.

From-SVN: r264595

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/thunk1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/thunk2a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/thunk2b.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/vthunk1.C [deleted file]

index d3f3de2cf84d8c7cfa255f9f4df52bd18921b4a4..4f606d35373ded6c4c74637214fe31a66f52ebe6 100644 (file)
@@ -1,3 +1,8 @@
+2018-09-26  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * config/arm/arm.c (arm_reorg): Skip Thumb reorg pass for thunks.
+       (arm32_output_mi_thunk): Deal with long calls.
+
 2018-09-26  Richard Biener  <rguenther@suse.de>
 
        PR debug/87428
index 6332e68df0506bb980cf55e05e7293b4a44d1e91..c6e3f7954fb414834674717c976e69650df6076e 100644 (file)
@@ -17647,7 +17647,11 @@ arm_reorg (void)
 
   if (use_cmse)
     cmse_nonsecure_call_clear_caller_saved ();
-  if (TARGET_THUMB1)
+
+  /* We cannot run the Thumb passes for thunks because there is no CFG.  */
+  if (cfun->is_thunk)
+    ;
+  else if (TARGET_THUMB1)
     thumb1_reorg ();
   else if (TARGET_THUMB2)
     thumb2_reorg ();
@@ -26721,6 +26725,8 @@ static void
 arm32_output_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,
                       HOST_WIDE_INT vcall_offset, tree function)
 {
+  const bool long_call_p = arm_is_long_call_p (function);
+
   /* On ARM, this_regno is R0 or R1 depending on
      whether the function returns an aggregate or not.
   */
@@ -26758,9 +26764,22 @@ arm32_output_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,
       TREE_USED (function) = 1;
     }
   rtx funexp = XEXP (DECL_RTL (function), 0);
+  if (long_call_p)
+    {
+      emit_move_insn (temp, funexp);
+      funexp = temp;
+    }
   funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
-  rtx_insn * insn = emit_call_insn (gen_sibcall (funexp, const0_rtx, NULL_RTX));
+  rtx_insn *insn = emit_call_insn (gen_sibcall (funexp, const0_rtx, NULL_RTX));
   SIBLING_CALL_P (insn) = 1;
+  emit_barrier ();
+
+  /* Indirect calls require a bit of fixup in PIC mode.  */
+  if (long_call_p)
+    {
+      split_all_insns_noflow ();
+      arm_reorg ();
+    }
 
   insn = get_insns ();
   shorten_branches (insn);
index f690e62a4456f9fe8577e78b6f2e04a95aa684c6..60b23ba33d355fad11b0c9a329d0621d32251558 100644 (file)
@@ -1,3 +1,10 @@
+2018-09-26  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * g++.dg/other/vthunk1.C: Rename to...
+       * g++.dg/other/thunk1.C: ...this.
+       * g++.dg/other/thunk2a.C: New test.
+       * g++.dg/other/thunk2b.C: Likewise.
+
 2018-09-25  Jim Wilson  <jimw@sifive.com>
 
        * gcc.target/riscv/weak-1.c: New.
diff --git a/gcc/testsuite/g++.dg/other/thunk1.C b/gcc/testsuite/g++.dg/other/thunk1.C
new file mode 100644 (file)
index 0000000..9016562
--- /dev/null
@@ -0,0 +1,26 @@
+// PR c++/12007 Multiple inheritance float pass by value fails
+// { dg-do run }
+
+extern "C" void abort (void);
+
+class gvImpl
+{
+public:
+  virtual void PutVal(float value){}
+};
+
+class foo { public: virtual void Bar(){} };
+
+class myGv: public foo, public gvImpl
+{
+  void PutVal(float value){ if (value != 3.14159f) abort (); }
+};
+
+myGv x;
+gvImpl* object = &x;
+
+int main()
+{
+  object->PutVal(3.14159f);
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/other/thunk2a.C b/gcc/testsuite/g++.dg/other/thunk2a.C
new file mode 100644 (file)
index 0000000..8e5ebd4
--- /dev/null
@@ -0,0 +1,15 @@
+// { dg-do compile { target arm*-*-* } }
+// { dg-options "-mlong-calls -ffunction-sections" }
+
+class a {
+public:
+  virtual ~a();
+};
+
+class b : virtual a {};
+
+class c : b {
+  ~c();
+};
+
+c::~c() {}
diff --git a/gcc/testsuite/g++.dg/other/thunk2b.C b/gcc/testsuite/g++.dg/other/thunk2b.C
new file mode 100644 (file)
index 0000000..c8f4570
--- /dev/null
@@ -0,0 +1,16 @@
+// { dg-do compile { target arm*-*-* } }
+// { dg-options "-mlong-calls -ffunction-sections" }
+// { dg-additional-options "-fPIC" { target fpic } }
+
+class a {
+public:
+  virtual ~a();
+};
+
+class b : virtual a {};
+
+class c : b {
+  ~c();
+};
+
+c::~c() {}
diff --git a/gcc/testsuite/g++.dg/other/vthunk1.C b/gcc/testsuite/g++.dg/other/vthunk1.C
deleted file mode 100644 (file)
index 9016562..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// PR c++/12007 Multiple inheritance float pass by value fails
-// { dg-do run }
-
-extern "C" void abort (void);
-
-class gvImpl
-{
-public:
-  virtual void PutVal(float value){}
-};
-
-class foo { public: virtual void Bar(){} };
-
-class myGv: public foo, public gvImpl
-{
-  void PutVal(float value){ if (value != 3.14159f) abort (); }
-};
-
-myGv x;
-gvImpl* object = &x;
-
-int main()
-{
-  object->PutVal(3.14159f);
-  return 0;
-}