diff options
author | iains <iains@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-07-20 16:22:59 +0000 |
---|---|---|
committer | iains <iains@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-07-20 16:22:59 +0000 |
commit | f212a7d05f4f84d5e7215ff95657980102aa7620 (patch) | |
tree | 88e847313021b566970743f6d41c2ceb446ede0a | |
parent | d871a6e01939663277519bf634013f621da22d24 (diff) | |
download | gcc-f212a7d05f4f84d5e7215ff95657980102aa7620.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201086 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/config/darwin-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/darwin.c | 30 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 30 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 35 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 17 |
5 files changed, 93 insertions, 20 deletions
diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h index 0755e94692a..70b7fb00959 100644 --- a/gcc/config/darwin-protos.h +++ b/gcc/config/darwin-protos.h @@ -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 diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index a049a5d0796..e07fa4c8324 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -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. */ diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5df6ab741da..a8b1759061a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -8822,17 +8822,12 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED) if (!flag_pic) { - xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ()); + 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) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 2777e9c8617..a4778fed1a9 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ae3b789ff42..1bd6b0443f7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. |