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
This commit is contained in:
Richard Henderson 2002-05-23 00:43:13 -07:00 committed by Richard Henderson
parent d51f363255
commit c8c0350922
4 changed files with 93 additions and 59 deletions

View File

@ -1,3 +1,16 @@
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>
* gcse.c (hash_expr): Do not use alias set for hashing.

View File

@ -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));

View File

@ -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 ()
/* Emit code for the SET_GOT patterns. */
const char *
output_set_got (dest)
rtx dest;
{
rtx gotsym, pclab;
rtx xops[3];
if (TARGET_64BIT)
abort ();
xops[0] = dest;
xops[1] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
gotsym = 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 (!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);
if (! TARGET_DEEP_BRANCH_PREDICTION)
emit_insn (gen_popsi1 (pic_offset_table_rtx));
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

View File

@ -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 && !flag_pic"
{ return output_set_got (operands[0]); }
[(set_attr "type" "multi")
(set_attr "length" "11")])
(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: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")])
(define_insn "prologue_get_pc"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))]
UNSPECV_PROLOGUE_GET_PC))]
"!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;
})