This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFA: new reload macro: MODE_BASE_REG_CLASS
- From: Nick Clifton <nickc at cambridge dot redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 14 Dec 2001 11:03:39 +0000
- Subject: RFA: new reload macro: MODE_BASE_REG_CLASS
Hi Guys,
I would like to obtain permission to apply the following patch. It
creates a new macro for use by reload. This macro, called
MODE_BASE_REG_CLASS is a variant of the current BASE_REG_CLASS macro
except that it allows the selection of the base register class in a
mode dependent fashion.
The patch was created by Bernd Schmidt some time ago, and I have
recently found that it is needed by the ARM port in order to fix
some code generation problems when it is running in THUMB mode. In
particular for the Thumb, the stack pointer is a valid base register
for SI mode quantities but not QI or HI mode quantities.
This patch fixes several unexpected failures in the gcc testsuite
when running in the Thumb mode.
OK to apply ?
Cheers
Nick
2001-12-14 Nick Clifton <nickc@cambridge.redhat.com>
* reload.c (MODE_BASE_REG_CLASS): Provide default definition
if one has not been supplied by the backend.
(find_reloads): Use MODE_BASE_REG_CLASS instead of
BASE_REG_CLASS.
(find_reloads_address); Use MODE_BASE_REG_CLASS instead of
BASE_REG_CLASS.
(find_reloads_address_1); Use MODE_BASE_REG_CLASS instead of
BASE_REG_CLASS.
* doc/tm.texi: Document new MODE_BASE_REG_CLASS macro.
* config/arm/arm.h (MODE_BASE_REG_CLASS): Define.
Index: gcc/reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.172
diff -p -c -r1.172 reload.c
*** reload.c 2001/12/03 15:22:47 1.172
--- reload.c 2001/12/14 10:56:28
*************** a register with any other reload. */
*** 114,119 ****
--- 114,123 ----
#ifndef REG_MODE_OK_FOR_BASE_P
#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
#endif
+
+ #ifndef MODE_BASE_REG_CLASS
+ #define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
+ #endif
/* All reloads of the current insn are recorded here. See reload.h for
comments. */
*************** find_reloads (insn, replace, ind_levels,
*** 3029,3035 ****
case 'p':
/* All necessary reloads for an address_operand
were handled in find_reloads_address. */
! this_alternative[i] = (int) BASE_REG_CLASS;
win = 1;
break;
--- 3033,3039 ----
case 'p':
/* All necessary reloads for an address_operand
were handled in find_reloads_address. */
! this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
win = 1;
break;
*************** find_reloads (insn, replace, ind_levels,
*** 3686,3692 ****
operand_reloadnum[i]
= push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
&XEXP (recog_data.operand[i], 0), (rtx*)0,
! BASE_REG_CLASS,
GET_MODE (XEXP (recog_data.operand[i], 0)),
VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
rld[operand_reloadnum[i]].inc
--- 3690,3696 ----
operand_reloadnum[i]
= push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
&XEXP (recog_data.operand[i], 0), (rtx*)0,
! 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
*************** find_reloads_address (mode, memrefloc, a
*** 4617,4623 ****
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,
GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
return 1;
}
--- 4621,4627 ----
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, MODE_BASE_REG_CLASS (mode),
GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
return 1;
}
*************** find_reloads_address (mode, memrefloc, a
*** 4718,4724 ****
/* 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),
VOIDmode, 0,
0, opnum, type);
return ! removed_and;
--- 4722,4728 ----
/* 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,
! MODE_BASE_REG_CLASS (mode), GET_MODE (tem),
VOIDmode, 0,
0, opnum, type);
return ! removed_and;
*************** find_reloads_address (mode, memrefloc, a
*** 4764,4770 ****
/* 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,
Pmode, opnum, type, ind_levels);
}
return ! removed_and;
--- 4768,4774 ----
/* 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, MODE_BASE_REG_CLASS (mode),
Pmode, opnum, type, ind_levels);
}
return ! removed_and;
*************** find_reloads_address (mode, memrefloc, a
*** 4807,4813 ****
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,
GET_MODE (ad), opnum, type, ind_levels);
find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum,
type, 0, insn);
--- 4811,4818 ----
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),
! 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);
*************** find_reloads_address (mode, memrefloc, a
*** 4831,4837 ****
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,
GET_MODE (ad), opnum, type, ind_levels);
find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum,
type, 0, insn);
--- 4836,4843 ----
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),
! 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);
*************** find_reloads_address (mode, memrefloc, a
*** 4877,4884 ****
loc = &XEXP (*loc, 0);
}
! find_reloads_address_part (ad, loc, BASE_REG_CLASS, Pmode, opnum, type,
! ind_levels);
return ! removed_and;
}
--- 4883,4890 ----
loc = &XEXP (*loc, 0);
}
! find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode),
! Pmode, opnum, type, ind_levels);
return ! removed_and;
}
*************** find_reloads_address_1 (mode, x, context
*** 5303,5309 ****
/* Then reload the memory location into a base
register. */
reloadnum = push_reload (tem, tem, &XEXP (x, 0),
! &XEXP (op1, 0), BASE_REG_CLASS,
GET_MODE (x), GET_MODE (x), 0,
0, opnum, RELOAD_OTHER);
--- 5309,5316 ----
/* Then reload the memory location into a base
register. */
reloadnum = push_reload (tem, tem, &XEXP (x, 0),
! &XEXP (op1, 0),
! MODE_BASE_REG_CLASS (mode),
GET_MODE (x), GET_MODE (x), 0,
0, opnum, RELOAD_OTHER);
*************** find_reloads_address_1 (mode, x, context
*** 5320,5326 ****
{
reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
&XEXP (op1, 0), &XEXP (x, 0),
! BASE_REG_CLASS,
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, RELOAD_OTHER);
--- 5327,5333 ----
{
reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
&XEXP (op1, 0), &XEXP (x, 0),
! MODE_BASE_REG_CLASS (mode),
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, RELOAD_OTHER);
*************** find_reloads_address_1 (mode, x, context
*** 5421,5427 ****
x = XEXP (x, 0);
reloadnum
= push_reload (x, x, loc, loc,
! (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, RELOAD_OTHER);
}
--- 5428,5435 ----
x = XEXP (x, 0);
reloadnum
= push_reload (x, x, loc, loc,
! (context ? INDEX_REG_CLASS :
! MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, RELOAD_OTHER);
}
*************** find_reloads_address_1 (mode, x, context
*** 5429,5435 ****
{
reloadnum
= push_reload (x, NULL_RTX, loc, (rtx*)0,
! (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, type);
rld[reloadnum].inc
--- 5437,5444 ----
{
reloadnum
= push_reload (x, NULL_RTX, loc, (rtx*)0,
! (context ? INDEX_REG_CLASS :
! MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, type);
rld[reloadnum].inc
*************** find_reloads_address_1 (mode, x, context
*** 5469,5475 ****
opnum, type, ind_levels, insn);
reloadnum = push_reload (x, NULL_RTX, loc, (rtx*)0,
! (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
rld[reloadnum].inc
= find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
--- 5478,5485 ----
opnum, type, ind_levels, insn);
reloadnum = push_reload (x, NULL_RTX, loc, (rtx*)0,
! (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));
*************** find_reloads_address_1 (mode, x, context
*** 5498,5504 ****
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),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
--- 5508,5514 ----
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 : MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
*************** find_reloads_address_1 (mode, x, context
*** 5509,5515 ****
if (reg_equiv_constant[regno] != 0)
{
find_reloads_address_part (reg_equiv_constant[regno], loc,
! (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), opnum, type, ind_levels);
return 1;
}
--- 5519,5526 ----
if (reg_equiv_constant[regno] != 0)
{
find_reloads_address_part (reg_equiv_constant[regno], loc,
! (context ? INDEX_REG_CLASS :
! MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), opnum, type, ind_levels);
return 1;
}
*************** find_reloads_address_1 (mode, x, context
*** 5519,5525 ****
if (reg_equiv_mem[regno] != 0)
{
push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*)0,
! (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
--- 5530,5537 ----
if (reg_equiv_mem[regno] != 0)
{
push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*)0,
! (context ? INDEX_REG_CLASS :
! MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
*************** find_reloads_address_1 (mode, x, context
*** 5547,5553 ****
: REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
{
push_reload (x, NULL_RTX, loc, (rtx*)0,
! (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
--- 5559,5565 ----
: REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
{
push_reload (x, NULL_RTX, loc, (rtx*)0,
! (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
*************** find_reloads_address_1 (mode, x, context
*** 5559,5565 ****
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),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
--- 5571,5577 ----
if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
{
push_reload (x, NULL_RTX, loc, (rtx*)0,
! (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
*************** find_reloads_address_1 (mode, x, context
*** 5580,5586 ****
: REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
{
push_reload (x, NULL_RTX, loc, (rtx*)0,
! (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
--- 5592,5599 ----
: REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
{
push_reload (x, NULL_RTX, loc, (rtx*)0,
! (context ? INDEX_REG_CLASS :
! MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
*************** find_reloads_address_1 (mode, x, context
*** 5590,5596 ****
else
{
enum reg_class class = (context ? INDEX_REG_CLASS
! : BASE_REG_CLASS);
if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
> reg_class_size[class])
{
--- 5603,5609 ----
else
{
enum reg_class class = (context ? INDEX_REG_CLASS
! : MODE_BASE_REG_CLASS (mode));
if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
> reg_class_size[class])
{
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.79
diff -p -c -r1.79 tm.texi
*** tm.texi 2001/12/13 14:24:03 1.79
--- tm.texi 2001/12/14 10:56:31
*************** A macro whose definition is the name of
*** 2203,2208 ****
--- 2203,2213 ----
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.
+
@findex INDEX_REG_CLASS
@item INDEX_REG_CLASS
A macro whose definition is the name of the class to which a valid
Index: gcc/config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.127
diff -p -c -r1.127 arm.h
*** arm.h 2001/12/13 00:27:30 1.127
--- arm.h 2001/12/14 10:56:32
*************** enum reg_class
*** 1099,1104 ****
--- 1099,1111 ----
#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) \
+ ? BASE_REGS : LO_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