From 3dcc68a44a005cd6d2802fed3c62e5a3f897a1c5 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 17 Dec 2001 16:46:11 +0000 Subject: Implement MODE_BASE_REG_CLASS From-SVN: r48104 --- gcc/caller-save.c | 4 +++- gcc/config/arm/arm.h | 11 +++++++++++ gcc/defaults.h | 7 +++++++ gcc/doc/tm.texi | 7 +++++++ gcc/recog.c | 3 ++- gcc/regclass.c | 33 ++++++++++++++++++--------------- gcc/regrename.c | 16 ++++++++++------ gcc/reload.c | 51 ++++++++++++++++++++++++++++++--------------------- gcc/reload1.c | 3 ++- 9 files changed, 90 insertions(+), 45 deletions(-) diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 7c89197..1e6e634 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -151,7 +151,9 @@ init_caller_save () that register in every mode we will use to save registers. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (reg_class_contents[(int) BASE_REG_CLASS], i)) + if (TEST_HARD_REG_BIT + (reg_class_contents + [(int) MODE_BASE_REG_CLASS (regno_save_mode [i][1])], i)) break; if (i == FIRST_PSEUDO_REGISTER) diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 6060275..85fea19 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -256,6 +256,10 @@ Unrecognized value in TARGET_CPU_DEFAULT. %{!mthumb-interwork:%{!mno-thumb-interwork:%(cpp_interwork_default)}} \ " +#ifndef CPP_PREDEFINES +#define CPP_PREDEFINES "" +#endif + #ifndef CC1_SPEC #define CC1_SPEC "" #endif @@ -1099,6 +1103,13 @@ enum reg_class #define INDEX_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS) #define BASE_REG_CLASS (TARGET_THUMB ? BASE_REGS : GENERAL_REGS) +/* For the Thumb the high registers cannot be used as base + registers when addressing quanitities in QI or HI mode. */ +#define MODE_BASE_REG_CLASS(MODE) \ + (TARGET_ARM ? BASE_REGS : \ + (((MODE) == QImode || (MODE) == HImode || (MODE) == VOIDmode) \ + ? LO_REGS : BASE_REGS)) + /* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows registers explicitly used in the rtl to be used as spill registers but prevents the compiler from extending the lifetime of these diff --git a/gcc/defaults.h b/gcc/defaults.h index 91962d4..2a7c567 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -450,4 +450,11 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE! #define FUNCTION_ARG_REG_LITTLE_ENDIAN 0 #endif +/* Determine the register class for registers suitable to be the base + address register in a MEM. Allow the choice to be dependent upon + the mode of the memory access. */ +#ifndef MODE_BASE_REG_CLASS +#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS +#endif + #endif /* ! GCC_DEFAULTS_H */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index da3b4d5..30c94ee 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -2203,6 +2203,13 @@ A macro whose definition is the name of the class to which a valid base register must belong. A base register is one used in an address which is the register value plus a displacement. +@findex MODE_BASE_REG_CLASS +@item MODE_BASE_REG_CLASS (@var{mode}) +This is a variation of the @code{BASE_REG_CLASS} macro which allows +the selection of a base register in a mode depenedent manner. If +@var{mode} is VOIDmode then it should return the same value as +@code{BASE_REG_CLASS}. + @findex INDEX_REG_CLASS @item INDEX_REG_CLASS A macro whose definition is the name of the class to which a valid diff --git a/gcc/recog.c b/gcc/recog.c index adcd2d4..652038a 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -2244,7 +2244,8 @@ preprocess_constraints () case 'p': op_alt[j].is_address = 1; - op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) BASE_REG_CLASS]; + op_alt[j].class = reg_class_subunion[(int) op_alt[j].class] + [(int) MODE_BASE_REG_CLASS (VOIDmode)]; break; case 'g': case 'r': diff --git a/gcc/regclass.c b/gcc/regclass.c index 9ef8c8c..9bdb2b0 100644 --- a/gcc/regclass.c +++ b/gcc/regclass.c @@ -1005,10 +1005,10 @@ record_operand_costs (insn, op_costs, reg_pref) if (GET_CODE (recog_data.operand[i]) == MEM) record_address_regs (XEXP (recog_data.operand[i], 0), - BASE_REG_CLASS, frequency * 2); + MODE_BASE_REG_CLASS (modes[i]), frequency * 2); else if (constraints[i][0] == 'p') record_address_regs (recog_data.operand[i], - BASE_REG_CLASS, frequency * 2); + MODE_BASE_REG_CLASS (modes[i]), frequency * 2); } /* Check for commutative in a separate loop so everything will @@ -1086,7 +1086,7 @@ scan_one_insn (insn, pass) GENERAL_REGS, 1) * frequency); record_address_regs (XEXP (SET_SRC (set), 0), - BASE_REG_CLASS, frequency * 2); + MODE_BASE_REG_CLASS (VOIDmode), frequency * 2); return insn; } @@ -1228,15 +1228,15 @@ regclass (f, nregs, dump) if ((0 #ifdef SECONDARY_RELOAD_CLASS - || (SECONDARY_RELOAD_CLASS (BASE_REG_CLASS, m, r) + || (SECONDARY_RELOAD_CLASS (MODE_BASE_REG_CLASS (VOIDmode), m, r) != NO_REGS) #else #ifdef SECONDARY_INPUT_RELOAD_CLASS - || (SECONDARY_INPUT_RELOAD_CLASS (BASE_REG_CLASS, m, r) + || (SECONDARY_INPUT_RELOAD_CLASS (MODE_BASE_REG_CLASS (VOIDmode), m, r) != NO_REGS) #endif #ifdef SECONDARY_OUTPUT_RELOAD_CLASS - || (SECONDARY_OUTPUT_RELOAD_CLASS (BASE_REG_CLASS, m, r) + || (SECONDARY_OUTPUT_RELOAD_CLASS (MODE_BASE_REG_CLASS (VOIDmode), m, r) != NO_REGS) #endif #endif @@ -1609,7 +1609,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, address, ie BASE_REG_CLASS. */ classes[i] = reg_class_subunion[(int) classes[i]] - [(int) BASE_REG_CLASS]; + [(int) MODE_BASE_REG_CLASS (VOIDmode)]; break; case 'm': case 'o': case 'V': @@ -2016,7 +2016,7 @@ record_address_regs (x, class, scale) as well as in the tests below, that all addresses are in canonical form. */ - else if (INDEX_REG_CLASS == BASE_REG_CLASS) + else if (INDEX_REG_CLASS == MODE_BASE_REG_CLASS (VOIDmode)) { record_address_regs (arg0, class, scale); if (! CONSTANT_P (arg1)) @@ -2045,14 +2045,14 @@ record_address_regs (x, class, scale) && (REG_OK_FOR_BASE_P (arg0) || REG_OK_FOR_INDEX_P (arg0))) record_address_regs (arg1, REG_OK_FOR_BASE_P (arg0) - ? INDEX_REG_CLASS : BASE_REG_CLASS, + ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (VOIDmode), scale); else if (code0 == REG && code1 == REG && REGNO (arg1) < FIRST_PSEUDO_REGISTER && (REG_OK_FOR_BASE_P (arg1) || REG_OK_FOR_INDEX_P (arg1))) record_address_regs (arg0, REG_OK_FOR_BASE_P (arg1) - ? INDEX_REG_CLASS : BASE_REG_CLASS, + ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (VOIDmode), scale); #endif @@ -2063,14 +2063,14 @@ record_address_regs (x, class, scale) else if ((code0 == REG && REG_POINTER (arg0)) || code1 == MULT) { - record_address_regs (arg0, BASE_REG_CLASS, scale); + record_address_regs (arg0, MODE_BASE_REG_CLASS (VOIDmode), scale); record_address_regs (arg1, INDEX_REG_CLASS, scale); } else if ((code1 == REG && REG_POINTER (arg1)) || code0 == MULT) { record_address_regs (arg0, INDEX_REG_CLASS, scale); - record_address_regs (arg1, BASE_REG_CLASS, scale); + record_address_regs (arg1, MODE_BASE_REG_CLASS (VOIDmode), scale); } /* Otherwise, count equal chances that each might be a base @@ -2078,9 +2078,11 @@ record_address_regs (x, class, scale) else { - record_address_regs (arg0, BASE_REG_CLASS, scale / 2); + record_address_regs (arg0, MODE_BASE_REG_CLASS (VOIDmode), + scale / 2); record_address_regs (arg0, INDEX_REG_CLASS, scale / 2); - record_address_regs (arg1, BASE_REG_CLASS, scale / 2); + record_address_regs (arg1, MODE_BASE_REG_CLASS (VOIDmode), + scale / 2); record_address_regs (arg1, INDEX_REG_CLASS, scale / 2); } } @@ -2091,7 +2093,8 @@ record_address_regs (x, class, scale) if it ends up in the wrong place. */ case POST_MODIFY: case PRE_MODIFY: - record_address_regs (XEXP (x, 0), BASE_REG_CLASS, 2 * scale); + record_address_regs (XEXP (x, 0), MODE_BASE_REG_CLASS (VOIDmode), + 2 * scale); if (REG_P (XEXP (XEXP (x, 1), 1))) record_address_regs (XEXP (XEXP (x, 1), 1), INDEX_REG_CLASS, 2 * scale); diff --git a/gcc/regrename.c b/gcc/regrename.c index 3236a43..fca249e 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -611,7 +611,7 @@ scan_rtx_address (insn, loc, class, action, mode) if (locI) scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode); if (locB) - scan_rtx_address (insn, locB, BASE_REG_CLASS, action, mode); + scan_rtx_address (insn, locB, MODE_BASE_REG_CLASS (mode), action, mode); return; } @@ -629,7 +629,8 @@ scan_rtx_address (insn, loc, class, action, mode) break; case MEM: - scan_rtx_address (insn, &XEXP (x, 0), BASE_REG_CLASS, action, + scan_rtx_address (insn, &XEXP (x, 0), + MODE_BASE_REG_CLASS (GET_MODE (x)), action, GET_MODE (x)); return; @@ -683,7 +684,8 @@ scan_rtx (insn, loc, class, action, type, earlyclobber) return; case MEM: - scan_rtx_address (insn, &XEXP (x, 0), BASE_REG_CLASS, action, + scan_rtx_address (insn, &XEXP (x, 0), + MODE_BASE_REG_CLASS (GET_MODE (x)), action, GET_MODE (x)); return; @@ -1376,8 +1378,9 @@ replace_oldest_value_addr (loc, class, mode, insn, vd) changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode, insn, vd); if (locB) - changed |= replace_oldest_value_addr (locB, BASE_REG_CLASS, mode, - insn, vd); + changed |= replace_oldest_value_addr (locB, + MODE_BASE_REG_CLASS (mode), + mode, insn, vd); return changed; } @@ -1422,7 +1425,8 @@ replace_oldest_value_mem (x, insn, vd) rtx insn; struct value_data *vd; { - return replace_oldest_value_addr (&XEXP (x, 0), BASE_REG_CLASS, + return replace_oldest_value_addr (&XEXP (x, 0), + MODE_BASE_REG_CLASS (GET_MODE (x)), GET_MODE (x), insn, vd); } diff --git a/gcc/reload.c b/gcc/reload.c index e8adcfa..579cb1b 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -3029,7 +3029,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) case 'p': /* All necessary reloads for an address_operand were handled in find_reloads_address. */ - this_alternative[i] = (int) BASE_REG_CLASS; + this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode); win = 1; break; @@ -3686,7 +3686,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) operand_reloadnum[i] = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX, &XEXP (recog_data.operand[i], 0), (rtx*)0, - BASE_REG_CLASS, + MODE_BASE_REG_CLASS (VOIDmode), GET_MODE (XEXP (recog_data.operand[i], 0)), VOIDmode, 0, 0, i, RELOAD_FOR_INPUT); rld[operand_reloadnum[i]].inc @@ -4617,7 +4617,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn) 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, + push_reload (ad, NULL_RTX, loc, (rtx*)0, MODE_BASE_REG_CLASS (mode), GET_MODE (ad), VOIDmode, 0, 0, opnum, type); return 1; } @@ -4718,7 +4718,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn) /* 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, GET_MODE (tem), + MODE_BASE_REG_CLASS (mode), GET_MODE (tem), VOIDmode, 0, 0, opnum, type); return ! removed_and; @@ -4764,7 +4764,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn) /* If the sum of two regs is not necessarily valid, reload the sum into a base reg. That will at least work. */ - find_reloads_address_part (ad, loc, BASE_REG_CLASS, + find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode), Pmode, opnum, type, ind_levels); } return ! removed_and; @@ -4807,7 +4807,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn) plus_constant (XEXP (XEXP (ad, 0), 0), INTVAL (XEXP (ad, 1))), XEXP (XEXP (ad, 0), 1)); - find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0), BASE_REG_CLASS, + find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0), + MODE_BASE_REG_CLASS (mode), GET_MODE (ad), opnum, type, ind_levels); find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum, type, 0, insn); @@ -4831,7 +4832,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn) XEXP (XEXP (ad, 0), 0), plus_constant (XEXP (XEXP (ad, 0), 1), INTVAL (XEXP (ad, 1)))); - find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1), BASE_REG_CLASS, + find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1), + MODE_BASE_REG_CLASS (mode), GET_MODE (ad), opnum, type, ind_levels); find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum, type, 0, insn); @@ -4877,8 +4879,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn) loc = &XEXP (*loc, 0); } - find_reloads_address_part (ad, loc, BASE_REG_CLASS, Pmode, opnum, type, - ind_levels); + find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode), + Pmode, opnum, type, ind_levels); return ! removed_and; } @@ -5303,7 +5305,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) /* Then reload the memory location into a base register. */ reloadnum = push_reload (tem, tem, &XEXP (x, 0), - &XEXP (op1, 0), BASE_REG_CLASS, + &XEXP (op1, 0), + MODE_BASE_REG_CLASS (mode), GET_MODE (x), GET_MODE (x), 0, 0, opnum, RELOAD_OTHER); @@ -5320,7 +5323,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) { reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0), &XEXP (op1, 0), &XEXP (x, 0), - BASE_REG_CLASS, + MODE_BASE_REG_CLASS (mode), GET_MODE (x), GET_MODE (x), 0, 0, opnum, RELOAD_OTHER); @@ -5421,7 +5424,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) x = XEXP (x, 0); reloadnum = push_reload (x, x, loc, loc, - (context ? INDEX_REG_CLASS : BASE_REG_CLASS), + (context ? INDEX_REG_CLASS : + MODE_BASE_REG_CLASS (mode)), GET_MODE (x), GET_MODE (x), 0, 0, opnum, RELOAD_OTHER); } @@ -5429,7 +5433,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) { reloadnum = push_reload (x, NULL_RTX, loc, (rtx*)0, - (context ? INDEX_REG_CLASS : BASE_REG_CLASS), + (context ? INDEX_REG_CLASS : + MODE_BASE_REG_CLASS (mode)), GET_MODE (x), GET_MODE (x), 0, 0, opnum, type); rld[reloadnum].inc @@ -5469,7 +5474,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) opnum, type, ind_levels, insn); reloadnum = push_reload (x, NULL_RTX, loc, (rtx*)0, - (context ? INDEX_REG_CLASS : BASE_REG_CLASS), + (context ? INDEX_REG_CLASS : + MODE_BASE_REG_CLASS (mode)), GET_MODE (x), VOIDmode, 0, 0, opnum, type); rld[reloadnum].inc = find_inc_amount (PATTERN (this_insn), XEXP (x, 0)); @@ -5498,7 +5504,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0), opnum, ADDR_TYPE (type), ind_levels, insn); push_reload (*loc, NULL_RTX, loc, (rtx*)0, - (context ? INDEX_REG_CLASS : BASE_REG_CLASS), + (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)), GET_MODE (x), VOIDmode, 0, 0, opnum, type); return 1; @@ -5509,7 +5515,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) if (reg_equiv_constant[regno] != 0) { find_reloads_address_part (reg_equiv_constant[regno], loc, - (context ? INDEX_REG_CLASS : BASE_REG_CLASS), + (context ? INDEX_REG_CLASS : + MODE_BASE_REG_CLASS (mode)), GET_MODE (x), opnum, type, ind_levels); return 1; } @@ -5519,7 +5526,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) if (reg_equiv_mem[regno] != 0) { push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*)0, - (context ? INDEX_REG_CLASS : BASE_REG_CLASS), + (context ? INDEX_REG_CLASS : + MODE_BASE_REG_CLASS (mode)), GET_MODE (x), VOIDmode, 0, 0, opnum, type); return 1; } @@ -5547,7 +5555,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) : REGNO_MODE_OK_FOR_BASE_P (regno, mode)))) { push_reload (x, NULL_RTX, loc, (rtx*)0, - (context ? INDEX_REG_CLASS : BASE_REG_CLASS), + (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)), GET_MODE (x), VOIDmode, 0, 0, opnum, type); return 1; } @@ -5559,7 +5567,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0)) { push_reload (x, NULL_RTX, loc, (rtx*)0, - (context ? INDEX_REG_CLASS : BASE_REG_CLASS), + (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)), GET_MODE (x), VOIDmode, 0, 0, opnum, type); return 1; } @@ -5580,7 +5588,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) : REGNO_MODE_OK_FOR_BASE_P (regno, mode))) { push_reload (x, NULL_RTX, loc, (rtx*)0, - (context ? INDEX_REG_CLASS : BASE_REG_CLASS), + (context ? INDEX_REG_CLASS : + MODE_BASE_REG_CLASS (mode)), GET_MODE (x), VOIDmode, 0, 0, opnum, type); return 1; } @@ -5590,7 +5599,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn) else { enum reg_class class = (context ? INDEX_REG_CLASS - : BASE_REG_CLASS); + : MODE_BASE_REG_CLASS (mode)); if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x))) > reg_class_size[class]) { diff --git a/gcc/reload1.c b/gcc/reload1.c index 58019b0..0f41718 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1363,7 +1363,8 @@ maybe_fix_stack_asms () break; case 'p': - cls = (int) reg_class_subunion[cls][(int) BASE_REG_CLASS]; + cls = (int) reg_class_subunion[cls] + [(int) MODE_BASE_REG_CLASS (VOIDmode)]; break; case 'g': -- cgit v1.1