Commit c8c03509 by Richard Henderson Committed by Richard Henderson

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
parent d51f3632
2002-05-23 Richard Henderson <rth@redhat.com>
* 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 <jh@suse.cz> Thu May 23 09:22:23 CEST 2002 Jan Hubicka <jh@suse.cz>
* gcse.c (hash_expr): Do not use alias set for hashing. * gcse.c (hash_expr): Do not use alias set for hashing.
......
...@@ -28,7 +28,6 @@ extern int ix86_frame_pointer_required PARAMS ((void)); ...@@ -28,7 +28,6 @@ extern int ix86_frame_pointer_required PARAMS ((void));
extern void ix86_setup_frame_addresses PARAMS ((void)); extern void ix86_setup_frame_addresses PARAMS ((void));
extern void ix86_asm_file_end PARAMS ((FILE *)); 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 HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int));
extern void ix86_expand_prologue PARAMS ((void)); extern void ix86_expand_prologue PARAMS ((void));
extern void ix86_expand_epilogue PARAMS ((int)); extern void ix86_expand_epilogue PARAMS ((int));
...@@ -96,6 +95,7 @@ extern void print_operand_address PARAMS ((FILE*, rtx)); ...@@ -96,6 +95,7 @@ extern void print_operand_address PARAMS ((FILE*, rtx));
extern void split_di PARAMS ((rtx[], int, rtx[], rtx[])); extern void split_di PARAMS ((rtx[], int, rtx[], rtx[]));
extern void split_ti 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_387_binary_op PARAMS ((rtx, rtx*));
extern const char *output_fix_trunc PARAMS ((rtx, rtx*)); extern const char *output_fix_trunc PARAMS ((rtx, rtx*));
extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int)); extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int));
......
...@@ -647,6 +647,7 @@ static char internal_label_prefix[16]; ...@@ -647,6 +647,7 @@ static char internal_label_prefix[16];
static int internal_label_prefix_len; static int internal_label_prefix_len;
static int local_symbolic_operand PARAMS ((rtx, enum machine_mode)); 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 output_pic_addr_const PARAMS ((FILE *, rtx, int));
static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode, static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
int, int, FILE *)); int, int, FILE *));
...@@ -3795,6 +3796,14 @@ ix86_setup_frame_addresses () ...@@ -3795,6 +3796,14 @@ ix86_setup_frame_addresses ()
static char pic_label_name[32]; 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 /* This function generates code for -fpic that loads %ebx with
the return address of the caller and then returns. */ the return address of the caller and then returns. */
...@@ -3847,33 +3856,45 @@ ix86_asm_file_end (file) ...@@ -3847,33 +3856,45 @@ ix86_asm_file_end (file)
output_asm_insn ("ret", xops); output_asm_insn ("ret", xops);
} }
void /* Emit code for the SET_GOT patterns. */
load_pic_register ()
{
rtx gotsym, pclab;
if (TARGET_64BIT) const char *
abort (); 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]) xops[2] = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0);
pclab = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, pic_label_name)); 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 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 (!flag_pic || TARGET_DEEP_BRANCH_PREDICTION)
output_asm_insn ("add{l}\t{%1, %0|%0, %1}", xops);
if (! TARGET_DEEP_BRANCH_PREDICTION) else
emit_insn (gen_popsi1 (pic_offset_table_rtx)); 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. */ /* Generate an "push" pattern for input ARG. */
...@@ -4197,7 +4218,15 @@ ix86_expand_prologue () ...@@ -4197,7 +4218,15 @@ ix86_expand_prologue ()
#endif #endif
if (pic_reg_used) 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 /* If we are profiling, make sure no instructions are scheduled before
the call to mcount. However, if -fpic, the above call will have the call to mcount. However, if -fpic, the above call will have
......
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
(UNSPEC_SSE_PROLOGUE_SAVE 13) (UNSPEC_SSE_PROLOGUE_SAVE 13)
(UNSPEC_FLDCW 14) (UNSPEC_FLDCW 14)
(UNSPEC_GOTPCREL 15) (UNSPEC_GOTPCREL 15)
(UNSPEC_SET_GOT 16)
; For SSE/MMX support: ; For SSE/MMX support:
(UNSPEC_FIX 30) (UNSPEC_FIX 30)
...@@ -97,8 +98,6 @@ ...@@ -97,8 +98,6 @@
(define_constants (define_constants
[(UNSPECV_BLOCKAGE 0) [(UNSPECV_BLOCKAGE 0)
(UNSPECV_PROLOGUE_SET_GOT 1)
(UNSPECV_PROLOGUE_GET_PC 2)
(UNSPECV_EH_RETURN 13) (UNSPECV_EH_RETURN 13)
(UNSPECV_EMMS 31) (UNSPECV_EMMS 31)
(UNSPECV_LDMXCSR 37) (UNSPECV_LDMXCSR 37)
...@@ -13120,46 +13119,39 @@ ...@@ -13120,46 +13119,39 @@
"" ""
"ix86_expand_prologue (); DONE;") "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") [(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
[(plus:SI (match_dup 0)
(plus:SI (match_operand:SI 1 "symbolic_operand" "")
(minus:SI (pc) (match_operand 2 "" ""))))]
UNSPECV_PROLOGUE_SET_GOT))
(clobber (reg:CC 17))] (clobber (reg:CC 17))]
"!TARGET_64BIT" "!TARGET_64BIT && !flag_pic"
{ { return output_set_got (operands[0]); }
if (GET_CODE (operands[2]) == LABEL_REF) [(set_attr "type" "multi")
operands[2] = XEXP (operands[2], 0); (set_attr "length" "11")])
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")])
(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") [(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
UNSPECV_PROLOGUE_GET_PC))] (clobber (reg:CC 17))]
"!TARGET_64BIT" "!TARGET_64BIT"
{ { return output_set_got (operands[0]); }
if (GET_CODE (operands[1]) == LABEL_REF) [(set_attr "type" "multi")
operands[1] = XEXP (operands[1], 0); (set_attr "length" "12")])
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")])
(define_expand "epilogue" (define_expand "epilogue"
[(const_int 1)] [(const_int 1)]
...@@ -16212,7 +16204,7 @@ ...@@ -16212,7 +16204,7 @@
[(label_ref (match_operand 0 "" ""))] [(label_ref (match_operand 0 "" ""))]
"!TARGET_64BIT && flag_pic" "!TARGET_64BIT && flag_pic"
{ {
load_pic_register (); emit_insn (gen_set_got (pic_offset_table_rtx));
DONE; DONE;
}) })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment