diff options
author | Michael Meissner <meissner@gcc.gnu.org> | 1992-12-16 17:00:05 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 1992-12-16 17:00:05 +0000 |
commit | 7bea35e74679d46e30981d2fce2763517501d3fe (patch) | |
tree | a79262cf2cfa43e9f96bb858e75f351cb3e39b97 /gcc | |
parent | f49acdb4d6348a0926eda78fc2ac0be9255d602c (diff) | |
download | gcc-7bea35e74679d46e30981d2fce2763517501d3fe.zip gcc-7bea35e74679d46e30981d2fce2763517501d3fe.tar.gz gcc-7bea35e74679d46e30981d2fce2763517501d3fe.tar.bz2 |
Rework large stack frame support.
From-SVN: r2884
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/mips/mips.c | 394 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 40 |
2 files changed, 283 insertions, 151 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 018e9ab..b4920a7 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -3732,6 +3732,72 @@ mips_output_float (stream, value) } +/* Return TRUE if any register used in the epilogue is used. This to insure + any insn put into the epilogue delay slots is safe. */ + +int +epilogue_reg_mentioned_p (insn) + rtx insn; +{ + register char *fmt; + register int i; + register enum rtx_code code; + register int regno; + + if (insn == (rtx)0) + return 0; + + if (GET_CODE (insn) == LABEL_REF) + return 0; + + code = GET_CODE (insn); + switch (code) + { + case REG: + regno = REGNO (insn); + if (regno == STACK_POINTER_REGNUM) + return 1; + + if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed) + return 1; + + if (!call_used_regs[regno]) + return 1; + + if (regno != MIPS_TEMP1_REGNUM && regno != MIPS_TEMP2_REGNUM) + return 0; + + if (!current_frame_info.initialized) + compute_frame_size (get_frame_size ()); + + return (current_frame_info.total_size >= 32768); + + case SCRATCH: + case CC0: + case PC: + case CONST_INT: + case CONST_DOUBLE: + return 0; + } + + fmt = GET_RTX_FORMAT (code); + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + { + if (fmt[i] == 'E') + { + register int j; + for (j = XVECLEN (insn, i) - 1; j >= 0; j--) + if (epilogue_reg_mentioned_p (XVECEXP (insn, i, j))) + return 1; + } + else if (fmt[i] == 'e' && epilogue_reg_mentioned_p (XEXP (insn, i))) + return 1; + } + + return 0; +} + + /* Return the bytes needed to compute the frame pointer from the current stack pointer. @@ -3785,22 +3851,22 @@ mips_output_float (stream, value) */ -unsigned long +long compute_frame_size (size) int size; /* # of var. bytes allocated */ { int regno; - unsigned long total_size; /* # bytes that the entire frame takes up */ - unsigned long var_size; /* # bytes that variables take up */ - unsigned long args_size; /* # bytes that outgoing arguments take up */ - unsigned long extra_size; /* # extra bytes */ - unsigned int gp_reg_rounded; /* # bytes needed to store gp after rounding */ - unsigned int gp_reg_size; /* # bytes needed to store gp regs */ - unsigned int fp_reg_size; /* # bytes needed to store fp regs */ - unsigned long mask; /* mask of saved gp registers */ - unsigned long fmask; /* mask of saved fp registers */ - int fp_inc; /* 1 or 2 depending on the size of fp regs */ - int fp_bits; /* bitmask to use for each fp register */ + long total_size; /* # bytes that the entire frame takes up */ + long var_size; /* # bytes that variables take up */ + long args_size; /* # bytes that outgoing arguments take up */ + long extra_size; /* # extra bytes */ + long gp_reg_rounded; /* # bytes needed to store gp after rounding */ + long gp_reg_size; /* # bytes needed to store gp regs */ + long fp_reg_size; /* # bytes needed to store fp regs */ + long mask; /* mask of saved gp registers */ + long fmask; /* mask of saved fp registers */ + int fp_inc; /* 1 or 2 depending on the size of fp regs */ + long fp_bits; /* bitmask to use for each fp register */ gp_reg_size = 0; fp_reg_size = 0; @@ -3826,7 +3892,7 @@ compute_frame_size (size) if (MUST_SAVE_REGISTER (regno)) { gp_reg_size += UNITS_PER_WORD; - mask |= 1 << (regno - GP_REG_FIRST); + mask |= 1L << (regno - GP_REG_FIRST); } } @@ -3900,156 +3966,213 @@ compute_frame_size (size) } -/* Save/restore registers printing out the instructions to a file. */ +/* Common code to emit the insns (or to write the instructions to a file) + to save/restore registers. -void -save_restore (file, gp_op, gp_2word_op, fp_op) - FILE *file; /* stream to write to */ - char *gp_op; /* operation to do on gp registers */ - char *gp_2word_op; /* 2 word op to do on gp registers */ - char *fp_op; /* operation to do on fp registers */ + Other parts of the code assume that MIPS_TEMP1_REGNUM (aka large_reg) + is not modified within save_restore_insns. */ + +#define BITSET_P(value,bit) (((value) & (1L << (bit))) != 0) + +static void +save_restore_insns (store_p, large_reg, large_offset, file) + int store_p; /* true if this is prologue */ + rtx large_reg; /* register holding large offset constant or NULL */ + long large_offset; /* large constant offset value */ + FILE *file; /* file to write instructions to instead of making RTL */ { + long mask = current_frame_info.mask; + long fmask = current_frame_info.fmask; int regno; - unsigned long mask = current_frame_info.mask; - unsigned long fmask = current_frame_info.fmask; - unsigned long gp_offset; - unsigned long fp_offset; - unsigned long min_offset; - char *base_reg; + rtx base_reg_rtx; + long base_offset; + long gp_offset; + long fp_offset; + long end_offset; + + if (frame_pointer_needed && !BITSET_P (mask, FRAME_POINTER_REGNUM - GP_REG_FIRST)) + abort (); if (mask == 0 && fmask == 0) return; - base_reg = reg_names[STACK_POINTER_REGNUM]; - gp_offset = current_frame_info.gp_sp_offset; - fp_offset = current_frame_info.fp_sp_offset; - min_offset = (gp_offset < fp_offset && mask != 0) ? gp_offset : fp_offset; - - /* Deal with calling functions with a large structure. */ - if (min_offset >= 32768) - { - char *temp = reg_names[MIPS_TEMP2_REGNUM]; - fprintf (file, "\tli\t%s,%ld\n", temp, min_offset); - fprintf (file, "\taddu\t%s,%s,%s\n", temp, temp, base_reg); - base_reg = temp; - gp_offset = min_offset - gp_offset; - fp_offset = min_offset - fp_offset; - } - /* Save registers starting from high to low. The debuggers prefer at least the return register be stored at func+4, and also it allows us not to need a nop in the epilog if at least one register is reloaded in addition to return address. */ - if (mask || frame_pointer_needed) + /* Save GP registers if needed. */ + if (mask) { - for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--) - { - if ((mask & (1L << (regno - GP_REG_FIRST))) != 0 - || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)) - { - fprintf (file, "\t%s\t%s,%d(%s)\n", - gp_op, reg_names[regno], - gp_offset, base_reg); + /* Pick which pointer to use as a base register. For small + frames, just use the stack pointer. Otherwise, use a + temporary register. Save 2 cycles if the save area is near + the end of a large frame, by reusing the constant created in + the prologue/epilogue to adjust the stack frame. */ - gp_offset -= UNITS_PER_WORD; - } + gp_offset = current_frame_info.gp_sp_offset; + end_offset = gp_offset - (current_frame_info.gp_reg_size - UNITS_PER_WORD); + + if (gp_offset < 0 || end_offset < 0) + fatal ("gp_offset (%ld) or end_offset (%ld) is less than zero.", + gp_offset, end_offset); + + else if (gp_offset < 32768) + { + base_reg_rtx = stack_pointer_rtx; + base_offset = 0; } - } - if (fmask) - { - int fp_inc = (TARGET_FLOAT64) ? 1 : 2; + else if (large_reg != (rtx)0 + && (((unsigned long)(large_offset - gp_offset)) < 32768) + && (((unsigned long)(large_offset - end_offset)) < 32768)) + { + base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM); + base_offset = large_offset; + if (file == (FILE *)0) + emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx)); + else + fprintf (file, "\taddu\t%s,%s,%s\n", + reg_names[MIPS_TEMP2_REGNUM], + reg_names[REGNO (large_reg)], + reg_names[STACK_POINTER_REGNUM]); + } - for (regno = FP_REG_LAST-1; regno >= FP_REG_FIRST; regno -= fp_inc) + else { - if ((fmask & (1L << (regno - FP_REG_FIRST))) != 0) + base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM); + base_offset = gp_offset; + if (file == (FILE *)0) { - fprintf (file, "\t%s\t%s,%d(%s)\n", - fp_op, reg_names[regno], fp_offset, base_reg); - - fp_offset -= 2*UNITS_PER_WORD; + emit_move_insn (base_reg_rtx, GEN_INT (gp_offset)); + emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx)); } + else + fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n\taddu\t%s,%s,%s\n", + reg_names[MIPS_TEMP2_REGNUM], + (long)base_offset, + (long)base_offset, + reg_names[MIPS_TEMP2_REGNUM], + reg_names[MIPS_TEMP2_REGNUM], + reg_names[STACK_POINTER_REGNUM]); } - } -} - - -/* Common code to emit the insns to save/restore registers. */ - -static void -save_restore_insns (store_p) - int store_p; /* true if this is prologue */ -{ - int regno; - rtx base_reg_rtx = stack_pointer_rtx; - unsigned long mask = current_frame_info.mask; - unsigned long fmask = current_frame_info.fmask; - unsigned long gp_offset; - unsigned long fp_offset; - unsigned long min_offset; - - if (mask == 0 && fmask == 0) - return; - - gp_offset = current_frame_info.gp_sp_offset; - fp_offset = current_frame_info.fp_sp_offset; - min_offset = (gp_offset < fp_offset && mask != 0) ? gp_offset : fp_offset; - - /* Deal with calling functions with a large structure. */ - if (min_offset >= 32768) - { - base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM); - emit_move_insn (base_reg_rtx, GEN_INT (min_offset)); - emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx)); - gp_offset = min_offset - gp_offset; - fp_offset = min_offset - fp_offset; - } - /* Save registers starting from high to low. The debuggers prefer - at least the return register be stored at func+4, and also it - allows us not to need a nop in the epilog if at least one - register is reloaded in addition to return address. */ - - if (mask || frame_pointer_needed) - { for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--) { - if ((mask & (1L << (regno - GP_REG_FIRST))) != 0 - || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)) + if (BITSET_P (mask, regno - GP_REG_FIRST)) { - rtx reg_rtx = gen_rtx (REG, Pmode, regno); - rtx mem_rtx = gen_rtx (MEM, Pmode, - gen_rtx (PLUS, Pmode, base_reg_rtx, - GEN_INT (gp_offset))); + if (file == (FILE *)0) + { + rtx reg_rtx = gen_rtx (REG, Pmode, regno); + rtx mem_rtx = gen_rtx (MEM, Pmode, + gen_rtx (PLUS, Pmode, base_reg_rtx, + GEN_INT (gp_offset - base_offset))); - if (store_p) - emit_move_insn (mem_rtx, reg_rtx); + if (store_p) + emit_move_insn (mem_rtx, reg_rtx); + else + emit_move_insn (reg_rtx, mem_rtx); + } else - emit_move_insn (reg_rtx, mem_rtx); + fprintf (file, "\t%s\t%s,%ld(%s)\n", + (store_p) ? "sw" : "lw", + reg_names[regno], + gp_offset - base_offset, + reg_names[REGNO(base_reg_rtx)]); gp_offset -= UNITS_PER_WORD; } } } + else + { + base_reg_rtx = (rtx)0; /* Make sure these are initialzed */ + base_offset = 0; + } + /* Save floating point registers if needed. */ if (fmask) { int fp_inc = (TARGET_FLOAT64) ? 1 : 2; + /* Pick which pointer to use as a base register. */ + fp_offset = current_frame_info.fp_sp_offset; + end_offset = fp_offset - (current_frame_info.fp_reg_size - UNITS_PER_WORD); + + if (fp_offset < 0 || end_offset < 0) + fatal ("fp_offset (%ld) or end_offset (%ld) is less than zero.", + fp_offset, end_offset); + + else if (fp_offset < 32768) + { + base_reg_rtx = stack_pointer_rtx; + base_offset = 0; + } + + else if (base_reg_rtx != (rtx)0 + && (((unsigned long)(base_offset - fp_offset)) < 32768) + && (((unsigned long)(base_offset - end_offset)) < 32768)) + { + ; /* already set up for gp registers above */ + } + + else if (large_reg != (rtx)0 + && (((unsigned long)(large_offset - fp_offset)) < 32768) + && (((unsigned long)(large_offset - end_offset)) < 32768)) + { + base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM); + base_offset = large_offset; + if (file == (FILE *)0) + emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx)); + else + fprintf (file, "\taddu\t%s,%s,%s\n", + reg_names[MIPS_TEMP2_REGNUM], + reg_names[REGNO (large_reg)], + reg_names[STACK_POINTER_REGNUM]); + } + + else + { + base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM); + base_offset = fp_offset; + if (file == (FILE *)0) + { + emit_move_insn (base_reg_rtx, GEN_INT (fp_offset)); + emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx)); + } + else + fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n\taddu\t%s,%s,%s\n", + reg_names[MIPS_TEMP2_REGNUM], + (long)base_offset, + (long)base_offset, + reg_names[MIPS_TEMP2_REGNUM], + reg_names[MIPS_TEMP2_REGNUM], + reg_names[STACK_POINTER_REGNUM]); + } + for (regno = FP_REG_LAST-1; regno >= FP_REG_FIRST; regno -= fp_inc) { - if ((fmask & (1L << (regno - FP_REG_FIRST))) != 0) + if (BITSET_P (fmask, regno - FP_REG_FIRST)) { - rtx reg_rtx = gen_rtx (REG, DFmode, regno); - rtx mem_rtx = gen_rtx (MEM, DFmode, - gen_rtx (PLUS, Pmode, base_reg_rtx, - GEN_INT (fp_offset))); + if (file == (FILE *)0) + { + rtx reg_rtx = gen_rtx (REG, DFmode, regno); + rtx mem_rtx = gen_rtx (MEM, DFmode, + gen_rtx (PLUS, Pmode, base_reg_rtx, + GEN_INT (fp_offset - base_offset))); - if (store_p) - emit_move_insn (mem_rtx, reg_rtx); + if (store_p) + emit_move_insn (mem_rtx, reg_rtx); + else + emit_move_insn (reg_rtx, mem_rtx); + } else - emit_move_insn (reg_rtx, mem_rtx); + fprintf (file, "\t%s\t%s,%ld(%s)\n", + (store_p) ? "s.d" : "l.d", + reg_names[regno], + fp_offset - base_offset, + reg_names[REGNO(base_reg_rtx)]); + fp_offset -= 2*UNITS_PER_WORD; } @@ -4065,7 +4188,7 @@ function_prologue (file, size) FILE *file; int size; { - int tsize = current_frame_info.total_size; + long tsize = current_frame_info.total_size; ASM_OUTPUT_SOURCE_FILENAME (file, DECL_SOURCE_FILE (current_function_decl)); @@ -4076,6 +4199,7 @@ function_prologue (file, size) fputs ("\t.ent\t", file); assemble_name (file, current_function_name); fputs ("\n", file); + assemble_name (file, current_function_name); fputs (":\n", file); @@ -4112,7 +4236,7 @@ void mips_expand_prologue () { int regno; - int tsize; + long tsize; tree fndecl = current_function_decl; /* current... is tooo long */ tree fntype = TREE_TYPE (fndecl); tree fnargs = (TREE_CODE (fntype) != METHOD_TYPE) @@ -4120,6 +4244,7 @@ mips_expand_prologue () : 0; tree next_arg; tree cur_arg; + rtx tmp_rtx = (rtx)0; char *arg_name = (char *)0; CUMULATIVE_ARGS args_so_far; @@ -4200,14 +4325,14 @@ mips_expand_prologue () if (tsize > 32767) { - rtx tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM); + tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM); emit_move_insn (tmp_rtx, tsize_rtx); tsize_rtx = tmp_rtx; } emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx)); - save_restore_insns (TRUE); + save_restore_insns (TRUE, tmp_rtx, tsize, (FILE *)0); if (frame_pointer_needed) emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx)); @@ -4228,7 +4353,7 @@ function_epilogue (file, size) FILE *file; int size; { - int tsize; + long tsize; char *sp_str = reg_names[STACK_POINTER_REGNUM]; char *t1_str = reg_names[MIPS_TEMP1_REGNUM]; rtx epilogue_delay = current_function_epilogue_delay_list; @@ -4236,6 +4361,9 @@ function_epilogue (file, size) int noepilogue = FALSE; int load_nop = FALSE; int load_only_r31; + rtx tmp_rtx = (rtx)0; + rtx restore_rtx; + int i; /* The epilogue does not depend on any registers, but the stack registers, so we assume that if we have 1 pending nop, it can be @@ -4316,13 +4444,16 @@ function_epilogue (file, size) fprintf (file, "\t.set\tnoreorder\n"); if (tsize > 32767) - fprintf (file, "\tli\t%s,%d\n", t1_str, tsize); + { + fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n", t1_str, (long)tsize, (long)tsize); + tmp_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM); + } if (frame_pointer_needed) fprintf (file, "\tmove\t%s,%s\t\t\t# sp not trusted here\n", sp_str, reg_names[FRAME_POINTER_REGNUM]); - save_restore (file, "lw", "ld", "l.d"); + save_restore_insns (FALSE, tmp_rtx, tsize, file); load_only_r31 = (current_frame_info.mask == (1 << 31) && current_frame_info.fmask == 0); @@ -4469,12 +4600,13 @@ function_epilogue (file, size) void mips_expand_epilogue () { - int tsize = current_frame_info.total_size; + long tsize = current_frame_info.total_size; rtx tsize_rtx = GEN_INT (tsize); + rtx tmp_rtx = (rtx)0; if (tsize > 32767) { - rtx tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM); + tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM); emit_move_insn (tmp_rtx, tsize_rtx); tsize_rtx = tmp_rtx; } @@ -4484,7 +4616,7 @@ mips_expand_epilogue () if (frame_pointer_needed) emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx)); - save_restore_insns (FALSE); + save_restore_insns (FALSE, tmp_rtx, tsize, (FILE *)0); emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx)); } diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index d581ff3..6ca50ea 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -126,7 +126,8 @@ extern int arith32_operand (); extern int arith_operand (); extern int cmp_op (); extern int cmp2_op (); -extern unsigned long compute_frame_size (); +extern long compute_frame_size (); +extern int epilogue_reg_mentioned_p (); extern void expand_block_move (); extern int equality_op (); extern int fcmp_op (); @@ -482,7 +483,7 @@ while (0) /* Print subsidiary information on the compiler version in use. */ -#define MIPS_VERSION "[AL 1.1, MM 31]" +#define MIPS_VERSION "[AL 1.1, MM 32]" #ifndef MACHINE_TYPE #define MACHINE_TYPE "BSD Mips" @@ -1229,6 +1230,7 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER]; scratch register set, and not used for passing and returning arguments and any other information used in the calling sequence (such as pic). */ + #define MIPS_TEMP1_REGNUM (GP_REG_FIRST + 8) #define MIPS_TEMP2_REGNUM (GP_REG_FIRST + 9) @@ -1540,21 +1542,21 @@ extern enum reg_class mips_char_to_class[]; struct mips_frame_info { - unsigned long total_size; /* # bytes that the entire frame takes up */ - unsigned long var_size; /* # bytes that variables take up */ - unsigned long args_size; /* # bytes that outgoing arguments take up */ - unsigned long extra_size; /* # bytes of extra gunk */ - unsigned int gp_reg_size; /* # bytes needed to store gp regs */ - unsigned int fp_reg_size; /* # bytes needed to store fp regs */ - unsigned long mask; /* mask of saved gp registers */ - unsigned long fmask; /* mask of saved fp registers */ - long gp_save_offset; /* offset from vfp to store gp registers */ - long fp_save_offset; /* offset from vfp to store fp registers */ - unsigned long gp_sp_offset; /* offset from new sp to store gp registers */ - unsigned long fp_sp_offset; /* offset from new sp to store fp registers */ - int initialized; /* != 0 if frame size already calculated */ - int num_gp; /* number of gp registers saved */ - int num_fp; /* number of fp registers saved */ + long total_size; /* # bytes that the entire frame takes up */ + long var_size; /* # bytes that variables take up */ + long args_size; /* # bytes that outgoing arguments take up */ + long extra_size; /* # bytes of extra gunk */ + int gp_reg_size; /* # bytes needed to store gp regs */ + int fp_reg_size; /* # bytes needed to store fp regs */ + long mask; /* mask of saved gp registers */ + long fmask; /* mask of saved fp registers */ + long gp_save_offset; /* offset from vfp to store gp registers */ + long fp_save_offset; /* offset from vfp to store fp registers */ + long gp_sp_offset; /* offset from new sp to store gp registers */ + long fp_sp_offset; /* offset from new sp to store fp registers */ + int initialized; /* != 0 if frame size already calculated */ + int num_gp; /* number of gp registers saved */ + int num_fp; /* number of fp registers saved */ }; extern struct mips_frame_info current_frame_info; @@ -1896,9 +1898,7 @@ typedef struct mips_args { #define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN,N) \ (get_attr_dslot (INSN) == DSLOT_NO \ && get_attr_length (INSN) == 1 \ - && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (INSN)) \ - && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (INSN)) \ - && ! reg_mentioned_p (arg_pointer_rtx, PATTERN (INSN))) + && ! epilogue_reg_mentioned_p (PATTERN (INSN))) /* Tell prologue and epilogue if register REGNO should be saved / restored. */ |