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>
|
||||
|
||||
* builtins.c (CASE_MATHFN): New helper macro.
|
||||
|
|
|
@ -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,55 +6744,77 @@ 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
|
||||
{
|
||||
call_dest = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0);
|
||||
|
||||
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))
|
||||
return 8;
|
||||
length += 8;
|
||||
|
||||
if (TARGET_LONG_ABS_CALL && !flag_pic)
|
||||
return 16;
|
||||
/* 64-bit plabel sequence. */
|
||||
else if (TARGET_64BIT && !local_call)
|
||||
length += sibcall ? 28 : 24;
|
||||
|
||||
if ((TARGET_SOM && TARGET_LONG_PIC_SDIFF_CALL)
|
||||
|| (TARGET_GAS && TARGET_LONG_PIC_PCREL_CALL))
|
||||
/* 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)))
|
||||
{
|
||||
if (TARGET_PA_20)
|
||||
return 20;
|
||||
length += 20;
|
||||
|
||||
return 28;
|
||||
if (!TARGET_PA_20 && !TARGET_NO_SPACE_REGS)
|
||||
length += 8;
|
||||
}
|
||||
|
||||
/* 32-bit plabel sequence. */
|
||||
else
|
||||
{
|
||||
int length = 28;
|
||||
length += 32;
|
||||
|
||||
if (TARGET_SOM)
|
||||
length += length_fp_args (insn);
|
||||
|
@ -6814,21 +6822,17 @@ attr_length_call (insn, sibcall)
|
|||
if (flag_pic)
|
||||
length += 4;
|
||||
|
||||
if (!TARGET_PA_20)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
|
Loading…
Reference in New Issue