From patchwork Thu Oct 6 15:01:20 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georg-Johann Lay X-Patchwork-Id: 118108 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 A136CB6F84 for ; Fri, 7 Oct 2011 02:06:30 +1100 (EST) Received: (qmail 24537 invoked by alias); 6 Oct 2011 15:06:25 -0000 Received: (qmail 24503 invoked by uid 22791); 6 Oct 2011 15:06:05 -0000 X-SWARE-Spam-Status: No, hits=0.0 required=5.0 tests=AWL, BAYES_50, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, TW_OV, TW_PG, TW_VH, TW_VQ X-Spam-Check-By: sourceware.org Received: from mo-p00-ob.rzone.de (HELO mo-p00-ob.rzone.de) (81.169.146.161) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 06 Oct 2011 15:05:36 +0000 X-RZG-AUTH: :LXoWVUeid/7A29J/hMvvT2k715jHQaJercGObUOFkj18odoYNahU4Q== X-RZG-CLASS-ID: mo00 Received: from [192.168.0.22] (business-188-111-022-002.static.arcor-ip.net [188.111.22.2]) by post.strato.de (mrclete mo42) (RZmta 26.10 AUTH) with ESMTPA id J0437en96Dvwbk ; Thu, 6 Oct 2011 17:01:21 +0200 (MEST) Message-ID: <4E8DC2C0.8040703@gjlay.de> Date: Thu, 06 Oct 2011 17:01:20 +0200 From: Georg-Johann Lay User-Agent: Thunderbird 2.0.0.24 (X11/20100302) MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org CC: Ulrich Weigand , Denis Chertykov , Eric Weddington , Joerg Wunsch , Anatoly Sokolov Subject: [Patch]: PR49868: Named address space support for AVR X-IsSubscribed: yes 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 This patch adds named address space support to read data from flash (aka. progmem) to target AVR. The patch has two parts: The first part is a repost of Ulrich's work from http://gcc.gnu.org/ml/gcc/2011-08/msg00131.html with the needed changes to ./gcc and ./gcc/doc This patch is needed because the target hooks MODE_CODE_BASE_REG_CLASS and REGNO_MODE_CODE_OK_FOR_BASE_P don't distinguish between different address spaces. Ulrich's patch adds respective support to these hooks. The second part is the AVR dependent part that adds __pgm as address space qualifier for address space AS1. The AVR part is just the worker code. If there is agreement that AS support for AVR is okay in principle and Ulrich's work will go into GCC, I will supply test programs and updates to the user manual, of course. The major drawbacks of the current AS implementation are: - It works only for C. For C++, a language extension would be needed as indicated in ISO/IEC DTR 18037 Annex F - C++ Compatibility and Migration issues F.2 Multiple Address Spaces Support - Register allocation does not a good job. AS1 can only be addressed byte-wise by one single address register (Z) as per *Z or *Z++. The AVR part does several things: - It locates data in AS1 into appropriate section, i.e. somewhere in .progmem - It does early sanity checks to ensure that __pgm is always accompanied with const so that writing to AS1 in not possible. - It prints LPM instructions to access flash memory. Hint on how to proceed with this are appreciated, likewise I'd like to know if such extension is not appropriate so that I can focus on other stuff or if there are hints to improve the patch. Thanks, Johann PR target/49868 * config/avr/avr.h (ADDR_SPACE_PGM): New define for address space AS1. (REGISTER_TARGET_PRAGMAS): New define. (MODE_CODE_BASE_REG_CLASS): New define. (REGNO_MODE_CODE_OK_FOR_BASE_P): New define. (BASE_REG_CLASS): Remove define. (REGNO_OK_FOR_BASE_P): Remove define. (REG_OK_FOR_BASE_NOSTRICT_P): Remove define. (REG_OK_FOR_BASE_STRICT_P): Remove define. * config/avr/avr-protos.h (avr_mem_pgm_p): New prototype. (avr_register_target_pragmas): New prototype. (avr_mode_code_base_reg_class): New prototype. (avr_regno_mode_code_ok_for_base_p): New prototype. (avr_log_t): Add field "progmem". Order alphabetically. * config/avr/avr-log.c (avr_log_set_avr_log): Set avr_log.progmem. * config/avr/avr-c.c (avr_register_target_pragmas): New function. Register address space AS1 as "__pgm". * config/avr/avr.c: Include "c-family/c-common.h". (TARGET_LEGITIMATE_ADDRESS_P): Don't define this macro any more. (TARGET_LEGITIMIZE_ADDRESS): Don't define this macro any more. (TARGET_ADDR_SPACE_SUBSET_P): Define to... (avr_addr_space_subset_p): ...this new static function. (TARGET_ADDR_SPACE_CONVERT): Define to... (avr_addr_space_convert): ...this new static function. (TARGET_ADDR_SPACE_ADDRESS_MODE): Define to... (avr_addr_space_address_mode): ...this new static function. (TARGET_ADDR_SPACE_POINTER_MODE): Define to... (avr_addr_space_pointer_mode): ...this new static function. (TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P): Define to... (avr_addr_space_legitimate_address_p): ...this new static function. (TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS): Define to... (avr_addr_space_legitimize_address): ...this new static function. (avr_mode_code_base_reg_class): New function. (avr_regno_mode_code_ok_for_base_p): New function. (lpm_addr_reg_rtx, lpm_reg_rtx): New static GTYed variables. (avr_decl_pgm_p): New static function. (avr_mem_pgm_p): New function. (avr_reg_ok_for_addr): New static function. (avr_legitimate_address_p): Use it. (avr_asm_len): Return "" instead of void. (avr_out_lpm_no_lpmx): New static function. (avr_out_lpm): New static function. (output_movqi, output_movhi, output_movsisf): Call avr_out_lpm to handle loads from progmem. (avr_progmem_p): Test if decl is in AS1. (avr_pgm_pointer_const_p): New static function. (avr_pgm_check_var_decl): New static function. (avr_insert_attributes): Use it. Change error message to report cause when code wants to write to AS1. (avr_section_type_flags): Unset section flag SECTION_BSS for data in progmem. * config/avr/avr.md (LPM_REGNO): New define_constants. (movqi, movhi, movsi, movsf): Skip if code would write to AS1. (movmemhi): Ditto. Propagate address space information to newly created MEM. (split-lpmx): New split. Index: doc/tm.texi =================================================================== --- doc/tm.texi (revision 179594) +++ doc/tm.texi (working copy) @@ -2453,12 +2453,13 @@ register address. You should define thi addresses have different requirements than other base register uses. @end defmac -@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{outer_code}, @var{index_code}) +@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{address_space}, @var{outer_code}, @var{index_code}) A C expression whose value is the register class to which a valid -base register must belong. @var{outer_code} and @var{index_code} define the -context in which the base register occurs. @var{outer_code} is the code of -the immediately enclosing expression (@code{MEM} for the top level of an -address, @code{ADDRESS} for something that occurs in an +base register for a memory reference in mode @var{mode} to address +space @var{address_space} must belong. @var{outer_code} and @var{index_code} +define the context in which the base register occurs. @var{outer_code} is +the code of the immediately enclosing expression (@code{MEM} for the top level +of an address, @code{ADDRESS} for something that occurs in an @code{address_operand}). @var{index_code} is the code of the corresponding index expression if @var{outer_code} is @code{PLUS}; @code{SCRATCH} otherwise. @end defmac @@ -2498,8 +2499,11 @@ Use of this macro is deprecated; please @code{REGNO_MODE_CODE_OK_FOR_BASE_P}. @end defmac -@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, @var{outer_code}, @var{index_code}) -A C expression that is just like @code{REGNO_MODE_OK_FOR_BASE_P}, except +@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, @var{address_space}, @var{outer_code}, @var{index_code}) +A C expression which is nonzero if register number @var{num} is +suitable for use as a base register in operand addresses, accessing +memory in mode @var{mode} in address space @var{address_space}. +This is similar to @code{REGNO_MODE_OK_FOR_BASE_P}, except that that expression may examine the context in which the register appears in the memory reference. @var{outer_code} is the code of the immediately enclosing expression (@code{MEM} if at the top level of the Index: doc/tm.texi.in =================================================================== --- doc/tm.texi.in (revision 179594) +++ doc/tm.texi.in (working copy) @@ -2441,12 +2441,13 @@ register address. You should define thi addresses have different requirements than other base register uses. @end defmac -@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{outer_code}, @var{index_code}) +@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{address_space}, @var{outer_code}, @var{index_code}) A C expression whose value is the register class to which a valid -base register must belong. @var{outer_code} and @var{index_code} define the -context in which the base register occurs. @var{outer_code} is the code of -the immediately enclosing expression (@code{MEM} for the top level of an -address, @code{ADDRESS} for something that occurs in an +base register for a memory reference in mode @var{mode} to address +space @var{address_space} must belong. @var{outer_code} and @var{index_code} +define the context in which the base register occurs. @var{outer_code} is +the code of the immediately enclosing expression (@code{MEM} for the top level +of an address, @code{ADDRESS} for something that occurs in an @code{address_operand}). @var{index_code} is the code of the corresponding index expression if @var{outer_code} is @code{PLUS}; @code{SCRATCH} otherwise. @end defmac @@ -2486,8 +2487,11 @@ Use of this macro is deprecated; please @code{REGNO_MODE_CODE_OK_FOR_BASE_P}. @end defmac -@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, @var{outer_code}, @var{index_code}) -A C expression that is just like @code{REGNO_MODE_OK_FOR_BASE_P}, except +@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, @var{address_space}, @var{outer_code}, @var{index_code}) +A C expression which is nonzero if register number @var{num} is +suitable for use as a base register in operand addresses, accessing +memory in mode @var{mode} in address space @var{address_space}. +This is similar to @code{REGNO_MODE_OK_FOR_BASE_P}, except that that expression may examine the context in which the register appears in the memory reference. @var{outer_code} is the code of the immediately enclosing expression (@code{MEM} if at the top level of the Index: caller-save.c =================================================================== --- caller-save.c (revision 179594) +++ caller-save.c (working copy) @@ -231,7 +231,8 @@ init_caller_save (void) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (TEST_HARD_REG_BIT (reg_class_contents - [(int) base_reg_class (regno_save_mode[i][1], PLUS, CONST_INT)], i)) + [(int) base_reg_class (regno_save_mode[i][1], ADDR_SPACE_GENERIC, + PLUS, CONST_INT)], i)) break; gcc_assert (i < FIRST_PSEUDO_REGISTER); Index: ira-conflicts.c =================================================================== --- ira-conflicts.c (revision 179594) +++ ira-conflicts.c (working copy) @@ -845,6 +845,7 @@ ira_debug_conflicts (bool reg_p) void ira_build_conflicts (void) { + enum reg_class base; ira_allocno_t a; ira_allocno_iterator ai; HARD_REG_SET temp_hard_reg_set; @@ -874,13 +875,12 @@ ira_build_conflicts (void) ira_free (conflicts); } } - if (! targetm.class_likely_spilled_p (base_reg_class (VOIDmode, ADDRESS, - SCRATCH))) + base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH); + if (! targetm.class_likely_spilled_p (base)) CLEAR_HARD_REG_SET (temp_hard_reg_set); else { - COPY_HARD_REG_SET (temp_hard_reg_set, - reg_class_contents[base_reg_class (VOIDmode, ADDRESS, SCRATCH)]); + COPY_HARD_REG_SET (temp_hard_reg_set, reg_class_contents[base]); AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs); AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set); } Index: ira-costs.c =================================================================== --- ira-costs.c (revision 179594) +++ ira-costs.c (working copy) @@ -637,7 +637,8 @@ record_reg_classes (int n_alts, int n_op base of an address, i.e. BASE_REG_CLASS. */ classes[i] = ira_reg_class_subunion[classes[i]] - [base_reg_class (VOIDmode, ADDRESS, SCRATCH)]; + [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]; break; case 'm': case 'o': case 'V': @@ -752,7 +753,8 @@ record_reg_classes (int n_alts, int n_op i.e. BASE_REG_CLASS. */ classes[i] = ira_reg_class_subunion[classes[i]] - [base_reg_class (VOIDmode, ADDRESS, SCRATCH)]; + [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]; } #endif break; @@ -996,14 +998,14 @@ ok_for_index_p_nonstrict (rtx reg) pseudo-registers should count as OK. Arguments as for regno_ok_for_base_p. */ static inline bool -ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode, +ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode, addr_space_t as, enum rtx_code outer_code, enum rtx_code index_code) { unsigned regno = REGNO (reg); if (regno >= FIRST_PSEUDO_REGISTER) return true; - return ok_for_base_p_1 (regno, mode, outer_code, index_code); + return ok_for_base_p_1 (regno, mode, as, outer_code, index_code); } /* Record the pseudo registers we must reload into hard registers in a @@ -1012,16 +1014,16 @@ ok_for_base_p_nonstrict (rtx reg, enum m If CONTEXT is 0, we are looking at the base part of an address, otherwise we are looking at the index part. - MODE is the mode of the memory reference; OUTER_CODE and INDEX_CODE - give the context that the rtx appears in. These three arguments - are passed down to base_reg_class. + MODE and AS are the mode and address space of the memory reference; + OUTER_CODE and INDEX_CODE give the context that the rtx appears in. + These four arguments are passed down to base_reg_class. SCALE is twice the amount to multiply the cost by (it is twice so we can represent half-cost adjustments). */ static void -record_address_regs (enum machine_mode mode, rtx x, int context, - enum rtx_code outer_code, enum rtx_code index_code, - int scale) +record_address_regs (enum machine_mode mode, addr_space_t as, rtx x, + int context, enum rtx_code outer_code, + enum rtx_code index_code, int scale) { enum rtx_code code = GET_CODE (x); enum reg_class rclass; @@ -1029,7 +1031,7 @@ record_address_regs (enum machine_mode m if (context == 1) rclass = INDEX_REG_CLASS; else - rclass = base_reg_class (mode, outer_code, index_code); + rclass = base_reg_class (mode, as, outer_code, index_code); switch (code) { @@ -1068,67 +1070,68 @@ record_address_regs (enum machine_mode m /* If this machine only allows one register per address, it must be in the first operand. */ if (MAX_REGS_PER_ADDRESS == 1) - record_address_regs (mode, arg0, 0, PLUS, code1, scale); + record_address_regs (mode, as, arg0, 0, PLUS, code1, scale); /* If index and base registers are the same on this machine, just record registers in any non-constant operands. We assume here, as well as in the tests below, that all addresses are in canonical form. */ - else if (INDEX_REG_CLASS == base_reg_class (VOIDmode, PLUS, SCRATCH)) + else if (INDEX_REG_CLASS + == base_reg_class (VOIDmode, as, PLUS, SCRATCH)) { - record_address_regs (mode, arg0, context, PLUS, code1, scale); + record_address_regs (mode, as, arg0, context, PLUS, code1, scale); if (! CONSTANT_P (arg1)) - record_address_regs (mode, arg1, context, PLUS, code0, scale); + record_address_regs (mode, as, arg1, context, PLUS, code0, scale); } /* If the second operand is a constant integer, it doesn't change what class the first operand must be. */ else if (code1 == CONST_INT || code1 == CONST_DOUBLE) - record_address_regs (mode, arg0, context, PLUS, code1, scale); + record_address_regs (mode, as, arg0, context, PLUS, code1, scale); /* If the second operand is a symbolic constant, the first operand must be an index register. */ else if (code1 == SYMBOL_REF || code1 == CONST || code1 == LABEL_REF) - record_address_regs (mode, arg0, 1, PLUS, code1, scale); + record_address_regs (mode, as, arg0, 1, PLUS, code1, scale); /* If both operands are registers but one is already a hard register of index or reg-base class, give the other the class that the hard register is not. */ else if (code0 == REG && code1 == REG && REGNO (arg0) < FIRST_PSEUDO_REGISTER - && (ok_for_base_p_nonstrict (arg0, mode, PLUS, REG) + && (ok_for_base_p_nonstrict (arg0, mode, as, PLUS, REG) || ok_for_index_p_nonstrict (arg0))) - record_address_regs (mode, arg1, - ok_for_base_p_nonstrict (arg0, mode, PLUS, REG) - ? 1 : 0, + record_address_regs (mode, as, arg1, + ok_for_base_p_nonstrict (arg0, mode, as, + PLUS, REG) ? 1 : 0, PLUS, REG, scale); else if (code0 == REG && code1 == REG && REGNO (arg1) < FIRST_PSEUDO_REGISTER - && (ok_for_base_p_nonstrict (arg1, mode, PLUS, REG) + && (ok_for_base_p_nonstrict (arg1, mode, as, PLUS, REG) || ok_for_index_p_nonstrict (arg1))) - record_address_regs (mode, arg0, - ok_for_base_p_nonstrict (arg1, mode, PLUS, REG) - ? 1 : 0, + record_address_regs (mode, as, arg0, + ok_for_base_p_nonstrict (arg1, mode, as, + PLUS, REG) ? 1 : 0, PLUS, REG, scale); /* If one operand is known to be a pointer, it must be the base with the other operand the index. Likewise if the other operand is a MULT. */ else if ((code0 == REG && REG_POINTER (arg0)) || code1 == MULT) { - record_address_regs (mode, arg0, 0, PLUS, code1, scale); - record_address_regs (mode, arg1, 1, PLUS, code0, scale); + record_address_regs (mode, as, arg0, 0, PLUS, code1, scale); + record_address_regs (mode, as, arg1, 1, PLUS, code0, scale); } else if ((code1 == REG && REG_POINTER (arg1)) || code0 == MULT) { - record_address_regs (mode, arg0, 1, PLUS, code1, scale); - record_address_regs (mode, arg1, 0, PLUS, code0, scale); + record_address_regs (mode, as, arg0, 1, PLUS, code1, scale); + record_address_regs (mode, as, arg1, 0, PLUS, code0, scale); } /* Otherwise, count equal chances that each might be a base or index register. This case should be rare. */ else { - record_address_regs (mode, arg0, 0, PLUS, code1, scale / 2); - record_address_regs (mode, arg0, 1, PLUS, code1, scale / 2); - record_address_regs (mode, arg1, 0, PLUS, code0, scale / 2); - record_address_regs (mode, arg1, 1, PLUS, code0, scale / 2); + record_address_regs (mode, as, arg0, 0, PLUS, code1, scale / 2); + record_address_regs (mode, as, arg0, 1, PLUS, code1, scale / 2); + record_address_regs (mode, as, arg1, 0, PLUS, code0, scale / 2); + record_address_regs (mode, as, arg1, 1, PLUS, code0, scale / 2); } } break; @@ -1138,10 +1141,10 @@ record_address_regs (enum machine_mode m up in the wrong place. */ case POST_MODIFY: case PRE_MODIFY: - record_address_regs (mode, XEXP (x, 0), 0, code, + record_address_regs (mode, as, XEXP (x, 0), 0, code, GET_CODE (XEXP (XEXP (x, 1), 1)), 2 * scale); if (REG_P (XEXP (XEXP (x, 1), 1))) - record_address_regs (mode, XEXP (XEXP (x, 1), 1), 1, code, REG, + record_address_regs (mode, as, XEXP (XEXP (x, 1), 1), 1, code, REG, 2 * scale); break; @@ -1152,7 +1155,7 @@ record_address_regs (enum machine_mode m /* Double the importance of an allocno that is incremented or decremented, since it would take two extra insns if it ends up in the wrong place. */ - record_address_regs (mode, XEXP (x, 0), 0, code, SCRATCH, 2 * scale); + record_address_regs (mode, as, XEXP (x, 0), 0, code, SCRATCH, 2 * scale); break; case REG: @@ -1200,7 +1203,7 @@ record_address_regs (enum machine_mode m int i; for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) if (fmt[i] == 'e') - record_address_regs (mode, XEXP (x, i), context, code, SCRATCH, + record_address_regs (mode, as, XEXP (x, i), context, code, SCRATCH, scale); } } @@ -1236,13 +1239,15 @@ record_operand_costs (rtx insn, enum reg if (MEM_P (recog_data.operand[i])) record_address_regs (GET_MODE (recog_data.operand[i]), + MEM_ADDR_SPACE (recog_data.operand[i]), XEXP (recog_data.operand[i], 0), 0, MEM, SCRATCH, frequency * 2); else if (constraints[i][0] == 'p' || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i])) - record_address_regs (VOIDmode, recog_data.operand[i], 0, ADDRESS, - SCRATCH, frequency * 2); + record_address_regs (VOIDmode, ADDR_SPACE_GENERIC, + recog_data.operand[i], 0, ADDRESS, SCRATCH, + frequency * 2); } /* Check for commutative in a separate loop so everything will have @@ -1316,8 +1321,10 @@ scan_one_insn (rtx insn) COSTS (costs, num)->mem_cost -= ira_memory_move_cost[GET_MODE (reg)][cl][1] * frequency; - record_address_regs (GET_MODE (SET_SRC (set)), XEXP (SET_SRC (set), 0), - 0, MEM, SCRATCH, frequency * 2); + record_address_regs (GET_MODE (SET_SRC (set)), + MEM_ADDR_SPACE (SET_SRC (set)), + XEXP (SET_SRC (set), 0), 0, MEM, SCRATCH, + frequency * 2); counted_mem = true; } Index: recog.c =================================================================== --- recog.c (revision 179594) +++ recog.c (working copy) @@ -2281,7 +2281,8 @@ preprocess_constraints (void) case 'p': op_alt[j].is_address = 1; op_alt[j].cl = reg_class_subunion[(int) op_alt[j].cl] - [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)]; + [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]; break; case 'g': @@ -2302,8 +2303,8 @@ preprocess_constraints (void) op_alt[j].cl = (reg_class_subunion [(int) op_alt[j].cl] - [(int) base_reg_class (VOIDmode, ADDRESS, - SCRATCH)]); + [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]); break; } Index: regcprop.c =================================================================== --- regcprop.c (revision 179594) +++ regcprop.c (working copy) @@ -98,7 +98,7 @@ static rtx find_oldest_value_reg (enum r static bool replace_oldest_value_reg (rtx *, enum reg_class, rtx, struct value_data *); static bool replace_oldest_value_addr (rtx *, enum reg_class, - enum machine_mode, rtx, + enum machine_mode, addr_space_t, rtx, struct value_data *); static bool replace_oldest_value_mem (rtx, rtx, struct value_data *); static bool copyprop_hardreg_forward_1 (basic_block, struct value_data *); @@ -515,8 +515,8 @@ replace_oldest_value_reg (rtx *loc, enum static bool replace_oldest_value_addr (rtx *loc, enum reg_class cl, - enum machine_mode mode, rtx insn, - struct value_data *vd) + enum machine_mode mode, addr_space_t as, + rtx insn, struct value_data *vd) { rtx x = *loc; RTX_CODE code = GET_CODE (x); @@ -585,15 +585,15 @@ replace_oldest_value_addr (rtx *loc, enu unsigned regno0 = REGNO (op0), regno1 = REGNO (op1); if (REGNO_OK_FOR_INDEX_P (regno1) - && regno_ok_for_base_p (regno0, mode, PLUS, REG)) + && regno_ok_for_base_p (regno0, mode, as, PLUS, REG)) index_op = 1; else if (REGNO_OK_FOR_INDEX_P (regno0) - && regno_ok_for_base_p (regno1, mode, PLUS, REG)) + && regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; - else if (regno_ok_for_base_p (regno0, mode, PLUS, REG) + else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG) || REGNO_OK_FOR_INDEX_P (regno1)) index_op = 1; - else if (regno_ok_for_base_p (regno1, mode, PLUS, REG)) + else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; else index_op = 1; @@ -616,13 +616,13 @@ replace_oldest_value_addr (rtx *loc, enu } if (locI) - changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode, - insn, vd); + changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, + mode, as, insn, vd); if (locB) changed |= replace_oldest_value_addr (locB, - base_reg_class (mode, PLUS, + base_reg_class (mode, as, PLUS, index_code), - mode, insn, vd); + mode, as, insn, vd); return changed; } @@ -648,12 +648,12 @@ replace_oldest_value_addr (rtx *loc, enu for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') - changed |= replace_oldest_value_addr (&XEXP (x, i), cl, mode, + changed |= replace_oldest_value_addr (&XEXP (x, i), cl, mode, as, insn, vd); else if (fmt[i] == 'E') for (j = XVECLEN (x, i) - 1; j >= 0; j--) changed |= replace_oldest_value_addr (&XVECEXP (x, i, j), cl, - mode, insn, vd); + mode, as, insn, vd); } return changed; @@ -669,10 +669,11 @@ replace_oldest_value_mem (rtx x, rtx ins if (DEBUG_INSN_P (insn)) cl = ALL_REGS; else - cl = base_reg_class (GET_MODE (x), MEM, SCRATCH); + cl = base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x), MEM, SCRATCH); return replace_oldest_value_addr (&XEXP (x, 0), cl, - GET_MODE (x), insn, vd); + GET_MODE (x), MEM_ADDR_SPACE (x), + insn, vd); } /* Apply all queued updates for DEBUG_INSNs that change some reg to @@ -751,7 +752,7 @@ copyprop_hardreg_forward_1 (basic_block if (!VAR_LOC_UNKNOWN_P (loc)) replace_oldest_value_addr (&INSN_VAR_LOCATION_LOC (insn), ALL_REGS, GET_MODE (loc), - insn, vd); + ADDR_SPACE_GENERIC, insn, vd); } if (insn == BB_END (bb)) @@ -893,7 +894,8 @@ copyprop_hardreg_forward_1 (basic_block replaced[i] = replace_oldest_value_addr (recog_data.operand_loc[i], recog_op_alt[i][alt].cl, - VOIDmode, insn, vd); + VOIDmode, ADDR_SPACE_GENERIC, + insn, vd); else if (REG_P (recog_data.operand[i])) replaced[i] = replace_oldest_value_reg (recog_data.operand_loc[i], Index: regrename.c =================================================================== --- regrename.c (revision 179594) +++ regrename.c (working copy) @@ -145,6 +145,11 @@ static int this_tick = 0; static struct obstack rename_obstack; static void do_replace (struct du_head *, int); +static void scan_rtx_reg (rtx, rtx *, enum reg_class, + enum scan_actions, enum op_type); +static void scan_rtx_address (rtx, rtx *, enum reg_class, + enum scan_actions, enum machine_mode, + addr_space_t); static void scan_rtx (rtx, rtx *, enum reg_class, enum scan_actions, enum op_type); static bool build_def_use (basic_block); @@ -1177,7 +1182,8 @@ scan_rtx_reg (rtx insn, rtx *loc, enum r static void scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl, - enum scan_actions action, enum machine_mode mode) + enum scan_actions action, enum machine_mode mode, + addr_space_t as) { rtx x = *loc; RTX_CODE code = GET_CODE (x); @@ -1245,15 +1251,15 @@ scan_rtx_address (rtx insn, rtx *loc, en unsigned regno0 = REGNO (op0), regno1 = REGNO (op1); if (REGNO_OK_FOR_INDEX_P (regno1) - && regno_ok_for_base_p (regno0, mode, PLUS, REG)) + && regno_ok_for_base_p (regno0, mode, as, PLUS, REG)) index_op = 1; else if (REGNO_OK_FOR_INDEX_P (regno0) - && regno_ok_for_base_p (regno1, mode, PLUS, REG)) + && regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; - else if (regno_ok_for_base_p (regno0, mode, PLUS, REG) + else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG) || REGNO_OK_FOR_INDEX_P (regno1)) index_op = 1; - else if (regno_ok_for_base_p (regno1, mode, PLUS, REG)) + else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; else index_op = 1; @@ -1276,10 +1282,11 @@ scan_rtx_address (rtx insn, rtx *loc, en } if (locI) - scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode); + scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode, as); if (locB) - scan_rtx_address (insn, locB, base_reg_class (mode, PLUS, index_code), - action, mode); + scan_rtx_address (insn, locB, + base_reg_class (mode, as, PLUS, index_code), + action, mode, as); return; } @@ -1299,8 +1306,9 @@ scan_rtx_address (rtx insn, rtx *loc, en case MEM: scan_rtx_address (insn, &XEXP (x, 0), - base_reg_class (GET_MODE (x), MEM, SCRATCH), action, - GET_MODE (x)); + base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x), + MEM, SCRATCH), + action, GET_MODE (x), MEM_ADDR_SPACE (x)); return; case REG: @@ -1315,10 +1323,10 @@ scan_rtx_address (rtx insn, rtx *loc, en for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') - scan_rtx_address (insn, &XEXP (x, i), cl, action, mode); + scan_rtx_address (insn, &XEXP (x, i), cl, action, mode, as); else if (fmt[i] == 'E') for (j = XVECLEN (x, i) - 1; j >= 0; j--) - scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode); + scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode, as); } } @@ -1351,8 +1359,9 @@ scan_rtx (rtx insn, rtx *loc, enum reg_c case MEM: scan_rtx_address (insn, &XEXP (x, 0), - base_reg_class (GET_MODE (x), MEM, SCRATCH), action, - GET_MODE (x)); + base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x), + MEM, SCRATCH), + action, GET_MODE (x), MEM_ADDR_SPACE (x)); return; case SET: @@ -1675,7 +1684,8 @@ build_def_use (basic_block bb) continue; if (recog_op_alt[opn][alt].is_address) - scan_rtx_address (insn, loc, cl, mark_read, VOIDmode); + scan_rtx_address (insn, loc, cl, mark_read, + VOIDmode, ADDR_SPACE_GENERIC); else scan_rtx (insn, loc, cl, mark_read, type); } Index: reload1.c =================================================================== --- reload1.c (revision 179594) +++ reload1.c (working copy) @@ -1422,7 +1422,8 @@ maybe_fix_stack_asms (void) case 'p': cls = (int) reg_class_subunion[cls] - [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)]; + [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]; break; case 'g': @@ -1433,7 +1434,8 @@ maybe_fix_stack_asms (void) default: if (EXTRA_ADDRESS_CONSTRAINT (c, p)) cls = (int) reg_class_subunion[cls] - [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)]; + [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]; else cls = (int) reg_class_subunion[cls] [(int) REG_CLASS_FROM_CONSTRAINT (c, p)]; Index: reload.c =================================================================== --- reload.c (revision 179594) +++ reload.c (working copy) @@ -278,7 +278,7 @@ static int find_reloads_address (enum ma static rtx subst_reg_equivs (rtx, rtx); static rtx subst_indexed_address (rtx); static void update_auto_inc_notes (rtx, int, int); -static int find_reloads_address_1 (enum machine_mode, rtx, int, +static int find_reloads_address_1 (enum machine_mode, addr_space_t, rtx, int, enum rtx_code, enum rtx_code, rtx *, int, enum reload_type,int, rtx); static void find_reloads_address_part (rtx, rtx *, enum reg_class, @@ -3242,8 +3242,9 @@ find_reloads (rtx insn, int replace, int case 'p': /* All necessary reloads for an address_operand were handled in find_reloads_address. */ - this_alternative[i] = base_reg_class (VOIDmode, ADDRESS, - SCRATCH); + this_alternative[i] + = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH); win = 1; badop = 0; break; @@ -3448,9 +3449,9 @@ find_reloads (rtx insn, int replace, int /* If we didn't already win, we can reload the address into a base register. */ - this_alternative[i] = base_reg_class (VOIDmode, - ADDRESS, - SCRATCH); + this_alternative[i] + = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH); badop = 0; break; } @@ -3980,18 +3981,16 @@ find_reloads (rtx insn, int replace, int /* If the address to be reloaded is a VOIDmode constant, use the default address mode as mode of the reload register, as would have been done by find_reloads_address. */ + addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]); enum machine_mode address_mode; address_mode = GET_MODE (XEXP (recog_data.operand[i], 0)); if (address_mode == VOIDmode) - { - addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]); - address_mode = targetm.addr_space.address_mode (as); - } + address_mode = targetm.addr_space.address_mode (as); operand_reloadnum[i] = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX, &XEXP (recog_data.operand[i], 0), (rtx*) 0, - base_reg_class (VOIDmode, MEM, SCRATCH), + base_reg_class (VOIDmode, as, MEM, SCRATCH), address_mode, VOIDmode, 0, 0, i, RELOAD_FOR_INPUT); rld[operand_reloadnum[i]].inc @@ -4888,7 +4887,7 @@ find_reloads_address (enum machine_mode if (reg_equiv_constant (regno) != 0) { find_reloads_address_part (reg_equiv_constant (regno), loc, - base_reg_class (mode, MEM, SCRATCH), + base_reg_class (mode, as, MEM, SCRATCH), GET_MODE (ad), opnum, type, ind_levels); return 1; } @@ -4951,12 +4950,13 @@ find_reloads_address (enum machine_mode subject of a CLOBBER in this insn. */ else if (regno < FIRST_PSEUDO_REGISTER - && regno_ok_for_base_p (regno, mode, MEM, SCRATCH) + && regno_ok_for_base_p (regno, mode, as, MEM, SCRATCH) && ! regno_clobbered_p (regno, this_insn, mode, 0)) return 0; /* If we do not have one of the cases above, we must do the reload. */ - push_reload (ad, NULL_RTX, loc, (rtx*) 0, base_reg_class (mode, MEM, SCRATCH), + push_reload (ad, NULL_RTX, loc, (rtx*) 0, + base_reg_class (mode, as, MEM, SCRATCH), GET_MODE (ad), VOIDmode, 0, 0, opnum, type); return 1; } @@ -5057,7 +5057,7 @@ find_reloads_address (enum machine_mode /* Must use TEM here, not AD, since it is the one that will have any subexpressions reloaded, if needed. */ push_reload (tem, NULL_RTX, loc, (rtx*) 0, - base_reg_class (mode, MEM, SCRATCH), GET_MODE (tem), + base_reg_class (mode, as, MEM, SCRATCH), GET_MODE (tem), VOIDmode, 0, 0, opnum, type); return ! removed_and; @@ -5075,7 +5075,7 @@ find_reloads_address (enum machine_mode && REG_P (XEXP (ad, 0)) && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER && CONST_INT_P (XEXP (ad, 1)) - && (regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, PLUS, + && (regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, as, PLUS, CONST_INT) /* Similarly, if we were to reload the base register and the mem+offset address is still invalid, then we want to reload @@ -5094,7 +5094,7 @@ find_reloads_address (enum machine_mode } if (double_reg_address_ok - && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, + && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, as, PLUS, CONST_INT)) { /* Unshare the sum as well. */ @@ -5113,7 +5113,7 @@ find_reloads_address (enum machine_mode reload the sum into a base reg. That will at least work. */ find_reloads_address_part (ad, loc, - base_reg_class (mode, MEM, SCRATCH), + base_reg_class (mode, as, MEM, SCRATCH), GET_MODE (ad), opnum, type, ind_levels); } return ! removed_and; @@ -5165,7 +5165,7 @@ find_reloads_address (enum machine_mode addend = XEXP (XEXP (ad, 0), 1 - op_index); - if ((regno_ok_for_base_p (REGNO (operand), mode, inner_code, + if ((regno_ok_for_base_p (REGNO (operand), mode, as, inner_code, GET_CODE (addend)) || operand == frame_pointer_rtx #if !HARD_FRAME_POINTER_IS_FRAME_POINTER @@ -5194,11 +5194,11 @@ find_reloads_address (enum machine_mode op_index == 0 ? addend : offset_reg); *loc = ad; - cls = base_reg_class (mode, MEM, GET_CODE (addend)); + cls = base_reg_class (mode, as, MEM, GET_CODE (addend)); find_reloads_address_part (XEXP (ad, op_index), &XEXP (ad, op_index), cls, GET_MODE (ad), opnum, type, ind_levels); - find_reloads_address_1 (mode, + find_reloads_address_1 (mode, as, XEXP (ad, 1 - op_index), 1, GET_CODE (ad), GET_CODE (XEXP (ad, op_index)), &XEXP (ad, 1 - op_index), opnum, @@ -5251,13 +5251,14 @@ find_reloads_address (enum machine_mode loc = &XEXP (*loc, 0); } - find_reloads_address_part (ad, loc, base_reg_class (mode, MEM, SCRATCH), + find_reloads_address_part (ad, loc, + base_reg_class (mode, as, MEM, SCRATCH), address_mode, opnum, type, ind_levels); return ! removed_and; } - return find_reloads_address_1 (mode, ad, 0, MEM, SCRATCH, loc, opnum, type, - ind_levels, insn); + return find_reloads_address_1 (mode, as, ad, 0, MEM, SCRATCH, loc, + opnum, type, ind_levels, insn); } /* Find all pseudo regs appearing in AD @@ -5490,14 +5491,15 @@ update_auto_inc_notes (rtx insn ATTRIBUT handles those cases gracefully. */ static int -find_reloads_address_1 (enum machine_mode mode, rtx x, int context, +find_reloads_address_1 (enum machine_mode mode, addr_space_t as, + rtx x, int context, enum rtx_code outer_code, enum rtx_code index_code, rtx *loc, int opnum, enum reload_type type, int ind_levels, rtx insn) { -#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, OUTER, INDEX) \ +#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, AS, OUTER, INDEX) \ ((CONTEXT) == 0 \ - ? regno_ok_for_base_p (REGNO, MODE, OUTER, INDEX) \ + ? regno_ok_for_base_p (REGNO, MODE, AS, OUTER, INDEX) \ : REGNO_OK_FOR_INDEX_P (REGNO)) enum reg_class context_reg_class; @@ -5506,7 +5508,7 @@ find_reloads_address_1 (enum machine_mod if (context == 1) context_reg_class = INDEX_REG_CLASS; else - context_reg_class = base_reg_class (mode, outer_code, index_code); + context_reg_class = base_reg_class (mode, as, outer_code, index_code); switch (code) { @@ -5563,10 +5565,10 @@ find_reloads_address_1 (enum machine_mod if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE || code0 == ZERO_EXTEND || code1 == MEM) { - find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH, + find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH, &XEXP (x, 0), opnum, type, ind_levels, insn); - find_reloads_address_1 (mode, orig_op1, 0, PLUS, code0, + find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, code0, &XEXP (x, 1), opnum, type, ind_levels, insn); } @@ -5574,56 +5576,56 @@ find_reloads_address_1 (enum machine_mod else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE || code1 == ZERO_EXTEND || code0 == MEM) { - find_reloads_address_1 (mode, orig_op0, 0, PLUS, code1, + find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, code1, &XEXP (x, 0), opnum, type, ind_levels, insn); - find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH, + find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH, &XEXP (x, 1), opnum, type, ind_levels, insn); } else if (code0 == CONST_INT || code0 == CONST || code0 == SYMBOL_REF || code0 == LABEL_REF) - find_reloads_address_1 (mode, orig_op1, 0, PLUS, code0, + find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, code0, &XEXP (x, 1), opnum, type, ind_levels, insn); else if (code1 == CONST_INT || code1 == CONST || code1 == SYMBOL_REF || code1 == LABEL_REF) - find_reloads_address_1 (mode, orig_op0, 0, PLUS, code1, + find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, code1, &XEXP (x, 0), opnum, type, ind_levels, insn); else if (code0 == REG && code1 == REG) { if (REGNO_OK_FOR_INDEX_P (REGNO (op1)) - && regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG)) + && regno_ok_for_base_p (REGNO (op0), mode, as, PLUS, REG)) return 0; else if (REGNO_OK_FOR_INDEX_P (REGNO (op0)) - && regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG)) + && regno_ok_for_base_p (REGNO (op1), mode, as, PLUS, REG)) return 0; - else if (regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG)) - find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH, + else if (regno_ok_for_base_p (REGNO (op0), mode, as, PLUS, REG)) + find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH, &XEXP (x, 1), opnum, type, ind_levels, insn); else if (REGNO_OK_FOR_INDEX_P (REGNO (op1))) - find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG, + find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG, &XEXP (x, 0), opnum, type, ind_levels, insn); - else if (regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG)) - find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH, + else if (regno_ok_for_base_p (REGNO (op1), mode, as, PLUS, REG)) + find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH, &XEXP (x, 0), opnum, type, ind_levels, insn); else if (REGNO_OK_FOR_INDEX_P (REGNO (op0))) - find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG, + find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, REG, &XEXP (x, 1), opnum, type, ind_levels, insn); else { - find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG, + find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG, &XEXP (x, 0), opnum, type, ind_levels, insn); - find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH, + find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH, &XEXP (x, 1), opnum, type, ind_levels, insn); } @@ -5631,20 +5633,20 @@ find_reloads_address_1 (enum machine_mod else if (code0 == REG) { - find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH, + find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH, &XEXP (x, 0), opnum, type, ind_levels, insn); - find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG, + find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, REG, &XEXP (x, 1), opnum, type, ind_levels, insn); } else if (code1 == REG) { - find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH, + find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH, &XEXP (x, 1), opnum, type, ind_levels, insn); - find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG, + find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG, &XEXP (x, 0), opnum, type, ind_levels, insn); } @@ -5686,7 +5688,7 @@ find_reloads_address_1 (enum machine_mod if ((REG_P (XEXP (op1, 1)) && !REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1)))) || GET_CODE (XEXP (op1, 1)) == PLUS) - find_reloads_address_1 (mode, XEXP (op1, 1), 1, code, SCRATCH, + find_reloads_address_1 (mode, as, XEXP (op1, 1), 1, code, SCRATCH, &XEXP (op1, 1), opnum, RELOAD_OTHER, ind_levels, insn); @@ -5728,8 +5730,8 @@ find_reloads_address_1 (enum machine_mod register. */ reloadnum = push_reload (tem, tem, &XEXP (x, 0), &XEXP (op1, 0), - base_reg_class (mode, code, - index_code), + base_reg_class (mode, as, + code, index_code), GET_MODE (x), GET_MODE (x), 0, 0, opnum, RELOAD_OTHER); @@ -5742,11 +5744,12 @@ find_reloads_address_1 (enum machine_mod regno = reg_renumber[regno]; /* We require a base register here... */ - if (!regno_ok_for_base_p (regno, GET_MODE (x), code, index_code)) + if (!regno_ok_for_base_p (regno, GET_MODE (x), as, code, index_code)) { reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0), &XEXP (op1, 0), &XEXP (x, 0), - base_reg_class (mode, code, index_code), + base_reg_class (mode, as, + code, index_code), GET_MODE (x), GET_MODE (x), 0, 0, opnum, RELOAD_OTHER); @@ -5812,7 +5815,7 @@ find_reloads_address_1 (enum machine_mod if (reg_renumber[regno] >= 0) regno = reg_renumber[regno]; if (regno >= FIRST_PSEUDO_REGISTER - || !REG_OK_FOR_CONTEXT (context, regno, mode, code, + || !REG_OK_FOR_CONTEXT (context, regno, mode, as, code, index_code)) { int reloadnum; @@ -5881,7 +5884,7 @@ find_reloads_address_1 (enum machine_mod reloaded. Targets that are better off reloading just either part (or perhaps even a different part of an outer expression), should define LEGITIMIZE_RELOAD_ADDRESS. */ - find_reloads_address_1 (GET_MODE (XEXP (x, 0)), XEXP (x, 0), + find_reloads_address_1 (GET_MODE (XEXP (x, 0)), as, XEXP (x, 0), context, code, SCRATCH, &XEXP (x, 0), opnum, type, ind_levels, insn); push_reload (x, NULL_RTX, loc, (rtx*) 0, @@ -5952,7 +5955,7 @@ find_reloads_address_1 (enum machine_mod regno = reg_renumber[regno]; if (regno >= FIRST_PSEUDO_REGISTER - || !REG_OK_FOR_CONTEXT (context, regno, mode, outer_code, + || !REG_OK_FOR_CONTEXT (context, regno, mode, as, outer_code, index_code)) { push_reload (x, NULL_RTX, loc, (rtx*) 0, @@ -5985,7 +5988,7 @@ find_reloads_address_1 (enum machine_mod { int regno ATTRIBUTE_UNUSED = subreg_regno (x); - if (!REG_OK_FOR_CONTEXT (context, regno, mode, outer_code, + if (!REG_OK_FOR_CONTEXT (context, regno, mode, as, outer_code, index_code)) { push_reload (x, NULL_RTX, loc, (rtx*) 0, @@ -6026,8 +6029,9 @@ find_reloads_address_1 (enum machine_mod if (fmt[i] == 'e') /* Pass SCRATCH for INDEX_CODE, since CODE can never be a PLUS once we get here. */ - find_reloads_address_1 (mode, XEXP (x, i), context, code, SCRATCH, - &XEXP (x, i), opnum, type, ind_levels, insn); + find_reloads_address_1 (mode, as, XEXP (x, i), context, + code, SCRATCH, &XEXP (x, i), + opnum, type, ind_levels, insn); } } @@ -6204,7 +6208,9 @@ find_reloads_subreg_address (rtx x, int MEM_ADDR_SPACE (reg_equiv_mem (regno)))) { push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0, - base_reg_class (GET_MODE (tem), MEM, SCRATCH), + base_reg_class (GET_MODE (tem), + MEM_ADDR_SPACE (tem), + MEM, SCRATCH), GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0, opnum, type); reloaded = 1; Index: addresses.h =================================================================== --- addresses.h (revision 179594) +++ addresses.h (working copy) @@ -23,11 +23,12 @@ along with GCC; see the file COPYING3. static inline enum reg_class base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED, + addr_space_t as ATTRIBUTE_UNUSED, enum rtx_code outer_code ATTRIBUTE_UNUSED, enum rtx_code index_code ATTRIBUTE_UNUSED) { #ifdef MODE_CODE_BASE_REG_CLASS - return MODE_CODE_BASE_REG_CLASS (mode, outer_code, index_code); + return MODE_CODE_BASE_REG_CLASS (mode, as, outer_code, index_code); #else #ifdef MODE_BASE_REG_REG_CLASS if (index_code == REG) @@ -49,11 +50,13 @@ base_reg_class (enum machine_mode mode A static inline bool ok_for_base_p_1 (unsigned regno ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, + addr_space_t as ATTRIBUTE_UNUSED, enum rtx_code outer_code ATTRIBUTE_UNUSED, enum rtx_code index_code ATTRIBUTE_UNUSED) { #ifdef REGNO_MODE_CODE_OK_FOR_BASE_P - return REGNO_MODE_CODE_OK_FOR_BASE_P (regno, mode, outer_code, index_code); + return REGNO_MODE_CODE_OK_FOR_BASE_P (regno, mode, as, + outer_code, index_code); #else #ifdef REGNO_MODE_OK_FOR_REG_BASE_P if (index_code == REG) @@ -71,11 +74,11 @@ ok_for_base_p_1 (unsigned regno ATTRIBUT complete. Arguments as for the called function. */ static inline bool -regno_ok_for_base_p (unsigned regno, enum machine_mode mode, +regno_ok_for_base_p (unsigned regno, enum machine_mode mode, addr_space_t as, enum rtx_code outer_code, enum rtx_code index_code) { if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0) regno = reg_renumber[regno]; - return ok_for_base_p_1 (regno, mode, outer_code, index_code); + return ok_for_base_p_1 (regno, mode, as, outer_code, index_code); }