diff options
Diffstat (limited to 'contrib/gcc/caller-save.c')
-rw-r--r-- | contrib/gcc/caller-save.c | 35 |
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. */ |