summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/caller-save.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/caller-save.c')
-rw-r--r--contrib/gcc/caller-save.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/contrib/gcc/caller-save.c b/contrib/gcc/caller-save.c
index 87a13dc..b7e3cea 100644
--- a/contrib/gcc/caller-save.c
+++ b/contrib/gcc/caller-save.c
@@ -115,6 +115,9 @@ init_caller_save ()
rtx address;
int i, j;
enum machine_mode mode;
+ rtx savepat, restpat;
+ rtx test_reg, test_mem;
+ rtx saveinsn, restinsn;
/* First find all the registers that we need to deal with and all
the modes that they can have. If we can't find a mode to use,
@@ -179,22 +182,35 @@ init_caller_save ()
address = addr_reg;
/* Next we try to form an insn to save and restore the register. We
- see if such an insn is recognized and meets its constraints. */
+ see if such an insn is recognized and meets its constraints.
- start_sequence ();
+ To avoid lots of unnecessary RTL allocation, we construct all the RTL
+ once, then modify the memory and register operands in-place. */
+
+ test_reg = gen_rtx_REG (VOIDmode, 0);
+ test_mem = gen_rtx_MEM (VOIDmode, address);
+ savepat = gen_rtx_SET (VOIDmode, test_mem, test_reg);
+ restpat = gen_rtx_SET (VOIDmode, test_reg, test_mem);
+
+ saveinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, savepat, -1, 0, 0);
+ restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, restpat, -1, 0, 0);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
for (mode = 0 ; mode < MAX_MACHINE_MODE; mode++)
if (HARD_REGNO_MODE_OK (i, mode))
{
- rtx mem = gen_rtx_MEM (mode, address);
- rtx reg = gen_rtx_REG (mode, i);
- rtx savepat = gen_rtx_SET (VOIDmode, mem, reg);
- rtx restpat = gen_rtx_SET (VOIDmode, reg, mem);
- rtx saveinsn = emit_insn (savepat);
- rtx restinsn = emit_insn (restpat);
int ok;
+ /* Update the register number and modes of the register
+ and memory operand. */
+ REGNO (test_reg) = i;
+ 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;
+
reg_save_code[i][mode] = recog_memoized (saveinsn);
reg_restore_code[i][mode] = recog_memoized (restinsn);
@@ -221,6 +237,7 @@ init_caller_save ()
reg_save_code[i][mode] = -1;
reg_restore_code[i][mode] = -1;
}
+
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
for (j = 1; j <= MOVE_MAX_WORDS; j++)
if (reg_save_code [i][regno_save_mode[i][j]] == -1)
@@ -232,8 +249,6 @@ init_caller_save ()
SET_HARD_REG_BIT (call_fixed_reg_set, i);
}
}
-
- end_sequence ();
}
/* Initialize save areas by showing that we haven't allocated any yet. */
OpenPOWER on IntegriCloud