From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9522 invoked by alias); 8 Aug 2007 15:22:28 -0000 Received: (qmail 9109 invoked by uid 22791); 8 Aug 2007 15:22:26 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 08 Aug 2007 15:22:22 +0000 Received: (qmail 16872 invoked from network); 8 Aug 2007 15:22:20 -0000 Received: from unknown (HELO gateway) (10.0.0.100) by mail.codesourcery.com with SMTP; 8 Aug 2007 15:22:20 -0000 Received: by gateway (Postfix, from userid 1010) id 8B7416C0CF; Wed, 8 Aug 2007 08:22:20 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard@codesourcery.com Subject: [committed, 2/7] MIPS -mcode-readable support Date: Wed, 08 Aug 2007 15:22:00 -0000 Message-ID: <87lkcmrqz8.fsf@firetop.home> User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-08/txt/msg00515.txt.bz2 This is the second patch in the -mcode-readable series. Referring back to the description of the first patch, -mcode-readable=pcrel allows loads from executable sections only when the load is PC-relative. Thus we can use a minipool for constants that we load directly, but not those that we access via register indirection. The treatment of a constant pool symbol therefore depends on whether the symbol occurs in a MEM or a load-address (lea) operation. Also, as I said in the last message, the use of SYMBOL_GENERAL (now SYMBOL_ABSOLUTE) for %hi and %lo on MIPS means that we need another symbol classification for things that should be forced into memory. However, we do not want to distinguish between this new type and SYMBOL_ABSOLUTE for calls. Thus we have two situations where the classification depends on context: the result can be different for MEMs, leas and calls. This patch adds parameters to that effect. The parameters don't make any difference yet; that's done in the later patches. Tested in the same way as the first patch. Applied. Richard 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. Index: gcc/config/mips/mips-protos.h =================================================================== --- gcc/config/mips/mips-protos.h (revision 127294) +++ gcc/config/mips/mips-protos.h (working copy) @@ -25,6 +25,22 @@ the Free Software Foundation; either ver #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); Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c (revision 127294) +++ gcc/config/mips/mips.c (working copy) @@ -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 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, H 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 mi } 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_addre 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_addre 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 } /* 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 l 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 l } -/* 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 } #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: Index: gcc/config/mips/predicates.md =================================================================== --- gcc/config/mips/predicates.md (revision 127294) +++ gcc/config/mips/predicates.md (working copy) @@ -96,7 +96,7 @@ (define_predicate "const_call_insn_opera { 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 @@ (define_predicate "splittable_symbolic_o (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 @@ (define_predicate "move_operand" 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 @@ (define_predicate "symbolic_operand" (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"