PATCH:[darwin] fix load of a misaligned double word
Alan Modra
amodra@bigpond.net.au
Sat Feb 21 13:45:00 GMT 2004
On Fri, Feb 20, 2004 at 03:32:40PM +1030, Alan Modra wrote:
> To figure out whether we are using a gpr or not requires passing the
> insn to LEGITIMIZE_RELOAD_ADDRESS. Would such a patch be acceptable?
Like so. Patch against hammer branch, and obviously I need to update
all the other target defines of LEGITIMIZE_RELOAD_ADDRESS. Either that
or use a special invocation for rs6000..
* reload.c (find_reloads_address): Pass insn to
LEGITIMIZE_RELOAD_ADDRESS.
* config/rs6000/rs6000.c (gpr_load_or_store): New function.
(rs6000_legitimize_reload_address): Replace unused "ind_levels" arg
with "insn". Don't attempt to handle loads or stores of gprs
using non multiple of four offsets.
* config/rs6000/rs6000-protos.h (rs6000_legitimize_reload_address):
Update prototype.
* config/rs6000/rs6000.h (LEGITIMIZE_RELOAD_ADDRESS): Adjust.
Bootstrap in progress.
Index: gcc/reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.197.2.13
diff -u -p -r1.197.2.13 reload.c
--- gcc/reload.c 30 Jan 2004 20:38:53 -0000 1.197.2.13
+++ gcc/reload.c 20 Feb 2004 08:15:13 -0000
@@ -4797,7 +4797,7 @@ find_reloads_address (mode, memrefloc, a
if (memrefloc)
{
LEGITIMIZE_RELOAD_ADDRESS (ad, GET_MODE (*memrefloc), opnum, type,
- ind_levels, win);
+ ind_levels, insn, win);
}
break;
win:
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.47.2.8
diff -u -p -r1.47.2.8 rs6000-protos.h
--- gcc/config/rs6000/rs6000-protos.h 6 Feb 2004 08:35:52 -0000 1.47.2.8
+++ gcc/config/rs6000/rs6000-protos.h 20 Feb 2004 08:15:15 -0000
@@ -133,7 +133,7 @@ extern void rs6000_split_multireg_move (
extern void rs6000_emit_move PARAMS ((rtx, rtx, enum machine_mode));
extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
extern rtx rs6000_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
- int, int, int, int *));
+ int, int, rtx, int *));
extern int rs6000_legitimate_address PARAMS ((enum machine_mode, rtx, int));
extern bool rs6000_mode_dependent_address PARAMS ((rtx));
extern rtx rs6000_return_addr PARAMS ((int, rtx));
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.397.2.30
diff -u -p -r1.397.2.30 rs6000.c
--- gcc/config/rs6000/rs6000.c 12 Feb 2004 13:25:06 -0000 1.397.2.30
+++ gcc/config/rs6000/rs6000.c 20 Feb 2004 08:15:24 -0000
@@ -3120,6 +3120,55 @@ rs6000_tls_symbol_ref_1 (x, data)
return tls_symbolic_operand_type (*x);
}
+/* Return true if PAT, which contains a memref using AD as an address,
+ is loading or storing a gpr with that particular memref. */
+
+static bool
+gpr_load_or_store (rtx pat, rtx ad)
+{
+ if (GET_CODE (pat) == SET)
+ {
+ rtx reg, mem;
+ int regno;
+
+ if (GET_CODE (XEXP (pat, 0)) == MEM)
+ {
+ mem = XEXP (pat, 0);
+ reg = XEXP (pat, 1);
+ }
+ else if (GET_CODE (XEXP (pat, 1)) == MEM)
+ {
+ mem = XEXP (pat, 1);
+ reg = XEXP (pat, 0);
+ }
+ else
+ return false;
+
+ if (XEXP (mem, 0) != ad)
+ return false;
+
+ if (GET_CODE (reg) == REG)
+ regno = REGNO (reg);
+ else if (GET_CODE (reg) == SUBREG)
+ regno = REGNO (SUBREG_REG (reg));
+ else
+ return false;
+
+ return INT_REGNO_P (regno);
+ }
+
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ int i = XVECLEN (pat, 0);
+
+ while (--i >= 0)
+ if (gpr_load_or_store (XVECEXP (pat, 0, i), ad))
+ return true;
+ }
+
+ return false;
+}
+
/* The convention appears to be to define this wherever it is used.
With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
is now used here. */
@@ -3141,12 +3190,12 @@ rs6000_tls_symbol_ref_1 (x, data)
The Darwin code is inside #if TARGET_MACHO because only then is
machopic_function_base_name() defined. */
rtx
-rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
+rs6000_legitimize_reload_address (x, mode, opnum, type, insn, win)
rtx x;
enum machine_mode mode;
int opnum;
int type;
- int ind_levels ATTRIBUTE_UNUSED;
+ rtx insn;
int *win;
{
/* We must recognize output that we have already generated ourselves. */
@@ -3197,8 +3246,18 @@ rs6000_legitimize_reload_address (x, mod
HOST_WIDE_INT high
= (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
- /* Check for 32-bit overflow. */
- if (high + low != val)
+ /* We get here for two reasons: a) The offset is too large,
+ or b) the offset is invalid, for example, not a multiple of
+ 4 on a DImode access. Leave case b, and when we get 32-bit
+ overflow, to the generic parts of reload to handle. */
+
+ if (high + low != val
+ || high == 0
+ || ((low & 3) != 0
+ && GET_MODE_SIZE (mode) >= 8
+ && TARGET_POWERPC64
+ && insn != 0
+ && gpr_load_or_store (PATTERN (insn), x)))
{
*win = 0;
return x;
Index: gcc/config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.234.2.23
diff -u -p -r1.234.2.23 rs6000.h
--- gcc/config/rs6000/rs6000.h 15 Feb 2004 12:57:15 -0000 1.234.2.23
+++ gcc/config/rs6000/rs6000.h 20 Feb 2004 08:15:26 -0000
@@ -2150,12 +2150,12 @@ typedef struct rs6000_args
Implemented on rs6000 by rs6000_legitimize_reload_address.
Note that (X) is evaluated twice; this is safe in current usage. */
-#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
+#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,INSN,WIN) \
do { \
int win; \
(X) = rs6000_legitimize_reload_address ((X), (MODE), (OPNUM), \
- (int)(TYPE), (IND_LEVELS), &win); \
- if ( win ) \
+ (int) (TYPE), (INSN), &win); \
+ if (win) \
goto WIN; \
} while (0)
--
Alan Modra
IBM OzLabs - Linux Technology Centre
More information about the Gcc-patches
mailing list