aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pa/pa.c
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1996-03-05 00:34:13 -0700
committerJeff Law <law@gcc.gnu.org>1996-03-05 00:34:13 -0700
commit9e18f575557d94acced039000fa26958e75f69e6 (patch)
treefd229de8711cd62458a579be3ecc2a9f5d046fec /gcc/config/pa/pa.c
parent9ad2334b60dab68c60b33bb2c87b9590c6a4002a (diff)
downloadgcc-9e18f575557d94acced039000fa26958e75f69e6.zip
gcc-9e18f575557d94acced039000fa26958e75f69e6.tar.gz
gcc-9e18f575557d94acced039000fa26958e75f69e6.tar.bz2
lib2funcs.asm (__outline_prologue): New "function".
* lib2funcs.asm (__outline_prologue): New "function". (__outline_epilogue): New "function". * pa.h (TARGET_SPACE): Define. (target_flags): Add -mspace and -mno-space. Enable/disable space saving optimizations. (FRAME_POINTER_REQUIRED): Frame pointers are always required when generating out of line prologues and epilogues. * pa.c (compute_frame_size): Handle out of line prologues/epilogues. (hppa_expand_prologue): If optimizing for space, emit an out of line prologue. * pa.c (compute_frame_size): Handle out of line prologues/epilogues. (hppa_expand_prologue): If optimizing for space, emit an out of line prologue. (hppa_expand_epilogue): Similarly. (override_options): Optimizing for space is not compatable with either profiling or PIC code generation. * pa.md (outline_prologue_call): New pattern. (outline_epilogue_call): Likewise. From-SVN: r11438
Diffstat (limited to 'gcc/config/pa/pa.c')
-rw-r--r--gcc/config/pa/pa.c114
1 files changed, 112 insertions, 2 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 026821c..545dab5 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -113,6 +113,12 @@ override_options ()
{
warning ("PIC code generation is not compatable with profiling\n");
}
+
+ if (TARGET_SPACE && (flag_pic || profile_flag))
+ {
+ warning ("Out of line entry/exit sequences are not compatable\n");
+ warning ("with PIC or profiling\n");
+ }
}
@@ -2039,8 +2045,24 @@ compute_frame_size (size, fregs_live)
for (i = 18; i >= 4; i--)
{
if (regs_ever_live[i])
- fsize += 4;
+ {
+ /* For out of line prologues/epilogues we only need to
+ compute the highest register number to save and
+ allocate space for all the callee saved registers
+ with a lower number. */
+ if (TARGET_SPACE)
+ {
+ fsize += 4 * (i - 3);
+ break;
+ }
+ fsize += 4;
+ }
}
+
+ /* We always save %r3, make room for it. */
+ if (TARGET_SPACE)
+ fsize += 8;
+
/* If we don't have a frame pointer, the register normally used for that
purpose is saved just like other registers, not in the "frame marker". */
if (! frame_pointer_needed)
@@ -2053,9 +2075,19 @@ compute_frame_size (size, fregs_live)
for (i = 66; i >= 48; i -= 2)
if (regs_ever_live[i] || regs_ever_live[i + 1])
{
- fsize += 8;
if (fregs_live)
*fregs_live = 1;
+
+ /* For out of line prologues/epilogues we only need to
+ compute the highest register number to save and
+ allocate space for all the callee saved registers
+ with a lower number. */
+ if (TARGET_SPACE)
+ {
+ fsize += 4 * (i - 46);
+ break;
+ }
+ fsize += 8;
}
fsize += current_function_outgoing_args_size;
@@ -2148,6 +2180,47 @@ hppa_expand_prologue()
tmpreg = gen_rtx (REG, SImode, 1);
size_rtx = GEN_INT (actual_fsize);
+ /* Handle out of line prologues and epilogues. */
+ if (TARGET_SPACE)
+ {
+ rtx operands[2];
+ int saves = 0;
+
+ /* Put the local_fisze into %r19. */
+ operands[0] = gen_rtx (REG, SImode, 19);
+ operands[1] = GEN_INT (local_fsize);
+ emit_move_insn (operands[0], operands[1]);
+
+ /* Put the stack size into %r21. */
+ operands[0] = gen_rtx (REG, SImode, 21);
+ operands[1] = size_rtx;
+ emit_move_insn (operands[0], operands[1]);
+
+ /* Put the register save info into %r22. */
+ for (i = 18; i >= 3; i--)
+ if (regs_ever_live[i] && ! call_used_regs[i])
+ {
+ saves = i;
+ break;
+ }
+
+ for (i = 66; i >= 48; i -= 2)
+ if (regs_ever_live[i] || regs_ever_live[i + 1])
+ {
+ saves |= ((i/2 - 12 ) << 16);
+ break;
+ }
+
+ operands[0] = gen_rtx (REG, SImode, 22);
+ operands[1] = GEN_INT (saves);
+ emit_move_insn (operands[0], operands[1]);
+
+ /* Now call the out-of-line prologue. */
+ emit_insn (gen_outline_prologue_call ());
+ emit_insn (gen_blockage ());
+ return;
+ }
+
/* Save RP first. The calling conventions manual states RP will
always be stored into the caller's frame at sp-20. */
if (regs_ever_live[2] || profile_flag)
@@ -2416,6 +2489,43 @@ hppa_expand_epilogue ()
int offset,i;
int merge_sp_adjust_with_load = 0;
+ /* Handle out of line prologues and epilogues. */
+ if (TARGET_SPACE)
+ {
+ int saves = 0;
+ rtx operands[2];
+
+ /* Put the register save info into %r22. */
+ for (i = 18; i >= 3; i--)
+ if (regs_ever_live[i] && ! call_used_regs[i])
+ {
+ saves = i;
+ break;
+ }
+
+ for (i = 66; i >= 48; i -= 2)
+ if (regs_ever_live[i] || regs_ever_live[i + 1])
+ {
+ saves |= ((i/2 - 12 ) << 16);
+ break;
+ }
+
+ emit_insn (gen_blockage ());
+
+ /* Put the local_fisze into %r19. */
+ operands[0] = gen_rtx (REG, SImode, 19);
+ operands[1] = GEN_INT (local_fsize);
+ emit_move_insn (operands[0], operands[1]);
+
+ operands[0] = gen_rtx (REG, SImode, 22);
+ operands[1] = GEN_INT (saves);
+ emit_move_insn (operands[0], operands[1]);
+
+ /* Now call the out-of-line epilogue. */
+ emit_insn (gen_outline_epilogue_call ());
+ return;
+ }
+
/* We will use this often. */
tmpreg = gen_rtx (REG, SImode, 1);