re PR fortran/6138 (Incorrect access of integer*1 variables on PA)

PR f/6138.
	* function.c (fixup_memory_subreg): Add promoted_mode parameter.
	(walk_fixup_memory_subreg): Likewise.
	(fixup_var_refs_insn): Adjust accordingly.
	(fixup_var_refs_1): Likewise.

From-SVN: r52631
This commit is contained in:
Mark Mitchell 2002-04-22 19:26:19 +00:00 committed by Mark Mitchell
parent b2e4f4fda7
commit 8ed8f73189
2 changed files with 62 additions and 30 deletions

View File

@ -1,3 +1,11 @@
2002-04-21 Mark Mitchell <mark@codesourcery.com>
PR f/6138.
* function.c (fixup_memory_subreg): Add promoted_mode parameter.
(walk_fixup_memory_subreg): Likewise.
(fixup_var_refs_insn): Adjust accordingly.
(fixup_var_refs_1): Likewise.
2002-04-22 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/linux.h: (LIBPATH_SPEC, LIBPATH_ARCH31_SPEC,

View File

@ -246,8 +246,9 @@ static void fixup_var_refs_insn PARAMS ((rtx, rtx, enum machine_mode,
int, int, rtx));
static void fixup_var_refs_1 PARAMS ((rtx, enum machine_mode, rtx *, rtx,
struct fixup_replacement **, rtx));
static rtx fixup_memory_subreg PARAMS ((rtx, rtx, int));
static rtx walk_fixup_memory_subreg PARAMS ((rtx, rtx, int));
static rtx fixup_memory_subreg PARAMS ((rtx, rtx, enum machine_mode, int));
static rtx walk_fixup_memory_subreg PARAMS ((rtx, rtx, enum machine_mode,
int));
static rtx fixup_stack_1 PARAMS ((rtx, rtx));
static void optimize_bit_field PARAMS ((rtx, rtx, rtx *));
static void instantiate_decls PARAMS ((tree, int));
@ -1859,7 +1860,8 @@ fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel, no_share)
/* OLD might be a (subreg (mem)). */
if (GET_CODE (replacements->old) == SUBREG)
replacements->old
= fixup_memory_subreg (replacements->old, insn, 0);
= fixup_memory_subreg (replacements->old, insn,
promoted_mode, 0);
else
replacements->old
= fixup_stack_1 (replacements->old, insn);
@ -1899,7 +1901,8 @@ fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel, no_share)
{
if (GET_CODE (note) != INSN_LIST)
XEXP (note, 0)
= walk_fixup_memory_subreg (XEXP (note, 0), insn, 1);
= walk_fixup_memory_subreg (XEXP (note, 0), insn,
promoted_mode, 1);
note = XEXP (note, 1);
}
}
@ -2070,7 +2073,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
return;
}
else
tem = fixup_memory_subreg (tem, insn, 0);
tem = fixup_memory_subreg (tem, insn, promoted_mode, 0);
}
else
tem = fixup_stack_1 (tem, insn);
@ -2185,7 +2188,8 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
return;
}
replacement->new = *loc = fixup_memory_subreg (x, insn, 0);
replacement->new = *loc = fixup_memory_subreg (x, insn,
promoted_mode, 0);
INSN_CODE (insn) = -1;
if (! flag_force_mem && recog_memoized (insn) >= 0)
@ -2276,7 +2280,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
This was legitimate when the MEM was a REG. */
if (GET_CODE (tem) == SUBREG
&& SUBREG_REG (tem) == var)
tem = fixup_memory_subreg (tem, insn, 0);
tem = fixup_memory_subreg (tem, insn, promoted_mode, 0);
else
tem = fixup_stack_1 (tem, insn);
@ -2378,7 +2382,8 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
SET_SRC (x) = replacement->new;
else if (GET_CODE (SET_SRC (x)) == SUBREG)
SET_SRC (x) = replacement->new
= fixup_memory_subreg (SET_SRC (x), insn, 0);
= fixup_memory_subreg (SET_SRC (x), insn, promoted_mode,
0);
else
SET_SRC (x) = replacement->new
= fixup_stack_1 (SET_SRC (x), insn);
@ -2431,7 +2436,8 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
rtx pat, last;
if (GET_CODE (SET_DEST (x)) == SUBREG)
SET_DEST (x) = fixup_memory_subreg (SET_DEST (x), insn, 0);
SET_DEST (x) = fixup_memory_subreg (SET_DEST (x), insn,
promoted_mode, 0);
else
SET_DEST (x) = fixup_stack_1 (SET_DEST (x), insn);
@ -2476,6 +2482,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
{
rtx temp;
rtx fixeddest = SET_DEST (x);
enum machine_mode temp_mode;
/* STRICT_LOW_PART can be discarded, around a MEM. */
if (GET_CODE (fixeddest) == STRICT_LOW_PART)
@ -2483,13 +2490,17 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
/* Convert (SUBREG (MEM)) to a MEM in a changed mode. */
if (GET_CODE (fixeddest) == SUBREG)
{
fixeddest = fixup_memory_subreg (fixeddest, insn, 0);
promoted_mode = GET_MODE (fixeddest);
fixeddest = fixup_memory_subreg (fixeddest, insn,
promoted_mode, 0);
temp_mode = GET_MODE (fixeddest);
}
else
{
fixeddest = fixup_stack_1 (fixeddest, insn);
temp_mode = promoted_mode;
}
temp = gen_reg_rtx (promoted_mode);
temp = gen_reg_rtx (temp_mode);
emit_insn_after (gen_move_insn (fixeddest,
gen_lowpart (GET_MODE (fixeddest),
@ -2522,36 +2533,47 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
}
}
/* Given X, an rtx of the form (SUBREG:m1 (MEM:m2 addr)),
return an rtx (MEM:m1 newaddr) which is equivalent.
If any insns must be emitted to compute NEWADDR, put them before INSN.
/* Previously, X had the form (SUBREG:m1 (REG:PROMOTED_MODE ...)).
The REG was placed on the stack, so X now has the form (SUBREG:m1
(MEM:m2 ...)).
Return an rtx (MEM:m1 newaddr) which is equivalent. If any insns
must be emitted to compute NEWADDR, put them before INSN.
UNCRITICAL nonzero means accept paradoxical subregs.
This is used for subregs found inside REG_NOTES. */
static rtx
fixup_memory_subreg (x, insn, uncritical)
fixup_memory_subreg (x, insn, promoted_mode, uncritical)
rtx x;
rtx insn;
enum machine_mode promoted_mode;
int uncritical;
{
int offset = SUBREG_BYTE (x);
rtx addr = XEXP (SUBREG_REG (x), 0);
int offset;
rtx mem = SUBREG_REG (x);
rtx addr = XEXP (mem, 0);
enum machine_mode mode = GET_MODE (x);
rtx result;
/* Paradoxical SUBREGs are usually invalid during RTL generation. */
if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
&& ! uncritical)
if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (mem)) && ! uncritical)
abort ();
offset = SUBREG_BYTE (x);
if (BYTES_BIG_ENDIAN)
/* If the PROMOTED_MODE is wider than the mode of the MEM, adjust
the offset so that it points to the right location within the
MEM. */
offset -= (GET_MODE_SIZE (promoted_mode) - GET_MODE_SIZE (GET_MODE (mem)));
if (!flag_force_addr
&& memory_address_p (mode, plus_constant (addr, offset)))
/* Shortcut if no insns need be emitted. */
return adjust_address (SUBREG_REG (x), mode, offset);
return adjust_address (mem, mode, offset);
start_sequence ();
result = adjust_address (SUBREG_REG (x), mode, offset);
result = adjust_address (mem, mode, offset);
emit_insn_before (gen_sequence (), insn);
end_sequence ();
return result;
@ -2562,14 +2584,14 @@ fixup_memory_subreg (x, insn, uncritical)
If X itself is a (SUBREG (MEM ...) ...), return the replacement expression.
Otherwise return X, with its contents possibly altered.
If any insns must be emitted to compute NEWADDR, put them before INSN.
UNCRITICAL is as in fixup_memory_subreg. */
INSN, PROMOTED_MODE and UNCRITICAL are as for
fixup_memory_subreg. */
static rtx
walk_fixup_memory_subreg (x, insn, uncritical)
walk_fixup_memory_subreg (x, insn, promoted_mode, uncritical)
rtx x;
rtx insn;
enum machine_mode promoted_mode;
int uncritical;
{
enum rtx_code code;
@ -2582,7 +2604,7 @@ walk_fixup_memory_subreg (x, insn, uncritical)
code = GET_CODE (x);
if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM)
return fixup_memory_subreg (x, insn, uncritical);
return fixup_memory_subreg (x, insn, promoted_mode, uncritical);
/* Nothing special about this RTX; fix its operands. */
@ -2590,13 +2612,15 @@ walk_fixup_memory_subreg (x, insn, uncritical)
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
XEXP (x, i) = walk_fixup_memory_subreg (XEXP (x, i), insn, uncritical);
XEXP (x, i) = walk_fixup_memory_subreg (XEXP (x, i), insn,
promoted_mode, uncritical);
else if (fmt[i] == 'E')
{
int j;
for (j = 0; j < XVECLEN (x, i); j++)
XVECEXP (x, i, j)
= walk_fixup_memory_subreg (XVECEXP (x, i, j), insn, uncritical);
= walk_fixup_memory_subreg (XVECEXP (x, i, j), insn,
promoted_mode, uncritical);
}
}
return x;