+Fri Sep 11 23:55:54 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
+
+ * flow.c (mark_set_1): Recognize multi-register structure return
+ values in CALL insns.
+ (mark_used_regs): Likewise.
+ (count_reg_sets_1): Likewise.
+ (count_reg_references): Likewise.
+ * rtlanal.c (note_stores): Likewise.
+
Fri Sep 11 22:57:55 1998 Eric Dumazet <dumazet@cosmosbay.com>
* config/i386/sco5.h (ASM_WEAKEN_LABEL): Defined as in svr4.h.
register int regno;
register rtx reg = SET_DEST (x);
+ /* Some targets place small structures in registers for
+ return values of functions. We have to detect this
+ case specially here to get correct flow information. */
+ if (GET_CODE (reg) == PARALLEL
+ && GET_MODE (reg) == BLKmode)
+ {
+ register int i;
+
+ for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
+ mark_set_1 (needed, dead, XVECEXP (reg, 0, i), insn, significant);
+ return;
+ }
+
/* Modifying just one hardware register of a multi-reg value
or just a byte field of a register
does not mean the value from before this insn is now dead.
/* If this is a store into a register,
recursively scan the value being stored. */
- if (GET_CODE (testreg) == REG
- && (regno = REGNO (testreg), regno != FRAME_POINTER_REGNUM)
+ if ((GET_CODE (testreg) == PARALLEL
+ && GET_MODE (testreg) == BLKmode)
+ || (GET_CODE (testreg) == REG
+ && (regno = REGNO (testreg), regno != FRAME_POINTER_REGNUM)
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
- && regno != HARD_FRAME_POINTER_REGNUM
+ && regno != HARD_FRAME_POINTER_REGNUM
#endif
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
+ && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
#endif
- )
+ ))
/* We used to exclude global_regs here, but that seems wrong.
Storing in them is like storing in mem. */
{
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
+ if (GET_CODE (reg) == PARALLEL
+ && GET_MODE (reg) == BLKmode)
+ {
+ register int i;
+ for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
+ count_reg_sets_1 (XVECEXP (reg, 0, i));
+ return;
+ }
+
if (GET_CODE (reg) == REG)
{
regno = REGNO (reg);
/* If this is a store into a register,
recursively scan the value being stored. */
- if (GET_CODE (testreg) == REG)
+ if ((GET_CODE (testreg) == PARALLEL
+ && GET_MODE (testreg) == BLKmode)
+ || GET_CODE (testreg) == REG)
{
count_reg_references (SET_SRC (x));
if (mark_dest)
|| GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
- (*fun) (dest, x);
+
+ if (GET_CODE (dest) == PARALLEL
+ && GET_MODE (dest) == BLKmode)
+ {
+ register int i;
+ for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
+ (*fun) (SET_DEST (XVECEXP (dest, 0, i)), x);
+ }
+ else
+ (*fun) (dest, x);
}
else if (GET_CODE (x) == PARALLEL)
{
|| GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
- (*fun) (dest, y);
+ if (GET_CODE (dest) == PARALLEL
+ && GET_MODE (dest) == BLKmode)
+ {
+ register int i;
+ for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
+ (*fun) (SET_DEST (XVECEXP (dest, 0, i)), y);
+ }
+ else
+ (*fun) (dest, y);
}
}
}