#include "hard-reg-set.h"
#include "flags.h"
#include "insn-flags.h"
+#include "toplev.h"
#ifdef STACK_REGS
static void mark_regs_pat PROTO((rtx, HARD_REG_SET *));
static void straighten_stack PROTO((rtx, stack));
+static void pop_stack PROTO((stack, int));
static void record_label_references PROTO((rtx, rtx));
static rtx *get_true_reg PROTO((rtx *));
static int constrain_asm_operands PROTO((int, rtx *, char **, int *,
already guaranteed that all operands have the same number of
alternatives. */
- n_alternatives = 1;
- for (q = constraints[0]; *q; q++)
- n_alternatives += (*q == ',');
+ if (n_operands == 0)
+ n_alternatives = 0;
+ else
+ {
+ n_alternatives = 1;
+ for (q = constraints[0]; *q; q++)
+ n_alternatives += (*q == ',');
+ }
this_alternative = 0;
while (this_alternative < n_alternatives)
case IF_THEN_ELSE:
/* This insn requires the top of stack to be the destination. */
+ /* 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])
+ emit_swap_insn (insn, regstack, *dest);
+
src1 = get_true_reg (&XEXP (SET_SRC (pat), 1));
src2 = get_true_reg (&XEXP (SET_SRC (pat), 2));
subst_stack_regs (insn, ®stack);
} while (insn != block_end[block]);
+
+ /* For all further actions, INSN needs to be the last insn in
+ this basic block. If subst_stack_regs inserted additional
+ instructions after INSN, it is no longer the last one at
+ this point. */
+ next = PREV_INSN (next);
+
+ /* If subst_stack_regs inserted something after a JUMP_INSN, that
+ is almost certainly a bug. */
+ if (GET_CODE (insn) == JUMP_INSN && insn != next)
+ abort ();
+ insn = next;
/* Something failed if the stack life doesn't match. */