unsigned hreg0 = set->gpr_to_ra_reg[i + HALF_OFFSET][(j * 2) + 0];
unsigned hreg1 = set->gpr_to_ra_reg[i + HALF_OFFSET][(j * 2) + 1];
- ra_add_transitive_reg_conflict(set->regs, freg, hreg0);
- ra_add_transitive_reg_conflict(set->regs, freg, hreg1);
+ ra_add_transitive_reg_pair_conflict(set->regs, freg, hreg0, hreg1);
}
}
}
}
+/**
+ * Set up conflicts between base_reg and it's two half registers reg0 and
+ * reg1, but take care to not add conflicts between reg0 and reg1.
+ *
+ * This is useful for architectures where full size registers are aliased by
+ * two half size registers (eg 32 bit float and 16 bit float registers).
+ */
+void
+ra_add_transitive_reg_pair_conflict(struct ra_regs *regs,
+ unsigned int base_reg, unsigned int reg0, unsigned int reg1)
+{
+ unsigned int i;
+
+ ra_add_reg_conflict(regs, reg0, base_reg);
+ ra_add_reg_conflict(regs, reg1, base_reg);
+
+ for (i = 0; i < regs->regs[base_reg].num_conflicts; i++) {
+ unsigned int conflict = regs->regs[base_reg].conflict_list[i];
+ if (conflict != reg1)
+ ra_add_reg_conflict(regs, reg0, regs->regs[base_reg].conflict_list[i]);
+ if (conflict != reg0)
+ ra_add_reg_conflict(regs, reg1, regs->regs[base_reg].conflict_list[i]);
+ }
+}
+
/**
* Makes every conflict on the given register transitive. In other words,
* every register that conflicts with r will now conflict with every other
unsigned int r1, unsigned int r2);
void ra_add_transitive_reg_conflict(struct ra_regs *regs,
unsigned int base_reg, unsigned int reg);
+
+void
+ra_add_transitive_reg_pair_conflict(struct ra_regs *regs,
+ unsigned int base_reg, unsigned int reg0, unsigned int reg1);
+
void ra_make_reg_conflicts_transitive(struct ra_regs *regs, unsigned int reg);
void ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int reg);
void ra_set_num_conflicts(struct ra_regs *regs, unsigned int class_a,