From patchwork Sun Jul 25 21:47:16 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 59885 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id ED7B6B6F01 for ; Mon, 26 Jul 2010 07:47:24 +1000 (EST) Received: (qmail 13672 invoked by alias); 25 Jul 2010 21:47:23 -0000 Received: (qmail 13664 invoked by uid 22791); 25 Jul 2010 21:47:22 -0000 X-SWARE-Spam-Status: No, hits=-1.2 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (212.99.106.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 25 Jul 2010 21:47:17 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 0B5E2CB0229 for ; Sun, 25 Jul 2010 23:47:12 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 66mgpgPea0KP for ; Sun, 25 Jul 2010 23:47:11 +0200 (CEST) Received: from adijon-256-1-164-147.w90-13.abo.wanadoo.fr (ADijon-256-1-164-147.w90-13.abo.wanadoo.fr [90.13.39.147]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id 53A33CB0215 for ; Sun, 25 Jul 2010 23:47:11 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [SPARC] Fix PR target/44707 Date: Sun, 25 Jul 2010 23:47:16 +0200 User-Agent: KMail/1.9.9 MIME-Version: 1.0 Message-Id: <201007252347.16520.ebotcazou@adacore.com> Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org We need the same treatment on the SPARC as on the PowerPC, see http://gcc.gnu.org/ml/gcc-patches/2010-07/msg00082.html Tested on SPARC/Solaris and SPARC64/Solaris, applied on the mainline. 2010-07-25 Eric Botcazou PR target/44707 * config/sparc/sparc-protos.h (sparc_legitimize_reload_address): New. * config/sparc/sparc.c: Include reload.h. (legitimize_tls_address): Rename into... (sparc_legitimize_tls_address): ...this. (legitimize_pic_address): Rename into... (sparc_legitimize_pic_address): ...this. (sparc_expand_move): Adjust to above renaming. (sparc_tls_referenced_p): Likewise. (sparc_legitimize_tls_address): Likewise. (sparc_legitimize_pic_address): Likewise. (sparc_legitimize_address): Likewise. (sparc_output_mi_thunk): Likewise. (sparc_legitimize_reload_address): New global function. Recognize (lo_sum (high ...) ...) patterns generated by earlier passes. * config/sparc/sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Use above function. Index: config/sparc/sparc-protos.h =================================================================== --- config/sparc/sparc-protos.h (revision 162502) +++ config/sparc/sparc-protos.h (working copy) @@ -63,6 +63,8 @@ extern void emit_tfmode_cvt (enum rtx_co extern bool legitimate_constant_p (rtx); extern bool constant_address_p (rtx); extern bool legitimate_pic_operand_p (rtx); +extern rtx sparc_legitimize_reload_address (rtx, enum machine_mode, int, int, + int, int *win); extern void sparc_emit_call_insn (rtx, rtx); extern void sparc_defer_case_vector (rtx, rtx, int); extern bool sparc_expand_move (enum machine_mode, rtx *); Index: config/sparc/sparc.c =================================================================== --- config/sparc/sparc.c (revision 162502) +++ config/sparc/sparc.c (working copy) @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. #include "cfglayout.h" #include "gimple.h" #include "langhooks.h" +#include "reload.h" #include "params.h" #include "df.h" #include "dwarf2out.h" @@ -416,8 +417,8 @@ static void sparc_va_start (tree, rtx); static tree sparc_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *); static bool sparc_vector_mode_supported_p (enum machine_mode); static bool sparc_tls_referenced_p (rtx); -static rtx legitimize_tls_address (rtx); -static rtx legitimize_pic_address (rtx, rtx); +static rtx sparc_legitimize_tls_address (rtx); +static rtx sparc_legitimize_pic_address (rtx, rtx); static rtx sparc_legitimize_address (rtx, rtx, enum machine_mode); static bool sparc_mode_dependent_address_p (const_rtx); static bool sparc_pass_by_reference (CUMULATIVE_ARGS *, @@ -1006,7 +1007,7 @@ sparc_expand_move (enum machine_mode mod && CONSTANT_P (operands[1]) && sparc_tls_referenced_p (operands [1])) { - operands[1] = legitimize_tls_address (operands[1]); + operands[1] = sparc_legitimize_tls_address (operands[1]); return false; } @@ -1014,7 +1015,7 @@ sparc_expand_move (enum machine_mode mod if (flag_pic && CONSTANT_P (operands[1])) { if (pic_address_needs_scratch (operands[1])) - operands[1] = legitimize_pic_address (operands[1], NULL_RTX); + operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX); /* VxWorks does not impose a fixed gap between segments; the run-time gap can be different from the object-file gap. We therefore can't @@ -1041,9 +1042,10 @@ sparc_expand_move (enum machine_mode mod if (symbolic_operand (operands[1], mode)) { - operands[1] = legitimize_pic_address (operands[1], - reload_in_progress - ? operands[0] : NULL_RTX); + operands[1] + = sparc_legitimize_pic_address (operands[1], + reload_in_progress + ? operands[0] : NULL_RTX); return false; } } @@ -3217,7 +3219,7 @@ sparc_tls_referenced_p (rtx x) if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x)) return true; - /* That's all we handle in legitimize_tls_address for now. */ + /* That's all we handle in sparc_legitimize_tls_address for now. */ return false; } @@ -3225,7 +3227,7 @@ sparc_tls_referenced_p (rtx x) this (thread-local) address. */ static rtx -legitimize_tls_address (rtx addr) +sparc_legitimize_tls_address (rtx addr) { rtx temp1, temp2, temp3, ret, o0, got, insn; @@ -3354,7 +3356,7 @@ legitimize_tls_address (rtx addr) gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS); - base = legitimize_tls_address (XEXP (XEXP (addr, 0), 0)); + base = sparc_legitimize_tls_address (XEXP (XEXP (addr, 0), 0)); offset = XEXP (XEXP (addr, 0), 1); base = force_operand (base, NULL_RTX); @@ -3375,7 +3377,7 @@ legitimize_tls_address (rtx addr) necessary. */ static rtx -legitimize_pic_address (rtx orig, rtx reg) +sparc_legitimize_pic_address (rtx orig, rtx reg) { bool gotdata_op = false; @@ -3424,10 +3426,12 @@ legitimize_pic_address (rtx orig, rtx re if (gotdata_op) { if (TARGET_ARCH64) - insn = emit_insn (gen_movdi_pic_gotdata_op (reg, pic_offset_table_rtx, + insn = emit_insn (gen_movdi_pic_gotdata_op (reg, + pic_offset_table_rtx, address, orig)); else - insn = emit_insn (gen_movsi_pic_gotdata_op (reg, pic_offset_table_rtx, + insn = emit_insn (gen_movsi_pic_gotdata_op (reg, + pic_offset_table_rtx, address, orig)); } else @@ -3457,9 +3461,9 @@ legitimize_pic_address (rtx orig, rtx re } gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS); - base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg); - offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), - base == reg ? NULL_RTX : reg); + base = sparc_legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg); + offset = sparc_legitimize_pic_address (XEXP (XEXP (orig, 0), 1), + base == reg ? NULL_RTX : reg); if (GET_CODE (offset) == CONST_INT) { @@ -3515,9 +3519,9 @@ sparc_legitimize_address (rtx x, rtx old return x; if (sparc_tls_referenced_p (x)) - x = legitimize_tls_address (x); + x = sparc_legitimize_tls_address (x); else if (flag_pic) - x = legitimize_pic_address (x, NULL_RTX); + x = sparc_legitimize_pic_address (x, NULL_RTX); else if (GET_CODE (x) == PLUS && CONSTANT_ADDRESS_P (XEXP (x, 1))) x = gen_rtx_PLUS (Pmode, XEXP (x, 0), copy_to_mode_reg (Pmode, XEXP (x, 1))); @@ -3532,6 +3536,55 @@ sparc_legitimize_address (rtx x, rtx old return x; } +/* SPARC implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to + replace the input X, or the original X if no replacement is called for. + The output parameter *WIN is 1 if the calling macro should goto WIN, + 0 if it should not. + + For SPARC, we wish to handle addresses by splitting them into + HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference. + This cuts the number of extra insns by one. + + Do nothing when generating PIC code and the address is a symbolic + operand or requires a scratch register. */ + +rtx +sparc_legitimize_reload_address (rtx x, enum machine_mode mode, + int opnum, int type, + int ind_levels ATTRIBUTE_UNUSED, int *win) +{ + /* Decompose SImode constants into HIGH+LO_SUM. */ + if (CONSTANT_P (x) + && (mode != TFmode || TARGET_ARCH64) + && GET_MODE (x) == SImode + && GET_CODE (x) != LO_SUM + && GET_CODE (x) != HIGH + && sparc_cmodel <= CM_MEDLOW + && !(flag_pic + && (symbolic_operand (x, Pmode) || pic_address_needs_scratch (x)))) + { + x = gen_rtx_LO_SUM (GET_MODE (x), gen_rtx_HIGH (GET_MODE (x), x), x); + push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, + BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, + opnum, (enum reload_type)type); + *win = 1; + return x; + } + + /* We have to recognize what we have already generated above. */ + if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == HIGH) + { + push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, + BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, + opnum, (enum reload_type)type); + *win = 1; + return x; + } + + *win = 0; + return x; +} + /* Return true if ADDR (a legitimate address expression) has an effect that depends on the machine mode it is used for. @@ -9111,7 +9164,7 @@ sparc_output_mi_thunk (FILE *file, tree /* Delay emitting the PIC helper function because it needs to change the section and we are emitting assembly code. */ load_pic_register (); /* clobbers %o7 */ - scratch = legitimize_pic_address (funexp, scratch); + scratch = sparc_legitimize_pic_address (funexp, scratch); seq = get_insns (); end_sequence (); emit_and_preserve (seq, spill_reg, spill_reg2); Index: config/sparc/sparc.h =================================================================== --- config/sparc/sparc.h (revision 162502) +++ config/sparc/sparc.h (working copy) @@ -1801,36 +1801,14 @@ do { \ /* Try a machine-dependent way of reloading an illegitimate address operand. If we find one, push the reload and jump to WIN. This - macro is used in only one place: `find_reloads_address' in reload.c. - - For SPARC 32, we wish to handle addresses by splitting them into - HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference. - This cuts the number of extra insns by one. - - Do nothing when generating PIC code and the address is a - symbolic operand or requires a scratch register. */ - -#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \ -do { \ - /* Decompose SImode constants into hi+lo_sum. We do have to \ - rerecognize what we produce, so be careful. */ \ - if (CONSTANT_P (X) \ - && (MODE != TFmode || TARGET_ARCH64) \ - && GET_MODE (X) == SImode \ - && GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH \ - && ! (flag_pic \ - && (symbolic_operand (X, Pmode) \ - || pic_address_needs_scratch (X))) \ - && sparc_cmodel <= CM_MEDLOW) \ - { \ - X = gen_rtx_LO_SUM (GET_MODE (X), \ - gen_rtx_HIGH (GET_MODE (X), X), X); \ - push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \ - BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \ - OPNUM, TYPE); \ - goto WIN; \ - } \ - /* ??? 64-bit reloads. */ \ + macro is used in only one place: `find_reloads_address' in reload.c. */ +#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \ +do { \ + int win; \ + (X) = sparc_legitimize_reload_address ((X), (MODE), (OPNUM), \ + (int)(TYPE), (IND_LEVELS), &win); \ + if (win) \ + goto WIN; \ } while (0) /* Specify the machine mode that this machine uses