OSDN Git Service

* lib2funcs.asm (__outline_prologue): Remove frame pointer
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Mar 1996 20:18:32 +0000 (20:18 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Mar 1996 20:18:32 +0000 (20:18 +0000)
        support.
        (__outline_prologue_fp): Out of line prologue with frame pointer.
        (__outline_epilogue, outline_epilogue_fp): Similarly.
        * pa.c (compute_frame_size): Allocate enough space to avoid holes
        in the callee register saves.  Remove some special handling of %r3.
        (hppa_expand_prologue): Don't do an out of line prologue/epilogue
        if it would take more insns than an inline prologue/epilogue.
        Don't leave holes in the callee register save set.
        (hppa_expand_prologue): Corresponding changes.  Pass stack size
        to out of line epilogue code.
        * pa.h (FRAME_POINTER_REQUIRED): Revert last change.
        * pa.md (outline_prologue_call): Handle outline prologues which
        don't need frame pointers.
        (outline_epilogue_call): Similarly.
        * t-pro: Reenable multilib code.  Build a set of libraries that
        optimize for space.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@11483 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/pa/lib2funcs.asm
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/pa.md
gcc/config/pa/t-pro

index d6f5cbc..7ea7fbf 100644 (file)
@@ -1,5 +1,6 @@
 ;  Subroutines for calling unbound dynamic functions from within GDB for HPPA.
-;  Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+;  Subroutines for out of line prologues and epilogues on for the HPPA
+;  Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
 
 ;  This file is part of GNU CC.
 
@@ -75,7 +76,7 @@ L$foo
 ;
 ;      * Creates a new stack frame (sp'), size of the frame is passed in %r21
 ;
-;      * The old stack pointer is saved at sp
+;      * The old stack pointer is saved at sp (frame pointer version only).
 ;
 ;      * Saves grs (passed in low 16 bits of %r22 into the stack frame
 ;      at sp' + local_fsize (passed in %r19).
@@ -83,7 +84,7 @@ L$foo
 ;      * Saves frs (passed in high 16 bits of %r22) into the stack
 ;      frame at sp' + local_fsize (passed in %r19).
 ;
-;      * Sets up a frame pointer (in %r3).
+;      * Sets up a frame pointer (in %r3) (frame pointer version only).
 ;
 ;      * Returns to the instruction _immediately_ after the call to
 ;      this function.
@@ -107,9 +108,6 @@ __outline_prologue
        ; Make our new frame.
        add %r21,%r30,%r30
 
-       ; Save our old stack pointer.
-       stw %r20,0(0,%r20)
-
        ; Add in local_fsize to our frame pointer so we do register
        ; saves into the right place
        add %r20,%r19,%r20
@@ -192,13 +190,124 @@ L$0000
        fstws,ma %fr12,8(0,%r20)
        nop
 L$0001
+       ; Return
+       bv,n 0(%r31)
+       .EXIT
+       .PROCEND
+
+
+
+       .align 32
+       .NSUBSPA $MILLICODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+       .EXPORT __outline_prologue_fp,MILLICODE
+__outline_prologue_fp
+       .PROC
+       .CALLINFO FRAME=0,NO_CALLS
+       .ENTRY
+       copy %r30,%r20
+
+       ; Subtract 4 from our return pointer so that we return to
+       ; the right location.
+        ldo -4(%r31),%r31
+
+       ; Save off %r2
+       stw %r2,-20(0,%r30)
+
+       ; Make our new frame.
+       add %r21,%r30,%r30
+
+       ; Save our old stack pointer.
+       stw %r20,0(0,%r20)
+
+       ; Add in local_fsize to our frame pointer so we do register
+       ; saves into the right place
+       add %r20,%r19,%r20
+
+       ; %r22 tells us what registers we need to save.  The upper half
+       ; is for fp registers, the lower half for integer registers.
+       ; We put the lower half in %r1 and the upper half into %r22
+       ; for later use.
+       extru %r22,31,16,%r1
+       extrs %r22,15,16,%r22
+
+       ; %r1 now olds a value 0-18 which corresponds to the number
+       ; of grs we need to save.  We need to reverse that value so
+       ; we can just into the table and straight-line execute to the
+       ; end of the gr saves.
+       comb,= %r0,%r1,L$0002
+       subi 18,%r1,%r1
+       blr,n %r1,%r0
+       b,n L$0002
+       stws,ma %r18,4(0,%r20)
+       nop
+       stws,ma %r17,4(0,%r20)
+       nop
+       stws,ma %r16,4(0,%r20)
+       nop
+       stws,ma %r15,4(0,%r20)
+       nop
+       stws,ma %r14,4(0,%r20)
+       nop
+       stws,ma %r13,4(0,%r20)
+       nop
+       stws,ma %r12,4(0,%r20)
+       nop
+       stws,ma %r11,4(0,%r20)
+       nop
+       stws,ma %r10,4(0,%r20)
+       nop
+       stws,ma %r9,4(0,%r20)
+       nop
+       stws,ma %r8,4(0,%r20)
+       nop
+       stws,ma %r7,4(0,%r20)
+       nop
+       stws,ma %r6,4(0,%r20)
+       nop
+       stws,ma %r5,4(0,%r20)
+       nop
+       stws,ma %r4,4(0,%r20)
+       nop
+       stws,ma %r3,4(0,%r20)
+       nop
+L$0002
+       ; All gr saves are done.  Align the temporary frame pointer and
+       ; do the fr saves.
+       ldo 7(%r20),%r20
+       depi 0,31,3,%r20
+
+       comb,= %r0,%r22,L$0003
+       subi 21,%r22,%r22
+       blr,n %r22,%r0
+       b,n L$0003
+       fstws,ma %fr21,8(0,%r20)
+       nop
+       fstws,ma %fr20,8(0,%r20)
+       nop
+       fstws,ma %fr19,8(0,%r20)
+       nop
+       fstws,ma %fr18,8(0,%r20)
+       nop
+       fstws,ma %fr17,8(0,%r20)
+       nop
+       fstws,ma %fr16,8(0,%r20)
+       nop
+       fstws,ma %fr15,8(0,%r20)
+       nop
+       fstws,ma %fr14,8(0,%r20)
+       nop
+       fstws,ma %fr13,8(0,%r20)
+       nop
+       fstws,ma %fr12,8(0,%r20)
+       nop
+L$0003
        ; Return, setting up a frame pointer in the delay slot
        bv 0(%r31)
        sub %r30,%r21,%r3
-
        .EXIT
        .PROCEND
 
+
 ; This is an out-of-line epilogue.  It's operation is basically the reverse
 ; of the out-of-line prologue.
 
@@ -209,6 +318,114 @@ __outline_epilogue
        .PROC
        .CALLINFO FRAME=0,NO_CALLS
        .ENTRY
+       ; Get our original stack pointer and put it in %r20
+       sub %r30,%r21,%r20
+
+       ; Subtract 4 from our return pointer so that we return to
+       ; the right location.
+        ldo -4(%r31),%r31
+
+       ; Reload %r2
+       ldw -20(0,%r20),%r2
+
+       ; Add in local_fsize (%r19) to the frame pointer to find
+       ; the saved registers.
+       add %r20,%r19,%r20
+
+       ; %r22 tells us what registers we need to restore.  The upper half
+       ; is for fp registers, the lower half for integer registers.
+       ; We put the lower half in %r1 and the upper half into %r22
+       ; for later use.
+       extru %r22,31,16,%r1
+       extrs %r22,15,16,%r22
+
+       ; %r1 now olds a value 0-18 which corresponds to the number
+       ; of grs we need to restore.  We need to reverse that value so
+       ; we can just into the table and straight-line execute to the
+       ; end of the gr restore.
+       comb,= %r0,%r1,L$0004
+       subi 18,%r1,%r1
+       blr,n %r1,%r0
+       b,n L$0004
+       ldws,ma 4(0,%r20),%r18
+       nop
+       ldws,ma 4(0,%r20),%r17
+       nop
+       ldws,ma 4(0,%r20),%r16
+       nop
+       ldws,ma 4(0,%r20),%r15
+       nop
+       ldws,ma 4(0,%r20),%r14
+       nop
+       ldws,ma 4(0,%r20),%r13
+       nop
+       ldws,ma 4(0,%r20),%r12
+       nop
+       ldws,ma 4(0,%r20),%r11
+       nop
+       ldws,ma 4(0,%r20),%r10
+       nop
+       ldws,ma 4(0,%r20),%r9
+       nop
+       ldws,ma 4(0,%r20),%r8
+       nop
+       ldws,ma 4(0,%r20),%r7
+       nop
+       ldws,ma 4(0,%r20),%r6
+       nop
+       ldws,ma 4(0,%r20),%r5
+       nop
+       ldws,ma 4(0,%r20),%r4
+       nop
+       ldws,ma 4(0,%r20),%r3
+       nop
+L$0004
+       ; All gr restore are done.  Align the temporary frame pointer and
+       ; do the fr restore.
+       ldo 7(%r20),%r20
+       depi 0,31,3,%r20
+
+       comb,= %r0,%r22,L$0005
+       subi 21,%r22,%r22
+       blr,n %r22,%r0
+       b,n L$0005
+       fldws,ma 8(0,%r20),%fr21
+       nop
+       fldws,ma 8(0,%r20),%fr20
+       nop
+       fldws,ma 8(0,%r20),%fr19
+       nop
+       fldws,ma 8(0,%r20),%fr18
+       nop
+       fldws,ma 8(0,%r20),%fr17
+       nop
+       fldws,ma 8(0,%r20),%fr16
+       nop
+       fldws,ma 8(0,%r20),%fr15
+       nop
+       fldws,ma 8(0,%r20),%fr14
+       nop
+       fldws,ma 8(0,%r20),%fr13
+       nop
+       fldws,ma 8(0,%r20),%fr12
+       nop
+L$0005
+       ; Return and deallocate our frame.
+       bv 0(%r31)
+       sub %r30,%r21,%r30
+       .EXIT
+       .PROCEND
+
+; This is an out-of-line epilogue.  It's operation is basically the reverse
+; of the out-of-line prologue.
+
+       .align 32
+       .NSUBSPA $MILLICODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+       .EXPORT __outline_epilogue_fp,MILLICODE
+__outline_epilogue_fp
+       .PROC
+       .CALLINFO FRAME=0,NO_CALLS
+       .ENTRY
        ; Make a copy of our frame pointer into %r20
        copy %r3,%r20
 
@@ -238,10 +455,10 @@ __outline_epilogue
        ; of grs we need to restore.  We need to reverse that value so
        ; we can just into the table and straight-line execute to the
        ; end of the gr restore.
-       comb,= %r0,%r1,L$0002
+       comb,= %r0,%r1,L$0006
        subi 18,%r1,%r1
        blr,n %r1,%r0
-       b,n L$0002
+       b,n L$0006
        ldws,ma 4(0,%r20),%r18
        nop
        ldws,ma 4(0,%r20),%r17
@@ -274,16 +491,16 @@ __outline_epilogue
        nop
        ldws,ma 4(0,%r20),%r3
        nop
-L$0002
+L$0006
        ; All gr restore are done.  Align the temporary frame pointer and
        ; do the fr restore.
        ldo 7(%r20),%r20
        depi 0,31,3,%r20
 
-       comb,= %r0,%r22,L$0003
+       comb,= %r0,%r22,L$0007
        subi 21,%r22,%r22
        blr,n %r22,%r0
-       b,n L$0003
+       b,n L$0007
        fldws,ma 8(0,%r20),%fr21
        nop
        fldws,ma 8(0,%r20),%fr20
@@ -304,10 +521,11 @@ L$0002
        nop
        fldws,ma 8(0,%r20),%fr12
        nop
-L$0003
+L$0007
        ; Return and deallocate our frame.
        bv 0(%r31)
        copy %r21,%r30
        .EXIT
        .PROCEND
 
+
index 545dab5..679716d 100644 (file)
@@ -1,5 +1,5 @@
 /* Subroutines for insn-output.c for HPPA.
-   Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
    Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
 
 This file is part of GNU CC.
@@ -55,6 +55,10 @@ int hp_profile_labelno;
    registers which were saved by the current function's prologue.  */
 static int gr_saved, fr_saved;
 
+/* Whether or not the current function uses an out-of-line prologue
+   and epilogue.  */
+static int out_of_line_prologue_epilogue;
+
 static rtx find_addr_reg ();
 
 /* Keep track of the number of bytes we have output in the CODE subspaces
@@ -2042,52 +2046,30 @@ compute_frame_size (size, fregs_live)
      we need to add this in because of STARTING_FRAME_OFFSET. */
   fsize = size + (size || frame_pointer_needed ? 8 : 0);
 
-  for (i = 18; i >= 4; i--)
-    {
-      if (regs_ever_live[i])
-       {
-         /* 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;
+  /* We do not want to create holes in the callee registers that
+     get saved (confuses gdb), so once we know the highest we just
+     save all the ones below it, whether they're used or not.  */
+  for (i = 18; i >= 3; i--)
+    if (regs_ever_live[i])
+      {
+       fsize += 4 * (i - 2);
+       break;
+      }
 
-  /* 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)
-    {
-      if (regs_ever_live[FRAME_POINTER_REGNUM])
-       fsize += 4;
-    }
+  /* Round the stack.  */
   fsize = (fsize + 7) & ~7;
 
+  /* We do not want to create holes in the callee registers that
+     get saved (confuses gdb), so once we know the highest we just
+     save all the ones below it, whether they're used or not.  */
   for (i = 66; i >= 48; i -= 2)
     if (regs_ever_live[i] || regs_ever_live[i + 1])
       {
        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 += 4 * (i = 46);
+       break;
       }
 
   fsize += current_function_outgoing_args_size;
@@ -2185,42 +2167,86 @@ hppa_expand_prologue()
     {
       rtx operands[2];
       int saves = 0;
+      int outline_insn_count = 0;
+      int inline_insn_count = 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]);
+      /* Count the number of insns for the inline and out of line
+        variants so we can choose one appropriately.
 
-      /* Put the stack size into %r21.  */
-      operands[0] = gen_rtx (REG, SImode, 21);
-      operands[1] = size_rtx;
-      emit_move_insn (operands[0], operands[1]);
+        No need to screw with counting actual_fsize operations -- they're
+        done for both inline and out of line prologues.  */
+      if (regs_ever_live[2])
+       inline_insn_count += 1;
+
+      if (! cint_ok_for_move (local_fsize))
+       outline_insn_count += 2;
+      else
+       outline_insn_count += 1;
 
       /* Put the register save info into %r22.  */
       for (i = 18; i >= 3; i--)
        if (regs_ever_live[i] && ! call_used_regs[i])
          {
+           /* -1 because the stack adjustment is normally done in
+              the same insn as a register save.  */
+           inline_insn_count += (i - 2) - 1;
            saves = i;
             break;
          }
-         
+  
       for (i = 66; i >= 48; i -= 2)
        if (regs_ever_live[i] || regs_ever_live[i + 1])
          {
+           /* +1 needed as we load %r1 with the start of the freg
+              save area.  */
+           inline_insn_count += (i/2 - 23) + 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]);
+      if (frame_pointer_needed)
+       inline_insn_count += 3;
 
-      /* Now call the out-of-line prologue.  */
-      emit_insn (gen_outline_prologue_call ());
-      emit_insn (gen_blockage ());
-      return;     
+      if (! cint_ok_for_move (saves))
+       outline_insn_count += 2;
+      else
+       outline_insn_count += 1;
+
+      if (TARGET_PORTABLE_RUNTIME)
+       outline_insn_count += 2;
+      else
+       outline_insn_count += 1;
+       
+      /* If there's a lot of insns in the prologue, then do it as
+        an out-of-line sequence.  */
+      if (inline_insn_count > outline_insn_count)
+       {
+         /* 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]);
+
+         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 ());
+
+         /* Note that we're using an out-of-line prologue.  */
+         out_of_line_prologue_epilogue = 1;
+         return;     
+       }
     }
 
+  out_of_line_prologue_epilogue = 0;
+
   /* 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)
@@ -2345,22 +2371,28 @@ hppa_expand_prologue()
      was done earlier.  */
   if (frame_pointer_needed)
     {
+      int found_one = 0;
       for (i = 18, offset = local_fsize; i >= 4; i--)
-       if (regs_ever_live[i] && ! call_used_regs[i])
+       if (regs_ever_live[i] && ! call_used_regs[i]
+           || found_one)
          {
+           found_one = 1;
            store_reg (i, offset, FRAME_POINTER_REGNUM);
            offset += 4;
            gr_saved++;
          }
-      /* Account for %r4 which is saved in a special place.  */
+      /* Account for %r3 which is saved in a special place.  */
       gr_saved++;
     }
   /* No frame pointer needed.  */
   else
     {
+      int found_one = 0;
       for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
-       if (regs_ever_live[i] && ! call_used_regs[i])
+       if (regs_ever_live[i] && ! call_used_regs[i]
+           || found_one)
          {
+           found_one = 1;
            /* If merge_sp_adjust_with_store is nonzero, then we can
               optimize the first GR save.  */
            if (merge_sp_adjust_with_store)
@@ -2400,13 +2432,18 @@ hppa_expand_prologue()
 
       /* Now actually save the FP registers.  */
       for (i = 66; i >= 48; i -= 2)
-       if (regs_ever_live[i] || regs_ever_live[i + 1])
-         {
-           emit_move_insn (gen_rtx (MEM, DFmode,
-                                    gen_rtx (POST_INC, DFmode, tmpreg)),
-                           gen_rtx (REG, DFmode, i));
-           fr_saved++;
-         }
+       {
+         int found_one = 0;
+         if (regs_ever_live[i] || regs_ever_live[i + 1]
+             || found_one)
+           {
+             found_one = 1;
+             emit_move_insn (gen_rtx (MEM, DFmode,
+                                      gen_rtx (POST_INC, DFmode, tmpreg)),
+                             gen_rtx (REG, DFmode, i));
+             fr_saved++;
+           }
+       }
     }
 
   /* When generating PIC code it is necessary to save/restore the
@@ -2490,7 +2527,7 @@ hppa_expand_epilogue ()
   int merge_sp_adjust_with_load  = 0;
 
   /* Handle out of line prologues and epilogues.  */
-  if (TARGET_SPACE)
+  if (TARGET_SPACE && out_of_line_prologue_epilogue)
     {
       int saves = 0;
       rtx operands[2];
@@ -2517,6 +2554,11 @@ hppa_expand_epilogue ()
       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] = GEN_INT (actual_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]);
@@ -2545,9 +2587,12 @@ hppa_expand_epilogue ()
   /* General register restores.  */
   if (frame_pointer_needed)
     {
+      int found_one = 0;
       for (i = 18, offset = local_fsize; i >= 4; i--)
-       if (regs_ever_live[i] && ! call_used_regs[i])
+       if (regs_ever_live[i] && ! call_used_regs[i]
+           || found_one)
          {
+           found_one = 1;
            load_reg (i, offset, FRAME_POINTER_REGNUM);
            offset += 4;
          }
@@ -2555,19 +2600,24 @@ hppa_expand_epilogue ()
   else
     {
       for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
-       if (regs_ever_live[i] && ! call_used_regs[i])
-         {
-           /* Only for the first load.
-              merge_sp_adjust_with_load holds the register load
-              with which we will merge the sp adjustment.  */
-           if (VAL_14_BITS_P (actual_fsize + 20)
-               && local_fsize == 0
-               && ! merge_sp_adjust_with_load)
-             merge_sp_adjust_with_load = i;
-           else
-             load_reg (i, offset, STACK_POINTER_REGNUM);
-           offset += 4;
-         }
+       {
+         int found_one = 0;
+         if (regs_ever_live[i] && ! call_used_regs[i]
+             || found_one)
+           {
+             found_one = 1;
+             /* Only for the first load.
+                merge_sp_adjust_with_load holds the register load
+                with which we will merge the sp adjustment.  */
+             if (VAL_14_BITS_P (actual_fsize + 20)
+                 && local_fsize == 0
+                 && ! merge_sp_adjust_with_load)
+               merge_sp_adjust_with_load = i;
+             else
+               load_reg (i, offset, STACK_POINTER_REGNUM);
+             offset += 4;
+           }
+       }
     }
 
   /* Align pointer properly (doubleword boundary).  */
@@ -2584,10 +2634,16 @@ hppa_expand_epilogue ()
 
       /* Actually do the restores now.  */
       for (i = 66; i >= 48; i -= 2)
-       if (regs_ever_live[i] || regs_ever_live[i + 1])
-         emit_move_insn (gen_rtx (REG, DFmode, i),
-                         gen_rtx (MEM, DFmode,
-                                  gen_rtx (POST_INC, DFmode, tmpreg)));
+       {
+         int found_one = 0;
+         if (regs_ever_live[i] || regs_ever_live[i + 1])
+           {
+             found_one = 1;
+             emit_move_insn (gen_rtx (REG, DFmode, i),
+                             gen_rtx (MEM, DFmode,
+                                      gen_rtx (POST_INC, DFmode, tmpreg)));
+           }
+       }
     }
 
   /* Emit a blockage insn here to keep these insns from being moved to
index df1fedd..a464bda 100644 (file)
@@ -560,11 +560,9 @@ do {                                                               \
 /* Base register for access to local variables of the function.  */
 #define FRAME_POINTER_REGNUM 3
 
-/* Value should be nonzero if functions must have frame pointers.
-   All functions have frame pointers when optimizing for space
-   (for now).  */
+/* Value should be nonzero if functions must have frame pointers.  */
 #define FRAME_POINTER_REQUIRED \
-  (current_function_calls_alloca || TARGET_SPACE)
+  (current_function_calls_alloca)
 
 /* C statement to store the difference between the frame pointer
    and the stack pointer values immediately after the function prologue.
index a64d17b..116f372 100644 (file)
@@ -1,5 +1,5 @@
 ;;- Machine description for HP PA-RISC architecture for GNU C compiler
-;;   Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+;;   Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
 ;;   Contributed by the Center for Software Science at the University
 ;;   of Utah.
 
   ""
   "*
 {
-  /* Must import the magic millicode routine.  */
-  output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
+  extern int frame_pointer_needed;
 
-  /* The out-of-line prologue will make sure we return to the right
-     instruction.  */
-  if (TARGET_PORTABLE_RUNTIME)
+  /* We need two different versions depending on whether or not we
+     need a frame pointer.   Also note that we return to the instruction
+     immediately after the branch rather than two instructions after the
+     break as normally is the case.  */
+  if (frame_pointer_needed)
     {
-      output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
-      output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
+      /* Must import the magic millicode routine(s).  */
+      output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
+
+      if (TARGET_PORTABLE_RUNTIME)
+       {
+         output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
+         output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
+                          NULL);
+       }
+      else
+       output_asm_insn (\"bl,n __outline_prologue_fp,%%r31\", NULL);
     }
   else
-    output_asm_insn (\"bl,n __outline_prologue,%%r31\", NULL);
+    {
+      /* Must import the magic millicode routine(s).  */
+      output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
+
+      if (TARGET_PORTABLE_RUNTIME)
+       {
+         output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
+         output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
+       }
+      else
+       output_asm_insn (\"bl,n __outline_prologue,%%r31\", NULL);
+    }
   return \"\";
 }"
   [(set_attr "type" "multi")
   ""
   "*
 {
-  /* Must import the magic millicode routine.  */
-  output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
+  extern int frame_pointer_needed;
 
-  /* The out-of-line prologue will make sure we return to the right
-     instruction.  */
-  if (TARGET_PORTABLE_RUNTIME)
+  /* We need two different versions depending on whether or not we
+     need a frame pointer.   Also note that we return to the instruction
+     immediately after the branch rather than two instructions after the
+     break as normally is the case.  */
+  if (frame_pointer_needed)
     {
-      output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
-      output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
+      /* Must import the magic millicode routine.  */
+      output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
+
+      /* The out-of-line prologue will make sure we return to the right
+        instruction.  */
+      if (TARGET_PORTABLE_RUNTIME)
+       {
+         output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
+         output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
+                          NULL);
+       }
+      else
+       output_asm_insn (\"bl,n __outline_epilogue_fp,%%r31\", NULL);
     }
   else
-    output_asm_insn (\"bl,n __outline_epilogue,%%r31\", NULL);
+    {
+      /* Must import the magic millicode routine.  */
+      output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
+
+      /* The out-of-line prologue will make sure we return to the right
+        instruction.  */
+      if (TARGET_PORTABLE_RUNTIME)
+       {
+         output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
+         output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
+       }
+      else
+       output_asm_insn (\"bl,n __outline_epilogue,%%r31\", NULL);
+    }
   return \"\";
 }"
   [(set_attr "type" "multi")
index af77bd8..f9a7732 100644 (file)
@@ -19,3 +19,12 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
 lib2funcs.asm: $(srcdir)/config/pa/lib2funcs.asm
        rm -f lib2funcs.asm
        cp $(srcdir)/config/pa/lib2funcs.asm .
+
+# Build the libraries for both speed and space optimizations
+
+MULTILIB_OPTIONS=mspace
+MULTILIB_DIRNAMES=space
+MULTILIB_MATCHES=
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib