diff options
author | John David Anglin <dave.anglin@nrc-cnrc.gc.ca> | 2003-08-14 18:06:12 +0000 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2003-08-14 18:06:12 +0000 |
commit | 3256230283e35950672c596e3a9bbe68967941d1 (patch) | |
tree | cdd7610dcd50fe973582972d66a316d8c780186c /gcc | |
parent | daa027cc473c361231dd4aa9f362674fe2c9a0fb (diff) | |
download | gcc-3256230283e35950672c596e3a9bbe68967941d1.zip gcc-3256230283e35950672c596e3a9bbe68967941d1.tar.gz gcc-3256230283e35950672c596e3a9bbe68967941d1.tar.bz2 |
pa.c (pa_adjust_insn_length): Delete adjustment for delay slot in direct calls.
* pa.c (pa_adjust_insn_length): Delete adjustment for delay slot in
direct calls.
(attr_length_call): Include it here. Improve length estimate for
local calls.
(output_call): Use targetm.binds_local_p.
From-SVN: r70441
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/pa/pa.c | 122 |
2 files changed, 71 insertions, 59 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cf86c0a..565fc99 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2003-08-14 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + * pa.c (pa_adjust_insn_length): Delete adjustment for delay slot in + direct calls. + (attr_length_call): Include it here. Improve length estimate for + local calls. + (output_call): Use targetm.binds_local_p. + 2003-08-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * builtins.c (CASE_MATHFN): New helper macro. diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index eb875f8..88c3d08 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -4417,23 +4417,9 @@ pa_adjust_insn_length (insn, length) { rtx pat = PATTERN (insn); - /* Call insns which are *not* indirect and have unfilled delay slots. */ - if (GET_CODE (insn) == CALL_INSN) - { - - if (GET_CODE (XVECEXP (pat, 0, 0)) == CALL - && GET_CODE (XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0)) == SYMBOL_REF) - return 4; - else if (GET_CODE (XVECEXP (pat, 0, 0)) == SET - && GET_CODE (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)) - == SYMBOL_REF) - return 4; - else - return 0; - } - /* Jumps inside switch tables which have unfilled delay slots - also need adjustment. */ - else if (GET_CODE (insn) == JUMP_INSN + /* Jumps inside switch tables which have unfilled delay slots need + adjustment. */ + if (GET_CODE (insn) == JUMP_INSN && simplejump_p (insn) && GET_MODE (insn) == SImode) return 4; @@ -6758,77 +6744,95 @@ output_millicode_call (insn, call_dest) /* Return the attribute length of the call instruction INSN. The SIBCALL flag indicates whether INSN is a regular call or a sibling call. The - length returned must be longer than the code generated by output_call. - When the target supports jumps in the delay slot, we need an extra - four bytes to handle the situation where the jump can't reach its - destination. */ + length returned must be longer than the code actually generated by + output_call. Since branch shortening is done before delay branch + sequencing, there is no way to determine whether or not the delay + slot will be filled during branch shortening. Even when the delay + slot is filled, we may have to add a nop if the delay slot contains + a branch that can't reach its target. Thus, we always have to include + the delay slot in the length estimate. This used to be done in + pa_adjust_insn_length but we do it here now as some sequences always + fill the delay slot and we can save four bytes in the estimate for + these sequences. */ int attr_length_call (insn, sibcall) rtx insn; int sibcall; { + int local_call; + rtx call_dest; + tree call_decl; + int length = 0; + rtx pat = PATTERN (insn); unsigned long distance = -1; - unsigned long total = IN_NAMED_SECTION_P (cfun->decl) ? 0 : total_code_bytes; if (INSN_ADDRESSES_SET_P ()) { + unsigned long total; + + total = IN_NAMED_SECTION_P (cfun->decl) ? 0 : total_code_bytes; distance = (total + insn_current_reference_address (insn)); if (distance < total) distance = -1; } - if (TARGET_64BIT) - { - if (!TARGET_LONG_CALLS - && ((!sibcall && distance < 7600000) || distance < 240000)) - return 8; - - return (sibcall ? 28 : 24); - } + /* Determine if this is a local call. */ + if (GET_CODE (XVECEXP (pat, 0, 0)) == CALL) + call_dest = XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0); else - { - if (!TARGET_LONG_CALLS - && ((TARGET_PA_20 && !sibcall && distance < 7600000) - || distance < 240000)) - return 8; + call_dest = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0); - if (TARGET_LONG_ABS_CALL && !flag_pic) - return 16; + call_decl = SYMBOL_REF_DECL (call_dest); + local_call = call_decl && (*targetm.binds_local_p) (call_decl); - if ((TARGET_SOM && TARGET_LONG_PIC_SDIFF_CALL) - || (TARGET_GAS && TARGET_LONG_PIC_PCREL_CALL)) - { - if (TARGET_PA_20) - return 20; + /* pc-relative branch. */ + if (!TARGET_LONG_CALLS + && ((TARGET_PA_20 && !sibcall && distance < 7600000) + || distance < 240000)) + length += 8; - return 28; - } - else - { - int length = 28; + /* 64-bit plabel sequence. */ + else if (TARGET_64BIT && !local_call) + length += sibcall ? 28 : 24; - if (TARGET_SOM) - length += length_fp_args (insn); + /* non-pic long absolute branch sequence. */ + else if ((TARGET_LONG_ABS_CALL || local_call) && !flag_pic) + length += 12; - if (flag_pic) - length += 4; + /* long pc-relative branch sequence. */ + else if ((TARGET_SOM && TARGET_LONG_PIC_SDIFF_CALL) + || (TARGET_64BIT && !TARGET_GAS) + || (TARGET_GAS && (TARGET_LONG_PIC_PCREL_CALL || local_call))) + { + length += 20; - if (!sibcall) - length += 4; + if (!TARGET_PA_20 && !TARGET_NO_SPACE_REGS) + length += 8; + } - if (TARGET_PA_20) - return length; + /* 32-bit plabel sequence. */ + else + { + length += 32; - if (!TARGET_NO_SPACE_REGS) - length += 8; + if (TARGET_SOM) + length += length_fp_args (insn); + + if (flag_pic) + length += 4; + if (!TARGET_PA_20) + { if (!sibcall) length += 8; - return length; + if (!TARGET_NO_SPACE_REGS) + length += 8; } } + + return length; } /* INSN is a function call. It may have an unconditional jump @@ -6846,7 +6850,7 @@ output_call (insn, call_dest, sibcall) int delay_slot_filled = 0; int seq_length = dbr_sequence_length (); tree call_decl = SYMBOL_REF_DECL (call_dest); - int local_call = call_decl && !TREE_PUBLIC (call_decl); + int local_call = call_decl && (*targetm.binds_local_p) (call_decl); rtx xoperands[2]; xoperands[0] = call_dest; |