pa-protos.h (attr_length_millicode_call): Remove second argument.
* pa-protos.h (attr_length_millicode_call): Remove second argument. (attr_length_indirect_call, attr_length_indirect_call, attr_length_save_restore_dltp): New prototypes. * pa.c (attr_length_millicode_call): Remove second argument. Check INSN_ADDRESSES_SET_P in distance calculation. (output_millicode_call): Check INSN_ADDRESSES_SET_P before using INSN_ADDRESSES. (attr_length_call): Check INSN_ADDRESSES_SET_P in distance calculation. (output_call): Check INSN_ADDRESSES_SET_P before using INSN_ADDRESSES. Call attr_length_call directly. (attr_length_indirect_call, output_indirect_call, attr_length_save_restore_dltp): New functions. * pa.md (attr_length_millicode_call): Drop second argument from all patterns. (return_internal_pic): Delete. (return_external_pic): Remove use of PIC register and pic operand and flag checks. (epilogue): Use return_internal for both normal and pic code. (call, call_value): Emit new 32-bit pic patterns for symref and indirect calls. Remove uses for arg pointer and pic register. (call_symref_pic, call_symref_pic_post_reload, call_reg_pic, call_reg_pic_post_reload, call_val_symref_pic, call_val_symref_pic_post_reload, call_val_reg_pic, call_val_reg_pic_post_reload): New pre and post reload insn patterns. Implement define_split and define_peephole2 patterns for pre reload patterns. (call_symref_64bit, call_internal_reg_64bit, call_value_symref_64bit, call_value_internal_reg_64bit): Shorten names. (all call patterns): Explicitly indicate registers used and clobbered. Use attr_length_indirect_call and attr_length_save_restore_dltp for attribute length calculation. Move code generation for indirect calls to output_indirect_call. (sibcall, sibcall_value): Don't restore PIC register. (exception_receiver, builtin_setjmp_receiver): Add blockage after PIC register retore. From-SVN: r62272
This commit is contained in:
parent
8cacda7c8b
commit
611ad29eed
|
@ -1,3 +1,41 @@
|
|||
2003-02-02 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
|
||||
|
||||
* pa-protos.h (attr_length_millicode_call): Remove second argument.
|
||||
(attr_length_indirect_call, attr_length_indirect_call,
|
||||
attr_length_save_restore_dltp): New prototypes.
|
||||
* pa.c (attr_length_millicode_call): Remove second argument. Check
|
||||
INSN_ADDRESSES_SET_P in distance calculation.
|
||||
(output_millicode_call): Check INSN_ADDRESSES_SET_P before using
|
||||
INSN_ADDRESSES.
|
||||
(attr_length_call): Check INSN_ADDRESSES_SET_P in distance calculation.
|
||||
(output_call): Check INSN_ADDRESSES_SET_P before using INSN_ADDRESSES.
|
||||
Call attr_length_call directly.
|
||||
(attr_length_indirect_call, output_indirect_call,
|
||||
attr_length_save_restore_dltp): New functions.
|
||||
* pa.md (attr_length_millicode_call): Drop second argument from all
|
||||
patterns.
|
||||
(return_internal_pic): Delete.
|
||||
(return_external_pic): Remove use of PIC register and pic operand and
|
||||
flag checks.
|
||||
(epilogue): Use return_internal for both normal and pic code.
|
||||
(call, call_value): Emit new 32-bit pic patterns for symref and
|
||||
indirect calls. Remove uses for arg pointer and pic register.
|
||||
(call_symref_pic, call_symref_pic_post_reload, call_reg_pic,
|
||||
call_reg_pic_post_reload, call_val_symref_pic,
|
||||
call_val_symref_pic_post_reload, call_val_reg_pic,
|
||||
call_val_reg_pic_post_reload): New pre and post reload insn patterns.
|
||||
Implement define_split and define_peephole2 patterns for pre reload
|
||||
patterns.
|
||||
(call_symref_64bit, call_internal_reg_64bit, call_value_symref_64bit,
|
||||
call_value_internal_reg_64bit): Shorten names.
|
||||
(all call patterns): Explicitly indicate registers used and clobbered.
|
||||
Use attr_length_indirect_call and attr_length_save_restore_dltp for
|
||||
attribute length calculation. Move code generation for indirect calls
|
||||
to output_indirect_call.
|
||||
(sibcall, sibcall_value): Don't restore PIC register.
|
||||
(exception_receiver, builtin_setjmp_receiver): Add blockage after PIC
|
||||
register retore.
|
||||
|
||||
2003-02-02 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
|
||||
|
||||
* doc/install.texi (Testing): Simplify and compress instructions
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Prototypes for pa.c functions used in the md file & elsewhere.
|
||||
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
|
@ -51,6 +51,7 @@ extern const char *output_movb PARAMS ((rtx *, rtx, int, int));
|
|||
extern const char *output_parallel_movb PARAMS ((rtx *, int));
|
||||
extern const char *output_parallel_addb PARAMS ((rtx *, int));
|
||||
extern const char *output_call PARAMS ((rtx, rtx, int));
|
||||
extern const char *output_indirect_call PARAMS ((rtx, rtx));
|
||||
extern const char *output_millicode_call PARAMS ((rtx, rtx));
|
||||
extern const char *output_mul_insn PARAMS ((int, rtx));
|
||||
extern const char *output_div_insn PARAMS ((rtx *, int, rtx));
|
||||
|
@ -104,8 +105,10 @@ extern int jump_in_call_delay PARAMS ((rtx));
|
|||
extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
|
||||
enum machine_mode, rtx));
|
||||
extern int hppa_fpstore_bypass_p PARAMS ((rtx, rtx));
|
||||
extern int attr_length_millicode_call PARAMS ((rtx, int));
|
||||
extern int attr_length_millicode_call PARAMS ((rtx));
|
||||
extern int attr_length_call PARAMS ((rtx, int));
|
||||
extern int attr_length_indirect_call PARAMS ((rtx));
|
||||
extern int attr_length_save_restore_dltp PARAMS ((rtx));
|
||||
|
||||
/* Declare functions defined in pa.c and used in templates. */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Subroutines for insn-output.c for HPPA.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002 Free Software Foundation, Inc.
|
||||
2002, 2003 Free Software Foundation, Inc.
|
||||
Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
@ -6279,37 +6279,42 @@ length_fp_args (insn)
|
|||
return length;
|
||||
}
|
||||
|
||||
/* We include the delay slot in the returned length as it is better to
|
||||
/* Return the attribute length for the millicode call instruction INSN.
|
||||
The length must match the code generated by output_millicode_call.
|
||||
We include the delay slot in the returned length as it is better to
|
||||
over estimate the length than to under estimate it. */
|
||||
|
||||
int
|
||||
attr_length_millicode_call (insn, length)
|
||||
attr_length_millicode_call (insn)
|
||||
rtx insn;
|
||||
int length;
|
||||
{
|
||||
unsigned long distance = total_code_bytes + INSN_ADDRESSES (INSN_UID (insn));
|
||||
unsigned long distance = -1;
|
||||
|
||||
if (distance < total_code_bytes)
|
||||
distance = -1;
|
||||
if (INSN_ADDRESSES_SET_P ())
|
||||
{
|
||||
distance = (total_code_bytes + insn_current_reference_address (insn));
|
||||
if (distance < total_code_bytes)
|
||||
distance = -1;
|
||||
}
|
||||
|
||||
if (TARGET_64BIT)
|
||||
{
|
||||
if (!TARGET_LONG_CALLS && distance < 7600000)
|
||||
return length + 8;
|
||||
return 8;
|
||||
|
||||
return length + 20;
|
||||
return 20;
|
||||
}
|
||||
else if (TARGET_PORTABLE_RUNTIME)
|
||||
return length + 24;
|
||||
return 24;
|
||||
else
|
||||
{
|
||||
if (!TARGET_LONG_CALLS && distance < 240000)
|
||||
return length + 8;
|
||||
return 8;
|
||||
|
||||
if (TARGET_LONG_ABS_CALL && !flag_pic)
|
||||
return length + 12;
|
||||
return 12;
|
||||
|
||||
return length + 24;
|
||||
return 24;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6439,16 +6444,22 @@ output_millicode_call (insn, call_dest)
|
|||
|
||||
/* See if the return address can be adjusted. Use the containing
|
||||
sequence insn's address. */
|
||||
seq_insn = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));
|
||||
distance = (INSN_ADDRESSES (INSN_UID (JUMP_LABEL (NEXT_INSN (insn))))
|
||||
- INSN_ADDRESSES (INSN_UID (seq_insn)) - 8);
|
||||
|
||||
if (VAL_14_BITS_P (distance))
|
||||
if (INSN_ADDRESSES_SET_P ())
|
||||
{
|
||||
xoperands[1] = gen_label_rtx ();
|
||||
output_asm_insn ("ldo %0-%1(%2),%2", xoperands);
|
||||
(*targetm.asm_out.internal_label) (asm_out_file, "L",
|
||||
CODE_LABEL_NUMBER (xoperands[1]));
|
||||
seq_insn = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));
|
||||
distance = (INSN_ADDRESSES (INSN_UID (JUMP_LABEL (NEXT_INSN (insn))))
|
||||
- INSN_ADDRESSES (INSN_UID (seq_insn)) - 8);
|
||||
|
||||
if (VAL_14_BITS_P (distance))
|
||||
{
|
||||
xoperands[1] = gen_label_rtx ();
|
||||
output_asm_insn ("ldo %0-%1(%2),%2", xoperands);
|
||||
(*targetm.asm_out.internal_label) (asm_out_file, "L",
|
||||
CODE_LABEL_NUMBER (xoperands[1]));
|
||||
}
|
||||
else
|
||||
/* ??? This branch may not reach its target. */
|
||||
output_asm_insn ("nop\n\tb,n %0", xoperands);
|
||||
}
|
||||
else
|
||||
/* ??? This branch may not reach its target. */
|
||||
|
@ -6462,18 +6473,25 @@ output_millicode_call (insn, call_dest)
|
|||
return "";
|
||||
}
|
||||
|
||||
/* We include the delay slot in the returned length as it is better to
|
||||
over estimate the length than to under estimate it. */
|
||||
/* 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 must match the code generated by output_call. We include the delay
|
||||
slot in the returned length as it is better to over estimate the length
|
||||
than to under estimate it. */
|
||||
|
||||
int
|
||||
attr_length_call (insn, sibcall)
|
||||
rtx insn;
|
||||
int sibcall;
|
||||
{
|
||||
unsigned long distance = total_code_bytes + INSN_ADDRESSES (INSN_UID (insn));
|
||||
unsigned long distance = -1;
|
||||
|
||||
if (distance < total_code_bytes)
|
||||
distance = -1;
|
||||
if (INSN_ADDRESSES_SET_P ())
|
||||
{
|
||||
distance = (total_code_bytes + insn_current_reference_address (insn));
|
||||
if (distance < total_code_bytes)
|
||||
distance = -1;
|
||||
}
|
||||
|
||||
if (TARGET_64BIT)
|
||||
{
|
||||
|
@ -6535,7 +6553,6 @@ output_call (insn, call_dest, sibcall)
|
|||
{
|
||||
int delay_insn_deleted = 0;
|
||||
int delay_slot_filled = 0;
|
||||
int attr_length = get_attr_length (insn);
|
||||
int seq_length = dbr_sequence_length ();
|
||||
rtx xoperands[2];
|
||||
|
||||
|
@ -6543,9 +6560,7 @@ output_call (insn, call_dest, sibcall)
|
|||
|
||||
/* Handle the common case where we're sure that the branch will reach
|
||||
the beginning of the $CODE$ subspace. */
|
||||
if (!TARGET_LONG_CALLS
|
||||
&& ((seq_length == 0 && attr_length == 12)
|
||||
|| (seq_length != 0 && attr_length == 8)))
|
||||
if (!TARGET_LONG_CALLS && attr_length_call (insn, sibcall) == 8)
|
||||
{
|
||||
xoperands[1] = gen_rtx_REG (word_mode, sibcall ? 0 : 2);
|
||||
output_asm_insn ("{bl|b,l} %0,%1", xoperands);
|
||||
|
@ -6773,7 +6788,7 @@ output_call (insn, call_dest, sibcall)
|
|||
/* This call has an unconditional jump in its delay slot. */
|
||||
xoperands[0] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
|
||||
|
||||
if (!delay_slot_filled)
|
||||
if (!delay_slot_filled && INSN_ADDRESSES_SET_P ())
|
||||
{
|
||||
/* See if the return address can be adjusted. Use the containing
|
||||
sequence insn's address. */
|
||||
|
@ -6804,6 +6819,117 @@ output_call (insn, call_dest, sibcall)
|
|||
return "";
|
||||
}
|
||||
|
||||
/* Return the attribute length of the indirect call instruction INSN.
|
||||
The length must match the code generated by output_indirect call.
|
||||
The returned length includes the delay slot. Currently, the delay
|
||||
slot of an indirect call sequence is not exposed and it is used by
|
||||
the sequence itself. */
|
||||
|
||||
int
|
||||
attr_length_indirect_call (insn)
|
||||
rtx insn;
|
||||
{
|
||||
unsigned long distance = -1;
|
||||
|
||||
if (INSN_ADDRESSES_SET_P ())
|
||||
{
|
||||
distance = (total_code_bytes + insn_current_reference_address (insn));
|
||||
if (distance < total_code_bytes)
|
||||
distance = -1;
|
||||
}
|
||||
|
||||
if (TARGET_64BIT)
|
||||
return 12;
|
||||
|
||||
if (TARGET_FAST_INDIRECT_CALLS
|
||||
|| (!TARGET_PORTABLE_RUNTIME
|
||||
&& ((TARGET_PA_20 && distance < 7600000) || distance < 240000)))
|
||||
return 8;
|
||||
|
||||
if (flag_pic)
|
||||
return 24;
|
||||
|
||||
if (TARGET_PORTABLE_RUNTIME)
|
||||
return 20;
|
||||
|
||||
/* Out of reach, can use ble. */
|
||||
return 12;
|
||||
}
|
||||
|
||||
const char *
|
||||
output_indirect_call (insn, call_dest)
|
||||
rtx insn;
|
||||
rtx call_dest;
|
||||
{
|
||||
rtx xoperands[1];
|
||||
|
||||
if (TARGET_64BIT)
|
||||
{
|
||||
xoperands[0] = call_dest;
|
||||
output_asm_insn ("ldd 16(%0),%%r2", xoperands);
|
||||
output_asm_insn ("bve,l (%%r2),%%r2\n\tldd 24(%0),%%r27", xoperands);
|
||||
return "";
|
||||
}
|
||||
|
||||
/* First the special case for kernels, level 0 systems, etc. */
|
||||
if (TARGET_FAST_INDIRECT_CALLS)
|
||||
return "ble 0(%%sr4,%%r22)\n\tcopy %%r31,%%r2";
|
||||
|
||||
/* Now the normal case -- we can reach $$dyncall directly or
|
||||
we're sure that we can get there via a long-branch stub.
|
||||
|
||||
No need to check target flags as the length uniquely identifies
|
||||
the remaining cases. */
|
||||
if (attr_length_indirect_call (insn) == 8)
|
||||
return ".CALL\tARGW0=GR\n\t{bl|b,l} $$dyncall,%%r31\n\tcopy %%r31,%%r2";
|
||||
|
||||
/* Long millicode call, but we are not generating PIC or portable runtime
|
||||
code. */
|
||||
if (attr_length_indirect_call (insn) == 12)
|
||||
return ".CALL\tARGW0=GR\n\tldil L'$$dyncall,%%r2\n\tble R'$$dyncall(%%sr4,%%r2)\n\tcopy %%r31,%%r2";
|
||||
|
||||
/* Long millicode call for portable runtime. */
|
||||
if (attr_length_indirect_call (insn) == 20)
|
||||
return "ldil L'$$dyncall,%%r31\n\tldo R'$$dyncall(%%r31),%%r31\n\tblr %%r0,%%r2\n\tbv,n %%r0(%%r31)\n\tnop";
|
||||
|
||||
/* We need a long PIC call to $$dyncall. */
|
||||
xoperands[0] = NULL_RTX;
|
||||
output_asm_insn ("{bl|b,l} .+8,%%r1", xoperands);
|
||||
if (TARGET_SOM || !TARGET_GAS)
|
||||
{
|
||||
xoperands[0] = gen_label_rtx ();
|
||||
output_asm_insn ("addil L'$$dyncall-%0,%%r1", xoperands);
|
||||
(*targetm.asm_out.internal_label) (asm_out_file, "L",
|
||||
CODE_LABEL_NUMBER (xoperands[0]));
|
||||
output_asm_insn ("ldo R'$$dyncall-%0(%%r1),%%r1", xoperands);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_asm_insn ("addil L'$$dyncall-$PIC_pcrel$0+4,%%r1", xoperands);
|
||||
output_asm_insn ("ldo R'$$dyncall-$PIC_pcrel$0+8(%%r1),%%r1",
|
||||
xoperands);
|
||||
}
|
||||
output_asm_insn ("blr %%r0,%%r2", xoperands);
|
||||
output_asm_insn ("bv,n %%r0(%%r1)\n\tnop", xoperands);
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Return the total length of the save and restore instructions needed for
|
||||
the data linkage table pointer (i.e., the PIC register) across the call
|
||||
instruction INSN. No-return calls do not require a save and restore.
|
||||
In addition, we may be able to avoid the save and restore for calls
|
||||
within the same translation unit. */
|
||||
|
||||
int
|
||||
attr_length_save_restore_dltp (insn)
|
||||
rtx insn;
|
||||
{
|
||||
if (find_reg_note (insn, REG_NORETURN, NULL_RTX))
|
||||
return 0;
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
/* In HPUX 8.0's shared library scheme, special relocations are needed
|
||||
for function labels if they might be passed to a function
|
||||
in a shared library (because shared libraries don't live in code
|
||||
|
|
1100
gcc/config/pa/pa.md
1100
gcc/config/pa/pa.md
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue