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); }