+
+/* Parameter function for mark_referenced_regs() that adds registers
+ present in the insn and in equivalent mems and addresses to
+ referenced_regs. */
+
+static void
+mark_reg_as_referenced (rtx *loc ATTRIBUTE_UNUSED,
+ enum machine_mode mode,
+ int hardregno,
+ void *arg ATTRIBUTE_UNUSED)
+{
+ add_to_hard_reg_set (&referenced_regs, mode, hardregno);
+}
+
+/* Parameter function for mark_referenced_regs() that replaces
+ registers referenced in a debug_insn that would have been restored,
+ should it be a non-debug_insn, with their save locations. */
+
+static void
+replace_reg_with_saved_mem (rtx *loc,
+ enum machine_mode mode,
+ int regno,
+ void *arg)
+{
+ unsigned int i, nregs = hard_regno_nregs [regno][mode];
+ rtx mem;
+ enum machine_mode *save_mode = (enum machine_mode *)arg;
+
+ for (i = 0; i < nregs; i++)
+ if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
+ break;
+
+ /* If none of the registers in the range would need restoring, we're
+ all set. */
+ if (i == nregs)
+ return;
+
+ while (++i < nregs)
+ if (!TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
+ break;
+
+ if (i == nregs
+ && regno_save_mem[regno][nregs])
+ {
+ mem = copy_rtx (regno_save_mem[regno][nregs]);
+
+ if (nregs == (unsigned int) hard_regno_nregs[regno][save_mode[regno]])
+ mem = adjust_address_nv (mem, save_mode[regno], 0);
+
+ if (GET_MODE (mem) != mode)
+ {
+ /* This is gen_lowpart_if_possible(), but without validating
+ the newly-formed address. */
+ int offset = 0;
+
+ if (WORDS_BIG_ENDIAN)
+ offset = (MAX (GET_MODE_SIZE (GET_MODE (mem)), UNITS_PER_WORD)
+ - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
+ if (BYTES_BIG_ENDIAN)
+ /* Adjust the address so that the address-after-the-data is
+ unchanged. */
+ offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
+ - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (mem))));
+
+ mem = adjust_address_nv (mem, mode, offset);
+ }
+ }
+ else
+ {
+ mem = gen_rtx_CONCATN (mode, rtvec_alloc (nregs));
+ for (i = 0; i < nregs; i++)
+ if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
+ {
+ gcc_assert (regno_save_mem[regno + i][1]);
+ XVECEXP (mem, 0, i) = copy_rtx (regno_save_mem[regno + i][1]);
+ }
+ else
+ {
+ gcc_assert (save_mode[regno] != VOIDmode);
+ XVECEXP (mem, 0, i) = gen_rtx_REG (save_mode [regno],
+ regno + i);
+ }
+ }
+
+ gcc_assert (GET_MODE (mem) == mode);
+ *loc = mem;
+}
+