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
This commit is contained in:
John David Anglin 2003-08-14 18:06:12 +00:00 committed by John David Anglin
parent daa027cc47
commit 3256230283
2 changed files with 73 additions and 61 deletions

View File

@ -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.

View File

@ -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;
/* 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
call_dest = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0);
return (sibcall ? 28 : 24);
call_decl = SYMBOL_REF_DECL (call_dest);
local_call = call_decl && (*targetm.binds_local_p) (call_decl);
/* pc-relative branch. */
if (!TARGET_LONG_CALLS
&& ((TARGET_PA_20 && !sibcall && distance < 7600000)
|| distance < 240000))
length += 8;
/* 64-bit plabel sequence. */
else if (TARGET_64BIT && !local_call)
length += sibcall ? 28 : 24;
/* non-pic long absolute branch sequence. */
else if ((TARGET_LONG_ABS_CALL || local_call) && !flag_pic)
length += 12;
/* 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 (!TARGET_PA_20 && !TARGET_NO_SPACE_REGS)
length += 8;
}
/* 32-bit plabel sequence. */
else
{
if (!TARGET_LONG_CALLS
&& ((TARGET_PA_20 && !sibcall && distance < 7600000)
|| distance < 240000))
return 8;
length += 32;
if (TARGET_LONG_ABS_CALL && !flag_pic)
return 16;
if (TARGET_SOM)
length += length_fp_args (insn);
if ((TARGET_SOM && TARGET_LONG_PIC_SDIFF_CALL)
|| (TARGET_GAS && TARGET_LONG_PIC_PCREL_CALL))
if (flag_pic)
length += 4;
if (!TARGET_PA_20)
{
if (TARGET_PA_20)
return 20;
return 28;
}
else
{
int length = 28;
if (TARGET_SOM)
length += length_fp_args (insn);
if (flag_pic)
length += 4;
if (!sibcall)
length += 4;
if (TARGET_PA_20)
return length;
length += 8;
if (!TARGET_NO_SPACE_REGS)
length += 8;
if (!sibcall)
length += 8;
return length;
}
}
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;