+ swap_to_top (insn, regstack, *src1, *src2);
+
+ /* 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);
+ }
+
+ replace_reg (src1, FIRST_STACK_REG);
+ replace_reg (src2, FIRST_STACK_REG + 1);
+ break;
+
+ case UNSPEC_SINCOS_COS:
+ case UNSPEC_TAN_ONE:
+ case UNSPEC_XTRACT_FRACT:
+ /* These insns operate on the top two stack slots,
+ first part of one input, double output insn. */
+
+ src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
+
+ emit_swap_insn (insn, regstack, *src1);
+
+ /* Input should never die, it is
+ replaced with output. */
+ src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+ gcc_assert (!src1_note);
+
+ /* 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);
+ }
+
+ replace_reg (src1, FIRST_STACK_REG);
+ break;
+
+ case UNSPEC_SINCOS_SIN:
+ case UNSPEC_TAN_TAN:
+ case UNSPEC_XTRACT_EXP:
+ /* These insns operate on the top two stack slots,
+ second part of one input, double output insn. */
+
+ src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
+
+ emit_swap_insn (insn, regstack, *src1);
+
+ /* Input should never die, it is
+ replaced with output. */
+ src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+ gcc_assert (!src1_note);
+
+ /* 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);
+
+ regstack->top++;
+ }
+
+ replace_reg (src1, FIRST_STACK_REG);
+ break;
+
+ case UNSPEC_SAHF:
+ /* (unspec [(unspec [(compare)] UNSPEC_FNSTSW)] UNSPEC_SAHF)
+ The combination matches the PPRO fcomi instruction. */
+
+ pat_src = XVECEXP (pat_src, 0, 0);
+ gcc_assert (GET_CODE (pat_src) == UNSPEC);
+ gcc_assert (XINT (pat_src, 1) == UNSPEC_FNSTSW);
+ /* Fall through. */
+
+ case UNSPEC_FNSTSW:
+ /* Combined fcomp+fnstsw generated for doing well with
+ CSE. When optimizing this would have been broken
+ up before now. */
+
+ pat_src = XVECEXP (pat_src, 0, 0);
+ gcc_assert (GET_CODE (pat_src) == COMPARE);
+
+ compare_for_stack_reg (insn, regstack, pat_src);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ break;
+
+ case IF_THEN_ELSE:
+ /* This insn requires the top of stack to be the destination. */
+
+ src1 = get_true_reg (&XEXP (pat_src, 1));
+ src2 = get_true_reg (&XEXP (pat_src, 2));
+
+ src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+ src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
+
+ /* If the comparison operator is an FP comparison operator,
+ it is handled correctly by compare_for_stack_reg () who
+ will move the destination to the top of stack. But if the
+ comparison operator is not an FP comparison operator, we
+ have to handle it here. */
+ if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG
+ && REGNO (*dest) != regstack->reg[regstack->top])
+ {
+ /* In case one of operands is the top of stack and the operands
+ dies, it is safe to make it the destination operand by
+ reversing the direction of cmove and avoid fxch. */
+ if ((REGNO (*src1) == regstack->reg[regstack->top]