[SPARC] Fix fallout of PR target/83368

Message ID 6200077.SEmg0Osn0Z@polaris
State New
Headers show
Series
  • [SPARC] Fix fallout of PR target/83368
Related show

Commit Message

Eric Botcazou Feb. 4, 2019, 11:14 a.m.
The patch for PR target/83368 changed the PIC register from a hard register to 
a pseudo and broke the -mflat mode in the process.  The attached patch fixes 
it and does also a bit of housekeeping in the GOT support.

Tested on SPARC/Solaris 11, applied on the mainline and 8 branch.


2019-02-04  Eric Botcazou  <ebotcazou@adacore.com>

	* config/sparc/sparc.h: Remove superfluous blank lines.
	* config/sparc/sparc.c (global_offset_table_rtx): Rename into...
	(got_register_rtx): ...this.
	(sparc_got): Adjust to above renaming.
	(sparc_tls_got): Likewise.
	(sparc_delegitimize_address): Likewise.
	(sparc_output_mi_thunk): Likewise.
	(sparc_init_pic_reg): Likewise.
	(save_local_or_in_reg_p): Fix test on the GOT register.
	(USE_HIDDEN_LINKONCE): Move around.
	(get_pc_thunk_name): Likewise.
	(gen_load_pcrel_sym): Likewise.
	(load_got_register): Likewise.

-- 
Eric Botcazou

Patch

Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 268508)
+++ config/sparc/sparc.c	(working copy)
@@ -4269,19 +4269,84 @@  sparc_cannot_force_const_mem (machine_mo
 
 /* Global Offset Table support.  */
 static GTY(()) rtx got_helper_rtx = NULL_RTX;
-static GTY(()) rtx global_offset_table_rtx = NULL_RTX;
+static GTY(()) rtx got_register_rtx = NULL_RTX;
+static GTY(()) rtx got_symbol_rtx = NULL_RTX;
 
 /* Return the SYMBOL_REF for the Global Offset Table.  */
 
-static GTY(()) rtx sparc_got_symbol = NULL_RTX;
-
 static rtx
 sparc_got (void)
 {
-  if (!sparc_got_symbol)
-    sparc_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+  if (!got_symbol_rtx)
+    got_symbol_rtx = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+
+  return got_symbol_rtx;
+}
+
+#ifdef HAVE_GAS_HIDDEN
+# define USE_HIDDEN_LINKONCE 1
+#else
+# define USE_HIDDEN_LINKONCE 0
+#endif
+
+static void
+get_pc_thunk_name (char name[32], unsigned int regno)
+{
+  const char *reg_name = reg_names[regno];
+
+  /* Skip the leading '%' as that cannot be used in a
+     symbol name.  */
+  reg_name += 1;
+
+  if (USE_HIDDEN_LINKONCE)
+    sprintf (name, "__sparc_get_pc_thunk.%s", reg_name);
+  else
+    ASM_GENERATE_INTERNAL_LABEL (name, "LADDPC", regno);
+}
+
+/* Wrapper around the load_pcrel_sym{si,di} patterns.  */
+
+static rtx
+gen_load_pcrel_sym (rtx op0, rtx op1, rtx op2)
+{
+  int orig_flag_pic = flag_pic;
+  rtx insn;
+
+  /* The load_pcrel_sym{si,di} patterns require absolute addressing.  */
+  flag_pic = 0;
+  if (TARGET_ARCH64)
+    insn = gen_load_pcrel_symdi (op0, op1, op2, GEN_INT (REGNO (op0)));
+  else
+    insn = gen_load_pcrel_symsi (op0, op1, op2, GEN_INT (REGNO (op0)));
+  flag_pic = orig_flag_pic;
+
+  return insn;
+}
+
+/* Emit code to load the GOT register.  */
+
+void
+load_got_register (void)
+{
+  if (!got_register_rtx)
+    got_register_rtx = gen_rtx_REG (Pmode, GLOBAL_OFFSET_TABLE_REGNUM);
+
+  if (TARGET_VXWORKS_RTP)
+    emit_insn (gen_vxworks_load_got ());
+  else
+    {
+      /* The GOT symbol is subject to a PC-relative relocation so we need a
+	 helper function to add the PC value and thus get the final value.  */
+      if (!got_helper_rtx)
+	{
+	  char name[32];
+	  get_pc_thunk_name (name, GLOBAL_OFFSET_TABLE_REGNUM);
+	  got_helper_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
+	}
 
-  return sparc_got_symbol;
+      emit_insn (gen_load_pcrel_sym (got_register_rtx, sparc_got (),
+				     got_helper_rtx));
+    }
 }
 
 /* Ensure that we are not using patterns that are not OK with PIC.  */
@@ -4607,7 +4672,7 @@  sparc_tls_got (void)
   if (TARGET_SUN_TLS && TARGET_ARCH32)
     {
       load_got_register ();
-      return global_offset_table_rtx;
+      return got_register_rtx;
     }
 
   /* In all other cases, we load a new pseudo with the GOT symbol.  */
@@ -4995,7 +5060,7 @@  sparc_delegitimize_address (rtx x)
 
   /* This is generated by mov{si,di}_pic_label_ref in PIC mode.  */
   if (GET_CODE (x) == MINUS
-      && (XEXP (x, 0) == global_offset_table_rtx
+      && (XEXP (x, 0) == got_register_rtx
 	  || sparc_pic_register_p (XEXP (x, 0))))
     {
       rtx y = XEXP (x, 1);
@@ -5092,72 +5157,6 @@  sparc_mode_dependent_address_p (const_rt
   return false;
 }
 
-#ifdef HAVE_GAS_HIDDEN
-# define USE_HIDDEN_LINKONCE 1
-#else
-# define USE_HIDDEN_LINKONCE 0
-#endif
-
-static void
-get_pc_thunk_name (char name[32], unsigned int regno)
-{
-  const char *reg_name = reg_names[regno];
-
-  /* Skip the leading '%' as that cannot be used in a
-     symbol name.  */
-  reg_name += 1;
-
-  if (USE_HIDDEN_LINKONCE)
-    sprintf (name, "__sparc_get_pc_thunk.%s", reg_name);
-  else
-    ASM_GENERATE_INTERNAL_LABEL (name, "LADDPC", regno);
-}
-
-/* Wrapper around the load_pcrel_sym{si,di} patterns.  */
-
-static rtx
-gen_load_pcrel_sym (rtx op0, rtx op1, rtx op2)
-{
-  int orig_flag_pic = flag_pic;
-  rtx insn;
-
-  /* The load_pcrel_sym{si,di} patterns require absolute addressing.  */
-  flag_pic = 0;
-  if (TARGET_ARCH64)
-    insn = gen_load_pcrel_symdi (op0, op1, op2, GEN_INT (REGNO (op0)));
-  else
-    insn = gen_load_pcrel_symsi (op0, op1, op2, GEN_INT (REGNO (op0)));
-  flag_pic = orig_flag_pic;
-
-  return insn;
-}
-
-/* Emit code to load the GOT register.  */
-
-void
-load_got_register (void)
-{
-  if (!global_offset_table_rtx)
-    global_offset_table_rtx = gen_rtx_REG (Pmode, GLOBAL_OFFSET_TABLE_REGNUM);
-
-  if (TARGET_VXWORKS_RTP)
-    emit_insn (gen_vxworks_load_got ());
-  else
-    {
-      /* The GOT symbol is subject to a PC-relative relocation so we need a
-	 helper function to add the PC value and thus get the final value.  */
-      if (!got_helper_rtx)
-	{
-	  char name[32];
-	  get_pc_thunk_name (name, GLOBAL_OFFSET_TABLE_REGNUM);
-	  got_helper_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
-	}
-
-      emit_insn (gen_load_pcrel_sym (global_offset_table_rtx, sparc_got (),
-				     got_helper_rtx));
-    }
-}
-
 /* Emit a call instruction with the pattern given by PAT.  ADDR is the
    address of the call target.  */
 
@@ -5512,7 +5511,7 @@  save_local_or_in_reg_p (unsigned int reg
     return true;
 
   /* GOT register (%l7) if needed.  */
-  if (regno == PIC_OFFSET_TABLE_REGNUM && crtl->uses_pic_offset_table)
+  if (regno == GLOBAL_OFFSET_TABLE_REGNUM && got_register_rtx)
     return true;
 
   /* If the function accesses prior frames, the frame pointer and the return
@@ -12441,7 +12440,7 @@  sparc_output_mi_thunk (FILE *file, tree
 	  start_sequence ();
 	  load_got_register ();  /* clobbers %o7 */
 	  if (!TARGET_VXWORKS_RTP)
-	    pic_offset_table_rtx = global_offset_table_rtx;
+	    pic_offset_table_rtx = got_register_rtx;
 	  scratch = sparc_legitimize_pic_address (funexp, scratch);
 	  seq = get_insns ();
 	  end_sequence ();
@@ -13117,7 +13116,7 @@  sparc_init_pic_reg (void)
   start_sequence ();
   load_got_register ();
   if (!TARGET_VXWORKS_RTP)
-    emit_move_insn (pic_offset_table_rtx, global_offset_table_rtx);
+    emit_move_insn (pic_offset_table_rtx, got_register_rtx);
   seq = get_insns ();
   end_sequence ();
 
Index: config/sparc/sparc.h
===================================================================
--- config/sparc/sparc.h	(revision 268508)
+++ config/sparc/sparc.h	(working copy)
@@ -804,7 +804,6 @@  extern enum cmodel sparc_cmodel;
 #define STATIC_CHAIN_REGNUM (TARGET_ARCH64 ? 5 : 2)
 
 /* Register which holds the global offset table, if any.  */
-
 #define GLOBAL_OFFSET_TABLE_REGNUM 23
 
 /* Register which holds offset table for position-independent data references.
@@ -812,7 +811,6 @@  extern enum cmodel sparc_cmodel;
    so we use a pseudo-register to make sure it is properly saved and restored
    around calls to setjmp.  Now the ABI of VxWorks RTP makes it live on entry
    to PLT entries so we use the canonical GOT register in this case.  */
-
 #define PIC_OFFSET_TABLE_REGNUM \
   (TARGET_VXWORKS_RTP && flag_pic ? GLOBAL_OFFSET_TABLE_REGNUM : INVALID_REGNUM)
 
@@ -822,7 +820,6 @@  extern enum cmodel sparc_cmodel;
    Originally it was -1, but later on the container of options changed to
    unsigned byte, so we decided to pick 127 as default value, which does
    reflect an undefined default value in case of 0/1.  */
-
 #define DEFAULT_PCC_STRUCT_RETURN 127
 
 /* Functions which return large structures get the address