+ for (j = 1; j < num_sregs; ++j) {
+ int sreg = sregs [j];
+ int dest_sreg = dest_sregs [j];
+
+ if (dest_sreg == -1)
+ continue;
+
+ if (j == 2) {
+ int k;
+
+ /*
+ * CAS.
+ * We need to special case this, since on x86, there are only 3
+ * free registers, and the code below assigns one of them to
+ * sreg, so we can run out of registers when trying to assign
+ * dreg. Instead, we just set up the register masks, and let the
+ * normal sreg2 assignment code handle this. It would be nice to
+ * do this for all the fixed reg cases too, but there is too much
+ * risk of breakage.
+ */
+
+ /* Make sure sreg will be assigned to dest_sreg, and the other sregs won't */
+ sreg_masks [j] = regmask (dest_sreg);
+ for (k = 0; k < num_sregs; ++k) {
+ if (k != j)
+ sreg_masks [k] &= ~ (regmask (dest_sreg));
+ }
+
+ /*
+ * Spill sreg1/2 if they are assigned to dest_sreg.
+ */
+ for (k = 0; k < num_sregs; ++k) {
+ if (k != j && is_soft_reg (sregs [k], 0) && rs->vassign [sregs [k]] == dest_sreg)
+ free_up_hreg (cfg, bb, tmp, ins, dest_sreg, 0);
+ }
+
+ /*
+ * We can also run out of registers while processing sreg2 if sreg3 is
+ * assigned to another hreg, so spill sreg3 now.
+ */
+ if (is_soft_reg (sreg, 0) && rs->vassign [sreg] >= 0 && rs->vassign [sreg] != dest_sreg) {
+ spill_vreg (cfg, bb, tmp, ins, sreg, 0);
+ }
+ continue;
+ }
+
+ if (rs->ifree_mask & (regmask (dest_sreg))) {
+ if (is_global_ireg (sreg)) {
+ int k;