VxWorks6 used symbols __GOTT_BASE__ and __GOTT_INDEX__ to obtain the
address of the global offset table.  Starting with VxWorks7, that is
no longer the case, but we've still issued these symbols in
output_set_got.  Do that only with VxWorks<7.

Switching to the call-based PIC register sequence, we have to set the
flag that prevents the use of the red zone, and AFAICT the reasons
that ruled out GOTOFF and other relative addressing no longer apply to
VxWorks7+.

Bootstrapped on x86_64-linux-gnu; regression-tested on i586-vx7r2,
x86_64-vx7r2, ppc-vx7r2, ppc64-vx7r2, arm-vx7r2, and aarch64-vx7r2,
along with other patches.  I'm checking this in, pre-approved by Olivier
Hainque in his role of maintainer of VxWorks ports.


for  gcc/ChangeLog

        * config/vxworks-dummy.h (TARGET_VXWORKS_VAROFF): New.
        (TARGET_VXWORKS_GOTTPIC): New.
        * config/vxworks.h (TARGET_VXWORKS_VAROFF): Override.
        (TARGET_VXWORKS_GOTTPIC): Likewise.
        * config/i386/i386.cc (output_set_got): Disable VxWorks6 GOT
        sequence on VxWorks7.
        (legitimize_pic_address): Accept relative addressing of
        labels on VxWorks7.
        (ix86_delegitimize_address_1): Likewise.
        (ix86_output_addr_diff_elt): Likewise.
        * config/i386/i386.md (tablejump): Likewise.
        (set_got, set_got_labelled): Set no-red-zone flag on VxWorks7.
---
 gcc/config/i386/i386.cc       |    8 ++++----
 gcc/config/i386/i386.md       |    6 +++---
 gcc/config/i386/predicates.md |    3 ++-
 gcc/config/vxworks-dummy.h    |   12 ++++++++++++
 gcc/config/vxworks.h          |   12 ++++++++++++
 5 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index b64175d6c9398..fd3f35de14d3d 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -6526,7 +6526,7 @@ output_set_got (rtx dest, rtx label)
 
   xops[0] = dest;
 
-  if (TARGET_VXWORKS_RTP && flag_pic)
+  if (TARGET_VXWORKS_GOTTPIC && TARGET_VXWORKS_RTP && flag_pic)
     {
       /* Load (*VXWORKS_GOTT_BASE) into the PIC register.  */
       xops[2] = gen_rtx_MEM (Pmode,
@@ -12245,7 +12245,7 @@ legitimize_pic_address (rtx orig, rtx reg)
   else if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (addr) == 0)
           /* We can't always use @GOTOFF for text labels
              on VxWorks, see gotoff_operand.  */
-          || (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF))
+          || (TARGET_VXWORKS_VAROFF && GET_CODE (addr) == LABEL_REF))
     {
 #if TARGET_PECOFF
       rtx tmp = legitimize_pe_coff_symbol (addr, true);
@@ -13472,7 +13472,7 @@ ix86_delegitimize_address_1 (rtx x, bool base_term_p)
       else if (base_term_p
               && pic_offset_table_rtx
               && !TARGET_MACHO
-              && !TARGET_VXWORKS_RTP)
+              && !TARGET_VXWORKS_VAROFF)
        {
          rtx tmp = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
          tmp = gen_rtx_MINUS (Pmode, copy_rtx (addend), tmp);
@@ -15872,7 +15872,7 @@ ix86_output_addr_diff_elt (FILE *file, int value, int 
rel)
   gcc_assert (!TARGET_64BIT);
 #endif
   /* We can't use @GOTOFF for text labels on VxWorks; see gotoff_operand.  */
-  if (TARGET_64BIT || TARGET_VXWORKS_RTP)
+  if (TARGET_64BIT || TARGET_VXWORKS_VAROFF)
     fprintf (file, "%s%s%d-%s%d\n",
             directive, LPREFIX, value, LPREFIX, rel);
 #if TARGET_MACHO
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 21b9f5ccd7a1d..5825acabb9461 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -20102,7 +20102,7 @@ (define_expand "tablejump"
 
       /* We can't use @GOTOFF for text labels on VxWorks;
         see gotoff_operand.  */
-      if (TARGET_64BIT || TARGET_VXWORKS_RTP)
+      if (TARGET_64BIT || TARGET_VXWORKS_VAROFF)
        {
          code = PLUS;
          op0 = operands[0];
@@ -20970,7 +20970,7 @@ (define_expand "set_got"
       (clobber (reg:CC FLAGS_REG))])]
   "!TARGET_64BIT"
 {
-  if (flag_pic && !TARGET_VXWORKS_RTP)
+  if (flag_pic && !TARGET_VXWORKS_GOTTPIC)
     ix86_pc_thunk_call_expanded = true;
 })
 
@@ -20991,7 +20991,7 @@ (define_expand "set_got_labelled"
       (clobber (reg:CC FLAGS_REG))])]
   "!TARGET_64BIT"
 {
-  if (flag_pic && !TARGET_VXWORKS_RTP)
+  if (flag_pic && !TARGET_VXWORKS_GOTTPIC)
     ix86_pc_thunk_call_expanded = true;
 })
 
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 1bd63b2367e13..3afaf83a7a0c5 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -664,8 +664,9 @@ (define_predicate "local_func_symbolic_operand"
 ;; same segment as the GOT.  Unfortunately, the flexibility of linker
 ;; scripts means that we can't be sure of that in general, so assume
 ;; @GOTOFF is not valid on VxWorks, except with the large code model.
+;; The comments above seem to apply only to VxWorks releases before 7.
 (define_predicate "gotoff_operand"
-  (and (ior (not (match_test "TARGET_VXWORKS_RTP"))
+  (and (ior (not (match_test "TARGET_VXWORKS_VAROFF"))
             (match_test "ix86_cmodel == CM_LARGE")
             (match_test "ix86_cmodel == CM_LARGE_PIC"))
        (match_operand 0 "local_symbolic_operand")))
diff --git a/gcc/config/vxworks-dummy.h b/gcc/config/vxworks-dummy.h
index 494799da5f9a7..516728c6eff73 100644
--- a/gcc/config/vxworks-dummy.h
+++ b/gcc/config/vxworks-dummy.h
@@ -40,9 +40,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #define TARGET_VXWORKS_RTP false
 #endif
 
+/* True if offsets between different segments may vary, so we must avoid
+   cross-segment GOT- and PC-relative address computations.  */
+#ifndef TARGET_VXWORKS_VAROFF
+#define TARGET_VXWORKS_VAROFF false
+#endif
+
 /* The symbol that points to an RTP's table of GOTs.  */
 #define VXWORKS_GOTT_BASE (gcc_unreachable (), "")
 
 /* The symbol that holds the index of the current module's GOT in
    VXWORKS_GOTT_BASE.  */
 #define VXWORKS_GOTT_INDEX (gcc_unreachable (), "")
+
+/* True if PIC relies on the GOTT_* symbols above.  As of VxWorks7, they are no
+   longer used.  */
+#ifndef TARGET_VXWORKS_GOTTPIC
+#define TARGET_VXWORKS_GOTTPIC false
+#endif
diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h
index 204a8e000d405..d2b6025caad96 100644
--- a/gcc/config/vxworks.h
+++ b/gcc/config/vxworks.h
@@ -159,6 +159,18 @@ extern void vxworks_driver_init (unsigned int *, struct 
cl_decoded_option **);
    Earlier versions did not, not even for RTPS.  */
 #define VXWORKS_HAVE_TLS TARGET_VXWORKS7
 
+/* RTP segments could be loaded with varying offsets, so cross-segment offsets
+   could not be assumed to be constant.  This rules out some PC- and
+   GOT-relative addressing.  */
+#undef TARGET_VXWORKS_VAROFF
+#define TARGET_VXWORKS_VAROFF (!TARGET_VXWORKS7 && TARGET_VXWORKS_RTP)
+
+/* GOTT_BASE and GOTT_INDEX symbols are only used by some ports up to VxWorks6.
+   This macro is only used by i386 so far.  Other ports seem to keep on using
+   GOTTPIC from VxWorks7 on, but they don't test this macro.  */
+#undef TARGET_VXWORKS_GOTTPIC
+#define TARGET_VXWORKS_GOTTPIC (!TARGET_VXWORKS7)
+
 /* On Vx6 and previous, the libraries to pick up depends on the architecture,
    so cannot be defined for all archs at once.  On Vx7, a VSB is always needed
    and its structure is fixed and does not depend on the arch.  We can thus

-- 
Alexandre Oliva, happy hacker            https://blog.lx.oliva.nom.br/
Free Software Activist     FSFLA co-founder     GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity.
Excluding neuro-others for not behaving ""normal"" is *not* inclusive!

Reply via email to