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:
parent
8c081e84f7
commit
a02aa5b099
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
@ -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) \
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user