mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-28 03:20:28 +08:00
s390-protos.h (s390_emit_epilogue): Parameter added.
2004-04-29 Andreas Krebbel <krebbel1@de.ibm.com> ChangeLog: * config/s390/s390-protos.h (s390_emit_epilogue): Parameter added. (s390_emit_call): New function prototype added. (s390_tls_get_offset): Function removed. * config/s390/s390.c (s390_function_ok_for_sibcall, s390_call_saved_register_used_p): New functions. (TARGET_FUNCTION_OK_FOR_SIBCALL): Definition of target macro added. (s390_tls_get_offset): Function merged into s390_emit_tls_call_insn. (s390_emit_tls_call_insn): New function. (legitimize_tls_address): Call s390_emit_tls_call_insn instead of emit_call_insn. (s390_emit_prologue): Use s390_emit_call instead of emit_call_insn. (s390_emit_epilogue): Like s390_emit_prologue. Parameter for sibcalls added. * config/s390/s390.h (SIBCALL_REGNUM): New macro representing the register number used to hold the target address for sibcalls. * config/s390/s390.md ("sibcall", "sibcall_value", "sibcall_epilogue"): New expanders. ("*sibcall_br", "*sibcall_brc", "*sibcall_brcl", "*sibcall_value_br", "*sibcall_value_brc", "*sibcall_value_brcl"): New insns. ("call_exp", "call_value_exp", "call_value_tls", "call_value_tls_exp"): Expanders removed. ("call", "call_value"): Call s390_emit_call to emit the call patterns. ("*bras", "*brasl", "*bras_r", "*brasl_r", "*bras_tls", "*brasl_tls", "*basr", "*basr_r", "*basr_tls"): Added constraint: !SIBLING_CALL_P. ("epilogue"): Changed the call to s390_emit_epilogue to use the new parameter. testsuite/ChangeLog: * gcc.dg/sibcall-3.c: Delete s390 from expected fail list. * gcc.dg/sibcall-4.c: Likewise. * gcc.dg/sibcall-6.c: Enable s390 as test platform. From-SVN: r81347
This commit is contained in:
parent
1ae58c30e2
commit
ed9676cf0c
gcc
@ -1,3 +1,32 @@
|
|||||||
|
2004-04-29 Andreas Krebbel <krebbel1@de.ibm.com>
|
||||||
|
|
||||||
|
* config/s390/s390-protos.h (s390_emit_epilogue): Parameter added.
|
||||||
|
(s390_emit_call): New function prototype added.
|
||||||
|
(s390_tls_get_offset): Function removed.
|
||||||
|
* config/s390/s390.c (s390_function_ok_for_sibcall,
|
||||||
|
s390_call_saved_register_used_p): New functions.
|
||||||
|
(TARGET_FUNCTION_OK_FOR_SIBCALL): Definition of target macro added.
|
||||||
|
(s390_tls_get_offset): Function merged into s390_emit_tls_call_insn.
|
||||||
|
(s390_emit_tls_call_insn): New function.
|
||||||
|
(legitimize_tls_address): Call s390_emit_tls_call_insn instead of
|
||||||
|
emit_call_insn.
|
||||||
|
(s390_emit_prologue): Use s390_emit_call instead of emit_call_insn.
|
||||||
|
(s390_emit_epilogue): Like s390_emit_prologue. Parameter for sibcalls
|
||||||
|
added.
|
||||||
|
* config/s390/s390.h (SIBCALL_REGNUM): New macro representing the
|
||||||
|
register number used to hold the target address for sibcalls.
|
||||||
|
* config/s390/s390.md ("sibcall", "sibcall_value", "sibcall_epilogue"):
|
||||||
|
New expanders.
|
||||||
|
("*sibcall_br", "*sibcall_brc", "*sibcall_brcl", "*sibcall_value_br",
|
||||||
|
"*sibcall_value_brc", "*sibcall_value_brcl"): New insns.
|
||||||
|
("call_exp", "call_value_exp", "call_value_tls", "call_value_tls_exp"):
|
||||||
|
Expanders removed.
|
||||||
|
("call", "call_value"): Call s390_emit_call to emit the call patterns.
|
||||||
|
("*bras", "*brasl", "*bras_r", "*brasl_r", "*bras_tls", "*brasl_tls",
|
||||||
|
"*basr", "*basr_r", "*basr_tls"): Added constraint: !SIBLING_CALL_P.
|
||||||
|
("epilogue"): Changed the call to s390_emit_epilogue to use the
|
||||||
|
new parameter.
|
||||||
|
|
||||||
2004-04-30 Kazu Hirata <kazu@cs.umass.edu>
|
2004-04-30 Kazu Hirata <kazu@cs.umass.edu>
|
||||||
|
|
||||||
* bb-reorder.c, c-opts.c, cfglayout.c, cgraph.c, cgraphunit.c,
|
* bb-reorder.c, c-opts.c, cfglayout.c, cgraph.c, cgraphunit.c,
|
||||||
|
@ -26,7 +26,7 @@ extern void override_options (void);
|
|||||||
extern HOST_WIDE_INT s390_arg_frame_offset (void);
|
extern HOST_WIDE_INT s390_arg_frame_offset (void);
|
||||||
extern void s390_load_got (int);
|
extern void s390_load_got (int);
|
||||||
extern void s390_emit_prologue (void);
|
extern void s390_emit_prologue (void);
|
||||||
extern void s390_emit_epilogue (void);
|
extern void s390_emit_epilogue (bool);
|
||||||
extern void s390_function_profiler (FILE *, int);
|
extern void s390_function_profiler (FILE *, int);
|
||||||
|
|
||||||
#ifdef RTX_CODE
|
#ifdef RTX_CODE
|
||||||
@ -53,7 +53,6 @@ extern int s390_alc_comparison (rtx op, enum machine_mode mode);
|
|||||||
extern int s390_slb_comparison (rtx op, enum machine_mode mode);
|
extern int s390_slb_comparison (rtx op, enum machine_mode mode);
|
||||||
extern int symbolic_reference_mentioned_p (rtx);
|
extern int symbolic_reference_mentioned_p (rtx);
|
||||||
extern int tls_symbolic_reference_mentioned_p (rtx);
|
extern int tls_symbolic_reference_mentioned_p (rtx);
|
||||||
extern rtx s390_tls_get_offset (void);
|
|
||||||
extern int legitimate_la_operand_p (rtx);
|
extern int legitimate_la_operand_p (rtx);
|
||||||
extern int preferred_la_operand_p (rtx);
|
extern int preferred_la_operand_p (rtx);
|
||||||
extern int legitimate_pic_operand_p (rtx);
|
extern int legitimate_pic_operand_p (rtx);
|
||||||
@ -77,6 +76,7 @@ extern void s390_expand_movstr (rtx, rtx, rtx);
|
|||||||
extern void s390_expand_clrstr (rtx, rtx);
|
extern void s390_expand_clrstr (rtx, rtx);
|
||||||
extern void s390_expand_cmpmem (rtx, rtx, rtx, rtx);
|
extern void s390_expand_cmpmem (rtx, rtx, rtx, rtx);
|
||||||
extern rtx s390_return_addr_rtx (int, rtx);
|
extern rtx s390_return_addr_rtx (int, rtx);
|
||||||
|
extern rtx s390_emit_call (rtx, rtx, rtx, rtx);
|
||||||
|
|
||||||
extern bool s390_output_addr_const_extra (FILE*, rtx);
|
extern bool s390_output_addr_const_extra (FILE*, rtx);
|
||||||
extern void print_operand_address (FILE *, rtx);
|
extern void print_operand_address (FILE *, rtx);
|
||||||
|
@ -78,6 +78,8 @@ static int s390_address_cost (rtx);
|
|||||||
static void s390_reorg (void);
|
static void s390_reorg (void);
|
||||||
static bool s390_valid_pointer_mode (enum machine_mode);
|
static bool s390_valid_pointer_mode (enum machine_mode);
|
||||||
static tree s390_build_builtin_va_list (void);
|
static tree s390_build_builtin_va_list (void);
|
||||||
|
static bool s390_function_ok_for_sibcall (tree, tree);
|
||||||
|
static bool s390_call_saved_register_used (tree);
|
||||||
|
|
||||||
#undef TARGET_ASM_ALIGNED_HI_OP
|
#undef TARGET_ASM_ALIGNED_HI_OP
|
||||||
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
|
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
|
||||||
@ -151,6 +153,9 @@ static tree s390_build_builtin_va_list (void);
|
|||||||
#undef TARGET_PROMOTE_FUNCTION_RETURN
|
#undef TARGET_PROMOTE_FUNCTION_RETURN
|
||||||
#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
|
#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
|
||||||
|
|
||||||
|
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
|
||||||
|
#define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
|
||||||
|
|
||||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||||
|
|
||||||
extern int reload_completed;
|
extern int reload_completed;
|
||||||
@ -2610,16 +2615,29 @@ get_thread_pointer (void)
|
|||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct the SYMBOL_REF for the tls_get_offset function. */
|
/* Emit a tls call insn. The call target is the SYMBOL_REF stored
|
||||||
|
in s390_tls_symbol which always refers to __tls_get_offset.
|
||||||
|
The returned offset is written to RESULT_REG and an USE rtx is
|
||||||
|
generated for TLS_CALL. */
|
||||||
|
|
||||||
static GTY(()) rtx s390_tls_symbol;
|
static GTY(()) rtx s390_tls_symbol;
|
||||||
rtx
|
|
||||||
s390_tls_get_offset (void)
|
static void
|
||||||
|
s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
|
||||||
{
|
{
|
||||||
|
rtx insn;
|
||||||
|
|
||||||
|
if (!flag_pic)
|
||||||
|
abort ();
|
||||||
|
|
||||||
if (!s390_tls_symbol)
|
if (!s390_tls_symbol)
|
||||||
s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
|
s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
|
||||||
|
|
||||||
return s390_tls_symbol;
|
insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
|
||||||
|
gen_rtx_REG (Pmode, RETURN_REGNUM));
|
||||||
|
|
||||||
|
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
|
||||||
|
CONST_OR_PURE_CALL_P (insn) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
|
/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
|
||||||
@ -2640,7 +2658,7 @@ legitimize_tls_address (rtx addr, rtx reg)
|
|||||||
new = gen_rtx_CONST (Pmode, tls_call);
|
new = gen_rtx_CONST (Pmode, tls_call);
|
||||||
new = force_const_mem (Pmode, new);
|
new = force_const_mem (Pmode, new);
|
||||||
emit_move_insn (r2, new);
|
emit_move_insn (r2, new);
|
||||||
emit_call_insn (gen_call_value_tls (r2, tls_call));
|
s390_emit_tls_call_insn (r2, tls_call);
|
||||||
insn = get_insns ();
|
insn = get_insns ();
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
|
|
||||||
@ -2663,7 +2681,7 @@ legitimize_tls_address (rtx addr, rtx reg)
|
|||||||
new = gen_rtx_CONST (Pmode, tls_call);
|
new = gen_rtx_CONST (Pmode, tls_call);
|
||||||
new = force_const_mem (Pmode, new);
|
new = force_const_mem (Pmode, new);
|
||||||
emit_move_insn (r2, new);
|
emit_move_insn (r2, new);
|
||||||
emit_call_insn (gen_call_value_tls (r2, tls_call));
|
s390_emit_tls_call_insn (r2, tls_call);
|
||||||
insn = get_insns ();
|
insn = get_insns ();
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
|
|
||||||
@ -5668,15 +5686,8 @@ s390_emit_prologue (void)
|
|||||||
algorithms located at the branch target.
|
algorithms located at the branch target.
|
||||||
|
|
||||||
This must use register 1. */
|
This must use register 1. */
|
||||||
rtx addr;
|
s390_emit_call (GEN_INT (0xfe0), NULL_RTX, NULL_RTX,
|
||||||
rtx unkn;
|
gen_rtx_REG (Pmode, 1));
|
||||||
rtx link;
|
|
||||||
|
|
||||||
addr = GEN_INT (0xfe0);
|
|
||||||
unkn = CONST0_RTX (SImode);
|
|
||||||
link = gen_rtx_REG (Pmode, 1);
|
|
||||||
|
|
||||||
emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
|
|
||||||
|
|
||||||
/* Emit a blockage here so that all code
|
/* Emit a blockage here so that all code
|
||||||
lies between the profiling mechanisms. */
|
lies between the profiling mechanisms. */
|
||||||
@ -5687,7 +5698,7 @@ s390_emit_prologue (void)
|
|||||||
/* Expand the epilogue into a bunch of separate insns. */
|
/* Expand the epilogue into a bunch of separate insns. */
|
||||||
|
|
||||||
void
|
void
|
||||||
s390_emit_epilogue (void)
|
s390_emit_epilogue (bool sibcall)
|
||||||
{
|
{
|
||||||
rtx frame_pointer, return_reg;
|
rtx frame_pointer, return_reg;
|
||||||
int area_bottom, area_top, offset = 0;
|
int area_bottom, area_top, offset = 0;
|
||||||
@ -5703,19 +5714,12 @@ s390_emit_epilogue (void)
|
|||||||
|
|
||||||
This must use register 1. */
|
This must use register 1. */
|
||||||
|
|
||||||
rtx addr;
|
|
||||||
rtx unkn;
|
|
||||||
rtx link;
|
|
||||||
|
|
||||||
addr = GEN_INT (0xfe6);
|
|
||||||
unkn = CONST0_RTX (SImode);
|
|
||||||
link = gen_rtx_REG (Pmode, 1);
|
|
||||||
|
|
||||||
/* Emit a blockage here so that all code
|
/* Emit a blockage here so that all code
|
||||||
lies between the profiling mechanisms. */
|
lies between the profiling mechanisms. */
|
||||||
emit_insn (gen_blockage ());
|
emit_insn (gen_blockage ());
|
||||||
|
|
||||||
emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
|
s390_emit_call (GEN_INT (0xfe6), NULL_RTX, NULL_RTX,
|
||||||
|
gen_rtx_REG (Pmode, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether to use frame or stack pointer for restore. */
|
/* Check whether to use frame or stack pointer for restore. */
|
||||||
@ -5847,23 +5851,26 @@ s390_emit_epilogue (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch return address from stack before load multiple,
|
if (! sibcall)
|
||||||
this will do good for scheduling. */
|
|
||||||
|
|
||||||
if (cfun->machine->save_return_addr_p
|
|
||||||
|| (cfun->machine->first_restore_gpr < BASE_REGISTER
|
|
||||||
&& cfun->machine->last_save_gpr > RETURN_REGNUM))
|
|
||||||
{
|
{
|
||||||
int return_regnum = find_unused_clobbered_reg();
|
/* Fetch return address from stack before load multiple,
|
||||||
if (!return_regnum)
|
this will do good for scheduling. */
|
||||||
return_regnum = 4;
|
|
||||||
return_reg = gen_rtx_REG (Pmode, return_regnum);
|
if (cfun->machine->save_return_addr_p
|
||||||
|
|| (cfun->machine->first_restore_gpr < BASE_REGISTER
|
||||||
addr = plus_constant (frame_pointer,
|
&& cfun->machine->last_save_gpr > RETURN_REGNUM))
|
||||||
offset + RETURN_REGNUM * UNITS_PER_WORD);
|
{
|
||||||
addr = gen_rtx_MEM (Pmode, addr);
|
int return_regnum = find_unused_clobbered_reg();
|
||||||
set_mem_alias_set (addr, s390_sr_alias_set);
|
if (!return_regnum)
|
||||||
emit_move_insn (return_reg, addr);
|
return_regnum = 4;
|
||||||
|
return_reg = gen_rtx_REG (Pmode, return_regnum);
|
||||||
|
|
||||||
|
addr = plus_constant (frame_pointer,
|
||||||
|
offset + RETURN_REGNUM * UNITS_PER_WORD);
|
||||||
|
addr = gen_rtx_MEM (Pmode, addr);
|
||||||
|
set_mem_alias_set (addr, s390_sr_alias_set);
|
||||||
|
emit_move_insn (return_reg, addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ??? As references to the base register are not made
|
/* ??? As references to the base register are not made
|
||||||
@ -5878,13 +5885,17 @@ s390_emit_epilogue (void)
|
|||||||
emit_insn (insn);
|
emit_insn (insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return to caller. */
|
if (! sibcall)
|
||||||
|
{
|
||||||
|
|
||||||
p = rtvec_alloc (2);
|
/* Return to caller. */
|
||||||
|
|
||||||
RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
|
p = rtvec_alloc (2);
|
||||||
RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
|
|
||||||
emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
|
RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
|
||||||
|
RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
|
||||||
|
emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6999,4 +7010,179 @@ s390_init_machine_status (void)
|
|||||||
return ggc_alloc_cleared (sizeof (struct machine_function));
|
return ggc_alloc_cleared (sizeof (struct machine_function));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Checks whether the given ARGUMENT_LIST would use a caller
|
||||||
|
saved register. This is used to decide whether sibling call
|
||||||
|
optimization could be performed on the respective function
|
||||||
|
call. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
s390_call_saved_register_used (tree argument_list)
|
||||||
|
{
|
||||||
|
CUMULATIVE_ARGS cum;
|
||||||
|
tree parameter;
|
||||||
|
enum machine_mode mode;
|
||||||
|
tree type;
|
||||||
|
rtx parm_rtx;
|
||||||
|
int reg;
|
||||||
|
|
||||||
|
INIT_CUMULATIVE_ARGS (cum, NULL, NULL, 0, 0);
|
||||||
|
|
||||||
|
while (argument_list)
|
||||||
|
{
|
||||||
|
parameter = TREE_VALUE (argument_list);
|
||||||
|
argument_list = TREE_CHAIN (argument_list);
|
||||||
|
|
||||||
|
if (!parameter)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
/* For an undeclared variable passed as parameter we will get
|
||||||
|
an ERROR_MARK node here. */
|
||||||
|
if (TREE_CODE (parameter) == ERROR_MARK)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (! (type = TREE_TYPE (parameter)))
|
||||||
|
abort();
|
||||||
|
|
||||||
|
if (! (mode = TYPE_MODE (TREE_TYPE (parameter))))
|
||||||
|
abort();
|
||||||
|
|
||||||
|
if (s390_function_arg_pass_by_reference (mode, type))
|
||||||
|
{
|
||||||
|
mode = Pmode;
|
||||||
|
type = build_pointer_type (type);
|
||||||
|
}
|
||||||
|
|
||||||
|
parm_rtx = s390_function_arg (&cum, mode, type, 0);
|
||||||
|
|
||||||
|
s390_function_arg_advance (&cum, mode, type, 0);
|
||||||
|
|
||||||
|
if (parm_rtx && REG_P (parm_rtx))
|
||||||
|
{
|
||||||
|
for (reg = 0;
|
||||||
|
reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
|
||||||
|
reg++)
|
||||||
|
if (! call_used_regs[reg + REGNO (parm_rtx)])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return true if the given call expression can be
|
||||||
|
turned into a sibling call.
|
||||||
|
DECL holds the declaration of the function to be called whereas
|
||||||
|
EXP is the call expression itself. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
s390_function_ok_for_sibcall (tree decl, tree exp)
|
||||||
|
{
|
||||||
|
/* The TPF epilogue uses register 1. */
|
||||||
|
if (TARGET_TPF)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
|
||||||
|
which would have to be restored before the sibcall. */
|
||||||
|
if (!TARGET_64BIT && flag_pic && decl && TREE_PUBLIC (decl))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Register 6 on s390 is available as an argument register but unfortunately
|
||||||
|
"caller saved". This makes functions needing this register for arguments
|
||||||
|
not suitable for sibcalls. */
|
||||||
|
if (TREE_OPERAND (exp, 1)
|
||||||
|
&& s390_call_saved_register_used (TREE_OPERAND (exp, 1)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is used by the call expanders of the machine description.
|
||||||
|
It emits the call insn itself together with the necessary operations
|
||||||
|
to adjust the target address and returns the emitted insn.
|
||||||
|
ADDR_LOCATION is the target address rtx
|
||||||
|
TLS_CALL the location of the thread-local symbol
|
||||||
|
RESULT_REG the register where the result of the call should be stored
|
||||||
|
RETADDR_REG the register where the return address should be stored
|
||||||
|
If this parameter is NULL_RTX the call is considered
|
||||||
|
to be a sibling call. */
|
||||||
|
|
||||||
|
rtx
|
||||||
|
s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
|
||||||
|
rtx retaddr_reg)
|
||||||
|
{
|
||||||
|
bool plt_call = false;
|
||||||
|
rtx insn;
|
||||||
|
rtx call;
|
||||||
|
rtx clobber;
|
||||||
|
rtvec vec;
|
||||||
|
|
||||||
|
/* Direct function calls need special treatment. */
|
||||||
|
if (GET_CODE (addr_location) == SYMBOL_REF)
|
||||||
|
{
|
||||||
|
/* When calling a global routine in PIC mode, we must
|
||||||
|
replace the symbol itself with the PLT stub. */
|
||||||
|
if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
|
||||||
|
{
|
||||||
|
addr_location = gen_rtx_UNSPEC (Pmode,
|
||||||
|
gen_rtvec (1, addr_location),
|
||||||
|
UNSPEC_PLT);
|
||||||
|
addr_location = gen_rtx_CONST (Pmode, addr_location);
|
||||||
|
plt_call = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unless we can use the bras(l) insn, force the
|
||||||
|
routine address into a register. */
|
||||||
|
if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
|
||||||
|
{
|
||||||
|
if (flag_pic)
|
||||||
|
addr_location = legitimize_pic_address (addr_location, 0);
|
||||||
|
else
|
||||||
|
addr_location = force_reg (Pmode, addr_location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If it is already an indirect call or the code above moved the
|
||||||
|
SYMBOL_REF to somewhere else make sure the address can be found in
|
||||||
|
register 1. */
|
||||||
|
if (retaddr_reg == NULL_RTX
|
||||||
|
&& GET_CODE (addr_location) != SYMBOL_REF
|
||||||
|
&& !plt_call)
|
||||||
|
{
|
||||||
|
emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
|
||||||
|
addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_location = gen_rtx_MEM (QImode, addr_location);
|
||||||
|
call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
|
||||||
|
|
||||||
|
if (result_reg != NULL_RTX)
|
||||||
|
call = gen_rtx_SET (VOIDmode, result_reg, call);
|
||||||
|
|
||||||
|
if (retaddr_reg != NULL_RTX)
|
||||||
|
{
|
||||||
|
clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
|
||||||
|
|
||||||
|
if (tls_call != NULL_RTX)
|
||||||
|
vec = gen_rtvec (3, call, clobber,
|
||||||
|
gen_rtx_USE (VOIDmode, tls_call));
|
||||||
|
else
|
||||||
|
vec = gen_rtvec (2, call, clobber);
|
||||||
|
|
||||||
|
call = gen_rtx_PARALLEL (VOIDmode, vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
insn = emit_call_insn (call);
|
||||||
|
|
||||||
|
/* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
|
||||||
|
if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
|
||||||
|
{
|
||||||
|
/* s390_function_ok_for_sibcall should
|
||||||
|
have denied sibcalls in this case. */
|
||||||
|
if (retaddr_reg == NULL_RTX)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
|
||||||
|
}
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
|
||||||
#include "gt-s390.h"
|
#include "gt-s390.h"
|
||||||
|
@ -299,6 +299,7 @@ if (INTEGRAL_MODE_P (MODE) && \
|
|||||||
#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
|
#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
|
||||||
#define FRAME_REG_P(X) (REG_P (X) && FRAME_REGNO_P (REGNO (X)))
|
#define FRAME_REG_P(X) (REG_P (X) && FRAME_REGNO_P (REGNO (X)))
|
||||||
|
|
||||||
|
#define SIBCALL_REGNUM 1
|
||||||
#define BASE_REGISTER 13
|
#define BASE_REGISTER 13
|
||||||
#define RETURN_REGNUM 14
|
#define RETURN_REGNUM 14
|
||||||
#define CC_REGNUM 33
|
#define CC_REGNUM 33
|
||||||
|
@ -6970,6 +6970,87 @@
|
|||||||
[(set_attr "type" "none")
|
[(set_attr "type" "none")
|
||||||
(set_attr "length" "0")])
|
(set_attr "length" "0")])
|
||||||
|
|
||||||
|
;
|
||||||
|
; sibcall patterns
|
||||||
|
;
|
||||||
|
|
||||||
|
(define_expand "sibcall"
|
||||||
|
[(call (match_operand 0 "" "")
|
||||||
|
(match_operand 1 "" ""))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
|
||||||
|
DONE;
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_insn "*sibcall_br"
|
||||||
|
[(call (mem:QI (reg 1))
|
||||||
|
(match_operand 0 "const_int_operand" "n"))]
|
||||||
|
"SIBLING_CALL_P (insn)
|
||||||
|
&& GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
|
||||||
|
"br\t%%r1"
|
||||||
|
[(set_attr "op_type" "RR")
|
||||||
|
(set_attr "type" "branch")
|
||||||
|
(set_attr "atype" "agen")])
|
||||||
|
|
||||||
|
(define_insn "*sibcall_brc"
|
||||||
|
[(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
|
||||||
|
(match_operand 1 "const_int_operand" "n"))]
|
||||||
|
"SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
|
||||||
|
"j\t%0"
|
||||||
|
[(set_attr "op_type" "RI")
|
||||||
|
(set_attr "type" "branch")])
|
||||||
|
|
||||||
|
(define_insn "*sibcall_brcl"
|
||||||
|
[(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
|
||||||
|
(match_operand 1 "const_int_operand" "n"))]
|
||||||
|
"SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
|
||||||
|
"jg\t%0"
|
||||||
|
[(set_attr "op_type" "RIL")
|
||||||
|
(set_attr "type" "branch")])
|
||||||
|
|
||||||
|
;
|
||||||
|
; sibcall_value patterns
|
||||||
|
;
|
||||||
|
|
||||||
|
(define_expand "sibcall_value"
|
||||||
|
[(set (match_operand 0 "" "")
|
||||||
|
(call (match_operand 1 "" "")
|
||||||
|
(match_operand 2 "" "")))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
|
||||||
|
DONE;
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_insn "*sibcall_value_br"
|
||||||
|
[(set (match_operand 0 "" "")
|
||||||
|
(call (mem:QI (reg 1))
|
||||||
|
(match_operand 1 "const_int_operand" "n")))]
|
||||||
|
"SIBLING_CALL_P (insn)
|
||||||
|
&& GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
|
||||||
|
"br\t%%r1"
|
||||||
|
[(set_attr "op_type" "RR")
|
||||||
|
(set_attr "type" "branch")
|
||||||
|
(set_attr "atype" "agen")])
|
||||||
|
|
||||||
|
(define_insn "*sibcall_value_brc"
|
||||||
|
[(set (match_operand 0 "" "")
|
||||||
|
(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
|
||||||
|
(match_operand 2 "const_int_operand" "n")))]
|
||||||
|
"SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
|
||||||
|
"j\t%1"
|
||||||
|
[(set_attr "op_type" "RI")
|
||||||
|
(set_attr "type" "branch")])
|
||||||
|
|
||||||
|
(define_insn "*sibcall_value_brcl"
|
||||||
|
[(set (match_operand 0 "" "")
|
||||||
|
(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
|
||||||
|
(match_operand 2 "const_int_operand" "n")))]
|
||||||
|
"SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
|
||||||
|
"jg\t%1"
|
||||||
|
[(set_attr "op_type" "RIL")
|
||||||
|
(set_attr "type" "branch")])
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
@ -6982,59 +7063,18 @@
|
|||||||
(use (match_operand 2 "" ""))]
|
(use (match_operand 2 "" ""))]
|
||||||
""
|
""
|
||||||
{
|
{
|
||||||
bool plt_call = false;
|
s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
|
||||||
rtx insn;
|
gen_rtx_REG (Pmode, RETURN_REGNUM));
|
||||||
|
|
||||||
/* Direct function calls need special treatment. */
|
|
||||||
if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
|
|
||||||
{
|
|
||||||
rtx sym = XEXP (operands[0], 0);
|
|
||||||
|
|
||||||
/* When calling a global routine in PIC mode, we must
|
|
||||||
replace the symbol itself with the PLT stub. */
|
|
||||||
if (flag_pic && !SYMBOL_REF_LOCAL_P (sym))
|
|
||||||
{
|
|
||||||
sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
|
|
||||||
sym = gen_rtx_CONST (Pmode, sym);
|
|
||||||
plt_call = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unless we can use the bras(l) insn, force the
|
|
||||||
routine address into a register. */
|
|
||||||
if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
|
|
||||||
{
|
|
||||||
if (flag_pic)
|
|
||||||
sym = legitimize_pic_address (sym, 0);
|
|
||||||
else
|
|
||||||
sym = force_reg (Pmode, sym);
|
|
||||||
}
|
|
||||||
|
|
||||||
operands[0] = gen_rtx_MEM (QImode, sym);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Emit insn. */
|
|
||||||
insn = emit_call_insn (gen_call_exp (operands[0], operands[1],
|
|
||||||
gen_rtx_REG (Pmode, RETURN_REGNUM)));
|
|
||||||
|
|
||||||
/* 31-bit PLT stubs use the GOT register implicitly. */
|
|
||||||
if (!TARGET_64BIT && plt_call)
|
|
||||||
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
|
|
||||||
|
|
||||||
DONE;
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_expand "call_exp"
|
|
||||||
[(parallel [(call (match_operand 0 "" "")
|
|
||||||
(match_operand 1 "" ""))
|
|
||||||
(clobber (match_operand 2 "" ""))])]
|
|
||||||
""
|
|
||||||
"")
|
|
||||||
|
|
||||||
(define_insn "*bras"
|
(define_insn "*bras"
|
||||||
[(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
|
[(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
|
||||||
(match_operand 1 "const_int_operand" "n"))
|
(match_operand 1 "const_int_operand" "n"))
|
||||||
(clobber (match_operand 2 "register_operand" "=r"))]
|
(clobber (match_operand 2 "register_operand" "=r"))]
|
||||||
"TARGET_SMALL_EXEC && GET_MODE (operands[2]) == Pmode"
|
"!SIBLING_CALL_P (insn)
|
||||||
|
&& TARGET_SMALL_EXEC
|
||||||
|
&& GET_MODE (operands[2]) == Pmode"
|
||||||
"bras\t%2,%0"
|
"bras\t%2,%0"
|
||||||
[(set_attr "op_type" "RI")
|
[(set_attr "op_type" "RI")
|
||||||
(set_attr "type" "jsr")])
|
(set_attr "type" "jsr")])
|
||||||
@ -7043,7 +7083,9 @@
|
|||||||
[(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
|
[(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
|
||||||
(match_operand 1 "const_int_operand" "n"))
|
(match_operand 1 "const_int_operand" "n"))
|
||||||
(clobber (match_operand 2 "register_operand" "=r"))]
|
(clobber (match_operand 2 "register_operand" "=r"))]
|
||||||
"TARGET_CPU_ZARCH && GET_MODE (operands[2]) == Pmode"
|
"!SIBLING_CALL_P (insn)
|
||||||
|
&& TARGET_CPU_ZARCH
|
||||||
|
&& GET_MODE (operands[2]) == Pmode"
|
||||||
"brasl\t%2,%0"
|
"brasl\t%2,%0"
|
||||||
[(set_attr "op_type" "RIL")
|
[(set_attr "op_type" "RIL")
|
||||||
(set_attr "type" "jsr")])
|
(set_attr "type" "jsr")])
|
||||||
@ -7052,7 +7094,7 @@
|
|||||||
[(call (mem:QI (match_operand 0 "address_operand" "U"))
|
[(call (mem:QI (match_operand 0 "address_operand" "U"))
|
||||||
(match_operand 1 "const_int_operand" "n"))
|
(match_operand 1 "const_int_operand" "n"))
|
||||||
(clobber (match_operand 2 "register_operand" "=r"))]
|
(clobber (match_operand 2 "register_operand" "=r"))]
|
||||||
"GET_MODE (operands[2]) == Pmode"
|
"!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
|
||||||
{
|
{
|
||||||
if (get_attr_op_type (insn) == OP_TYPE_RR)
|
if (get_attr_op_type (insn) == OP_TYPE_RR)
|
||||||
return "basr\t%2,%0";
|
return "basr\t%2,%0";
|
||||||
@ -7076,62 +7118,19 @@
|
|||||||
(use (match_operand 3 "" ""))]
|
(use (match_operand 3 "" ""))]
|
||||||
""
|
""
|
||||||
{
|
{
|
||||||
bool plt_call = false;
|
s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
|
||||||
rtx insn;
|
gen_rtx_REG (Pmode, RETURN_REGNUM));
|
||||||
|
|
||||||
/* Direct function calls need special treatment. */
|
|
||||||
if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
|
|
||||||
{
|
|
||||||
rtx sym = XEXP (operands[1], 0);
|
|
||||||
|
|
||||||
/* When calling a global routine in PIC mode, we must
|
|
||||||
replace the symbol itself with the PLT stub. */
|
|
||||||
if (flag_pic && !SYMBOL_REF_LOCAL_P (sym))
|
|
||||||
{
|
|
||||||
sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
|
|
||||||
sym = gen_rtx_CONST (Pmode, sym);
|
|
||||||
plt_call = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unless we can use the bras(l) insn, force the
|
|
||||||
routine address into a register. */
|
|
||||||
if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
|
|
||||||
{
|
|
||||||
if (flag_pic)
|
|
||||||
sym = legitimize_pic_address (sym, 0);
|
|
||||||
else
|
|
||||||
sym = force_reg (Pmode, sym);
|
|
||||||
}
|
|
||||||
|
|
||||||
operands[1] = gen_rtx_MEM (QImode, sym);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Emit insn. */
|
|
||||||
insn = emit_call_insn (
|
|
||||||
gen_call_value_exp (operands[0], operands[1], operands[2],
|
|
||||||
gen_rtx_REG (Pmode, RETURN_REGNUM)));
|
|
||||||
|
|
||||||
/* 31-bit PLT stubs use the GOT register implicitly. */
|
|
||||||
if (!TARGET_64BIT && plt_call)
|
|
||||||
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
|
|
||||||
|
|
||||||
DONE;
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_expand "call_value_exp"
|
|
||||||
[(parallel [(set (match_operand 0 "" "")
|
|
||||||
(call (match_operand 1 "" "")
|
|
||||||
(match_operand 2 "" "")))
|
|
||||||
(clobber (match_operand 3 "" ""))])]
|
|
||||||
""
|
|
||||||
"")
|
|
||||||
|
|
||||||
(define_insn "*bras_r"
|
(define_insn "*bras_r"
|
||||||
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
||||||
(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
|
(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
|
||||||
(match_operand:SI 2 "const_int_operand" "n")))
|
(match_operand:SI 2 "const_int_operand" "n")))
|
||||||
(clobber (match_operand 3 "register_operand" "=r"))]
|
(clobber (match_operand 3 "register_operand" "=r"))]
|
||||||
"TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode"
|
"!SIBLING_CALL_P (insn)
|
||||||
|
&& TARGET_SMALL_EXEC
|
||||||
|
&& GET_MODE (operands[3]) == Pmode"
|
||||||
"bras\t%3,%1"
|
"bras\t%3,%1"
|
||||||
[(set_attr "op_type" "RI")
|
[(set_attr "op_type" "RI")
|
||||||
(set_attr "type" "jsr")])
|
(set_attr "type" "jsr")])
|
||||||
@ -7141,7 +7140,9 @@
|
|||||||
(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
|
(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
|
||||||
(match_operand 2 "const_int_operand" "n")))
|
(match_operand 2 "const_int_operand" "n")))
|
||||||
(clobber (match_operand 3 "register_operand" "=r"))]
|
(clobber (match_operand 3 "register_operand" "=r"))]
|
||||||
"TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode"
|
"!SIBLING_CALL_P (insn)
|
||||||
|
&& TARGET_CPU_ZARCH
|
||||||
|
&& GET_MODE (operands[3]) == Pmode"
|
||||||
"brasl\t%3,%1"
|
"brasl\t%3,%1"
|
||||||
[(set_attr "op_type" "RIL")
|
[(set_attr "op_type" "RIL")
|
||||||
(set_attr "type" "jsr")])
|
(set_attr "type" "jsr")])
|
||||||
@ -7151,7 +7152,7 @@
|
|||||||
(call (mem:QI (match_operand 1 "address_operand" "U"))
|
(call (mem:QI (match_operand 1 "address_operand" "U"))
|
||||||
(match_operand 2 "const_int_operand" "n")))
|
(match_operand 2 "const_int_operand" "n")))
|
||||||
(clobber (match_operand 3 "register_operand" "=r"))]
|
(clobber (match_operand 3 "register_operand" "=r"))]
|
||||||
"GET_MODE (operands[3]) == Pmode"
|
"!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
|
||||||
{
|
{
|
||||||
if (get_attr_op_type (insn) == OP_TYPE_RR)
|
if (get_attr_op_type (insn) == OP_TYPE_RR)
|
||||||
return "basr\t%3,%1";
|
return "basr\t%3,%1";
|
||||||
@ -7229,64 +7230,15 @@
|
|||||||
ly\t%0,%1%J2"
|
ly\t%0,%1%J2"
|
||||||
[(set_attr "op_type" "RX,RXY")])
|
[(set_attr "op_type" "RX,RXY")])
|
||||||
|
|
||||||
(define_expand "call_value_tls"
|
|
||||||
[(set (match_operand 0 "" "")
|
|
||||||
(call (const_int 0) (const_int 0)))
|
|
||||||
(use (match_operand 1 "" ""))]
|
|
||||||
""
|
|
||||||
{
|
|
||||||
rtx insn, sym;
|
|
||||||
|
|
||||||
if (!flag_pic)
|
|
||||||
abort ();
|
|
||||||
|
|
||||||
sym = s390_tls_get_offset ();
|
|
||||||
sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
|
|
||||||
sym = gen_rtx_CONST (Pmode, sym);
|
|
||||||
|
|
||||||
/* Unless we can use the bras(l) insn, force the
|
|
||||||
routine address into a register. */
|
|
||||||
if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
|
|
||||||
{
|
|
||||||
if (flag_pic)
|
|
||||||
sym = legitimize_pic_address (sym, 0);
|
|
||||||
else
|
|
||||||
sym = force_reg (Pmode, sym);
|
|
||||||
}
|
|
||||||
|
|
||||||
sym = gen_rtx_MEM (QImode, sym);
|
|
||||||
|
|
||||||
/* Emit insn. */
|
|
||||||
insn = emit_call_insn (
|
|
||||||
gen_call_value_tls_exp (operands[0], sym, const0_rtx,
|
|
||||||
gen_rtx_REG (Pmode, RETURN_REGNUM),
|
|
||||||
operands[1]));
|
|
||||||
|
|
||||||
/* The calling convention of __tls_get_offset uses the
|
|
||||||
GOT register implicitly. */
|
|
||||||
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
|
|
||||||
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), operands[0]);
|
|
||||||
CONST_OR_PURE_CALL_P (insn) = 1;
|
|
||||||
|
|
||||||
DONE;
|
|
||||||
})
|
|
||||||
|
|
||||||
(define_expand "call_value_tls_exp"
|
|
||||||
[(parallel [(set (match_operand 0 "" "")
|
|
||||||
(call (match_operand 1 "" "")
|
|
||||||
(match_operand 2 "" "")))
|
|
||||||
(clobber (match_operand 3 "" ""))
|
|
||||||
(use (match_operand 4 "" ""))])]
|
|
||||||
""
|
|
||||||
"")
|
|
||||||
|
|
||||||
(define_insn "*bras_tls"
|
(define_insn "*bras_tls"
|
||||||
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
||||||
(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
|
(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
|
||||||
(match_operand 2 "const_int_operand" "n")))
|
(match_operand 2 "const_int_operand" "n")))
|
||||||
(clobber (match_operand 3 "register_operand" "=r"))
|
(clobber (match_operand 3 "register_operand" "=r"))
|
||||||
(use (match_operand 4 "" ""))]
|
(use (match_operand 4 "" ""))]
|
||||||
"TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode"
|
"!SIBLING_CALL_P (insn)
|
||||||
|
&& TARGET_SMALL_EXEC
|
||||||
|
&& GET_MODE (operands[3]) == Pmode"
|
||||||
"bras\t%3,%1%J4"
|
"bras\t%3,%1%J4"
|
||||||
[(set_attr "op_type" "RI")
|
[(set_attr "op_type" "RI")
|
||||||
(set_attr "type" "jsr")])
|
(set_attr "type" "jsr")])
|
||||||
@ -7297,7 +7249,9 @@
|
|||||||
(match_operand 2 "const_int_operand" "n")))
|
(match_operand 2 "const_int_operand" "n")))
|
||||||
(clobber (match_operand 3 "register_operand" "=r"))
|
(clobber (match_operand 3 "register_operand" "=r"))
|
||||||
(use (match_operand 4 "" ""))]
|
(use (match_operand 4 "" ""))]
|
||||||
"TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode"
|
"!SIBLING_CALL_P (insn)
|
||||||
|
&& TARGET_CPU_ZARCH
|
||||||
|
&& GET_MODE (operands[3]) == Pmode"
|
||||||
"brasl\t%3,%1%J4"
|
"brasl\t%3,%1%J4"
|
||||||
[(set_attr "op_type" "RIL")
|
[(set_attr "op_type" "RIL")
|
||||||
(set_attr "type" "jsr")])
|
(set_attr "type" "jsr")])
|
||||||
@ -7308,7 +7262,7 @@
|
|||||||
(match_operand 2 "const_int_operand" "n")))
|
(match_operand 2 "const_int_operand" "n")))
|
||||||
(clobber (match_operand 3 "register_operand" "=r"))
|
(clobber (match_operand 3 "register_operand" "=r"))
|
||||||
(use (match_operand 4 "" ""))]
|
(use (match_operand 4 "" ""))]
|
||||||
"GET_MODE (operands[3]) == Pmode"
|
"!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
|
||||||
{
|
{
|
||||||
if (get_attr_op_type (insn) == OP_TYPE_RR)
|
if (get_attr_op_type (insn) == OP_TYPE_RR)
|
||||||
return "basr\t%3,%1%J4";
|
return "basr\t%3,%1%J4";
|
||||||
@ -7571,7 +7525,12 @@
|
|||||||
(define_expand "epilogue"
|
(define_expand "epilogue"
|
||||||
[(use (const_int 1))]
|
[(use (const_int 1))]
|
||||||
""
|
""
|
||||||
"s390_emit_epilogue (); DONE;")
|
"s390_emit_epilogue (false); DONE;")
|
||||||
|
|
||||||
|
(define_expand "sibcall_epilogue"
|
||||||
|
[(use (const_int 0))]
|
||||||
|
""
|
||||||
|
"s390_emit_epilogue (true); DONE;")
|
||||||
|
|
||||||
(define_insn "*return"
|
(define_insn "*return"
|
||||||
[(return)
|
[(return)
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2004-04-29 Andreas Krebbel <krebbel1@de.ibm.com>
|
||||||
|
|
||||||
|
* gcc.dg/sibcall-3.c: Delete s390 from expected fail list.
|
||||||
|
* gcc.dg/sibcall-4.c: Likewise.
|
||||||
|
* gcc.dg/sibcall-6.c: Enable s390 as test platform.
|
||||||
|
|
||||||
2004-04-30 Kazu Hirata <kazu@cs.umass.edu>
|
2004-04-30 Kazu Hirata <kazu@cs.umass.edu>
|
||||||
|
|
||||||
* gcc.c-torture/execute/20040331-1.c: Don't use too wide a
|
* gcc.c-torture/execute/20040331-1.c: Don't use too wide a
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
Copyright (C) 2002 Free Software Foundation Inc.
|
Copyright (C) 2002 Free Software Foundation Inc.
|
||||||
Contributed by Hans-Peter Nilsson <hp@bitrange.com> */
|
Contributed by Hans-Peter Nilsson <hp@bitrange.com> */
|
||||||
|
|
||||||
/* { dg-do run { xfail arc-*-* avr-*-* c4x-*-* cris-*-* h8300-*-* ip2k-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mips*-*-* mn10300-*-* ns32k-*-* s390*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
|
/* { dg-do run { xfail arc-*-* avr-*-* c4x-*-* cris-*-* h8300-*-* ip2k-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mips*-*-* mn10300-*-* ns32k-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
|
||||||
/* { dg-options "-O2 -foptimize-sibling-calls" } */
|
/* { dg-options "-O2 -foptimize-sibling-calls" } */
|
||||||
|
|
||||||
/* The option -foptimize-sibling-calls is the default, but serves as
|
/* The option -foptimize-sibling-calls is the default, but serves as
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
Copyright (C) 2002 Free Software Foundation Inc.
|
Copyright (C) 2002 Free Software Foundation Inc.
|
||||||
Contributed by Hans-Peter Nilsson <hp@bitrange.com> */
|
Contributed by Hans-Peter Nilsson <hp@bitrange.com> */
|
||||||
|
|
||||||
/* { dg-do run { xfail arc-*-* avr-*-* c4x-*-* cris-*-* h8300-*-* ip2k-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mips*-*-* mn10300-*-* ns32k-*-* s390*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
|
/* { dg-do run { xfail arc-*-* avr-*-* c4x-*-* cris-*-* h8300-*-* ip2k-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mips*-*-* mn10300-*-* ns32k-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
|
||||||
/* { dg-options "-O2 -foptimize-sibling-calls" } */
|
/* { dg-options "-O2 -foptimize-sibling-calls" } */
|
||||||
|
|
||||||
/* The option -foptimize-sibling-calls is the default, but serves as
|
/* The option -foptimize-sibling-calls is the default, but serves as
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
Copyright (C) 2002 Free Software Foundation Inc.
|
Copyright (C) 2002 Free Software Foundation Inc.
|
||||||
Contributed by Andreas Bauer <baueran@in.tum.de> */
|
Contributed by Andreas Bauer <baueran@in.tum.de> */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-* x86_64-*-*} } */
|
/* { dg-do run { target i?86-*-* s390*-*-* x86_64-*-*} } */
|
||||||
/* { dg-options "-O2 -foptimize-sibling-calls" } */
|
/* { dg-options "-O2 -foptimize-sibling-calls" } */
|
||||||
|
|
||||||
int foo (int);
|
int foo (int);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user