\f
/* 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. */
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. */
/* 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);
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. */
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
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 ();
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 ();