Commit 0d24ff5d by Richard Henderson Committed by Jim Wilson

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
parent 4da0677b
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) Mon Sep 15 15:39:26 1997 Jeffrey A Law (law@cygnus.com)
* cse.c (simplify_relational_operation): If MODE specifies a * cse.c (simplify_relational_operation): If MODE specifies a
......
...@@ -2317,7 +2317,7 @@ output_prolog (file, size) ...@@ -2317,7 +2317,7 @@ output_prolog (file, size)
int int_reg_save_area_size = 0; int int_reg_save_area_size = 0;
rtx insn; rtx insn;
unsigned reg_mask = 0; unsigned reg_mask = 0;
int i; int i, sa_reg;
/* Ecoff can handle multiple .file directives, so put out file and lineno. /* 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 We have to do that before the .ent directive as we cannot switch
...@@ -2463,12 +2463,30 @@ output_prolog (file, size) ...@@ -2463,12 +2463,30 @@ output_prolog (file, size)
? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM), ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
frame_size, current_function_pretend_args_size); 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. */ /* Save register 26 if any other register needs to be saved. */
if (sa_size != 0) if (sa_size != 0)
{ {
reg_mask |= 1 << 26; 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; reg_offset += 8;
int_reg_save_area_size += 8; int_reg_save_area_size += 8;
} }
...@@ -2478,7 +2496,7 @@ output_prolog (file, size) ...@@ -2478,7 +2496,7 @@ output_prolog (file, size)
if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i] && i != 26) if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i] && i != 26)
{ {
reg_mask |= 1 << i; 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; reg_offset += 8;
int_reg_save_area_size += 8; int_reg_save_area_size += 8;
} }
...@@ -2496,7 +2514,7 @@ output_prolog (file, size) ...@@ -2496,7 +2514,7 @@ output_prolog (file, size)
&& regs_ever_live[i + 32]) && regs_ever_live[i + 32])
{ {
reg_mask |= 1 << i; 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; reg_offset += 8;
} }
...@@ -2542,6 +2560,7 @@ output_epilog (file, size) ...@@ -2542,6 +2560,7 @@ output_epilog (file, size)
if (insn == 0 || GET_CODE (insn) != BARRIER) if (insn == 0 || GET_CODE (insn) != BARRIER)
{ {
int fp_offset = 0; int fp_offset = 0;
int sa_reg;
final_prescan_insn (NULL_RTX, NULL_PTR, 0); final_prescan_insn (NULL_RTX, NULL_PTR, 0);
...@@ -2549,11 +2568,29 @@ output_epilog (file, size) ...@@ -2549,11 +2568,29 @@ output_epilog (file, size)
if (frame_pointer_needed) if (frame_pointer_needed)
fprintf (file, "\tbis $15,$15,$30\n"); 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 /* Restore all the registers, starting with the return address
register. */ register. */
if (sa_size != 0) 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; reg_offset += 8;
} }
...@@ -2568,7 +2605,7 @@ output_epilog (file, size) ...@@ -2568,7 +2605,7 @@ output_epilog (file, size)
if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
fp_offset = reg_offset; fp_offset = reg_offset;
else 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; reg_offset += 8;
} }
...@@ -2576,7 +2613,7 @@ output_epilog (file, size) ...@@ -2576,7 +2613,7 @@ output_epilog (file, size)
if (! fixed_regs[i + 32] && ! call_used_regs[i + 32] if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
&& regs_ever_live[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; reg_offset += 8;
} }
...@@ -2591,7 +2628,7 @@ output_epilog (file, size) ...@@ -2591,7 +2628,7 @@ output_epilog (file, size)
now. This must be done in one instruction immediately now. This must be done in one instruction immediately
before the SP update. */ before the SP update. */
if (restore_fp && fp_offset) 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 /* Now update the stack pointer, if needed. Only one instruction must
modify the stack pointer. It must be the last instruction in the modify the stack pointer. It must be the last instruction in the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment