#include "reload.h"
#include "expr.h"
-#define CEIL(x,y) (((x) + (y) - 1) / (y))
-
/* Modes for each hard register that we can save. The smallest mode is wide
enough to save the entire contents of the register. When saving the
register because it is live we first try to save in multi-register modes.
int n_regs_saved;
-static void set_reg_live ();
-static void clear_reg_live ();
-static void restore_referenced_regs ();
-static int insert_save_restore ();
+static enum machine_mode choose_hard_reg_mode PROTO((int, int));
+static void set_reg_live PROTO((rtx, rtx));
+static void clear_reg_live PROTO((rtx));
+static void restore_referenced_regs PROTO((rtx, rtx, enum machine_mode));
+static int insert_save_restore PROTO((rtx, int, int,
+ enum machine_mode, int));
\f
/* Return a machine mode that is legitimate for hard reg REGNO and large
enough to save nregs. If we can't find one, return VOIDmode. */
static enum machine_mode
choose_hard_reg_mode (regno, nregs)
int regno;
+ int nregs;
{
enum machine_mode found_mode = VOIDmode, mode;
for (j = MOVE_MAX / UNITS_PER_WORD; j > 0; j--)
{
int ok = 1;
+ int do_save;
/* 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. */
+ do_save = 1;
+ 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++)
{
int regno = i + k;
else if (regno < FIRST_PSEUDO_REGISTER)
{
- int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
+ int numregs = MIN (HARD_REGNO_NREGS (regno, GET_MODE (x)),
+ MOVE_MAX / UNITS_PER_WORD);
+ int endregno = regno + numregs;
for (i = regno; i < endregno; i++)
if (TEST_HARD_REG_BIT (hard_regs_need_restore, i))
- i += insert_save_restore (insn, 0, i, insn_mode,
- CEIL (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD));
+ i += insert_save_restore (insn, 0, i, insn_mode, numregs);
}
return;