[prev in list] [next in list] [prev in thread] [next in thread]
List: gcc-patches
Subject: [csl-arm] Backport reg+reg addressing fix.
From: Paul Brook <paul () codesourcery ! com>
Date: 2005-08-31 22:40:53
Message-ID: 200508312340.54036.paul () codesourcery ! com
[Download RAW message or body]
I've backported the following patch to csl-arm-branch.
http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02009.html
Tested with cross to arm-none-eabi.
Paul
2005-08-31 Paul Brook <paul@codesourcery.com>
Backport from Mainline.
2004-09-20 Daniel Jacobowitz <dan@debian.org>
* defaults.h (REGNO_MODE_OK_FOR_BASE_P, REG_MODE_OK_FOR_BASE_P)
(MODE_BASE_REG_REG_CLASS, REGNO_MODE_OK_FOR_REG_BASE_P)
(REG_MODE_OK_FOR_REG_BASE_P): Provide default definitions.
* regclass.c (record_address_regs): Remove ifdef. Use
REG_MODE_OK_FOR_REG_BASE_P and MODE_BASE_REG_REG_CLASS.
* regrename.c (REG_MODE_OK_FOR_BASE_P): Remove unnecessary
definition.
(scan_rtx_address, replace_oldest_value_addr): Use
REG_MODE_OK_FOR_REG_BASE_P and MODE_BASE_REG_REG_CLASS.
* reload.c (REGNO_MODE_OK_FOR_BASE_P, REG_MODE_OK_FOR_BASE_P): Remove
unnecessary definitions.
(find_reloads_address_1): Support REG_MODE_OK_FOR_REG_BASE_P
and MODE_BASE_REG_REG_CLASS.
* config/arm/arm.h (MODE_BASE_REG_CLASS): Don't check reload_completed.
(MODE_BASE_REG_REG_CLASS): Define.
(REGNO_MODE_OK_FOR_REG_BASE_P): Define.
(REG_MODE_OK_FOR_REG_BASE_P): Define.
* doc/tm.texi (Register Classes): Document MODE_BASE_REG_REG_CLASS,
REG_MODE_OK_FOR_REG_BASE_P, and REGNO_MODE_OK_FOR_REG_BASE_P.
["patch" (text/x-diff)]
Index: gcc/defaults.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/defaults.h,v
retrieving revision 1.117.4.7
diff -u -p -r1.117.4.7 defaults.h
--- gcc/defaults.h 20 May 2005 14:46:25 -0000 1.117.4.7
+++ gcc/defaults.h 31 Aug 2005 20:34:51 -0000
@@ -549,6 +549,19 @@ You Lose! You must define PREFERRED_DEB
#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
#endif
+/* Some macros can be defined by the backend in either a mode-dependent
+ or mode-independent form. The compiler proper should only use the
+ mode-dependent form, providing VOIDmode when the mode is unknown.
+ We can't poison the macros because the backend may reference them. */
+
+#ifndef REGNO_MODE_OK_FOR_BASE_P
+#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
+#endif
+
+#ifndef REG_MODE_OK_FOR_BASE_P
+#define REG_MODE_OK_FOR_BASE_P(REG, MODE) REG_OK_FOR_BASE_P (REG)
+#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. */
@@ -556,6 +569,20 @@ You Lose! You must define PREFERRED_DEB
#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
#endif
+/* Some machines require a different base register class if the index
+ is a register. By default, assume that a base register is acceptable. */
+#ifndef MODE_BASE_REG_REG_CLASS
+#define MODE_BASE_REG_REG_CLASS(MODE) MODE_BASE_REG_CLASS(MODE)
+#endif
+
+#ifndef REGNO_MODE_OK_FOR_REG_BASE_P
+#define REGNO_MODE_OK_FOR_REG_BASE_P(REGNO, MODE) REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE)
+#endif
+
+#ifndef REG_MODE_OK_FOR_REG_BASE_P
+#define REG_MODE_OK_FOR_REG_BASE_P(REGNO, MODE) REG_MODE_OK_FOR_BASE_P (REGNO, MODE)
+#endif
+
#ifndef LARGEST_EXPONENT_IS_NORMAL
#define LARGEST_EXPONENT_IS_NORMAL(SIZE) 0
#endif
Index: gcc/regclass.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/regclass.c,v
retrieving revision 1.179.4.2
diff -u -p -r1.179.4.2 regclass.c
--- gcc/regclass.c 30 Dec 2004 22:33:36 -0000 1.179.4.2
+++ gcc/regclass.c 31 Aug 2005 20:34:51 -0000
@@ -1993,25 +1993,27 @@ record_address_regs (rtx x, enum reg_cla
record_address_regs (arg0, INDEX_REG_CLASS, scale);
/* If both operands are registers but one is already a hard register
- of index or base class, give the other the class that the hard
- register is not. */
+ of index or reg-base class, give the other the class that the
+ hard register is not. */
-#ifdef REG_OK_FOR_BASE_P
else if (code0 == REG && code1 == REG
&& REGNO (arg0) < FIRST_PSEUDO_REGISTER
- && (REG_OK_FOR_BASE_P (arg0) || REG_OK_FOR_INDEX_P (arg0)))
+ && (REG_MODE_OK_FOR_REG_BASE_P (arg0, VOIDmode)
+ || REG_OK_FOR_INDEX_P (arg0)))
record_address_regs (arg1,
- REG_OK_FOR_BASE_P (arg0)
- ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (VOIDmode),
+ REG_MODE_OK_FOR_REG_BASE_P (arg0, VOIDmode)
+ ? INDEX_REG_CLASS
+ : MODE_BASE_REG_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)))
+ && (REG_MODE_OK_FOR_REG_BASE_P (arg1, VOIDmode)
+ || REG_OK_FOR_INDEX_P (arg1)))
record_address_regs (arg0,
- REG_OK_FOR_BASE_P (arg1)
- ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (VOIDmode),
+ REG_MODE_OK_FOR_REG_BASE_P (arg1, VOIDmode)
+ ? INDEX_REG_CLASS
+ : MODE_BASE_REG_REG_CLASS (VOIDmode),
scale);
-#endif
/* 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
@@ -2020,14 +2022,16 @@ record_address_regs (rtx x, enum reg_cla
else if ((code0 == REG && REG_POINTER (arg0))
|| code1 == MULT)
{
- record_address_regs (arg0, MODE_BASE_REG_CLASS (VOIDmode), scale);
+ record_address_regs (arg0, MODE_BASE_REG_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, MODE_BASE_REG_CLASS (VOIDmode), scale);
+ record_address_regs (arg1, MODE_BASE_REG_REG_CLASS (VOIDmode),
+ scale);
}
/* Otherwise, count equal chances that each might be a base
@@ -2035,10 +2039,10 @@ record_address_regs (rtx x, enum reg_cla
else
{
- record_address_regs (arg0, MODE_BASE_REG_CLASS (VOIDmode),
+ record_address_regs (arg0, MODE_BASE_REG_REG_CLASS (VOIDmode),
scale / 2);
record_address_regs (arg0, INDEX_REG_CLASS, scale / 2);
- record_address_regs (arg1, MODE_BASE_REG_CLASS (VOIDmode),
+ record_address_regs (arg1, MODE_BASE_REG_REG_CLASS (VOIDmode),
scale / 2);
record_address_regs (arg1, INDEX_REG_CLASS, scale / 2);
}
Index: gcc/regrename.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/regrename.c,v
retrieving revision 1.69.4.4
diff -u -p -r1.69.4.4 regrename.c
--- gcc/regrename.c 20 May 2005 14:47:39 -0000 1.69.4.4
+++ gcc/regrename.c 31 Aug 2005 20:34:51 -0000
@@ -38,10 +38,6 @@
#include "toplev.h"
#include "obstack.h"
-#ifndef REG_MODE_OK_FOR_BASE_P
-#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
-#endif
-
static const char *const reg_class_names[] = REG_CLASS_NAMES;
struct du_chain
@@ -532,6 +528,7 @@ scan_rtx_address (rtx insn, rtx *loc, en
rtx op1 = orig_op1;
rtx *locI = NULL;
rtx *locB = NULL;
+ rtx *locB_reg = NULL;
if (GET_CODE (op0) == SUBREG)
{
@@ -568,14 +565,14 @@ scan_rtx_address (rtx insn, rtx *loc, en
int index_op;
if (REG_OK_FOR_INDEX_P (op0)
- && REG_MODE_OK_FOR_BASE_P (op1, mode))
+ && REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
index_op = 0;
else if (REG_OK_FOR_INDEX_P (op1)
- && REG_MODE_OK_FOR_BASE_P (op0, mode))
+ && REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
index_op = 1;
- else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
+ else if (REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
index_op = 0;
- else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
+ else if (REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
index_op = 1;
else if (REG_OK_FOR_INDEX_P (op1))
index_op = 1;
@@ -583,7 +580,7 @@ scan_rtx_address (rtx insn, rtx *loc, en
index_op = 0;
locI = &XEXP (x, index_op);
- locB = &XEXP (x, !index_op);
+ locB_reg = &XEXP (x, !index_op);
}
else if (code0 == REG)
{
@@ -600,6 +597,9 @@ scan_rtx_address (rtx insn, rtx *loc, en
scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode);
if (locB)
scan_rtx_address (insn, locB, MODE_BASE_REG_CLASS (mode), action, mode);
+ if (locB_reg)
+ scan_rtx_address (insn, locB_reg, MODE_BASE_REG_REG_CLASS (mode),
+ action, mode);
return;
}
@@ -1408,6 +1408,7 @@ replace_oldest_value_addr (rtx *loc, enu
rtx op1 = orig_op1;
rtx *locI = NULL;
rtx *locB = NULL;
+ rtx *locB_reg = NULL;
if (GET_CODE (op0) == SUBREG)
{
@@ -1444,14 +1445,14 @@ replace_oldest_value_addr (rtx *loc, enu
int index_op;
if (REG_OK_FOR_INDEX_P (op0)
- && REG_MODE_OK_FOR_BASE_P (op1, mode))
+ && REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
index_op = 0;
else if (REG_OK_FOR_INDEX_P (op1)
- && REG_MODE_OK_FOR_BASE_P (op0, mode))
+ && REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
index_op = 1;
- else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
+ else if (REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
index_op = 0;
- else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
+ else if (REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
index_op = 1;
else if (REG_OK_FOR_INDEX_P (op1))
index_op = 1;
@@ -1459,7 +1460,7 @@ replace_oldest_value_addr (rtx *loc, enu
index_op = 0;
locI = &XEXP (x, index_op);
- locB = &XEXP (x, !index_op);
+ locB_reg = &XEXP (x, !index_op);
}
else if (code0 == REG)
{
@@ -1479,6 +1480,10 @@ replace_oldest_value_addr (rtx *loc, enu
changed |= replace_oldest_value_addr (locB,
MODE_BASE_REG_CLASS (mode),
mode, insn, vd);
+ if (locB_reg)
+ changed |= replace_oldest_value_addr (locB_reg,
+ MODE_BASE_REG_REG_CLASS (mode),
+ mode, insn, vd);
return changed;
}
Index: gcc/reload.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/reload.c,v
retrieving revision 1.221.4.6
diff -u -p -r1.221.4.6 reload.c
--- gcc/reload.c 20 May 2005 14:47:42 -0000 1.221.4.6
+++ gcc/reload.c 31 Aug 2005 20:36:09 -0000
@@ -106,14 +106,6 @@ a register with any other reload. */
#include "toplev.h"
#include "params.h"
-#ifndef REGNO_MODE_OK_FOR_BASE_P
-#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
-#endif
-
-#ifndef REG_MODE_OK_FOR_BASE_P
-#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
-#endif
-
/* All reloads of the current insn are recorded here. See reload.h for
comments. */
int n_reloads;
@@ -5233,7 +5225,8 @@ update_auto_inc_notes (rtx insn ATTRIBUT
is strictly valid.)
CONTEXT = 1 means we are considering regs as index regs,
- = 0 means we are considering them as base regs.
+ = 0 means we are considering them as base regs, = 2 means we
+ are considering them as base regs for REG + REG.
OPNUM and TYPE specify the purpose of any reloads made.
@@ -5256,6 +5249,22 @@ find_reloads_address_1 (enum machine_mod
rtx *loc, int opnum, enum reload_type type,
int ind_levels, rtx insn)
{
+#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE) \
+ ((CONTEXT) == 2 \
+ ? REGNO_MODE_OK_FOR_REG_BASE_P (REGNO, MODE) \
+ : (CONTEXT) == 1 \
+ ? REGNO_OK_FOR_INDEX_P (REGNO) \
+ : REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE))
+
+ enum reg_class context_reg_class;
+
+ if (context == 2)
+ context_reg_class = MODE_BASE_REG_REG_CLASS (mode);
+ else if (context == 1)
+ context_reg_class = INDEX_REG_CLASS;
+ else
+ context_reg_class = MODE_BASE_REG_CLASS (mode);
+
RTX_CODE code = GET_CODE (x);
switch (code)
@@ -5300,12 +5309,12 @@ find_reloads_address_1 (enum machine_mod
register remateralization for expression like &localvar*4. Reload it.
It may be possible to combine the displacement on the outer level,
but it is probably not worthwhile to do so. */
- if (context)
+ if (context == 1)
{
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)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
@@ -5341,22 +5350,22 @@ find_reloads_address_1 (enum machine_mod
else if (code0 == REG && code1 == REG)
{
if (REG_OK_FOR_INDEX_P (op0)
- && REG_MODE_OK_FOR_BASE_P (op1, mode))
+ && REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
return 0;
else if (REG_OK_FOR_INDEX_P (op1)
- && REG_MODE_OK_FOR_BASE_P (op0, mode))
+ && REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
return 0;
- else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
+ else if (REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
type, ind_levels, insn);
- else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
+ else if (REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
type, ind_levels, insn);
else if (REG_OK_FOR_INDEX_P (op1))
- find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
+ find_reloads_address_1 (mode, orig_op0, 2, &XEXP (x, 0), opnum,
type, ind_levels, insn);
else if (REG_OK_FOR_INDEX_P (op0))
- find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
+ find_reloads_address_1 (mode, orig_op1, 2, &XEXP (x, 1), opnum,
type, ind_levels, insn);
else
{
@@ -5525,9 +5534,8 @@ find_reloads_address_1 (enum machine_mod
if (reg_renumber[regno] >= 0)
regno = reg_renumber[regno];
- if ((regno >= FIRST_PSEUDO_REGISTER
- || !(context ? REGNO_OK_FOR_INDEX_P (regno)
- : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
+ if (regno >= FIRST_PSEUDO_REGISTER
+ || !REG_OK_FOR_CONTEXT (context, regno, mode))
{
int reloadnum;
@@ -5563,8 +5571,7 @@ find_reloads_address_1 (enum machine_mod
x = XEXP (x, 0);
reloadnum
= push_reload (x, x, loc, loc,
- (context ? INDEX_REG_CLASS :
- MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, RELOAD_OTHER);
}
@@ -5572,8 +5579,7 @@ find_reloads_address_1 (enum machine_mod
{
reloadnum
= push_reload (x, NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS :
- MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, type);
rld[reloadnum].inc
@@ -5613,8 +5619,7 @@ find_reloads_address_1 (enum machine_mod
opnum, type, ind_levels, insn);
reloadnum = push_reload (x, NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS :
- MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
rld[reloadnum].inc
= find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
@@ -5643,7 +5648,7 @@ find_reloads_address_1 (enum machine_mod
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)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
@@ -5654,8 +5659,7 @@ find_reloads_address_1 (enum machine_mod
if (reg_equiv_constant[regno] != 0)
{
find_reloads_address_part (reg_equiv_constant[regno], loc,
- (context ? INDEX_REG_CLASS :
- MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), opnum, type, ind_levels);
return 1;
}
@@ -5665,8 +5669,7 @@ find_reloads_address_1 (enum machine_mod
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)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
@@ -5689,12 +5692,11 @@ find_reloads_address_1 (enum machine_mod
if (reg_renumber[regno] >= 0)
regno = reg_renumber[regno];
- if ((regno >= FIRST_PSEUDO_REGISTER
- || !(context ? REGNO_OK_FOR_INDEX_P (regno)
- : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
+ if (regno >= FIRST_PSEUDO_REGISTER
+ || !REG_OK_FOR_CONTEXT (context, regno, mode))
{
push_reload (x, NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
@@ -5706,7 +5708,7 @@ find_reloads_address_1 (enum machine_mod
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)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
@@ -5723,12 +5725,10 @@ find_reloads_address_1 (enum machine_mod
{
int regno ATTRIBUTE_UNUSED = subreg_regno (x);
- if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
- : REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
+ if (! REG_OK_FOR_CONTEXT (context, regno, mode))
{
push_reload (x, NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS :
- MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
@@ -5737,8 +5737,7 @@ find_reloads_address_1 (enum machine_mod
is larger than the class size, then reload the whole SUBREG. */
else
{
- enum reg_class class = (context ? INDEX_REG_CLASS
- : MODE_BASE_REG_CLASS (mode));
+ enum reg_class class = context_reg_class;
if ((unsigned) CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
> reg_class_size[class])
{
@@ -5768,6 +5767,7 @@ find_reloads_address_1 (enum machine_mod
}
}
+#undef REG_OK_FOR_CONTEXT
return 0;
}
Index: gcc/config/arm/arm.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.210.2.64
diff -u -p -r1.210.2.64 arm.h
--- gcc/config/arm/arm.h 12 Aug 2005 15:31:03 -0000 1.210.2.64
+++ gcc/config/arm/arm.h 31 Aug 2005 20:38:43 -0000
@@ -1292,13 +1292,15 @@ enum reg_class
/* For the Thumb the high registers cannot be used as base registers
when addressing quantities in QI or HI mode; if we don't know the
- mode, then we must be conservative. After reload we must also be
- conservative, since we can't support SP+reg addressing, and we
- can't fix up any bad substitutions. */
+ mode, then we must be conservative. */
#define MODE_BASE_REG_CLASS(MODE) \
(TARGET_32BIT ? GENERAL_REGS : \
- (((MODE) == SImode && !reload_completed) ? BASE_REGS : LO_REGS))
+ (((MODE) == SImode) ? BASE_REGS : LO_REGS))
+/* For Thumb we can not support SP+reg addressing, so we return LO_REGS
+ instead of BASE_REGS. */
+#define MODE_BASE_REG_REG_CLASS(MODE) BASE_REG_CLASS
+
/* 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
@@ -2157,6 +2159,11 @@ typedef struct
? THUMB1_REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE) \
: ARM_REGNO_OK_FOR_BASE_P (REGNO))
+/* Nonzero if X can be the base register in a reg+reg addressing mode.
+ For Thumb, we can not use SP + reg, so reject SP. */
+#define REGNO_MODE_OK_FOR_REG_BASE_P(X, MODE) \
+ REGNO_OK_FOR_INDEX_P (X)
+
/* For ARM code, we don't care about the mode, but for Thumb, the index
must be suitable for use in a QImode load. */
#define REGNO_OK_FOR_INDEX_P(REGNO) \
@@ -2366,6 +2373,10 @@ typedef struct
? THUMB1_REG_OK_FOR_INDEX_P (X) \
: ARM_REG_OK_FOR_INDEX_P (X))
+/* Nonzero if X can be the base register in a reg+reg addressing mode.
+ For Thumb, we can not use SP + reg, so reject SP. */
+#define REG_MODE_OK_FOR_REG_BASE_P(X, MODE) \
+ REG_OK_FOR_INDEX_P (X)
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
that is a valid memory address for an instruction.
Index: gcc/doc/tm.texi
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/doc/tm.texi,v
retrieving revision 1.264.2.29
diff -u -p -r1.264.2.29 tm.texi
--- gcc/doc/tm.texi 20 May 2005 14:52:45 -0000 1.264.2.29
+++ gcc/doc/tm.texi 31 Aug 2005 20:34:51 -0000
@@ -2400,6 +2400,13 @@ the selection of a base register in a mo
@code{BASE_REG_CLASS}.
@end defmac
+@defmac MODE_BASE_REG_REG_CLASS (@var{mode})
+A C expression whose value is the register class to which a valid
+base register must belong in order to be used in a base plus index
+register address. You should define this macro if base plus index
+addresses have different requirements than other base register uses.
+@end defmac
+
@defmac INDEX_REG_CLASS
A macro whose definition is the name of the class to which a valid
index register must belong. An index register is one used in an
@@ -2453,6 +2460,15 @@ you define this macro, the compiler will
@code{REGNO_OK_FOR_BASE_P}.
@end defmac
+@defmac REGNO_MODE_OK_FOR_REG_BASE_P (@var{num}, @var{mode})
+A C expression which is nonzero if register number @var{num} is suitable for
+use as a base register in base plus index operand addresses, accessing
+memory in mode @var{mode}. It may be either a suitable hard register or a
+pseudo register that has been allocated such a hard register. You should
+define this macro if base plus index addresses have different requirements
+than other base register uses.
+@end defmac
+
@defmac REGNO_OK_FOR_INDEX_P (@var{num})
A C expression which is nonzero if register number @var{num} is
suitable for use as an index register in operand addresses. It may be
@@ -5001,6 +5017,15 @@ you define this macro, the compiler will
@code{REG_OK_FOR_BASE_P}.
@end defmac
+@defmac REG_MODE_OK_FOR_REG_BASE_P (@var{x}, @var{mode})
+A C expression which is nonzero if @var{x} (assumed to be a @code{reg} RTX)
+is suitable for use as a base register in base plus index operand addresses,
+accessing memory in mode @var{mode}. It may be either a suitable hard
+register or a pseudo register that has been allocated such a hard register.
+You should define this macro if base plus index addresses have different
+requirements than other base register uses.
+@end defmac
+
@defmac REG_OK_FOR_INDEX_P (@var{x})
A C expression that is nonzero if @var{x} (assumed to be a @code{reg}
RTX) is valid for use as an index register.
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic