Commit 280fcbfa by Richard Sandiford Committed by Richard Sandiford

mips-protos.h (mips_symbol_context): New enumeration.

gcc/
	* config/mips/mips-protos.h (mips_symbol_context): New enumeration.
	* config/mips/mips.c (mips_classify_symbol): Take a context argument.
	(mips_symbolic_constant_p): Likewise.  Update the call to
	mips_classify_symbol.
	(mips_classify_address): Update the calls to mips_symbolic_constant_p.
	(mips_const_insns): Likewise.  Update the call to mips_classify_symbol.
	(mips_legitimize_address): Update the call to mips_symbolic_constant_p.
	(print_operand_reloc): Add a context argument.  Update the call to
	mips_symbolic_constant_p.
	(print_operand): Update the calls to print_operand_reloc.
	(print_operand_address): Use print_operand_reloc rather than
	print_operand.
	(mips_rewrite_small_data_p): Add a context argument.  Update the call
	to mips_symbolic_constant_p.
	(mips_small_data_pattern_1): Make DATA the containing mem.
	Update the call to mips_rewrite_small_data_p.
	(mips_rewrite_small_data_1): Likewise.
	(mips_use_anchors_for_symbol_p): Update the call to
	mips_symbolic_constant_p.
	* config/mips/predicates.md (const_call_insn_operand): Likewise.
	(splittable_symbolic_operand): Likewise.
	(move_operand): Likewise.
	(absolute_symbolic_operand): Likewise.
	(got_disp_operand): Likewise.
	(got_page_ofst_operand): Likewise.

From-SVN: r127295
parent 67da85da
2007-08-08 Richard Sandiford <richard@codesourcery.com> 2007-08-08 Richard Sandiford <richard@codesourcery.com>
* config/mips/mips-protos.h (mips_symbol_context): New enumeration.
* config/mips/mips.c (mips_classify_symbol): Take a context argument.
(mips_symbolic_constant_p): Likewise. Update the call to
mips_classify_symbol.
(mips_classify_address): Update the calls to mips_symbolic_constant_p.
(mips_const_insns): Likewise. Update the call to mips_classify_symbol.
(mips_legitimize_address): Update the call to mips_symbolic_constant_p.
(print_operand_reloc): Add a context argument. Update the call to
mips_symbolic_constant_p.
(print_operand): Update the calls to print_operand_reloc.
(print_operand_address): Use print_operand_reloc rather than
print_operand.
(mips_rewrite_small_data_p): Add a context argument. Update the call
to mips_symbolic_constant_p.
(mips_small_data_pattern_1): Make DATA the containing mem.
Update the call to mips_rewrite_small_data_p.
(mips_rewrite_small_data_1): Likewise.
(mips_use_anchors_for_symbol_p): Update the call to
mips_symbolic_constant_p.
* config/mips/predicates.md (const_call_insn_operand): Likewise.
(splittable_symbolic_operand): Likewise.
(move_operand): Likewise.
(absolute_symbolic_operand): Likewise.
(got_disp_operand): Likewise.
(got_page_ofst_operand): Likewise.
2007-08-08 Richard Sandiford <richard@codesourcery.com>
* config/mips/mips-protos.h (SYMBOL_GENERAL): Rename to... * config/mips/mips-protos.h (SYMBOL_GENERAL): Rename to...
(SYMBOL_ABSOLUTE): ...this. (SYMBOL_ABSOLUTE): ...this.
(SYMBOL_SMALL_DATA): Rename to... (SYMBOL_SMALL_DATA): Rename to...
......
...@@ -25,6 +25,22 @@ along with GCC; see the file COPYING3. If not see ...@@ -25,6 +25,22 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_MIPS_PROTOS_H #ifndef GCC_MIPS_PROTOS_H
#define GCC_MIPS_PROTOS_H #define GCC_MIPS_PROTOS_H
/* Describes how a symbol is used.
SYMBOL_CONTEXT_CALL
The symbol is used as the target of a call instruction.
SYMBOL_CONTEXT_LEA
The symbol is used in a load-address operation.
SYMBOL_CONTEXT_MEM
The symbol is used as the address in a MEM. */
enum mips_symbol_context {
SYMBOL_CONTEXT_CALL,
SYMBOL_CONTEXT_LEA,
SYMBOL_CONTEXT_MEM
};
/* Classifies a SYMBOL_REF, LABEL_REF or UNSPEC address. /* Classifies a SYMBOL_REF, LABEL_REF or UNSPEC address.
SYMBOL_ABSOLUTE SYMBOL_ABSOLUTE
...@@ -140,7 +156,8 @@ enum mips_loadgp_style { ...@@ -140,7 +156,8 @@ enum mips_loadgp_style {
struct mips16e_save_restore_info; struct mips16e_save_restore_info;
extern bool mips_symbolic_constant_p (rtx, enum mips_symbol_type *); extern bool mips_symbolic_constant_p (rtx, enum mips_symbol_context,
enum mips_symbol_type *);
extern int mips_regno_mode_ok_for_base_p (int, enum machine_mode, int); extern int mips_regno_mode_ok_for_base_p (int, enum machine_mode, int);
extern bool mips_stack_address_p (rtx, enum machine_mode); extern bool mips_stack_address_p (rtx, enum machine_mode);
extern int mips_address_insns (rtx, enum machine_mode); extern int mips_address_insns (rtx, enum machine_mode);
......
...@@ -287,7 +287,6 @@ struct mips_address_info; ...@@ -287,7 +287,6 @@ struct mips_address_info;
struct mips_integer_op; struct mips_integer_op;
struct mips_sim; struct mips_sim;
static enum mips_symbol_type mips_classify_symbol (rtx);
static bool mips_valid_base_register_p (rtx, enum machine_mode, int); static bool mips_valid_base_register_p (rtx, enum machine_mode, int);
static bool mips_symbolic_address_p (enum mips_symbol_type, enum machine_mode); static bool mips_symbolic_address_p (enum mips_symbol_type, enum machine_mode);
static bool mips_classify_address (struct mips_address_info *, rtx, static bool mips_classify_address (struct mips_address_info *, rtx,
...@@ -321,9 +320,9 @@ static void mips_set_architecture (const struct mips_cpu_info *); ...@@ -321,9 +320,9 @@ static void mips_set_architecture (const struct mips_cpu_info *);
static void mips_set_tune (const struct mips_cpu_info *); static void mips_set_tune (const struct mips_cpu_info *);
static bool mips_handle_option (size_t, const char *, int); static bool mips_handle_option (size_t, const char *, int);
static struct machine_function *mips_init_machine_status (void); static struct machine_function *mips_init_machine_status (void);
static void print_operand_reloc (FILE *, rtx, const char **); static void print_operand_reloc (FILE *, rtx, enum mips_symbol_context,
const char **);
static void mips_file_start (void); static void mips_file_start (void);
static bool mips_rewrite_small_data_p (rtx);
static int mips_small_data_pattern_1 (rtx *, void *); static int mips_small_data_pattern_1 (rtx *, void *);
static int mips_rewrite_small_data_1 (rtx *, void *); static int mips_rewrite_small_data_1 (rtx *, void *);
static bool mips_function_has_gp_insn (void); static bool mips_function_has_gp_insn (void);
...@@ -1435,10 +1434,11 @@ mips_symbol_binds_local_p (rtx x) ...@@ -1435,10 +1434,11 @@ mips_symbol_binds_local_p (rtx x)
: SYMBOL_REF_LOCAL_P (x)); : SYMBOL_REF_LOCAL_P (x));
} }
/* Classify symbol X, which must be a SYMBOL_REF or a LABEL_REF. */ /* Return the method that should be used to access SYMBOL_REF or
LABEL_REF X in context CONTEXT. */
static enum mips_symbol_type static enum mips_symbol_type
mips_classify_symbol (rtx x) mips_classify_symbol (rtx x, enum mips_symbol_context context ATTRIBUTE_UNUSED)
{ {
if (TARGET_RTP_PIC) if (TARGET_RTP_PIC)
return SYMBOL_GOT_DISP; return SYMBOL_GOT_DISP;
...@@ -1528,12 +1528,12 @@ mips_offset_within_alignment_p (rtx x, HOST_WIDE_INT offset) ...@@ -1528,12 +1528,12 @@ mips_offset_within_alignment_p (rtx x, HOST_WIDE_INT offset)
return offset >= 0 && offset < align; return offset >= 0 && offset < align;
} }
/* Return true if X is a symbolic constant that can be calculated in /* Return true if X is a symbolic constant that can be used in context
the same way as a bare symbol. If it is, store the type of the CONTEXT. If it is, store the type of the symbol in *SYMBOL_TYPE. */
symbol in *SYMBOL_TYPE. */
bool bool
mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type) mips_symbolic_constant_p (rtx x, enum mips_symbol_context context,
enum mips_symbol_type *symbol_type)
{ {
rtx offset; rtx offset;
...@@ -1545,7 +1545,7 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type) ...@@ -1545,7 +1545,7 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
} }
else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF) else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
{ {
*symbol_type = mips_classify_symbol (x); *symbol_type = mips_classify_symbol (x, context);
if (*symbol_type == SYMBOL_TLS) if (*symbol_type == SYMBOL_TLS)
return false; return false;
} }
...@@ -1747,7 +1747,8 @@ mips_classify_address (struct mips_address_info *info, rtx x, ...@@ -1747,7 +1747,8 @@ mips_classify_address (struct mips_address_info *info, rtx x,
info->reg = XEXP (x, 0); info->reg = XEXP (x, 0);
info->offset = XEXP (x, 1); info->offset = XEXP (x, 1);
return (mips_valid_base_register_p (info->reg, mode, strict) return (mips_valid_base_register_p (info->reg, mode, strict)
&& mips_symbolic_constant_p (info->offset, &info->symbol_type) && mips_symbolic_constant_p (info->offset, SYMBOL_CONTEXT_MEM,
&info->symbol_type)
&& mips_symbolic_address_p (info->symbol_type, mode) && mips_symbolic_address_p (info->symbol_type, mode)
&& mips_lo_relocs[info->symbol_type] != 0); && mips_lo_relocs[info->symbol_type] != 0);
...@@ -1761,7 +1762,8 @@ mips_classify_address (struct mips_address_info *info, rtx x, ...@@ -1761,7 +1762,8 @@ mips_classify_address (struct mips_address_info *info, rtx x,
case LABEL_REF: case LABEL_REF:
case SYMBOL_REF: case SYMBOL_REF:
info->type = ADDRESS_SYMBOLIC; info->type = ADDRESS_SYMBOLIC;
return (mips_symbolic_constant_p (x, &info->symbol_type) return (mips_symbolic_constant_p (x, SYMBOL_CONTEXT_MEM,
&info->symbol_type)
&& mips_symbolic_address_p (info->symbol_type, mode) && mips_symbolic_address_p (info->symbol_type, mode)
&& !mips_split_p[info->symbol_type]); && !mips_split_p[info->symbol_type]);
...@@ -2002,7 +2004,8 @@ mips_const_insns (rtx x) ...@@ -2002,7 +2004,8 @@ mips_const_insns (rtx x)
{ {
case HIGH: case HIGH:
if (TARGET_MIPS16 if (TARGET_MIPS16
|| !mips_symbolic_constant_p (XEXP (x, 0), &symbol_type) || !mips_symbolic_constant_p (XEXP (x, 0), SYMBOL_CONTEXT_LEA,
&symbol_type)
|| !mips_split_p[symbol_type]) || !mips_split_p[symbol_type])
return 0; return 0;
...@@ -2031,7 +2034,7 @@ mips_const_insns (rtx x) ...@@ -2031,7 +2034,7 @@ mips_const_insns (rtx x)
return 1; return 1;
/* See if we can refer to X directly. */ /* See if we can refer to X directly. */
if (mips_symbolic_constant_p (x, &symbol_type)) if (mips_symbolic_constant_p (x, SYMBOL_CONTEXT_LEA, &symbol_type))
return mips_symbol_insns (symbol_type); return mips_symbol_insns (symbol_type);
/* Otherwise try splitting the constant into a base and offset. /* Otherwise try splitting the constant into a base and offset.
...@@ -2053,7 +2056,7 @@ mips_const_insns (rtx x) ...@@ -2053,7 +2056,7 @@ mips_const_insns (rtx x)
case SYMBOL_REF: case SYMBOL_REF:
case LABEL_REF: case LABEL_REF:
return mips_symbol_insns (mips_classify_symbol (x)); return mips_symbol_insns (mips_classify_symbol (x, SYMBOL_CONTEXT_LEA));
default: default:
return 0; return 0;
...@@ -2340,7 +2343,7 @@ mips_legitimize_address (rtx *xloc, enum machine_mode mode) ...@@ -2340,7 +2343,7 @@ mips_legitimize_address (rtx *xloc, enum machine_mode mode)
} }
/* See if the address can split into a high part and a LO_SUM. */ /* See if the address can split into a high part and a LO_SUM. */
if (mips_symbolic_constant_p (*xloc, &symbol_type) if (mips_symbolic_constant_p (*xloc, SYMBOL_CONTEXT_MEM, &symbol_type)
&& mips_symbolic_address_p (symbol_type, mode) && mips_symbolic_address_p (symbol_type, mode)
&& mips_split_p[symbol_type]) && mips_split_p[symbol_type])
{ {
...@@ -5943,11 +5946,11 @@ print_operand (FILE *file, rtx op, int letter) ...@@ -5943,11 +5946,11 @@ print_operand (FILE *file, rtx op, int letter)
if (GET_CODE (op) == HIGH) if (GET_CODE (op) == HIGH)
op = XEXP (op, 0); op = XEXP (op, 0);
print_operand_reloc (file, op, mips_hi_relocs); print_operand_reloc (file, op, SYMBOL_CONTEXT_LEA, mips_hi_relocs);
} }
else if (letter == 'R') else if (letter == 'R')
print_operand_reloc (file, op, mips_lo_relocs); print_operand_reloc (file, op, SYMBOL_CONTEXT_LEA, mips_lo_relocs);
else if (letter == 'Y') else if (letter == 'Y')
{ {
...@@ -6038,17 +6041,19 @@ print_operand (FILE *file, rtx op, int letter) ...@@ -6038,17 +6041,19 @@ print_operand (FILE *file, rtx op, int letter)
} }
/* Print symbolic operand OP, which is part of a HIGH or LO_SUM. /* Print symbolic operand OP, which is part of a HIGH or LO_SUM
RELOCS is the array of relocations to use. */ in context CONTEXT. RELOCS is the array of relocations to use. */
static void static void
print_operand_reloc (FILE *file, rtx op, const char **relocs) print_operand_reloc (FILE *file, rtx op, enum mips_symbol_context context,
const char **relocs)
{ {
enum mips_symbol_type symbol_type; enum mips_symbol_type symbol_type;
const char *p; const char *p;
rtx base, offset; rtx base, offset;
if (!mips_symbolic_constant_p (op, &symbol_type) || relocs[symbol_type] == 0) if (!mips_symbolic_constant_p (op, context, &symbol_type)
|| relocs[symbol_type] == 0)
fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op); fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op);
/* If OP uses an UNSPEC address, we want to print the inner symbol. */ /* If OP uses an UNSPEC address, we want to print the inner symbol. */
...@@ -6079,7 +6084,8 @@ print_operand_address (FILE *file, rtx x) ...@@ -6079,7 +6084,8 @@ print_operand_address (FILE *file, rtx x)
return; return;
case ADDRESS_LO_SUM: case ADDRESS_LO_SUM:
print_operand (file, addr.offset, 'R'); print_operand_reloc (file, addr.offset, SYMBOL_CONTEXT_MEM,
mips_lo_relocs);
fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]); fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
return; return;
...@@ -6429,29 +6435,40 @@ mips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end) ...@@ -6429,29 +6435,40 @@ mips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end)
} }
#endif #endif
/* Return true if X is a small data address that can be rewritten /* Return true if X in context CONTEXT is a small data address that can
as a LO_SUM. */ be rewritten as a LO_SUM. */
static bool static bool
mips_rewrite_small_data_p (rtx x) mips_rewrite_small_data_p (rtx x, enum mips_symbol_context context)
{ {
enum mips_symbol_type symbol_type; enum mips_symbol_type symbol_type;
return (TARGET_EXPLICIT_RELOCS return (TARGET_EXPLICIT_RELOCS
&& mips_symbolic_constant_p (x, &symbol_type) && mips_symbolic_constant_p (x, context, &symbol_type)
&& symbol_type == SYMBOL_GP_RELATIVE); && symbol_type == SYMBOL_GP_RELATIVE);
} }
/* A for_each_rtx callback for mips_small_data_pattern_p. */ /* A for_each_rtx callback for mips_small_data_pattern_p. DATA is the
containing MEM, or null if none. */
static int static int
mips_small_data_pattern_1 (rtx *loc, void *data ATTRIBUTE_UNUSED) mips_small_data_pattern_1 (rtx *loc, void *data)
{ {
enum mips_symbol_context context;
if (GET_CODE (*loc) == LO_SUM) if (GET_CODE (*loc) == LO_SUM)
return -1; return -1;
return mips_rewrite_small_data_p (*loc); if (MEM_P (*loc))
{
if (for_each_rtx (&XEXP (*loc, 0), mips_small_data_pattern_1, *loc))
return 1;
return -1;
}
context = data ? SYMBOL_CONTEXT_MEM : SYMBOL_CONTEXT_LEA;
return mips_rewrite_small_data_p (*loc, context);
} }
/* Return true if OP refers to small data symbols directly, not through /* Return true if OP refers to small data symbols directly, not through
...@@ -6463,12 +6480,22 @@ mips_small_data_pattern_p (rtx op) ...@@ -6463,12 +6480,22 @@ mips_small_data_pattern_p (rtx op)
return for_each_rtx (&op, mips_small_data_pattern_1, 0); return for_each_rtx (&op, mips_small_data_pattern_1, 0);
} }
/* A for_each_rtx callback, used by mips_rewrite_small_data. */ /* A for_each_rtx callback, used by mips_rewrite_small_data.
DATA is the containing MEM, or null if none. */
static int static int
mips_rewrite_small_data_1 (rtx *loc, void *data ATTRIBUTE_UNUSED) mips_rewrite_small_data_1 (rtx *loc, void *data)
{ {
if (mips_rewrite_small_data_p (*loc)) enum mips_symbol_context context;
if (MEM_P (*loc))
{
for_each_rtx (&XEXP (*loc, 0), mips_rewrite_small_data_1, *loc);
return -1;
}
context = data ? SYMBOL_CONTEXT_MEM : SYMBOL_CONTEXT_LEA;
if (mips_rewrite_small_data_p (*loc, context))
*loc = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, *loc); *loc = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, *loc);
if (GET_CODE (*loc) == LO_SUM) if (GET_CODE (*loc) == LO_SUM)
...@@ -8307,7 +8334,7 @@ mips_in_small_data_p (tree decl) ...@@ -8307,7 +8334,7 @@ mips_in_small_data_p (tree decl)
static bool static bool
mips_use_anchors_for_symbol_p (rtx symbol) mips_use_anchors_for_symbol_p (rtx symbol)
{ {
switch (mips_classify_symbol (symbol)) switch (mips_classify_symbol (symbol, SYMBOL_CONTEXT_MEM))
{ {
case SYMBOL_PC_RELATIVE: case SYMBOL_PC_RELATIVE:
case SYMBOL_GP_RELATIVE: case SYMBOL_GP_RELATIVE:
......
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
{ {
enum mips_symbol_type symbol_type; enum mips_symbol_type symbol_type;
if (!mips_symbolic_constant_p (op, &symbol_type)) if (!mips_symbolic_constant_p (op, SYMBOL_CONTEXT_CALL, &symbol_type))
return false; return false;
switch (symbol_type) switch (symbol_type)
...@@ -160,7 +160,7 @@ ...@@ -160,7 +160,7 @@
(match_code "const,symbol_ref,label_ref") (match_code "const,symbol_ref,label_ref")
{ {
enum mips_symbol_type symbol_type; enum mips_symbol_type symbol_type;
return (mips_symbolic_constant_p (op, &symbol_type) return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type)
&& mips_split_p[symbol_type]); && mips_split_p[symbol_type]);
}) })
...@@ -211,7 +211,7 @@ ...@@ -211,7 +211,7 @@
case LABEL_REF: case LABEL_REF:
if (CONST_GP_P (op)) if (CONST_GP_P (op))
return true; return true;
return (mips_symbolic_constant_p (op, &symbol_type) return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type)
&& !mips_split_p[symbol_type]); && !mips_split_p[symbol_type]);
default: default:
...@@ -226,28 +226,31 @@ ...@@ -226,28 +226,31 @@
(match_code "const,symbol_ref,label_ref") (match_code "const,symbol_ref,label_ref")
{ {
enum mips_symbol_type type; enum mips_symbol_type type;
return mips_symbolic_constant_p (op, &type); return mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type);
}) })
(define_predicate "absolute_symbolic_operand" (define_predicate "absolute_symbolic_operand"
(match_code "const,symbol_ref,label_ref") (match_code "const,symbol_ref,label_ref")
{ {
enum mips_symbol_type type; enum mips_symbol_type type;
return mips_symbolic_constant_p (op, &type) && type == SYMBOL_ABSOLUTE; return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type)
&& type == SYMBOL_ABSOLUTE);
}) })
(define_predicate "got_disp_operand" (define_predicate "got_disp_operand"
(match_code "const,symbol_ref,label_ref") (match_code "const,symbol_ref,label_ref")
{ {
enum mips_symbol_type type; enum mips_symbol_type type;
return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_DISP; return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type)
&& type == SYMBOL_GOT_DISP);
}) })
(define_predicate "got_page_ofst_operand" (define_predicate "got_page_ofst_operand"
(match_code "const,symbol_ref,label_ref") (match_code "const,symbol_ref,label_ref")
{ {
enum mips_symbol_type type; enum mips_symbol_type type;
return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_PAGE_OFST; return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type)
&& type == SYMBOL_GOT_PAGE_OFST);
}) })
(define_predicate "symbol_ref_operand" (define_predicate "symbol_ref_operand"
......
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