pa-linux.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Define.

* pa-linux.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Define.
	* pa-protos.h (attr_length_millicode_call, attr_length_call,
	pa_init_machine_status): Declare new global functions.
	* pa.c (void copy_fp_args, length_fp_args, get_plabel): Declare and
	implement new functions.
	(attr_length_millicode_call, attr_length_call): Implement.
	(total_code_bytes): Change type to long.
	(pa_output_function_prologue): Compute total_code_bytes on TARGET_64BIT.
	Reset counter if flag_function_sections.
	(output_deferred_plabels): Set output alignment to 3 for TARGET_64BIT.
	(output_cbranch): Move call to gen_label_rtx.
	(output_millicode_call): Rewrite adding long TARGET_64BIT call, expose
	delay slot in all variants, shorten pc-relative calls.
	(output_call): Rewrite adding long TARGET_64BIT call, improved delay
	slot usage and exposure, various new call variants, and shortened
	sequences for some variants on TARGET_PA_20.
	Miscellaneous format changes.
	* pa.h (total_code_bytes): Change type to long.
	(MASK_LONG_CALLS, TARGET_LONG_CALLS, TARGET_LONG_ABS_CALL,
	TARGET_LONG_PIC_SDIFF_CALL, TARGET_LONG_PIC_PCREL_CALL): Define.
	(TARGET_SWITCHES): Add "-mlong-calls" and "-mno-long-calls" options.
	(EXTRA_CONSTRAINT, GO_IF_LEGITIMATE_ADDRESS,
	LEGITIMIZE_RELOAD_ADDRESS): Don't use long floating point loads and
	stores on TARGET_ELF32.
	*pa.md (define_delay): Allow insns in delay on TARGET_PORTABLE_RUNTIME.
	(unnamed patterns for mulsi3, divsi3, udivsi3, modsi3, umodsi3 and
	canonicalize_funcptr_for_compare expanders): Calculate attribute length
	attr_length_millicode_call().
	(call_internal_symref, call_value_internal_symref): Clobber register 1.
	Calculate attribute length using attr_length_call().
	(call_internal_reg_64bit, call_value_internal_reg_64bit): Move gp load
	to delay slot.
	(sibcall, sibcall_value): Rewrite.
	(sibcall_internal_symref, sibcall_value_internal_symref): Clobber
	register 1.  Use attr_length_call().
	(sibcall_internal_symref_64bit, sibcall_value_internal_symref_64bit):
	New patterns.
	(unamed pattern for canonicalize_funcptr_for_compare): Rewrite.
	* som.h (MEMBER_TYPE_FORCES_BLK): Define.
	* t-pa64 (TARGET_LIBGCC2_CFLAGS): Add "-mlong-calls".
	* doc/invoke.texi (mlong-calls): Document.

From-SVN: r58665
This commit is contained in:
John David Anglin 2002-10-31 03:13:44 +00:00 committed by John David Anglin
parent 8c081e84f7
commit a02aa5b099
9 changed files with 820 additions and 623 deletions

View File

@ -1,3 +1,47 @@
2002-10-30 John David Anglin <dave@hiauly.hia.nrc.ca>
* pa-linux.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Define.
* pa-protos.h (attr_length_millicode_call, attr_length_call,
pa_init_machine_status): Declare new global functions.
* pa.c (void copy_fp_args, length_fp_args, get_plabel): Declare and
implement new functions.
(attr_length_millicode_call, attr_length_call): Implement.
(total_code_bytes): Change type to long.
(pa_output_function_prologue): Compute total_code_bytes on TARGET_64BIT.
Reset counter if flag_function_sections.
(output_deferred_plabels): Set output alignment to 3 for TARGET_64BIT.
(output_cbranch): Move call to gen_label_rtx.
(output_millicode_call): Rewrite adding long TARGET_64BIT call, expose
delay slot in all variants, shorten pc-relative calls.
(output_call): Rewrite adding long TARGET_64BIT call, improved delay
slot usage and exposure, various new call variants, and shortened
sequences for some variants on TARGET_PA_20.
Miscellaneous format changes.
* pa.h (total_code_bytes): Change type to long.
(MASK_LONG_CALLS, TARGET_LONG_CALLS, TARGET_LONG_ABS_CALL,
TARGET_LONG_PIC_SDIFF_CALL, TARGET_LONG_PIC_PCREL_CALL): Define.
(TARGET_SWITCHES): Add "-mlong-calls" and "-mno-long-calls" options.
(EXTRA_CONSTRAINT, GO_IF_LEGITIMATE_ADDRESS,
LEGITIMIZE_RELOAD_ADDRESS): Don't use long floating point loads and
stores on TARGET_ELF32.
*pa.md (define_delay): Allow insns in delay on TARGET_PORTABLE_RUNTIME.
(unnamed patterns for mulsi3, divsi3, udivsi3, modsi3, umodsi3 and
canonicalize_funcptr_for_compare expanders): Calculate attribute length
attr_length_millicode_call().
(call_internal_symref, call_value_internal_symref): Clobber register 1.
Calculate attribute length using attr_length_call().
(call_internal_reg_64bit, call_value_internal_reg_64bit): Move gp load
to delay slot.
(sibcall, sibcall_value): Rewrite.
(sibcall_internal_symref, sibcall_value_internal_symref): Clobber
register 1. Use attr_length_call().
(sibcall_internal_symref_64bit, sibcall_value_internal_symref_64bit):
New patterns.
(unamed pattern for canonicalize_funcptr_for_compare): Rewrite.
* som.h (MEMBER_TYPE_FORCES_BLK): Define.
* t-pa64 (TARGET_LIBGCC2_CFLAGS): Add "-mlong-calls".
* doc/invoke.texi (mlong-calls): Document.
2002-10-30 Roger Sayle <roger@eyesopen.com>
* fold-const.c (fold_binary_op_with_conditional_arg): Improve

View File

@ -196,6 +196,19 @@ Boston, MA 02111-1307, USA. */
} \
while (0)
/* As well as globalizing the label, we need to encode the label
to ensure a plabel is generated in an indirect call. */
#undef ASM_OUTPUT_EXTERNAL_LIBCALL
#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
do \
{ \
if (!FUNCTION_NAME_P (XSTR (FUN, 0))) \
hppa_encode_label (FUN); \
(*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0)); \
} \
while (0)
/* Linux always uses gas. */
#undef TARGET_GAS
#define TARGET_GAS 1

View File

@ -105,6 +105,8 @@ 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_call PARAMS ((rtx, int));
/* Declare functions defined in pa.c and used in templates. */

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@ enum cmp_type /* comparison type */
};
/* For long call handling. */
extern unsigned int total_code_bytes;
extern unsigned long total_code_bytes;
/* Which processor to schedule for. */
@ -152,6 +152,12 @@ extern int target_flags;
#define TARGET_GNU_LD (target_flags & MASK_GNU_LD)
#endif
/* Force generation of long calls. */
#define MASK_LONG_CALLS 32768
#ifndef TARGET_LONG_CALLS
#define TARGET_LONG_CALLS (target_flags & MASK_LONG_CALLS)
#endif
#ifndef TARGET_PA_10
#define TARGET_PA_10 (target_flags & (MASK_PA_11 | MASK_PA_20) == 0)
#endif
@ -179,6 +185,27 @@ extern int target_flags;
#define TARGET_SOM 0
#endif
/* The following three defines are potential target switches. The current
defines are optimal given the current capabilities of GAS and GNU ld. */
/* Define to a C expression evaluating to true to use long absolute calls.
Currently, only the HP assembler and SOM linker support long absolute
calls. They are used only in non-pic code. */
#define TARGET_LONG_ABS_CALL (TARGET_SOM && !TARGET_GAS)
/* Define to a C expression evaluating to true to use long pic symbol
difference calls. This is a call variant similar to the long pic
pc-relative call. Long pic symbol difference calls are only used with
the HP SOM linker. Currently, only the HP assembler supports these
calls. GAS doesn't allow an arbritrary difference of two symbols. */
#define TARGET_LONG_PIC_SDIFF_CALL (!TARGET_GAS)
/* Define to a C expression evaluating to true to use long pic
pc-relative calls. Long pic pc-relative calls are only used with
GAS. Currently, they are usable for calls within a module but
not for external calls. */
#define TARGET_LONG_PIC_PCREL_CALL 0
/* Macro to define tables used to set the flags. This is a
list in braces of target switches with each switch being
{ "NAME", VALUE, "HELP_STRING" }. VALUE is the bits to set,
@ -237,6 +264,10 @@ extern int target_flags;
N_("Generate code for huge switch statements") }, \
{ "no-big-switch", -MASK_BIG_SWITCH, \
N_("Do not generate code for huge switch statements") }, \
{ "long-calls", MASK_LONG_CALLS, \
N_("Always generate long calls") }, \
{ "no-long-calls", -MASK_LONG_CALLS, \
N_("Generate long calls only when needed") }, \
{ "linker-opt", 0, \
N_("Enable linker optimizations") }, \
SUBTARGET_SWITCHES \
@ -1193,8 +1224,14 @@ extern int may_call_alloca;
/* Using DFmode forces only short displacements \
to be recognized as valid in reg+d addresses. \
However, this is not necessary for PA2.0 since\
it has long FP loads/stores. */ \
it has long FP loads/stores. \
\
FIXME: the ELF32 linker clobbers the LSB of \
the FP register number in {fldw,fstw} insns. \
Thus, we only allow long FP loads/stores on \
TARGET_64BIT. */ \
&& memory_address_p ((TARGET_PA_20 \
&& !TARGET_ELF32 \
? GET_MODE (OP) \
: DFmode), \
XEXP (OP, 0)) \
@ -1300,7 +1337,7 @@ extern int may_call_alloca;
if (GET_CODE (index) == CONST_INT \
&& ((INT_14_BITS (index) \
&& (TARGET_SOFT_FLOAT \
|| (TARGET_PA_20 \
|| (TARGET_PA_20 \
&& ((MODE == SFmode \
&& (INTVAL (index) % 4) == 0)\
|| (MODE == DFmode \
@ -1327,6 +1364,7 @@ extern int may_call_alloca;
/* We can allow symbolic LO_SUM addresses\
for PA2.0. */ \
|| (TARGET_PA_20 \
&& !TARGET_ELF32 \
&& GET_CODE (XEXP (X, 1)) != CONST_INT)\
|| ((MODE) != SFmode \
&& (MODE) != DFmode))) \
@ -1340,6 +1378,7 @@ extern int may_call_alloca;
/* We can allow symbolic LO_SUM addresses\
for PA2.0. */ \
|| (TARGET_PA_20 \
&& !TARGET_ELF32 \
&& GET_CODE (XEXP (X, 1)) != CONST_INT)\
|| ((MODE) != SFmode \
&& (MODE) != DFmode))) \
@ -1354,7 +1393,7 @@ extern int may_call_alloca;
&& REG_OK_FOR_BASE_P (XEXP (X, 0)) \
&& GET_CODE (XEXP (X, 1)) == UNSPEC \
&& (TARGET_SOFT_FLOAT \
|| TARGET_PA_20 \
|| (TARGET_PA_20 && !TARGET_ELF32) \
|| ((MODE) != SFmode \
&& (MODE) != DFmode))) \
goto ADDR; \
@ -1386,7 +1425,7 @@ do { \
rtx new, temp = NULL_RTX; \
\
mask = (GET_MODE_CLASS (MODE) == MODE_FLOAT \
? (TARGET_PA_20 ? 0x3fff : 0x1f) : 0x3fff); \
? (TARGET_PA_20 && !TARGET_ELF32 ? 0x3fff : 0x1f) : 0x3fff); \
\
if (optimize \
&& GET_CODE (AD) == PLUS) \

View File

@ -105,12 +105,9 @@
(define_delay (eq_attr "type" "call")
[(eq_attr "in_call_delay" "true") (nil) (nil)])
;; millicode call delay slot description. Note it disallows delay slot
;; when TARGET_PORTABLE_RUNTIME is true.
;; Millicode call delay slot description.
(define_delay (eq_attr "type" "milli")
[(and (eq_attr "in_call_delay" "true")
(eq (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0)))
(nil) (nil)])
[(eq_attr "in_call_delay" "true") (nil) (nil)])
;; Return and other similar instructions.
(define_delay (eq_attr "type" "branch,parallel_branch")
@ -4089,27 +4086,7 @@
"!TARGET_64BIT"
"* return output_mul_insn (0, insn);"
[(set_attr "type" "milli")
(set (attr "length")
(cond [
;; Target (or stub) within reach
(and (lt (plus (symbol_ref "total_code_bytes") (pc))
(const_int 240000))
(eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0)))
(const_int 4)
;; Out of reach PIC
(ne (symbol_ref "flag_pic")
(const_int 0))
(const_int 24)
;; Out of reach PORTABLE_RUNTIME
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0))
(const_int 20)]
;; Out of reach, can use ble
(const_int 12)))])
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn, 0)"))])
(define_insn ""
[(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
@ -4120,7 +4097,7 @@
"TARGET_64BIT"
"* return output_mul_insn (0, insn);"
[(set_attr "type" "milli")
(set (attr "length") (const_int 4))])
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn, 0)"))])
(define_expand "muldi3"
[(set (match_operand:DI 0 "register_operand" "")
@ -4211,27 +4188,7 @@
"*
return output_div_insn (operands, 0, insn);"
[(set_attr "type" "milli")
(set (attr "length")
(cond [
;; Target (or stub) within reach
(and (lt (plus (symbol_ref "total_code_bytes") (pc))
(const_int 240000))
(eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0)))
(const_int 4)
;; Out of reach PIC
(ne (symbol_ref "flag_pic")
(const_int 0))
(const_int 24)
;; Out of reach PORTABLE_RUNTIME
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0))
(const_int 20)]
;; Out of reach, can use ble
(const_int 12)))])
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn, 0)"))])
(define_insn ""
[(set (reg:SI 29)
@ -4245,7 +4202,7 @@
"*
return output_div_insn (operands, 0, insn);"
[(set_attr "type" "milli")
(set (attr "length") (const_int 4))])
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn, 0)"))])
(define_expand "udivsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
@ -4261,6 +4218,7 @@
"
{
operands[3] = gen_reg_rtx (SImode);
if (TARGET_64BIT)
{
operands[5] = gen_rtx_REG (SImode, 2);
@ -4287,27 +4245,7 @@
"*
return output_div_insn (operands, 1, insn);"
[(set_attr "type" "milli")
(set (attr "length")
(cond [
;; Target (or stub) within reach
(and (lt (plus (symbol_ref "total_code_bytes") (pc))
(const_int 240000))
(eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0)))
(const_int 4)
;; Out of reach PIC
(ne (symbol_ref "flag_pic")
(const_int 0))
(const_int 24)
;; Out of reach PORTABLE_RUNTIME
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0))
(const_int 20)]
;; Out of reach, can use ble
(const_int 12)))])
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn, 0)"))])
(define_insn ""
[(set (reg:SI 29)
@ -4321,7 +4259,7 @@
"*
return output_div_insn (operands, 1, insn);"
[(set_attr "type" "milli")
(set (attr "length") (const_int 4))])
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn, 0)"))])
(define_expand "modsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
@ -4360,27 +4298,7 @@
"*
return output_mod_insn (0, insn);"
[(set_attr "type" "milli")
(set (attr "length")
(cond [
;; Target (or stub) within reach
(and (lt (plus (symbol_ref "total_code_bytes") (pc))
(const_int 240000))
(eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0)))
(const_int 4)
;; Out of reach PIC
(ne (symbol_ref "flag_pic")
(const_int 0))
(const_int 24)
;; Out of reach PORTABLE_RUNTIME
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0))
(const_int 20)]
;; Out of reach, can use ble
(const_int 12)))])
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn, 0)"))])
(define_insn ""
[(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
@ -4393,7 +4311,7 @@
"*
return output_mod_insn (0, insn);"
[(set_attr "type" "milli")
(set (attr "length") (const_int 4))])
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn, 0)"))])
(define_expand "umodsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
@ -4432,27 +4350,7 @@
"*
return output_mod_insn (1, insn);"
[(set_attr "type" "milli")
(set (attr "length")
(cond [
;; Target (or stub) within reach
(and (lt (plus (symbol_ref "total_code_bytes") (pc))
(const_int 240000))
(eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0)))
(const_int 4)
;; Out of reach PIC
(ne (symbol_ref "flag_pic")
(const_int 0))
(const_int 24)
;; Out of reach PORTABLE_RUNTIME
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0))
(const_int 20)]
;; Out of reach, can use ble
(const_int 12)))])
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn, 0)"))])
(define_insn ""
[(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
@ -4465,7 +4363,7 @@
"*
return output_mod_insn (1, insn);"
[(set_attr "type" "milli")
(set (attr "length") (const_int 4))])
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn, 0)"))])
;;- and instructions
;; We define DImode `and` so with DImode `not` we can get
@ -6036,11 +5934,12 @@
call_insn = emit_call_insn (gen_call_internal_reg (operands[1]));
}
if (TARGET_64BIT)
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
if (flag_pic)
{
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
if (TARGET_64BIT)
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
/* After each call we must restore the PIC register, even if it
doesn't appear to be used. */
@ -6052,6 +5951,7 @@
(define_insn "call_internal_symref"
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" "i"))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (const_int 0))]
"! TARGET_PORTABLE_RUNTIME"
@ -6061,21 +5961,7 @@
return output_call (insn, operands[0], 0);
}"
[(set_attr "type" "call")
(set (attr "length")
;; If we're sure that we can either reach the target or that the
;; linker can use a long-branch stub, then the length is at most
;; 8 bytes.
;;
;; For long-calls the length will be at most 68 bytes (non-pic)
;; or 84 bytes (pic). */
;; Else we have to use a long-call;
(if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
(const_int 240000))
(const_int 8)
(if_then_else (eq (symbol_ref "flag_pic")
(const_int 0))
(const_int 68)
(const_int 84))))])
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
(define_insn "call_internal_reg_64bit"
[(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
@ -6086,15 +5972,16 @@
"*
{
/* ??? Needs more work. Length computation, split into multiple insns,
do not use %r22 directly, expose delay slot. */
return \"ldd 16(%0),%%r2\;ldd 24(%0),%%r27\;bve,l (%%r2),%%r2\;nop\";
expose delay slot. */
return \"ldd 16(%0),%%r2\;bve,l (%%r2),%%r2\;ldd 24(%0),%%r27\";
}"
[(set_attr "type" "dyncall")
(set (attr "length") (const_int 16))])
(set (attr "length") (const_int 12))])
(define_insn "call_internal_reg"
[(call (mem:SI (reg:SI 22))
(match_operand 0 "" "i"))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (const_int 1))]
""
@ -6218,11 +6105,13 @@
call_insn = emit_call_insn (gen_call_value_internal_reg (operands[0],
operands[2]));
}
if (TARGET_64BIT)
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
if (flag_pic)
{
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
if (TARGET_64BIT)
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
/* After each call we must restore the PIC register, even if it
doesn't appear to be used. */
@ -6235,6 +6124,7 @@
[(set (match_operand 0 "" "=rf")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "i")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (const_int 0))]
;;- Don't use operand 1 for most machines.
@ -6245,21 +6135,7 @@
return output_call (insn, operands[1], 0);
}"
[(set_attr "type" "call")
(set (attr "length")
;; If we're sure that we can either reach the target or that the
;; linker can use a long-branch stub, then the length is at most
;; 8 bytes.
;;
;; For long-calls the length will be at most 68 bytes (non-pic)
;; or 84 bytes (pic). */
;; Else we have to use a long-call;
(if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
(const_int 240000))
(const_int 8)
(if_then_else (eq (symbol_ref "flag_pic")
(const_int 0))
(const_int 68)
(const_int 84))))])
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
(define_insn "call_value_internal_reg_64bit"
[(set (match_operand 0 "" "=rf")
@ -6271,16 +6147,17 @@
"*
{
/* ??? Needs more work. Length computation, split into multiple insns,
do not use %r22 directly, expose delay slot. */
return \"ldd 16(%1),%%r2\;ldd 24(%1),%%r27\;bve,l (%%r2),%%r2\;nop\";
expose delay slot. */
return \"ldd 16(%1),%%r2\;bve,l (%%r2),%%r2\;ldd 24(%1),%%r27\";
}"
[(set_attr "type" "dyncall")
(set (attr "length") (const_int 16))])
(set (attr "length") (const_int 12))])
(define_insn "call_value_internal_reg"
[(set (match_operand 0 "" "=rf")
(call (mem:SI (reg:SI 22))
(match_operand 1 "" "i")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (const_int 1))]
""
@ -6389,10 +6266,9 @@
}")
(define_expand "sibcall"
[(parallel [(call (match_operand:SI 0 "" "")
(match_operand 1 "" ""))
(clobber (reg:SI 0))])]
"! TARGET_PORTABLE_RUNTIME"
[(call (match_operand:SI 0 "" "")
(match_operand 1 "" ""))]
"!TARGET_PORTABLE_RUNTIME"
"
{
rtx op;
@ -6400,8 +6276,21 @@
op = XEXP (operands[0], 0);
/* We do not allow indirect sibling calls. */
call_insn = emit_call_insn (gen_sibcall_internal_symref (op, operands[1]));
if (TARGET_64BIT)
emit_move_insn (arg_pointer_rtx,
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
GEN_INT (64)));
/* Indirect sibling calls are not allowed. */
if (TARGET_64BIT)
call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
else
call_insn = gen_sibcall_internal_symref (op, operands[1]);
call_insn = emit_call_insn (call_insn);
if (TARGET_64BIT)
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
if (flag_pic)
{
@ -6417,38 +6306,39 @@
(define_insn "sibcall_internal_symref"
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" "i"))
(clobber (reg:SI 0))
(clobber (reg:SI 1))
(use (reg:SI 2))
(use (const_int 0))]
"! TARGET_PORTABLE_RUNTIME"
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
"*
{
output_arg_descriptor (insn);
return output_call (insn, operands[0], 1);
}"
[(set_attr "type" "call")
(set (attr "length")
;; If we're sure that we can either reach the target or that the
;; linker can use a long-branch stub, then the length is at most
;; 8 bytes.
;;
;; For long-calls the length will be at most 68 bytes (non-pic)
;; or 84 bytes (pic). */
;; Else we have to use a long-call;
(if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
(const_int 240000))
(const_int 8)
(if_then_else (eq (symbol_ref "flag_pic")
(const_int 0))
(const_int 68)
(const_int 84))))])
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
(define_insn "sibcall_internal_symref_64bit"
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" "i"))
(clobber (reg:SI 1))
(clobber (reg:SI 27))
(use (reg:SI 2))
(use (const_int 0))]
"TARGET_64BIT"
"*
{
output_arg_descriptor (insn);
return output_call (insn, operands[0], 1);
}"
[(set_attr "type" "call")
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
(define_expand "sibcall_value"
[(parallel [(set (match_operand 0 "" "")
[(set (match_operand 0 "" "")
(call (match_operand:SI 1 "" "")
(match_operand 2 "" "")))
(clobber (reg:SI 0))])]
"! TARGET_PORTABLE_RUNTIME"
(match_operand 2 "" "")))]
"!TARGET_PORTABLE_RUNTIME"
"
{
rtx op;
@ -6456,10 +6346,24 @@
op = XEXP (operands[1], 0);
/* We do not allow indirect sibling calls. */
call_insn = emit_call_insn (gen_sibcall_value_internal_symref (operands[0],
op,
operands[2]));
if (TARGET_64BIT)
emit_move_insn (arg_pointer_rtx,
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
GEN_INT (64)));
/* Indirect sibling calls are not allowed. */
if (TARGET_64BIT)
call_insn
= gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
else
call_insn
= gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
call_insn = emit_call_insn (call_insn);
if (TARGET_64BIT)
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
if (flag_pic)
{
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
@ -6475,32 +6379,34 @@
[(set (match_operand 0 "" "=rf")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "i")))
(clobber (reg:SI 0))
(clobber (reg:SI 1))
(use (reg:SI 2))
(use (const_int 0))]
;;- Don't use operand 1 for most machines.
"! TARGET_PORTABLE_RUNTIME"
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
"*
{
output_arg_descriptor (insn);
return output_call (insn, operands[1], 1);
}"
[(set_attr "type" "call")
(set (attr "length")
;; If we're sure that we can either reach the target or that the
;; linker can use a long-branch stub, then the length is at most
;; 8 bytes.
;;
;; For long-calls the length will be at most 68 bytes (non-pic)
;; or 84 bytes (pic). */
;; Else we have to use a long-call;
(if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
(const_int 240000))
(const_int 8)
(if_then_else (eq (symbol_ref "flag_pic")
(const_int 0))
(const_int 68)
(const_int 84))))])
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
(define_insn "sibcall_value_internal_symref_64bit"
[(set (match_operand 0 "" "=rf")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "i")))
(clobber (reg:SI 1))
(clobber (reg:SI 27))
(use (reg:SI 2))
(use (const_int 0))]
"TARGET_64BIT"
"*
{
output_arg_descriptor (insn);
return output_call (insn, operands[1], 1);
}"
[(set_attr "type" "call")
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
(define_insn "nop"
[(const_int 0)]
@ -7392,6 +7298,12 @@
"!TARGET_64BIT"
"*
{
int length = get_attr_length (insn);
rtx xoperands[2];
xoperands[0] = GEN_INT (length - 8);
xoperands[1] = GEN_INT (length - 16);
/* Must import the magic millicode routine. */
output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
@ -7400,60 +7312,24 @@
First, copy our input parameter into %r29 just in case we don't
need to call $$sh_func_adrs. */
output_asm_insn (\"copy %%r26,%%r29\", NULL);
output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
/* Next, examine the low two bits in %r26, if they aren't 0x2, then
we use %r26 unchanged. */
if (get_attr_length (insn) == 32)
output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+24\", NULL);
else if (get_attr_length (insn) == 40)
output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+32\", NULL);
else if (get_attr_length (insn) == 44)
output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+36\", NULL);
else
output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+20\", NULL);
output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
output_asm_insn (\"ldi 4096,%%r31\", NULL);
/* Next, compare %r26 with 4096, if %r26 is less than or equal to
4096, then we use %r26 unchanged. */
if (get_attr_length (insn) == 32)
output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+16\",
NULL);
else if (get_attr_length (insn) == 40)
output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+24\",
NULL);
else if (get_attr_length (insn) == 44)
output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+28\",
NULL);
else
output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+12\",
NULL);
4096, then again we use %r26 unchanged. */
output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
/* Else call $$sh_func_adrs to extract the function's real add24. */
/* Finally, call $$sh_func_adrs to extract the function's real add24. */
return output_millicode_call (insn,
gen_rtx_SYMBOL_REF (SImode,
\"$$sh_func_adrs\"));
\"$$sh_func_adrs\"));
}"
[(set_attr "type" "multi")
(set (attr "length")
(cond [
;; Target (or stub) within reach
(and (lt (plus (symbol_ref "total_code_bytes") (pc))
(const_int 240000))
(eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0)))
(const_int 28)
;; Out of reach PIC
(ne (symbol_ref "flag_pic")
(const_int 0))
(const_int 44)
;; Out of reach PORTABLE_RUNTIME
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0))
(const_int 40)]
;; Out of reach, can use ble
(const_int 32)))])
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn, 20)"))])
;; On the PA, the PIC register is call clobbered, so it must
;; be saved & restored around calls by the caller. If the call

View File

@ -371,3 +371,7 @@ do { \
on the location of the GCC tool directory. The downside is GCC
cannot be moved after installation using a symlink. */
#define ALWAYS_STRIP_DOTDOT 1
/* Aggregates with a single float or double field should be passed and
returned in the general registers. */
#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) (MODE==SFmode || MODE==DFmode)

View File

@ -1,4 +1,4 @@
TARGET_LIBGCC2_CFLAGS = -fPIC -Dpa64=1 -DELF=1
TARGET_LIBGCC2_CFLAGS = -fPIC -Dpa64=1 -DELF=1 -mlong-calls
LIB2FUNCS_EXTRA=quadlib.c

View File

@ -508,7 +508,7 @@ in the following sections.
-march=@var{architecture-type} @gol
-mbig-switch -mdisable-fpregs -mdisable-indexing @gol
-mfast-indirect-calls -mgas -mgnu-ld -mhp-ld @gol
-mjump-in-delay -mlinker-opt @gol
-mjump-in-delay -mlinker-opt -mlong-calls @gol
-mlong-load-store -mno-big-switch -mno-disable-fpregs @gol
-mno-disable-indexing -mno-fast-indirect-calls -mno-gas @gol
-mno-jump-in-delay -mno-long-load-store @gol
@ -8094,6 +8094,33 @@ configure option, gcc's program search path, and finally by the user's
@env{PATH}. The linker used by GCC can be printed using @samp{which
`gcc -print-prog-name=ld`}.
@item -mlong-calls
@opindex mno-long-calls
Generate code that uses long call sequences. This ensures that a call
is always able to reach linker generated stubs. The default is to generate
long calls only when the distance from the call site to the beginning
of the function or translation unit, as the case may be, exceeds a
predefined limit set by the branch type being used. The limits for
normal calls are 7,600,000 and 240,000 bytes, respectively for the
PA 2.0 and PA 1.X architectures. Sibcalls are always limited at
240,000 bytes.
Distances are measured from the beginning of functions when using the
@option{-ffunction-sections} option, or when using the @option{-mgas}
and @option{-mno-portable-runtime} options together under HP-UX with
the SOM linker.
It is normally not desirable to use this option as it will degrade
performance. However, it may be useful in large applications,
particularly when partial linking is used to build the application.
The types of long calls used depends on the capabilities of the
assembler and linker, and the type of code being generated. The
impact on systems that support long absolute calls, and long pic
symbol-difference or pc-relative calls should be relatively small.
However, an indirect call is used on 32-bit ELF systems in pic code
and it is quite long.
@end table
@node Intel 960 Options