Commit 32562302 by John David Anglin Committed by John David Anglin

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
parent daa027cc
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> 2003-08-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* builtins.c (CASE_MATHFN): New helper macro. * builtins.c (CASE_MATHFN): New helper macro.
......
...@@ -4417,23 +4417,9 @@ pa_adjust_insn_length (insn, length) ...@@ -4417,23 +4417,9 @@ pa_adjust_insn_length (insn, length)
{ {
rtx pat = PATTERN (insn); rtx pat = PATTERN (insn);
/* Call insns which are *not* indirect and have unfilled delay slots. */ /* Jumps inside switch tables which have unfilled delay slots need
if (GET_CODE (insn) == CALL_INSN) adjustment. */
{ if (GET_CODE (insn) == JUMP_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
&& simplejump_p (insn) && simplejump_p (insn)
&& GET_MODE (insn) == SImode) && GET_MODE (insn) == SImode)
return 4; return 4;
...@@ -6758,77 +6744,95 @@ output_millicode_call (insn, call_dest) ...@@ -6758,77 +6744,95 @@ output_millicode_call (insn, call_dest)
/* Return the attribute length of the call instruction INSN. The SIBCALL /* Return the attribute length of the call instruction INSN. The SIBCALL
flag indicates whether INSN is a regular call or a sibling call. The 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. length returned must be longer than the code actually generated by
When the target supports jumps in the delay slot, we need an extra output_call. Since branch shortening is done before delay branch
four bytes to handle the situation where the jump can't reach its sequencing, there is no way to determine whether or not the delay
destination. */ 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 int
attr_length_call (insn, sibcall) attr_length_call (insn, sibcall)
rtx insn; rtx insn;
int sibcall; int sibcall;
{ {
int local_call;
rtx call_dest;
tree call_decl;
int length = 0;
rtx pat = PATTERN (insn);
unsigned long distance = -1; unsigned long distance = -1;
unsigned long total = IN_NAMED_SECTION_P (cfun->decl) ? 0 : total_code_bytes;
if (INSN_ADDRESSES_SET_P ()) 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)); distance = (total + insn_current_reference_address (insn));
if (distance < total) if (distance < total)
distance = -1; distance = -1;
} }
if (TARGET_64BIT) /* Determine if this is a local call. */
{ if (GET_CODE (XVECEXP (pat, 0, 0)) == CALL)
if (!TARGET_LONG_CALLS call_dest = XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0);
&& ((!sibcall && distance < 7600000) || distance < 240000))
return 8;
return (sibcall ? 28 : 24);
}
else else
{ call_dest = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0);
if (!TARGET_LONG_CALLS
&& ((TARGET_PA_20 && !sibcall && distance < 7600000)
|| distance < 240000))
return 8;
if (TARGET_LONG_ABS_CALL && !flag_pic) call_decl = SYMBOL_REF_DECL (call_dest);
return 16; local_call = call_decl && (*targetm.binds_local_p) (call_decl);
if ((TARGET_SOM && TARGET_LONG_PIC_SDIFF_CALL) /* pc-relative branch. */
|| (TARGET_GAS && TARGET_LONG_PIC_PCREL_CALL)) if (!TARGET_LONG_CALLS
{ && ((TARGET_PA_20 && !sibcall && distance < 7600000)
if (TARGET_PA_20) || distance < 240000))
return 20; length += 8;
return 28; /* 64-bit plabel sequence. */
} else if (TARGET_64BIT && !local_call)
else length += sibcall ? 28 : 24;
{
int length = 28;
if (TARGET_SOM) /* non-pic long absolute branch sequence. */
length += length_fp_args (insn); else if ((TARGET_LONG_ABS_CALL || local_call) && !flag_pic)
length += 12;
if (flag_pic) /* long pc-relative branch sequence. */
length += 4; 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) if (!TARGET_PA_20 && !TARGET_NO_SPACE_REGS)
length += 4; length += 8;
}
if (TARGET_PA_20) /* 32-bit plabel sequence. */
return length; else
{
length += 32;
if (!TARGET_NO_SPACE_REGS) if (TARGET_SOM)
length += 8; length += length_fp_args (insn);
if (flag_pic)
length += 4;
if (!TARGET_PA_20)
{
if (!sibcall) if (!sibcall)
length += 8; length += 8;
return length; if (!TARGET_NO_SPACE_REGS)
length += 8;
} }
} }
return length;
} }
/* INSN is a function call. It may have an unconditional jump /* INSN is a function call. It may have an unconditional jump
...@@ -6846,7 +6850,7 @@ output_call (insn, call_dest, sibcall) ...@@ -6846,7 +6850,7 @@ output_call (insn, call_dest, sibcall)
int delay_slot_filled = 0; int delay_slot_filled = 0;
int seq_length = dbr_sequence_length (); int seq_length = dbr_sequence_length ();
tree call_decl = SYMBOL_REF_DECL (call_dest); 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]; rtx xoperands[2];
xoperands[0] = call_dest; xoperands[0] = call_dest;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment