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:
John David Anglin 2003-02-02 06:04:58 +00:00 committed by John David Anglin
parent 8cacda7c8b
commit 611ad29eed
4 changed files with 1028 additions and 307 deletions

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff