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:
parent
d51f363255
commit
c8c0350922
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user