From: Richard Henderson Date: Thu, 23 May 2002 07:43:13 +0000 (-0700) Subject: i386.c (get_pic_label_name): New. X-Git-Tag: releases/gcc-3.3.0~4865 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=c8c0350922dd6b8f75d96bd79bb50defc1b13776;p=gcc.git i386.c (get_pic_label_name): New. * config/i386/i386.c (get_pic_label_name): New. (load_pic_register): Remove. (output_set_got): New. (ix86_expand_prologue): Use gen_set_got; mark insn REG_MAYBE_DEAD. * config/i386/i386.md (UNSPEC_SET_GOT): New. (UNSPECV_PROLOGUE_SET_GOT, UNSPECV_PROLOGUE_GET_PC): Remove. (prologue_set_got, prologue_get_pc): Remove. (set_got, set_got_nopic, set_got_deep, set_got_nodeep): New. (builtin_setjmp_receiver): Use gen_set_got. * config/i386/i386-protos.h: Update. From-SVN: r53773 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 67381fdacf74..cb83350e9ea2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2002-05-23 Richard Henderson + + * config/i386/i386.c (get_pic_label_name): New. + (load_pic_register): Remove. + (output_set_got): New. + (ix86_expand_prologue): Use gen_set_got; mark insn REG_MAYBE_DEAD. + * config/i386/i386.md (UNSPEC_SET_GOT): New. + (UNSPECV_PROLOGUE_SET_GOT, UNSPECV_PROLOGUE_GET_PC): Remove. + (prologue_set_got, prologue_get_pc): Remove. + (set_got, set_got_nopic, set_got_deep, set_got_nodeep): New. + (builtin_setjmp_receiver): Use gen_set_got. + * config/i386/i386-protos.h: Update. + Thu May 23 09:22:23 CEST 2002 Jan Hubicka * gcse.c (hash_expr): Do not use alias set for hashing. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index c02e2e3ffc76..21babe91c2d1 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -28,7 +28,6 @@ extern int ix86_frame_pointer_required PARAMS ((void)); extern void ix86_setup_frame_addresses PARAMS ((void)); extern void ix86_asm_file_end PARAMS ((FILE *)); -extern void load_pic_register PARAMS ((void)); extern HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int)); extern void ix86_expand_prologue PARAMS ((void)); extern void ix86_expand_epilogue PARAMS ((int)); @@ -96,6 +95,7 @@ extern void print_operand_address PARAMS ((FILE*, rtx)); extern void split_di PARAMS ((rtx[], int, rtx[], rtx[])); extern void split_ti PARAMS ((rtx[], int, rtx[], rtx[])); +extern const char *output_set_got PARAMS ((rtx)); extern const char *output_387_binary_op PARAMS ((rtx, rtx*)); extern const char *output_fix_trunc PARAMS ((rtx, rtx*)); extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int)); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 650513191697..96d0916d86a6 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -647,6 +647,7 @@ static char internal_label_prefix[16]; static int internal_label_prefix_len; static int local_symbolic_operand PARAMS ((rtx, enum machine_mode)); +static const char *get_pic_label_name PARAMS ((void)); static void output_pic_addr_const PARAMS ((FILE *, rtx, int)); static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode, int, int, FILE *)); @@ -3795,6 +3796,14 @@ ix86_setup_frame_addresses () static char pic_label_name[32]; +static const char * +get_pic_label_name () +{ + if (! pic_label_name[0]) + ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0); + return pic_label_name; +} + /* This function generates code for -fpic that loads %ebx with the return address of the caller and then returns. */ @@ -3847,33 +3856,45 @@ ix86_asm_file_end (file) output_asm_insn ("ret", xops); } -void -load_pic_register () -{ - rtx gotsym, pclab; +/* Emit code for the SET_GOT patterns. */ - if (TARGET_64BIT) - abort (); +const char * +output_set_got (dest) + rtx dest; +{ + rtx xops[3]; - gotsym = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); + xops[0] = dest; + xops[1] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); - if (TARGET_DEEP_BRANCH_PREDICTION) + if (! TARGET_DEEP_BRANCH_PREDICTION || !flag_pic) { - if (! pic_label_name[0]) - ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0); - pclab = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, pic_label_name)); + xops[2] = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ()); + + if (!flag_pic) + output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops); + else + output_asm_insn ("call\t%a2", xops); + + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", + CODE_LABEL_NUMBER (XEXP (xops[2], 0))); + + if (flag_pic) + output_asm_insn ("pop{l}\t%0", xops); } else { - pclab = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); + xops[2] = gen_rtx_SYMBOL_REF (Pmode, get_pic_label_name ()); + xops[2] = gen_rtx_MEM (QImode, xops[2]); + output_asm_insn ("call\t%X2", xops); } - emit_insn (gen_prologue_get_pc (pic_offset_table_rtx, pclab)); - - if (! TARGET_DEEP_BRANCH_PREDICTION) - emit_insn (gen_popsi1 (pic_offset_table_rtx)); + if (!flag_pic || TARGET_DEEP_BRANCH_PREDICTION) + output_asm_insn ("add{l}\t{%1, %0|%0, %1}", xops); + else + output_asm_insn ("add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}", xops); - emit_insn (gen_prologue_set_got (pic_offset_table_rtx, gotsym, pclab)); + return ""; } /* Generate an "push" pattern for input ARG. */ @@ -4197,7 +4218,15 @@ ix86_expand_prologue () #endif if (pic_reg_used) - load_pic_register (); + { + insn = emit_insn (gen_set_got (pic_offset_table_rtx)); + + /* ??? The current_function_uses_pic_offset_table flag is woefully + inaccurate, as it isn't updated as code gets deleted. Allow the + thing to be removed. A better solution would be to actually get + proper liveness for ebx, as then we won't save/restore it too. */ + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx, NULL); + } /* If we are profiling, make sure no instructions are scheduled before the call to mcount. However, if -fpic, the above call will have diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index cdd99fc22d50..a385ead7ad57 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -69,6 +69,7 @@ (UNSPEC_SSE_PROLOGUE_SAVE 13) (UNSPEC_FLDCW 14) (UNSPEC_GOTPCREL 15) + (UNSPEC_SET_GOT 16) ; For SSE/MMX support: (UNSPEC_FIX 30) @@ -97,8 +98,6 @@ (define_constants [(UNSPECV_BLOCKAGE 0) - (UNSPECV_PROLOGUE_SET_GOT 1) - (UNSPECV_PROLOGUE_GET_PC 2) (UNSPECV_EH_RETURN 13) (UNSPECV_EMMS 31) (UNSPECV_LDMXCSR 37) @@ -13120,46 +13119,39 @@ "" "ix86_expand_prologue (); DONE;") -(define_insn "prologue_set_got" +(define_expand "set_got" + [(parallel [(set (match_operand:SI 0 "register_operand" "") + (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) + (clobber (reg:CC 17))])] + "!TARGET_64BIT" + "") + +(define_insn "*set_got_nopic" [(set (match_operand:SI 0 "register_operand" "=r") - (unspec_volatile:SI - [(plus:SI (match_dup 0) - (plus:SI (match_operand:SI 1 "symbolic_operand" "") - (minus:SI (pc) (match_operand 2 "" ""))))] - UNSPECV_PROLOGUE_SET_GOT)) + (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) (clobber (reg:CC 17))] - "!TARGET_64BIT" -{ - if (GET_CODE (operands[2]) == LABEL_REF) - operands[2] = XEXP (operands[2], 0); - if (TARGET_DEEP_BRANCH_PREDICTION) - return "add{l}\t{%1, %0|%0, %1}"; - else - return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}"; -} - [(set_attr "type" "alu") - ; Since this insn may have two constant operands, we must set the - ; length manually. - (set_attr "length_immediate" "4") - (set_attr "mode" "SI")]) + "!TARGET_64BIT && !flag_pic" + { return output_set_got (operands[0]); } + [(set_attr "type" "multi") + (set_attr "length" "11")]) -(define_insn "prologue_get_pc" +(define_insn "*set_got_deep" + [(set (match_operand:SI 0 "register_operand" "=b") + (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) + (clobber (reg:CC 17))] + "!TARGET_64BIT && TARGET_DEEP_BRANCH_PREDICTION" + { return output_set_got (operands[0]); } + [(set_attr "type" "multi") + (set_attr "length" "11")]) + +(define_insn "*set_got_nodeep" [(set (match_operand:SI 0 "register_operand" "=r") - (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] - UNSPECV_PROLOGUE_GET_PC))] + (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) + (clobber (reg:CC 17))] "!TARGET_64BIT" -{ - if (GET_CODE (operands[1]) == LABEL_REF) - operands[1] = XEXP (operands[1], 0); - output_asm_insn ("call\t%X1", operands); - if (! TARGET_DEEP_BRANCH_PREDICTION) - { - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", - CODE_LABEL_NUMBER (operands[1])); - } - RET; -} - [(set_attr "type" "multi")]) + { return output_set_got (operands[0]); } + [(set_attr "type" "multi") + (set_attr "length" "12")]) (define_expand "epilogue" [(const_int 1)] @@ -16212,7 +16204,7 @@ [(label_ref (match_operand 0 "" ""))] "!TARGET_64BIT && flag_pic" { - load_pic_register (); + emit_insn (gen_set_got (pic_offset_table_rtx)); DONE; })