#endif /* FORBIDDEN_INC_DEC_CLASSES */
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+
+/* These are the classes containing only registers that can be used in
+ a SUBREG expression that changes the size of the register. */
+
+static int class_can_change_size[N_REG_CLASSES];
+
+/* Registers, including pseudos, which change size. */
+
+static regset reg_changes_size;
+
+#endif /* CLASS_CANNOT_CHANGE_SIZE */
+
#ifdef HAVE_SECONDARY_RELOADS
/* Sample MEM values for use by memory_move_secondary_cost. */
else
may_move_out_cost[i][j] = cost;
}
+
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+ {
+ HARD_REG_SET c;
+ COMPL_HARD_REG_SET (c, reg_class_contents[CLASS_CANNOT_CHANGE_SIZE]);
+
+ for (i = 0; i < N_REG_CLASSES; i++)
+ {
+ GO_IF_HARD_REG_SUBSET (reg_class_contents[i], c, ok_class);
+ class_can_change_size [i] = 0;
+ continue;
+ ok_class:
+ class_can_change_size [i] = 1;
+ }
+ }
+#endif /* CLASS_CANNOT_CHANGE_SIZE */
}
/* Compute the table of register modes.
static void record_operand_costs PARAMS ((rtx, struct costs *, struct reg_pref *));
static void dump_regclass PARAMS ((FILE *));
static void record_reg_classes PARAMS ((int, int, rtx *, enum machine_mode *,
- char *, const char **, rtx,
+ const char **, rtx,
struct costs *, struct reg_pref *));
static int copy_cost PARAMS ((rtx, enum machine_mode,
enum reg_class, int));
{
const char *constraints[MAX_RECOG_OPERANDS];
enum machine_mode modes[MAX_RECOG_OPERANDS];
- char subreg_changes_size[MAX_RECOG_OPERANDS];
int i;
for (i = 0; i < recog_data.n_operands; i++)
constraints[i] = recog_data.constraints[i];
modes[i] = recog_data.operand_mode[i];
}
- memset (subreg_changes_size, 0, sizeof (subreg_changes_size));
/* If we get here, we are set up to record the costs of all the
operands for this insn. Start by initializing the costs.
if (GET_CODE (recog_data.operand[i]) == SUBREG)
{
rtx inner = SUBREG_REG (recog_data.operand[i]);
- if (GET_MODE_SIZE (modes[i]) != GET_MODE_SIZE (GET_MODE (inner)))
- subreg_changes_size[i] = 1;
+ if (GET_MODE_SIZE (modes[i]) != GET_MODE_SIZE (GET_MODE (inner))
+ && GET_CODE (inner) == REG)
+ SET_REGNO_REG_SET (reg_changes_size, REGNO (inner));
recog_data.operand[i] = inner;
}
xconstraints[i] = constraints[i+1];
xconstraints[i+1] = constraints[i];
record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
- recog_data.operand, modes, subreg_changes_size,
+ recog_data.operand, modes,
xconstraints, insn, op_costs, reg_pref);
}
record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
- recog_data.operand, modes, subreg_changes_size,
+ recog_data.operand, modes,
constraints, insn, op_costs, reg_pref);
}
\f
costs = (struct costs *) xmalloc (nregs * sizeof (struct costs));
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+ reg_changes_size = BITMAP_XMALLOC();
+#endif
+
#ifdef FORBIDDEN_INC_DEC_CLASSES
in_inc_dec = (char *) xmalloc (nregs);
#ifdef FORBIDDEN_INC_DEC_CLASSES
|| (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+ || (REGNO_REG_SET_P (reg_changes_size, i)
+ && ! class_can_change_size [class])
+#endif
)
;
else if (p->cost[class] < best_cost)
#ifdef FORBIDDEN_INC_DEC_CLASSES
&& ! (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+ && ! (REGNO_REG_SET_P (reg_changes_size, i)
+ && ! class_can_change_size [class])
+#endif
)
alt = reg_class_subunion[(int) alt][class];
#ifdef FORBIDDEN_INC_DEC_CLASSES
free (in_inc_dec);
#endif
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+ BITMAP_XFREE (reg_changes_size);
+#endif
free (costs);
}
\f
alternatives. */
static void
-record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
+record_reg_classes (n_alts, n_ops, ops, modes,
constraints, insn, op_costs, reg_pref)
int n_alts;
int n_ops;
rtx *ops;
enum machine_mode *modes;
- char *subreg_changes_size ATTRIBUTE_UNUSED;
const char **constraints;
rtx insn;
struct costs *op_costs;
constraints[i] = p;
-#ifdef CLASS_CANNOT_CHANGE_SIZE
- /* If we noted a subreg earlier, and the selected class is a
- subclass of CLASS_CANNOT_CHANGE_SIZE, zap it. */
- if (subreg_changes_size[i]
- && (reg_class_subunion[(int) CLASS_CANNOT_CHANGE_SIZE]
- [(int) classes[i]]
- == CLASS_CANNOT_CHANGE_SIZE))
- classes[i] = NO_REGS;
-#endif
-
/* How we account for this operand now depends on whether it is a
pseudo register or not. If it is, we first check if any
register classes are valid. If not, we ignore this alternative,
{
if (classes[i] == NO_REGS)
{
- /* We must always fail if the operand is a REG, but
- we did not find a suitable class.
-
- Otherwise we may perform an uninitialized read
- from this_op_costs after the `continue' statement
- below. */
- alt_fail = 1;
+ /* We must always fail if the operand is a REG, but
+ we did not find a suitable class.
+
+ Otherwise we may perform an uninitialized read
+ from this_op_costs after the `continue' statement
+ below. */
+ alt_fail = 1;
}
else
{