#define REG_STACK_SIZE (LAST_STACK_REG - FIRST_STACK_REG + 1)
+int regstack_completed = 0;
+
/* This is the basic stack record. TOP is an index into REG[] such
that REG[TOP] is the top of stack. If TOP is -1 the stack is empty.
if (!note)
{
rtx t = *dest;
- if (get_hard_regnum (regstack, t) == -1)
- control_flow_insn_deleted
- |= move_nan_for_stack_reg (insn, regstack, t);
if (COMPLEX_MODE_P (GET_MODE (t)))
{
- t = FP_MODE_REG (REGNO (t) + 1, DFmode);
- if (get_hard_regnum (regstack, t) == -1)
- control_flow_insn_deleted
- |= move_nan_for_stack_reg (insn, regstack, t);
+ rtx u = FP_MODE_REG (REGNO (t) + 1, SFmode);
+ if (get_hard_regnum (regstack, u) == -1)
+ {
+ rtx pat2 = gen_rtx_CLOBBER (VOIDmode, u);
+ rtx insn2 = emit_insn_before (pat2, insn);
+ control_flow_insn_deleted
+ |= move_nan_for_stack_reg (insn2, regstack, u);
+ }
}
+ if (get_hard_regnum (regstack, t) == -1)
+ control_flow_insn_deleted
+ |= move_nan_for_stack_reg (insn, regstack, t);
}
}
}
/* Push the result back onto stack. Empty stack slot
will be filled in second part of insn. */
- if (STACK_REG_P (*dest)) {
- regstack->reg[regstack->top] = REGNO (*dest);
- SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
- replace_reg (dest, FIRST_STACK_REG);
- }
+ if (STACK_REG_P (*dest))
+ {
+ regstack->reg[regstack->top] = REGNO (*dest);
+ SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+ replace_reg (dest, FIRST_STACK_REG);
+ }
replace_reg (src1, FIRST_STACK_REG);
replace_reg (src2, FIRST_STACK_REG + 1);
/* Push the result back onto stack. Fill empty slot from
first part of insn and fix top of stack pointer. */
- if (STACK_REG_P (*dest)) {
- regstack->reg[regstack->top - 1] = REGNO (*dest);
- SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
- replace_reg (dest, FIRST_STACK_REG + 1);
- }
+ if (STACK_REG_P (*dest))
+ {
+ regstack->reg[regstack->top - 1] = REGNO (*dest);
+ SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+ replace_reg (dest, FIRST_STACK_REG + 1);
+ }
replace_reg (src1, FIRST_STACK_REG);
replace_reg (src2, FIRST_STACK_REG + 1);
/* Push the result back onto stack. Empty stack slot
will be filled in second part of insn. */
- if (STACK_REG_P (*dest)) {
- regstack->reg[regstack->top + 1] = REGNO (*dest);
- SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
- replace_reg (dest, FIRST_STACK_REG);
- }
+ if (STACK_REG_P (*dest))
+ {
+ regstack->reg[regstack->top + 1] = REGNO (*dest);
+ SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+ replace_reg (dest, FIRST_STACK_REG);
+ }
replace_reg (src1, FIRST_STACK_REG);
break;
/* Push the result back onto stack. Fill empty slot from
first part of insn and fix top of stack pointer. */
- if (STACK_REG_P (*dest)) {
- regstack->reg[regstack->top] = REGNO (*dest);
- SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
- replace_reg (dest, FIRST_STACK_REG + 1);
+ if (STACK_REG_P (*dest))
+ {
+ regstack->reg[regstack->top] = REGNO (*dest);
+ SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+ replace_reg (dest, FIRST_STACK_REG + 1);
- regstack->top++;
- }
+ regstack->top++;
+ }
replace_reg (src1, FIRST_STACK_REG);
break;
if (NOTE_P (insn) || INSN_DELETED_P (insn))
return control_flow_insn_deleted;
+ /* If this a noreturn call, we can't insert pop insns after it.
+ Instead, reset the stack state to empty. */
+ if (CALL_P (insn)
+ && find_reg_note (insn, REG_NORETURN, NULL))
+ {
+ regstack->top = -1;
+ CLEAR_HARD_REG_SET (regstack->reg_set);
+ return control_flow_insn_deleted;
+ }
+
/* If there is a REG_UNUSED note on a stack register on this insn,
the indicated reg must be popped. The REG_UNUSED note is removed,
since the form of the newly emitted pop insn references the reg,
#ifdef STACK_REGS
if (reg_to_stack () && optimize)
{
+ regstack_completed = 1;
if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
| (flag_crossjumping ? CLEANUP_CROSSJUMP : 0))
&& (flag_reorder_blocks || flag_reorder_blocks_and_partition))
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
}
}
+ else
+ regstack_completed = 1;
#endif
return 0;
}