diff options
author | Richard Sandiford <richard@codesourcery.com> | 2007-08-08 15:22:16 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-08-08 15:22:16 +0000 |
commit | 280fcbfab4eab60574d827533e6ca4c4e7cdf732 (patch) | |
tree | 257de26a35c98ec1f77709b20a5b1c9122bf366b /gcc | |
parent | 67da85da7923399850541459ffb67c812ef0625d (diff) | |
download | gcc-280fcbfab4eab60574d827533e6ca4c4e7cdf732.zip gcc-280fcbfab4eab60574d827533e6ca4c4e7cdf732.tar.gz gcc-280fcbfab4eab60574d827533e6ca4c4e7cdf732.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 28 | ||||
-rw-r--r-- | gcc/config/mips/mips-protos.h | 19 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 95 | ||||
-rw-r--r-- | gcc/config/mips/predicates.md | 17 |
4 files changed, 117 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4b4229..c5ad716 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,33 @@ 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... (SYMBOL_ABSOLUTE): ...this. (SYMBOL_SMALL_DATA): Rename to... diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 233ffea..f88c7c9 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -25,6 +25,22 @@ along with GCC; see the file COPYING3. If not see #ifndef 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. SYMBOL_ABSOLUTE @@ -140,7 +156,8 @@ enum mips_loadgp_style { 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 bool mips_stack_address_p (rtx, enum machine_mode); extern int mips_address_insns (rtx, enum machine_mode); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index afa46b4..416f19ac 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -287,7 +287,6 @@ struct mips_address_info; struct mips_integer_op; 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_symbolic_address_p (enum mips_symbol_type, enum machine_mode); static bool mips_classify_address (struct mips_address_info *, rtx, @@ -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 bool mips_handle_option (size_t, const char *, int); 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 bool mips_rewrite_small_data_p (rtx); static int mips_small_data_pattern_1 (rtx *, void *); static int mips_rewrite_small_data_1 (rtx *, void *); static bool mips_function_has_gp_insn (void); @@ -1435,10 +1434,11 @@ mips_symbol_binds_local_p (rtx 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 -mips_classify_symbol (rtx x) +mips_classify_symbol (rtx x, enum mips_symbol_context context ATTRIBUTE_UNUSED) { if (TARGET_RTP_PIC) return SYMBOL_GOT_DISP; @@ -1528,12 +1528,12 @@ mips_offset_within_alignment_p (rtx x, HOST_WIDE_INT offset) return offset >= 0 && offset < align; } -/* Return true if X is a symbolic constant that can be calculated in - the same way as a bare symbol. If it is, store the type of the - symbol in *SYMBOL_TYPE. */ +/* Return true if X is a symbolic constant that can be used in context + CONTEXT. If it is, store the type of the symbol in *SYMBOL_TYPE. */ 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; @@ -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) { - *symbol_type = mips_classify_symbol (x); + *symbol_type = mips_classify_symbol (x, context); if (*symbol_type == SYMBOL_TLS) return false; } @@ -1747,7 +1747,8 @@ mips_classify_address (struct mips_address_info *info, rtx x, info->reg = XEXP (x, 0); info->offset = XEXP (x, 1); 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_lo_relocs[info->symbol_type] != 0); @@ -1761,7 +1762,8 @@ mips_classify_address (struct mips_address_info *info, rtx x, case LABEL_REF: case SYMBOL_REF: 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_split_p[info->symbol_type]); @@ -2002,7 +2004,8 @@ mips_const_insns (rtx x) { case HIGH: 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]) return 0; @@ -2031,7 +2034,7 @@ mips_const_insns (rtx x) return 1; /* 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); /* Otherwise try splitting the constant into a base and offset. @@ -2053,7 +2056,7 @@ mips_const_insns (rtx x) case SYMBOL_REF: case LABEL_REF: - return mips_symbol_insns (mips_classify_symbol (x)); + return mips_symbol_insns (mips_classify_symbol (x, SYMBOL_CONTEXT_LEA)); default: return 0; @@ -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. */ - 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_split_p[symbol_type]) { @@ -5943,11 +5946,11 @@ print_operand (FILE *file, rtx op, int letter) if (GET_CODE (op) == HIGH) 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') - print_operand_reloc (file, op, mips_lo_relocs); + print_operand_reloc (file, op, SYMBOL_CONTEXT_LEA, mips_lo_relocs); else if (letter == 'Y') { @@ -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. - RELOCS is the array of relocations to use. */ +/* Print symbolic operand OP, which is part of a HIGH or LO_SUM + in context CONTEXT. RELOCS is the array of relocations to use. */ 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; const char *p; 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); /* If OP uses an UNSPEC address, we want to print the inner symbol. */ @@ -6079,7 +6084,8 @@ print_operand_address (FILE *file, rtx x) return; 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)]); return; @@ -6429,29 +6435,40 @@ mips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end) } #endif -/* Return true if X is a small data address that can be rewritten - as a LO_SUM. */ +/* Return true if X in context CONTEXT is a small data address that can + be rewritten as a LO_SUM. */ 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; return (TARGET_EXPLICIT_RELOCS - && mips_symbolic_constant_p (x, &symbol_type) + && mips_symbolic_constant_p (x, context, &symbol_type) && 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 -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) 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 @@ -6463,12 +6480,22 @@ mips_small_data_pattern_p (rtx op) 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 -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); if (GET_CODE (*loc) == LO_SUM) @@ -8307,7 +8334,7 @@ mips_in_small_data_p (tree decl) static bool 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_GP_RELATIVE: diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md index 7f69f98..1171291 100644 --- a/gcc/config/mips/predicates.md +++ b/gcc/config/mips/predicates.md @@ -96,7 +96,7 @@ { 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; switch (symbol_type) @@ -160,7 +160,7 @@ (match_code "const,symbol_ref,label_ref") { 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]); }) @@ -211,7 +211,7 @@ case LABEL_REF: if (CONST_GP_P (op)) 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]); default: @@ -226,28 +226,31 @@ (match_code "const,symbol_ref,label_ref") { 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" (match_code "const,symbol_ref,label_ref") { 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" (match_code "const,symbol_ref,label_ref") { 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" (match_code "const,symbol_ref,label_ref") { 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" |