+ }
+ /* Sort saved hard regs. */
+ qsort (all_saved_regs, saved_regs_num, sizeof (struct saved_hard_reg *),
+ saved_hard_reg_compare_func);
+ /* Initiate slots available from the previous reload
+ iteration. */
+ prev_save_slots_num = save_slots_num;
+ memcpy (prev_save_slots, save_slots, save_slots_num * sizeof (rtx));
+ save_slots_num = 0;
+ /* Allocate stack slots for the saved hard registers. */
+ for (i = 0; i < saved_regs_num; i++)
+ {
+ saved_reg = all_saved_regs[i];
+ regno = saved_reg->hard_regno;
+ for (j = 0; j < i; j++)
+ {
+ saved_reg2 = all_saved_regs[j];
+ if (! saved_reg2->first_p)
+ continue;
+ slot = saved_reg2->slot;
+ for (k = j; k >= 0; k = next_k)
+ {
+ saved_reg3 = all_saved_regs[k];
+ next_k = saved_reg3->next;
+ if (saved_reg_conflicts[saved_reg->num * saved_regs_num
+ + saved_reg3->num])
+ break;
+ }
+ if (k < 0
+ && (GET_MODE_SIZE (regno_save_mode[regno][1])
+ <= GET_MODE_SIZE (regno_save_mode
+ [saved_reg2->hard_regno][1])))
+ {
+ saved_reg->slot
+ = adjust_address_nv
+ (slot, regno_save_mode[saved_reg->hard_regno][1], 0);
+ regno_save_mem[regno][1] = saved_reg->slot;
+ saved_reg->next = saved_reg2->next;
+ saved_reg2->next = i;
+ if (dump_file != NULL)
+ fprintf (dump_file, "%d uses slot of %d\n",
+ regno, saved_reg2->hard_regno);
+ break;
+ }
+ }
+ if (j == i)
+ {
+ saved_reg->first_p = TRUE;
+ for (best_slot_num = -1, j = 0; j < prev_save_slots_num; j++)
+ {
+ slot = prev_save_slots[j];
+ if (slot == NULL_RTX)
+ continue;
+ if (GET_MODE_SIZE (regno_save_mode[regno][1])
+ <= GET_MODE_SIZE (GET_MODE (slot))
+ && best_slot_num < 0)
+ best_slot_num = j;
+ if (GET_MODE (slot) == regno_save_mode[regno][1])
+ break;
+ }
+ if (best_slot_num >= 0)
+ {
+ saved_reg->slot = prev_save_slots[best_slot_num];
+ saved_reg->slot
+ = adjust_address_nv
+ (saved_reg->slot,
+ regno_save_mode[saved_reg->hard_regno][1], 0);
+ if (dump_file != NULL)
+ fprintf (dump_file,
+ "%d uses a slot from prev iteration\n", regno);
+ prev_save_slots[best_slot_num] = NULL_RTX;
+ if (best_slot_num + 1 == prev_save_slots_num)
+ prev_save_slots_num--;
+ }
+ else
+ {
+ saved_reg->slot
+ = assign_stack_local_1
+ (regno_save_mode[regno][1],
+ GET_MODE_SIZE (regno_save_mode[regno][1]), 0, true);
+ if (dump_file != NULL)
+ fprintf (dump_file, "%d uses a new slot\n", regno);
+ }
+ regno_save_mem[regno][1] = saved_reg->slot;
+ save_slots[save_slots_num++] = saved_reg->slot;
+ }
+ }
+ free (saved_reg_conflicts);
+ finish_saved_hard_regs ();
+ }
+ else
+ {
+ /* Now run through all the call-used hard-registers and allocate
+ space for them in the caller-save area. Try to allocate space
+ in a manner which allows multi-register saves/restores to be done. */
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ for (j = MOVE_MAX_WORDS; j > 0; j--)
+ {
+ int do_save = 1;
+
+ /* If no mode exists for this size, try another. Also break out
+ if we have already saved this hard register. */
+ if (regno_save_mode[i][j] == VOIDmode || regno_save_mem[i][1] != 0)
+ continue;
+
+ /* See if any register in this group has been saved. */
+ for (k = 0; k < j; k++)
+ if (regno_save_mem[i + k][1])
+ {
+ do_save = 0;
+ break;
+ }
+ if (! do_save)
+ continue;
+
+ for (k = 0; k < j; k++)
+ if (! TEST_HARD_REG_BIT (hard_regs_used, i + k))
+ {
+ do_save = 0;
+ break;
+ }
+ if (! do_save)
+ continue;
+
+ /* We have found an acceptable mode to store in. Since
+ hard register is always saved in the widest mode
+ available, the mode may be wider than necessary, it is
+ OK to reduce the alignment of spill space. We will
+ verify that it is equal to or greater than required
+ when we restore and save the hard register in
+ insert_restore and insert_save. */
+ regno_save_mem[i][j]
+ = assign_stack_local_1 (regno_save_mode[i][j],
+ GET_MODE_SIZE (regno_save_mode[i][j]),
+ 0, true);
+
+ /* Setup single word save area just in case... */
+ for (k = 0; k < j; k++)
+ /* This should not depend on WORDS_BIG_ENDIAN.
+ The order of words in regs is the same as in memory. */
+ regno_save_mem[i + k][1]
+ = adjust_address_nv (regno_save_mem[i][j],
+ regno_save_mode[i + k][1],
+ k * UNITS_PER_WORD);
+ }
+ }