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:
parent
daa027cc47
commit
3256230283
|
@ -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>
|
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
|
||||||
/* 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))
|
else
|
||||||
return 8;
|
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
|
else
|
||||||
{
|
{
|
||||||
if (!TARGET_LONG_CALLS
|
length += 32;
|
||||||
&& ((TARGET_PA_20 && !sibcall && distance < 7600000)
|
|
||||||
|| distance < 240000))
|
|
||||||
return 8;
|
|
||||||
|
|
||||||
if (TARGET_LONG_ABS_CALL && !flag_pic)
|
if (TARGET_SOM)
|
||||||
return 16;
|
length += length_fp_args (insn);
|
||||||
|
|
||||||
if ((TARGET_SOM && TARGET_LONG_PIC_SDIFF_CALL)
|
if (flag_pic)
|
||||||
|| (TARGET_GAS && TARGET_LONG_PIC_PCREL_CALL))
|
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)
|
if (!sibcall)
|
||||||
length += 4;
|
length += 8;
|
||||||
|
|
||||||
if (TARGET_PA_20)
|
|
||||||
return length;
|
|
||||||
|
|
||||||
if (!TARGET_NO_SPACE_REGS)
|
if (!TARGET_NO_SPACE_REGS)
|
||||||
length += 8;
|
length += 8;
|
||||||
|
|
||||||
if (!sibcall)
|
|
||||||
length += 8;
|
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue