summaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1996-06-08 13:49:13 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1996-06-08 13:49:13 -0400
commit0e09cc26eee23001577e0851562172fa92cb1a53 (patch)
tree479cd63556d7ce770fccffb8e5dd5e186d9e50d8 /gcc/function.c
parentd5a1d1c7584b6b0adb0ba959b61e54693b96bd3e (diff)
downloadgcc-0e09cc26eee23001577e0851562172fa92cb1a53.tar.gz
(fixup_var_refs_1, case SIGN_EXTEND): Handle paradoxical SUBREGs as first operand.
(fixup_var_refs_1, case SIGN_EXTEND): Handle paradoxical SUBREGs as first operand. (fixup_var_regs_1, case SET): Handle paradoxical SUBREGs as first operand of a ZERO_EXTRACT in SET_DEST. From-SVN: r12243
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/gcc/function.c b/gcc/function.c
index e4d73d0b1bb..27a01c1aea5 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -1755,8 +1755,20 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
tem = XEXP (x, 0);
if (GET_CODE (tem) == SUBREG)
- tem = fixup_memory_subreg (tem, insn, 1);
- tem = fixup_stack_1 (tem, insn);
+ {
+ if (GET_MODE_BITSIZE (GET_MODE (tem))
+ > GET_MODE_BITSIZE (GET_MODE (var)))
+ {
+ replacement = find_fixup_replacement (replacements, var);
+ if (replacement->new == 0)
+ replacement->new = gen_reg_rtx (GET_MODE (var));
+ SUBREG_REG (tem) = replacement->new;
+ }
+
+ tem = fixup_memory_subreg (tem, insn, 0);
+ }
+ else
+ tem = fixup_stack_1 (tem, insn);
/* Unless we want to load from memory, get TEM into the proper mode
for an extract from memory. This can only be done if the
@@ -1885,6 +1897,22 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
|| GET_CODE (SET_SRC (x)) == ZERO_EXTRACT)
optimize_bit_field (x, insn, NULL_PTR);
+ /* For a paradoxical SUBREG inside a ZERO_EXTRACT, load the object
+ into a register and then store it back out. */
+ if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
+ && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG
+ && SUBREG_REG (XEXP (SET_DEST (x), 0)) == var
+ && (GET_MODE_SIZE (GET_MODE (XEXP (SET_DEST (x), 0)))
+ > GET_MODE_SIZE (GET_MODE (var))))
+ {
+ replacement = find_fixup_replacement (replacements, var);
+ if (replacement->new == 0)
+ replacement->new = gen_reg_rtx (GET_MODE (var));
+
+ SUBREG_REG (XEXP (SET_DEST (x), 0)) = replacement->new;
+ emit_insn_after (gen_move_insn (var, replacement->new), insn);
+ }
+
/* If SET_DEST is now a paradoxical SUBREG, put the result of this
insn into a pseudo and store the low part of the pseudo into VAR. */
if (GET_CODE (SET_DEST (x)) == SUBREG
@@ -1940,7 +1968,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
This was legitimate when the MEM was a REG. */
if (GET_CODE (tem) == SUBREG
&& SUBREG_REG (tem) == var)
- tem = fixup_memory_subreg (tem, insn, 1);
+ tem = fixup_memory_subreg (tem, insn, 0);
else
tem = fixup_stack_1 (tem, insn);
@@ -2158,7 +2186,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
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 of ZERO_EXTRACTs and in REG_NOTES. */
+ This is used for subregs found inside REG_NOTES. */
static rtx
fixup_memory_subreg (x, insn, uncritical)