Commit 8ed8f731 by Mark Mitchell Committed by Mark Mitchell

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