+static void add_stored_regs (rtx, const_rtx, void *);
+\f
+static GTY(()) rtx savepat;
+static GTY(()) rtx restpat;
+static GTY(()) rtx test_reg;
+static GTY(()) rtx test_mem;
+static GTY(()) rtx saveinsn;
+static GTY(()) rtx restinsn;
+
+/* Return the INSN_CODE used to save register REG in mode MODE. */
+static int
+reg_save_code (int reg, enum machine_mode mode)
+{
+ bool ok;
+ if (cached_reg_save_code[reg][mode])
+ return cached_reg_save_code[reg][mode];
+ if (!HARD_REGNO_MODE_OK (reg, mode))
+ {
+ cached_reg_save_code[reg][mode] = -1;
+ cached_reg_restore_code[reg][mode] = -1;
+ return -1;
+ }
+
+ /* Update the register number and modes of the register
+ and memory operand. */
+ SET_REGNO (test_reg, reg);
+ PUT_MODE (test_reg, mode);
+ PUT_MODE (test_mem, mode);
+
+ /* Force re-recognition of the modified insns. */
+ INSN_CODE (saveinsn) = -1;
+ INSN_CODE (restinsn) = -1;
+
+ cached_reg_save_code[reg][mode] = recog_memoized (saveinsn);
+ cached_reg_restore_code[reg][mode] = recog_memoized (restinsn);
+
+ /* Now extract both insns and see if we can meet their
+ constraints. */
+ ok = (cached_reg_save_code[reg][mode] != -1
+ && cached_reg_restore_code[reg][mode] != -1);
+ if (ok)
+ {
+ extract_insn (saveinsn);
+ ok = constrain_operands (1);
+ extract_insn (restinsn);
+ ok &= constrain_operands (1);
+ }
+
+ if (! ok)
+ {
+ cached_reg_save_code[reg][mode] = -1;
+ cached_reg_restore_code[reg][mode] = -1;
+ }
+ gcc_assert (cached_reg_save_code[reg][mode]);
+ return cached_reg_save_code[reg][mode];
+}
+
+/* Return the INSN_CODE used to restore register REG in mode MODE. */
+static int
+reg_restore_code (int reg, enum machine_mode mode)
+{
+ if (cached_reg_restore_code[reg][mode])
+ return cached_reg_restore_code[reg][mode];
+ /* Populate our cache. */
+ reg_save_code (reg, mode);
+ return cached_reg_restore_code[reg][mode];
+}