diff options
author | Richard Henderson <rth@cygnus.com> | 1997-09-15 15:28:34 -0700 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1997-09-15 15:28:34 -0700 |
commit | 0d24ff5d2450f8de4c1b6aa1e7b727cf49bc2e1b (patch) | |
tree | ac81a2e948e3063220a9bd42602e09de475b8a09 | |
parent | 4da0677ba75d38283579fb4d6054641384310653 (diff) | |
download | gcc-0d24ff5d2450f8de4c1b6aa1e7b727cf49bc2e1b.zip gcc-0d24ff5d2450f8de4c1b6aa1e7b727cf49bc2e1b.tar.gz gcc-0d24ff5d2450f8de4c1b6aa1e7b727cf49bc2e1b.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.c | 53 |
2 files changed, 51 insertions, 8 deletions
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 <rth@cygnus.com> + + * 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 |