re PR target/51784 (PIC register not correctly preserved in nested funcs / with non-local goto)
gcc/ PR target/51784 * config/i386/i386.c (output_set_got) [TARGET_MACHO]: Adjust to emit a second label for nonlocal goto receivers. Don't output pic base labels unless we're producing PIC; mark that action unreachable(). (ix86_save_reg): If the function contains a nonlocal label, save the PIC base reg. * config/darwin-protos.h (machopic_should_output_picbase_label): New. * gcc/config/darwin.c (emitted_pic_label_num): New GTY. (update_pic_label_number_if_needed): New. (machopic_output_function_base_name): Adjust for nonlocal receiver case. (machopic_should_output_picbase_label): New. * config/i386/i386.md (enum unspecv): UNSPECV_NLGR: New. (nonlocal_goto_receiver): New insn and split. From-SVN: r201086
This commit is contained in:
parent
2d586fb432
commit
88d9bfe6b9
5 changed files with 93 additions and 20 deletions
|
@ -25,6 +25,7 @@ extern void machopic_validate_stub_or_non_lazy_ptr (const char *);
|
|||
extern void machopic_output_function_base_name (FILE *);
|
||||
extern const char *machopic_indirection_name (rtx, bool);
|
||||
extern const char *machopic_mcount_stub_name (void);
|
||||
extern bool machopic_should_output_picbase_label (void);
|
||||
|
||||
#ifdef RTX_CODE
|
||||
|
||||
|
|
|
@ -369,14 +369,13 @@ machopic_gen_offset (rtx orig)
|
|||
|
||||
static GTY(()) const char * function_base_func_name;
|
||||
static GTY(()) int current_pic_label_num;
|
||||
static GTY(()) int emitted_pic_label_num;
|
||||
|
||||
void
|
||||
machopic_output_function_base_name (FILE *file)
|
||||
static void
|
||||
update_pic_label_number_if_needed (void)
|
||||
{
|
||||
const char *current_name;
|
||||
|
||||
/* If dynamic-no-pic is on, we should not get here. */
|
||||
gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
|
||||
/* When we are generating _get_pc thunks within stubs, there is no current
|
||||
function. */
|
||||
if (current_function_decl)
|
||||
|
@ -394,7 +393,28 @@ machopic_output_function_base_name (FILE *file)
|
|||
++current_pic_label_num;
|
||||
function_base_func_name = "L_machopic_stub_dummy";
|
||||
}
|
||||
fprintf (file, "L%011d$pb", current_pic_label_num);
|
||||
}
|
||||
|
||||
void
|
||||
machopic_output_function_base_name (FILE *file)
|
||||
{
|
||||
/* If dynamic-no-pic is on, we should not get here. */
|
||||
gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
|
||||
|
||||
update_pic_label_number_if_needed ();
|
||||
fprintf (file, "L%d$pb", current_pic_label_num);
|
||||
}
|
||||
|
||||
bool
|
||||
machopic_should_output_picbase_label (void)
|
||||
{
|
||||
update_pic_label_number_if_needed ();
|
||||
|
||||
if (current_pic_label_num == emitted_pic_label_num)
|
||||
return false;
|
||||
|
||||
emitted_pic_label_num = current_pic_label_num;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* The suffix attached to non-lazy pointer symbols. */
|
||||
|
|
|
@ -8822,17 +8822,12 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED)
|
|||
|
||||
if (!flag_pic)
|
||||
{
|
||||
if (TARGET_MACHO)
|
||||
/* We don't need a pic base, we're not producing pic. */
|
||||
gcc_unreachable ();
|
||||
|
||||
xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
|
||||
|
||||
output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops);
|
||||
|
||||
#if TARGET_MACHO
|
||||
/* Output the Mach-O "canonical" label name ("Lxx$pb") here too. This
|
||||
is what will be referenced by the Mach-O PIC subsystem. */
|
||||
if (!label)
|
||||
ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
|
||||
#endif
|
||||
|
||||
targetm.asm_out.internal_label (asm_out_file, "L",
|
||||
CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
|
||||
}
|
||||
|
@ -8845,12 +8840,18 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED)
|
|||
xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
|
||||
xops[2] = gen_rtx_MEM (QImode, xops[2]);
|
||||
output_asm_insn ("call\t%X2", xops);
|
||||
/* Output the Mach-O "canonical" label name ("Lxx$pb") here too. This
|
||||
is what will be referenced by the Mach-O PIC subsystem. */
|
||||
|
||||
#if TARGET_MACHO
|
||||
if (!label)
|
||||
/* Output the Mach-O "canonical" pic base label name ("Lxx$pb") here.
|
||||
This is what will be referenced by the Mach-O PIC subsystem. */
|
||||
if (machopic_should_output_picbase_label () || !label)
|
||||
ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
|
||||
else
|
||||
|
||||
/* When we are restoring the pic base at the site of a nonlocal label,
|
||||
and we decided to emit the pic base above, we will still output a
|
||||
local label used for calculating the correction offset (even though
|
||||
the offset will be 0 in that case). */
|
||||
if (label)
|
||||
targetm.asm_out.internal_label (asm_out_file, "L",
|
||||
CODE_LABEL_NUMBER (label));
|
||||
#endif
|
||||
|
@ -8932,7 +8933,8 @@ ix86_save_reg (unsigned int regno, bool maybe_eh_return)
|
|||
&& (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
|
||||
|| crtl->profile
|
||||
|| crtl->calls_eh_return
|
||||
|| crtl->uses_const_pool))
|
||||
|| crtl->uses_const_pool
|
||||
|| cfun->has_nonlocal_label))
|
||||
return ix86_select_alt_pic_regnum () == INVALID_REGNUM;
|
||||
|
||||
if (crtl->calls_eh_return && maybe_eh_return)
|
||||
|
|
|
@ -222,6 +222,8 @@
|
|||
UNSPECV_XEND
|
||||
UNSPECV_XABORT
|
||||
UNSPECV_XTEST
|
||||
|
||||
UNSPECV_NLGR
|
||||
])
|
||||
|
||||
;; Constants to represent rounding modes in the ROUND instruction
|
||||
|
@ -16227,7 +16229,38 @@
|
|||
emit_insn (gen_set_got (pic_offset_table_rtx));
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
||||
(define_insn_and_split "nonlocal_goto_receiver"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
|
||||
"TARGET_MACHO && !TARGET_64BIT && flag_pic"
|
||||
{
|
||||
if (crtl->uses_pic_offset_table)
|
||||
return "#";
|
||||
else
|
||||
return ""; /* No pic reg restore needed. */
|
||||
}
|
||||
"&& reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
if (crtl->uses_pic_offset_table)
|
||||
{
|
||||
rtx xops[3];
|
||||
rtx label_rtx = gen_label_rtx ();
|
||||
rtx tmp;
|
||||
|
||||
/* Get a new pic base. */
|
||||
emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
|
||||
/* Correct this with the offset from the new to the old. */
|
||||
xops[0] = xops[1] = pic_offset_table_rtx;
|
||||
label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
|
||||
tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
|
||||
UNSPEC_MACHOPIC_OFFSET);
|
||||
xops[2] = gen_rtx_CONST (Pmode, tmp);
|
||||
ix86_expand_binary_operator (MINUS, SImode, xops);
|
||||
}
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
|
||||
|
||||
(define_split
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
2013-07-20 Iain Sandoe <iain@codesourcery.com>
|
||||
|
||||
PR target/51784
|
||||
* config/i386/i386.c (output_set_got) [TARGET_MACHO]: Adjust to emit a
|
||||
second label for nonlocal goto receivers. Don't output pic base labels
|
||||
unless we're producing PIC; mark that action unreachable().
|
||||
(ix86_save_reg): If the function contains a nonlocal label, save the
|
||||
PIC base reg.
|
||||
* config/darwin-protos.h (machopic_should_output_picbase_label): New.
|
||||
* gcc/config/darwin.c (emitted_pic_label_num): New GTY.
|
||||
(update_pic_label_number_if_needed): New.
|
||||
(machopic_output_function_base_name): Adjust for nonlocal receiver
|
||||
case.
|
||||
(machopic_should_output_picbase_label): New.
|
||||
* config/i386/i386.md (enum unspecv): UNSPECV_NLGR: New.
|
||||
(nonlocal_goto_receiver): New insn and split.
|
||||
|
||||
2013-07-20 James Greenhalgh <james.greenhalgh@arm.com>
|
||||
|
||||
* gcc.target/aarch64/vabs_intrinsic_1.c: New file.
|
||||
|
|
Loading…
Add table
Reference in a new issue