From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12212 invoked by alias); 8 Aug 2007 15:42:09 -0000 Received: (qmail 12123 invoked by uid 22791); 8 Aug 2007 15:42:08 -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:41:57 +0000 Received: (qmail 18091 invoked from network); 8 Aug 2007 15:41:56 -0000 Received: from unknown (HELO gateway) (10.0.0.100) by mail.codesourcery.com with SMTP; 8 Aug 2007 15:41:56 -0000 Received: by gateway (Postfix, from userid 1010) id CBD9F6C0CF; Wed, 8 Aug 2007 08:41:55 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard@codesourcery.com Subject: [committed, 5/7] MIPS -mcode-readable support Date: Wed, 08 Aug 2007 15:42:00 -0000 Message-ID: <871weerq2l.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/msg00522.txt.bz2 This is the fifth patch in the -mcode-readable series. Life used to be simple for mips_split_symbol: when generating MIPS16 code, the high part of a symbol was a copy of the $gp constant; when generating non-MIPS16 code, the high part of a symbol was a HIGH expression. However, we now need to use HIGH for MIPS16 too. mips_split_symbol must therefore choose the high part based on the symbol type rather than the MIPS16 mode. mips_split_symbol is currently defined in such a way that the caller checks whether a split is needed. This check involves determining the symbol type, so rather than pass the type down to mips_split_symbol, it seemed better to move the "is a split needed?" check to mips_split_symbol itself. The patch below does that. Tested in the same way as the first patch. Applied. Richard gcc/ * config/mips/mips-protos.h (mips_split_symbol): Add a mode and an "rtx *" argument. Return a bool. * config/mips/mips.c (mips_split_symbol): Accept arbitrary source values and return true if they can be split. Take the same kind of mode argument as mips_symbol_insns. Add a "lo_sum_out" parameter and store the lo_sum there if nonnull. Use the symbol type to determine whether a $gp or HIGH is needed. (mips_legitimize_address): Update call to mips_split_symbol and simplify accordingly. (mips_legitimize_const_move): Likewise. * config/mips/mips.md: In the combine define_split, check mips_split_symbol instead of splittable_symbolic_operand. Update use of mips_split_symbol in the generator code. * config/mips/predicates.md (splittable_symbolic_operand): Delete. Index: gcc/config/mips/mips-protos.h =================================================================== --- gcc/config/mips/mips-protos.h 2007-07-28 12:41:01.000000000 -0700 +++ gcc/config/mips/mips-protos.h 2007-07-31 02:57:35.000000000 -0700 @@ -172,7 +172,7 @@ extern int mips_idiv_insns (void); extern int fp_register_operand (rtx, enum machine_mode); extern int lo_operand (rtx, enum machine_mode); extern bool mips_legitimate_address_p (enum machine_mode, rtx, int); -extern rtx mips_split_symbol (rtx, rtx); +extern bool mips_split_symbol (rtx, rtx, enum machine_mode, rtx *); extern rtx mips_unspec_address (rtx, enum mips_symbol_type); extern bool mips_legitimize_address (rtx *, enum machine_mode); extern void mips_move_integer (rtx, rtx, unsigned HOST_WIDE_INT); Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2007-07-28 12:41:02.000000000 -0700 +++ gcc/config/mips/mips.c 2007-07-31 02:58:08.000000000 -0700 @@ -2114,24 +2114,50 @@ mips_force_temporary (rtx dest, rtx valu } -/* Return a LO_SUM expression for ADDR. TEMP is as for mips_force_temporary - and is used to load the high part into a register. */ +/* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise + it appears in a MEM of that mode. Return true if ADDR is a legitimate + constant in that context and can be split into a high part and a LO_SUM. + If so, and if LO_SUM_OUT is nonnull, emit the high part and return + the LO_SUM in *LO_SUM_OUT. Leave *LO_SUM_OUT unchanged otherwise. -rtx -mips_split_symbol (rtx temp, rtx addr) + TEMP is as for mips_force_temporary and is used to load the high + part into a register. */ + +bool +mips_split_symbol (rtx temp, rtx addr, enum machine_mode mode, rtx *lo_sum_out) { + enum mips_symbol_context context; + enum mips_symbol_type symbol_type; rtx high; - if (!TARGET_MIPS16) - high = mips_force_temporary (temp, gen_rtx_HIGH (Pmode, copy_rtx (addr))); - else if (!can_create_pseudo_p ()) + context = (mode == MAX_MACHINE_MODE + ? SYMBOL_CONTEXT_LEA + : SYMBOL_CONTEXT_MEM); + if (!mips_symbolic_constant_p (addr, context, &symbol_type) + || mips_symbol_insns (symbol_type, mode) == 0 + || !mips_split_p[symbol_type]) + return false; + + if (lo_sum_out) { - emit_insn (gen_load_const_gp (copy_rtx (temp))); - high = temp; + if (symbol_type == SYMBOL_GP_RELATIVE) + { + if (!can_create_pseudo_p ()) + { + emit_insn (gen_load_const_gp (copy_rtx (temp))); + high = temp; + } + else + high = mips16_gp_pseudo_reg (); + } + else + { + high = gen_rtx_HIGH (Pmode, copy_rtx (addr)); + high = mips_force_temporary (temp, high); + } + *lo_sum_out = gen_rtx_LO_SUM (Pmode, high, addr); } - else - high = mips16_gp_pseudo_reg (); - return gen_rtx_LO_SUM (Pmode, high, addr); + return true; } @@ -2322,8 +2348,6 @@ mips_legitimize_tls_address (rtx loc) bool mips_legitimize_address (rtx *xloc, enum machine_mode mode) { - enum mips_symbol_type symbol_type; - if (mips_tls_operand_p (*xloc)) { *xloc = mips_legitimize_tls_address (*xloc); @@ -2331,13 +2355,8 @@ 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_CONTEXT_MEM, &symbol_type) - && mips_symbol_insns (symbol_type, mode) > 0 - && mips_split_p[symbol_type]) - { - *xloc = mips_split_symbol (0, *xloc); - return true; - } + if (mips_split_symbol (NULL, *xloc, mode, xloc)) + return true; if (GET_CODE (*xloc) == PLUS && GET_CODE (XEXP (*xloc, 1)) == CONST_INT) { @@ -2506,9 +2525,9 @@ mips_legitimize_const_move (enum machine } /* Split moves of symbolic constants into high/low pairs. */ - if (splittable_symbolic_operand (src, mode)) + if (mips_split_symbol (dest, src, MAX_MACHINE_MODE, &src)) { - emit_insn (gen_rtx_SET (VOIDmode, dest, mips_split_symbol (dest, src))); + emit_insn (gen_rtx_SET (VOIDmode, dest, src)); return; } @@ -2535,8 +2554,7 @@ mips_legitimize_const_move (enum machine /* When using explicit relocs, constant pool references are sometimes not legitimate addresses. */ - if (!memory_operand (src, VOIDmode)) - src = replace_equiv_address (src, mips_split_symbol (dest, XEXP (src, 0))); + mips_split_symbol (dest, XEXP (src, 0), mode, &XEXP (src, 0)); emit_move_insn (dest, src); } Index: gcc/config/mips/mips.md =================================================================== --- gcc/config/mips/mips.md 2007-07-28 12:30:41.000000000 -0700 +++ gcc/config/mips/mips.md 2007-07-31 02:57:56.000000000 -0700 @@ -3300,11 +3300,14 @@ (define_split ;; Likewise, for symbolic operands. (define_split [(set (match_operand:P 0 "register_operand") - (match_operand:P 1 "splittable_symbolic_operand")) + (match_operand:P 1)) (clobber (match_operand:P 2 "register_operand"))] - "" - [(set (match_dup 0) (match_dup 1))] - { operands[1] = mips_split_symbol (operands[2], operands[1]); }) + "mips_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)" + [(set (match_dup 0) (match_dup 3))] +{ + mips_split_symbol (operands[2], operands[1], + MAX_MACHINE_MODE, &operands[3]); +}) ;; 64-bit integer moves Index: gcc/config/mips/predicates.md =================================================================== --- gcc/config/mips/predicates.md 2007-07-28 12:38:49.000000000 -0700 +++ gcc/config/mips/predicates.md 2007-07-31 02:23:13.000000000 -0700 @@ -155,16 +155,6 @@ (define_predicate "splittable_const_int_ return !LUI_INT (op) && !SMALL_INT (op) && !SMALL_INT_UNSIGNED (op); }) -;; A legitimate symbolic operand that takes more than one instruction -;; to load. -(define_predicate "splittable_symbolic_operand" - (match_code "const,symbol_ref,label_ref") -{ - enum mips_symbol_type symbol_type; - return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type) - && mips_split_p[symbol_type]); -}) - (define_predicate "move_operand" (match_operand 0 "general_operand") {