diff options
-rw-r--r-- | gcc/config/pa/lib2funcs.asm | 244 | ||||
-rw-r--r-- | gcc/config/pa/pa.c | 222 | ||||
-rw-r--r-- | gcc/config/pa/pa.h | 6 | ||||
-rw-r--r-- | gcc/config/pa/pa.md | 80 | ||||
-rw-r--r-- | gcc/config/pa/t-pro | 9 |
5 files changed, 444 insertions, 117 deletions
diff --git a/gcc/config/pa/lib2funcs.asm b/gcc/config/pa/lib2funcs.asm index d6f5cbc..7ea7fbf 100644 --- a/gcc/config/pa/lib2funcs.asm +++ b/gcc/config/pa/lib2funcs.asm @@ -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 + diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 545dab5..679716d 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -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 diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index df1fedd..a464bda 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -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. diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index a64d17b..116f372 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -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. @@ -4850,18 +4850,39 @@ "" "* { - /* 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") @@ -4882,18 +4903,43 @@ "" "* { - /* 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") diff --git a/gcc/config/pa/t-pro b/gcc/config/pa/t-pro index af77bd8..f9a7732 100644 --- a/gcc/config/pa/t-pro +++ b/gcc/config/pa/t-pro @@ -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 |