Commit 108b61d5 by Richard Sandiford Committed by Richard Sandiford

mips-protos.h (mips_global_pic_constant_p): Delete.

	* config/mips/mips-protos.h (mips_global_pic_constant_p): Delete.
	(mips_delegitimize_address): Delete.
	(mips_gotoff_global, mips_load_got_page): Declare.
	(mips_load_got_global, mips_rewrite_small_data): Declare.

	* config/mips/mips.h (FIND_BASE_TERM): Remove definition.
	(DANGEROUS_FOR_LA25_P): Use global_got_operand.
	(PREDICATE_CODES): Add global_got_operand, local_got_operand and
	small_data_pattern.  Remove CONST from const_arith_operand's entry.

	* config/mips/mips.c (UNSPEC_ADDRESS_P, CONST_GP_P): New macros.
	(UNSPEC_ADDRESS, UNSPEC_ADDRESS_TYPE): Likewise.
	(mips_constant_type): Delete.
	(mips_symbol_type): Add SYMBOL_GOTOFF_PAGE, SYMBOL_GOTOFF_GLOBAL,
	SYMBOL_GOTOFF_CALL and SYMBOL_GOTOFF_LOADGP.
	(NUM_SYMBOL_TYPES): New macro.
	(mips_address_type): Remove ADDRESS_INVALID.
	(machine_function): Add has_gp_insn_p.
	(mips_constant_info): Delete.
	(mips_address_info): Add the address type as an extra field.  Replace
	the c field with symbol_type.
	(mips_split_p, mips_lo_relocs, mips_hi_relocs): New arrays.
	(TARGET_DELEGITIMIZE_ADDRESS): Remove definition.
	(mips_reloc_offset_ok_p, mips_classify_constant): Delete.
	(mips_split_const, mips_symbolic_constant_p): New functions.
	(mips_symbolic_address_p): Take the symbol type and mode as arguments.
	(mips_classify_address): Return true if the address is valid, storing
	its type in INFO.  Use mips_symbolic_constant_p.  Use mips_lo_relocs[]
	to test whether a LO_SUM address is allowed.
	(mips_symbol_insns): Return 0 for general mips16 symbols.
	Reorder SYMBOL_GOT_GLOBAL case to match mips_symbol_type definition.
	Handle the new SYMBOL_GOTOFF_*s.
	(mips_address_insns): Update call to mips_classify_address.
	(mips_const_insns): Be more fussy about HIGH constants.  Remove use
	of mips_classify_constant.  Be more accurate about CONSTs.
	(mips_global_pic_constant_p): Delete.
	(const_arith_operand): Only accept CONST_INTs.
	(call_insn_operand): Remove call to mips_classify_constant.
	Let mips_symbolic_constant_p check for invalid offsets.
	(move_operand): Check for general_operands first.  Only accept symbolic
	constants if they satisfy mips_symbolic_constant_p and cannot be split.
	(symbolic_constant): Use mips_symbolic_constant_p.
	(global_got_operand, local_got_operand): New predicates.
	(stack_operand): Update call to mips_classify_address.
	(mips_legitimate_address_p): Likewise.
	(mips_reloc, mips_lui_reloc): Delete.
	(mips_force_temporary): Only use the given temporary if no_new_pseudos.
	Use emit_move_insn.
	(mips_split_symbol, mips_unspec_address): New functions.
	(mips_unspec_offset_high): New function.
	(mips_load_got): Replace reloc argument with a symbol_type.
	Use mips_unspec_address to create the address and put it in a
	LO_SUM with the base register.
	(mips_load_got16, mips_load_got32): Delete.
	(mips_emit_high, mips_legitimize_symbol): Delete.
	(mips_gotoff_global): New function.
	(mips_load_got_page, mips_load_got_global): New functions.
	(mips_legitimize_symbol): Inline handling of LO_SUM splits.
	(mips_legitimize_const_move): Likewise.  Remove HIGH handling.
	Inline code to handle constants plus invalid offsets.  Use
	mips_split_symbol to legitimize constant pool addresses.
	(mips_delegitimize_address): Delete.
	(mips_rtx_costs): Give legitimate symbolic constants and CONST_DOUBLEs
	a cost of 1 insn.  Give the rest a cost of CONSTANT_POOL_ADDRESS.
	(mips_subword): Pass memrefs through mips_rewrite_small_data.
	(mips_output_move): Remove use of mips_classify_constant.
	(mips_expand_call): Use mips_unspec_offset_high to calculate the
	high part of the GOT address for calls to global functions.
	(override_options): Initialize mips_split_p[], mips_lo_relocs[]
	and mips_hi_relocs[].
	(print_operand): Use print_operand_reloc to handle '%h' and '%R'.
	Remove use of mips_classify_constant.
	(mips_reloc_string): Delete.
	(print_operand_reloc): New function.
	(print_operand_address): Update call to mips_classify_address.
	(mips_rewrite_small_data_p, small_data_pattern_1): New functions.
	(small_data_pattern): New predicate.
	(mips_rewrite_small_data_1, mips_rewrite_small_data): New functions.
	(mips_function_has_gp_insn): New function.
	(mips_global_pointer): Use it.
	(mips_gp_insn): Delete.
	(mips_expand_prologue): When compiling for n32/n64 abicalls, use a
	single loadgp pattern to initialize $gp.  Pass it the offset of _gp
	from the start of the current function.
	(mips16_gp_pseudo_reg): Revert last patch.

	* config/mips/mips.md (RELOC_*): Delete.
	(UNSPEC_LOADGP, UNSPEC_FIRST_ADDRESS): New constants.
	(got): New insn attribute.
	(type): Set to "load" if got == load.
	(length): Set to 4 if got == load, 8 if got == xgot_high.
	(lui[sd]i): Delete.
	(*xgot_hi[sd]i, *xgot_lo[sd]i): New patterns.
	(*got_disp[sd]i, *got_page[sd]i): Likewise.
	(*low[sd]i): Change constraints to "d".  Add a new define_split to
	rewrite small data constants into LO_SUMs.
	(loadgp): New insns.

From-SVN: r73259
parent 487e9fff
2003-11-04 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips-protos.h (mips_global_pic_constant_p): Delete.
(mips_delegitimize_address): Delete.
(mips_gotoff_global, mips_load_got_page): Declare.
(mips_load_got_global, mips_rewrite_small_data): Declare.
* config/mips/mips.h (FIND_BASE_TERM): Remove definition.
(DANGEROUS_FOR_LA25_P): Use global_got_operand.
(PREDICATE_CODES): Add global_got_operand, local_got_operand and
small_data_pattern. Remove CONST from const_arith_operand's entry.
* config/mips/mips.c (UNSPEC_ADDRESS_P, CONST_GP_P): New macros.
(UNSPEC_ADDRESS, UNSPEC_ADDRESS_TYPE): Likewise.
(mips_constant_type): Delete.
(mips_symbol_type): Add SYMBOL_GOTOFF_PAGE, SYMBOL_GOTOFF_GLOBAL,
SYMBOL_GOTOFF_CALL and SYMBOL_GOTOFF_LOADGP.
(NUM_SYMBOL_TYPES): New macro.
(mips_address_type): Remove ADDRESS_INVALID.
(machine_function): Add has_gp_insn_p.
(mips_constant_info): Delete.
(mips_address_info): Add the address type as an extra field. Replace
the c field with symbol_type.
(mips_split_p, mips_lo_relocs, mips_hi_relocs): New arrays.
(TARGET_DELEGITIMIZE_ADDRESS): Remove definition.
(mips_reloc_offset_ok_p, mips_classify_constant): Delete.
(mips_split_const, mips_symbolic_constant_p): New functions.
(mips_symbolic_address_p): Take the symbol type and mode as arguments.
(mips_classify_address): Return true if the address is valid, storing
its type in INFO. Use mips_symbolic_constant_p. Use mips_lo_relocs[]
to test whether a LO_SUM address is allowed.
(mips_symbol_insns): Return 0 for general mips16 symbols.
Reorder SYMBOL_GOT_GLOBAL case to match mips_symbol_type definition.
Handle the new SYMBOL_GOTOFF_*s.
(mips_address_insns): Update call to mips_classify_address.
(mips_const_insns): Be more fussy about HIGH constants. Remove use
of mips_classify_constant. Be more accurate about CONSTs.
(mips_global_pic_constant_p): Delete.
(const_arith_operand): Only accept CONST_INTs.
(call_insn_operand): Remove call to mips_classify_constant.
Let mips_symbolic_constant_p check for invalid offsets.
(move_operand): Check for general_operands first. Only accept symbolic
constants if they satisfy mips_symbolic_constant_p and cannot be split.
(symbolic_constant): Use mips_symbolic_constant_p.
(global_got_operand, local_got_operand): New predicates.
(stack_operand): Update call to mips_classify_address.
(mips_legitimate_address_p): Likewise.
(mips_reloc, mips_lui_reloc): Delete.
(mips_force_temporary): Only use the given temporary if no_new_pseudos.
Use emit_move_insn.
(mips_split_symbol, mips_unspec_address): New functions.
(mips_unspec_offset_high): New function.
(mips_load_got): Replace reloc argument with a symbol_type.
Use mips_unspec_address to create the address and put it in a
LO_SUM with the base register.
(mips_load_got16, mips_load_got32): Delete.
(mips_emit_high, mips_legitimize_symbol): Delete.
(mips_gotoff_global): New function.
(mips_load_got_page, mips_load_got_global): New functions.
(mips_legitimize_symbol): Inline handling of LO_SUM splits.
(mips_legitimize_const_move): Likewise. Remove HIGH handling.
Inline code to handle constants plus invalid offsets. Use
mips_split_symbol to legitimize constant pool addresses.
(mips_delegitimize_address): Delete.
(mips_rtx_costs): Give legitimate symbolic constants and CONST_DOUBLEs
a cost of 1 insn. Give the rest a cost of CONSTANT_POOL_ADDRESS.
(mips_subword): Pass memrefs through mips_rewrite_small_data.
(mips_output_move): Remove use of mips_classify_constant.
(mips_expand_call): Use mips_unspec_offset_high to calculate the
high part of the GOT address for calls to global functions.
(override_options): Initialize mips_split_p[], mips_lo_relocs[]
and mips_hi_relocs[].
(print_operand): Use print_operand_reloc to handle '%h' and '%R'.
Remove use of mips_classify_constant.
(mips_reloc_string): Delete.
(print_operand_reloc): New function.
(print_operand_address): Update call to mips_classify_address.
(mips_rewrite_small_data_p, small_data_pattern_1): New functions.
(small_data_pattern): New predicate.
(mips_rewrite_small_data_1, mips_rewrite_small_data): New functions.
(mips_function_has_gp_insn): New function.
(mips_global_pointer): Use it.
(mips_gp_insn): Delete.
(mips_expand_prologue): When compiling for n32/n64 abicalls, use a
single loadgp pattern to initialize $gp. Pass it the offset of _gp
from the start of the current function.
(mips16_gp_pseudo_reg): Revert last patch.
* config/mips/mips.md (RELOC_*): Delete.
(UNSPEC_LOADGP, UNSPEC_FIRST_ADDRESS): New constants.
(got): New insn attribute.
(type): Set to "load" if got == load.
(length): Set to 4 if got == load, 8 if got == xgot_high.
(lui[sd]i): Delete.
(*xgot_hi[sd]i, *xgot_lo[sd]i): New patterns.
(*got_disp[sd]i, *got_page[sd]i): Likewise.
(*low[sd]i): Change constraints to "d". Add a new define_split to
rewrite small data constants into LO_SUMs.
(loadgp): New insns.
2003-11-04 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* config/mips/_tilib.c: Use _ABI* in _MIPS_SIM tests.
......
......@@ -30,11 +30,12 @@ extern int mips_reg_mode_ok_for_base_p (rtx, enum machine_mode, int);
extern int mips_address_insns (rtx, enum machine_mode);
extern int mips_const_insns (rtx);
extern int mips_fetch_insns (rtx);
extern bool mips_global_pic_constant_p (rtx);
extern bool mips_legitimate_address_p (enum machine_mode, rtx, int);
extern bool mips_legitimize_address (rtx *, enum machine_mode);
extern rtx mips_gotoff_global (rtx);
extern rtx mips_load_got_page (rtx);
extern rtx mips_load_got_global (rtx, rtx);
extern bool mips_legitimize_move (enum machine_mode, rtx, rtx);
extern rtx mips_delegitimize_address (rtx);
extern int m16_uimm3_b (rtx, enum machine_mode);
extern int m16_simm4_1 (rtx, enum machine_mode);
......@@ -110,6 +111,7 @@ extern void mips_declare_object (FILE *, const char *, const char *,
extern void mips_declare_object_name (FILE *, const char *, tree);
extern void mips_finish_declare_object (FILE *, tree, int, int);
extern rtx mips_rewrite_small_data (rtx);
extern HOST_WIDE_INT compute_frame_size (HOST_WIDE_INT);
extern int mips_initial_elimination_offset (int, int);
extern rtx mips_return_addr (int, rtx);
......
......@@ -1244,8 +1244,6 @@ extern const struct mips_cpu_info *mips_tune_info;
SFmode register saves. */
#define DWARF_CIE_DATA_ALIGNMENT 4
#define FIND_BASE_TERM(X) mips_delegitimize_address (X)
/* Correct the offset of automatic variables and arguments. Note that
the MIPS debug format wants all automatic variables and arguments
to be in terms of the virtual frame pointer (stack pointer before
......@@ -2028,9 +2026,7 @@ extern enum reg_class mips_char_to_class[256];
part of a call sequence and allow a global 'foo' to be lazily bound. */
#define DANGEROUS_FOR_LA25_P(OP) \
(TARGET_ABICALLS \
&& !TARGET_EXPLICIT_RELOCS \
&& mips_global_pic_constant_p (OP))
(!TARGET_EXPLICIT_RELOCS && global_got_operand (OP, VOIDmode))
/* Letters in the range `Q' through `U' may be defined in a
machine-dependent fashion to stand for arbitrary operand types.
......@@ -2798,7 +2794,11 @@ typedef struct mips_args {
#define PREDICATE_CODES \
{"uns_arith_operand", { REG, CONST_INT, SUBREG, ADDRESSOF }}, \
{"symbolic_operand", { CONST, SYMBOL_REF, LABEL_REF }}, \
{"const_arith_operand", { CONST, CONST_INT }}, \
{"global_got_operand", { CONST, SYMBOL_REF, LABEL_REF }}, \
{"local_got_operand", { CONST, SYMBOL_REF, LABEL_REF }}, \
{"const_arith_operand", { CONST_INT }}, \
{"small_data_pattern", { SET, PARALLEL, UNSPEC, \
UNSPEC_VOLATILE }}, \
{"arith_operand", { REG, CONST_INT, CONST, SUBREG, ADDRESSOF }}, \
{"reg_or_0_operand", { REG, CONST_INT, CONST_DOUBLE, SUBREG, ADDRESSOF }}, \
{"small_int", { CONST_INT }}, \
......
......@@ -53,20 +53,9 @@
(UNSPEC_LDR 23)
(UNSPEC_SDL 24)
(UNSPEC_SDR 25)
(UNSPEC_LOADGP 26)
;; Constants used in relocation unspecs. RELOC_GOT_PAGE and RELOC_GOT_DISP
;; are really only available for n32 and n64. However, it is convenient
;; to reuse them for SVR4 PIC, where they represent the local and global
;; forms of R_MIPS_GOT16.
(RELOC_GOT_HI 100)
(RELOC_GOT_LO 101)
(RELOC_GOT_PAGE 102)
(RELOC_GOT_DISP 103)
(RELOC_CALL16 104)
(RELOC_CALL_HI 105)
(RELOC_CALL_LO 106)
(RELOC_LOADGP_HI 107)
(RELOC_LOADGP_LO 108)])
(UNSPEC_ADDRESS_FIRST 100)])
;; ....................
;;
......@@ -74,6 +63,9 @@
;;
;; ....................
(define_attr "got" "unset,xgot_high,load"
(const_string "unset"))
;; For jal instructions, this attribute is DIRECT when the target address
;; is symbolic and INDIRECT when it is a register.
(define_attr "jal" "unset,direct,indirect"
......@@ -125,8 +117,8 @@
;; nop no operation
(define_attr "type"
"unknown,branch,jump,call,load,store,prefetch,prefetchx,move,condmove,xfer,hilo,const,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
(cond [(eq_attr "jal" "!unset")
(const_string "call")]
(cond [(eq_attr "jal" "!unset") (const_string "call")
(eq_attr "got" "load") (const_string "load")]
(const_string "unknown")))
;; Main data type used by the insn
......@@ -179,6 +171,11 @@
(const_int 24)
] (const_int 12))
(eq_attr "got" "load")
(const_int 4)
(eq_attr "got" "xgot_high")
(const_int 8)
(eq_attr "type" "const")
(symbol_ref "mips_const_insns (operands[1]) * 4")
(eq_attr "type" "load")
......@@ -4147,31 +4144,109 @@ dsrl\t%3,%3,1\n\
[(set_attr "type" "store")
(set_attr "mode" "DI")])
;; Insns to fetch a global symbol from a big GOT.
;; Instructions for loading a relocation expression using "lui".
(define_insn_and_split "*xgot_hisi"
[(set (match_operand:SI 0 "register_operand" "=d")
(high:SI (match_operand:SI 1 "global_got_operand" "")))]
"TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
"#"
"&& reload_completed"
[(set (match_dup 0) (high:SI (match_dup 2)))
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
{
operands[2] = mips_gotoff_global (operands[1]);
operands[3] = pic_offset_table_rtx;
}
[(set_attr "got" "xgot_high")])
(define_insn "luisi"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))]
""
"lui\t%0,%1"
[(set_attr "type" "arith")])
(define_insn_and_split "*xgot_losi"
[(set (match_operand:SI 0 "register_operand" "=d")
(lo_sum:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "global_got_operand" "")))]
"TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
"#"
"&& reload_completed"
[(set (match_dup 0) (match_dup 3))]
{ operands[3] = mips_load_got_global (operands[1], operands[2]); }
[(set_attr "got" "load")])
(define_insn "luidi"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))]
"TARGET_64BIT"
"lui\t%0,%1"
[(set_attr "type" "arith")])
(define_insn_and_split "*xgot_hidi"
[(set (match_operand:DI 0 "register_operand" "=d")
(high:DI (match_operand:DI 1 "global_got_operand" "")))]
"TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
"#"
"&& reload_completed"
[(set (match_dup 0) (high:DI (match_dup 2)))
(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
{
operands[2] = mips_gotoff_global (operands[1]);
operands[3] = pic_offset_table_rtx;
}
[(set_attr "got" "xgot_high")])
(define_insn_and_split "*xgot_lodi"
[(set (match_operand:DI 0 "register_operand" "=d")
(lo_sum:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "global_got_operand" "")))]
"TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
"#"
"&& reload_completed"
[(set (match_dup 0) (match_dup 3))]
{ operands[3] = mips_load_got_global (operands[1], operands[2]); }
[(set_attr "got" "load")])
;; Insns to fetch a global symbol from a normal GOT.
(define_insn_and_split "*got_dispsi"
[(set (match_operand:SI 0 "register_operand" "=d")
(match_operand:SI 1 "global_got_operand" ""))]
"TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
"#"
"&& reload_completed"
[(set (match_dup 0) (match_dup 2))]
{ operands[2] = mips_load_got_global (pic_offset_table_rtx, operands[1]); }
[(set_attr "got" "load")])
(define_insn_and_split "*got_dispdi"
[(set (match_operand:DI 0 "register_operand" "=d")
(match_operand:DI 1 "global_got_operand" ""))]
"TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
"#"
"&& reload_completed"
[(set (match_dup 0) (match_dup 2))]
{ operands[2] = mips_load_got_global (pic_offset_table_rtx, operands[1]); }
[(set_attr "got" "load")])
;; Insns for loading the high part of a local symbol.
(define_insn_and_split "*got_pagesi"
[(set (match_operand:SI 0 "register_operand" "=d")
(high:SI (match_operand:SI 1 "local_got_operand" "")))]
"TARGET_EXPLICIT_RELOCS"
"#"
"&& reload_completed"
[(set (match_dup 0) (match_dup 2))]
{ operands[2] = mips_load_got_page (operands[1]); }
[(set_attr "got" "load")])
(define_insn_and_split "*got_pagedi"
[(set (match_operand:DI 0 "register_operand" "=d")
(high:DI (match_operand:DI 1 "local_got_operand" "")))]
"TARGET_EXPLICIT_RELOCS"
"#"
"&& reload_completed"
[(set (match_dup 0) (match_dup 2))]
{ operands[2] = mips_load_got_page (operands[1]); }
[(set_attr "got" "load")])
;; Instructions for adding the low 16 bits of an address to a register.
;; Operand 2 is the address: print_operand works out which relocation
;; should be applied.
(define_insn "*lowsi"
[(set (match_operand:SI 0 "register_operand" "=r")
(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
[(set (match_operand:SI 0 "register_operand" "=d")
(lo_sum:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "immediate_operand" "")))]
"!TARGET_MIPS16"
"addiu\t%0,%1,%R2"
......@@ -4179,8 +4254,8 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "SI")])
(define_insn "*lowdi"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
[(set (match_operand:DI 0 "register_operand" "=d")
(lo_sum:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "immediate_operand" "")))]
"!TARGET_MIPS16 && TARGET_64BIT"
"daddiu\t%0,%1,%R2"
......@@ -5048,6 +5123,23 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "SF")
(set_attr "length" "4")])
(define_insn_and_split "loadgp"
[(unspec_volatile [(match_operand 0 "" "")] UNSPEC_LOADGP)]
"TARGET_ABICALLS && TARGET_NEWABI"
"#"
""
[(set (match_dup 1) (match_dup 2))
(set (match_dup 1) (match_dup 3))
(set (match_dup 1) (match_dup 4))]
{
operands[1] = pic_offset_table_rtx;
operands[2] = gen_rtx_HIGH (Pmode, operands[0]);
operands[3] = gen_rtx_PLUS (Pmode, operands[1],
gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM));
operands[4] = gen_rtx_LO_SUM (Pmode, operands[1], operands[0]);
}
[(set_attr "length" "12")])
;; The use of gp is hidden when not using explicit relocations.
;; This blockage instruction prevents the gp load from being
;; scheduled after an implicit use of gp. It also prevents
......@@ -9038,3 +9130,9 @@ ld\t%2,%1-%S1(%2)\;daddu\t%2,%2,$31\;%*j\t%2%/"
[(set_attr "type" "branch")
(set_attr "mode" "none")
(set_attr "length" "8")])
(define_split
[(match_operand 0 "small_data_pattern" "")]
"reload_completed"
[(match_dup 0)]
{ operands[0] = mips_rewrite_small_data (operands[0]); })
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