mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-24 05:18:55 +08:00
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:
parent
b2e4f4fda7
commit
8ed8f73189
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user