From 0d24ff5d2450f8de4c1b6aa1e7b727cf49bc2e1b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 15 Sep 1997 15:28:34 -0700 Subject: Patch from Richard Henderson for large frames. * alpha/alpha.c (output_prolog): New variable sa_reg. Use it for out-or-range reg_offset. (output_epilog): Likewise. From-SVN: r15458 --- gcc/ChangeLog | 6 ++++++ gcc/config/alpha/alpha.c | 53 ++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f3b148c..0fd4105 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Mon Sep 15 15:24:00 1997 Richard Henderson + + * alpha/alpha.c (output_prolog): New variable sa_reg. Use it for + out-or-range reg_offset. + (output_epilog): Likewise. + Mon Sep 15 15:39:26 1997 Jeffrey A Law (law@cygnus.com) * cse.c (simplify_relational_operation): If MODE specifies a diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index de66e1d..a054f8c 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -2317,7 +2317,7 @@ output_prolog (file, size) int int_reg_save_area_size = 0; rtx insn; unsigned reg_mask = 0; - int i; + int i, sa_reg; /* Ecoff can handle multiple .file directives, so put out file and lineno. We have to do that before the .ent directive as we cannot switch @@ -2463,12 +2463,30 @@ output_prolog (file, size) ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM), frame_size, current_function_pretend_args_size); } + + /* Cope with very large offsets to the register save area. */ + sa_reg = 30; + if (reg_offset + sa_size > 0x8000) + { + int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000; + if (low + sa_size <= 0x8000) + { + add_long_const (file, reg_offset - low, 30, 24, 24); + reg_offset = low; + } + else + { + add_long_const (file, reg_offset, 30, 24, 24); + reg_offset = 0; + } + sa_reg = 24; + } /* Save register 26 if any other register needs to be saved. */ if (sa_size != 0) { reg_mask |= 1 << 26; - fprintf (file, "\tstq $26,%d($30)\n", reg_offset); + fprintf (file, "\tstq $26,%d($%d)\n", reg_offset, sa_reg); reg_offset += 8; int_reg_save_area_size += 8; } @@ -2478,7 +2496,7 @@ output_prolog (file, size) if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i] && i != 26) { reg_mask |= 1 << i; - fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset); + fprintf (file, "\tstq $%d,%d($%d)\n", i, reg_offset, sa_reg); reg_offset += 8; int_reg_save_area_size += 8; } @@ -2496,7 +2514,7 @@ output_prolog (file, size) && regs_ever_live[i + 32]) { reg_mask |= 1 << i; - fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset); + fprintf (file, "\tstt $f%d,%d($%d)\n", i, reg_offset, sa_reg); reg_offset += 8; } @@ -2542,6 +2560,7 @@ output_epilog (file, size) if (insn == 0 || GET_CODE (insn) != BARRIER) { int fp_offset = 0; + int sa_reg; final_prescan_insn (NULL_RTX, NULL_PTR, 0); @@ -2549,11 +2568,29 @@ output_epilog (file, size) if (frame_pointer_needed) fprintf (file, "\tbis $15,$15,$30\n"); + /* Cope with large offsets to the register save area. */ + sa_reg = 30; + if (reg_offset + sa_size > 0x8000) + { + int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000; + if (low + sa_size <= 0x8000) + { + add_long_const (file, reg_offset - low, 30, 24, 24); + reg_offset = low; + } + else + { + add_long_const (file, reg_offset, 30, 24, 24); + reg_offset = 0; + } + sa_reg = 24; + } + /* Restore all the registers, starting with the return address register. */ if (sa_size != 0) { - fprintf (file, "\tldq $26,%d($30)\n", reg_offset); + fprintf (file, "\tldq $26,%d($%d)\n", reg_offset, sa_reg); reg_offset += 8; } @@ -2568,7 +2605,7 @@ output_epilog (file, size) if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) fp_offset = reg_offset; else - fprintf (file, "\tldq $%d,%d($30)\n", i, reg_offset); + fprintf (file, "\tldq $%d,%d($%d)\n", i, reg_offset, sa_reg); reg_offset += 8; } @@ -2576,7 +2613,7 @@ output_epilog (file, size) if (! fixed_regs[i + 32] && ! call_used_regs[i + 32] && regs_ever_live[i + 32]) { - fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset); + fprintf (file, "\tldt $f%d,%d($%d)\n", i, reg_offset, sa_reg); reg_offset += 8; } @@ -2591,7 +2628,7 @@ output_epilog (file, size) now. This must be done in one instruction immediately before the SP update. */ if (restore_fp && fp_offset) - fprintf (file, "\tldq $15,%d($30)\n", fp_offset); + fprintf (file, "\tldq $15,%d($%d)\n", fp_offset, sa_reg); /* Now update the stack pointer, if needed. Only one instruction must modify the stack pointer. It must be the last instruction in the -- cgit v1.1