@@ -899,8 +900,6 @@ static const char *rs6000_mangle_type (c
static void rs6000_set_default_type_attributes (tree);
static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
-static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
- enum machine_mode, bool, bool, bool);
static bool rs6000_reg_live_or_pic_offset_p (int);
static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
static tree rs6000_builtin_vectorized_function (tree, tree, tree);
@@ -19729,10 +19764,11 @@ rs6000_emit_stack_reset (rs6000_stack_t
}
/* Construct a parallel rtx describing the effect of a call to an
- out-of-line register save/restore routine. */
+ out-of-line register save/restore routine, and emit the insn
+ or jump_insn as appropriate. */
static rtx
-rs6000_make_savres_rtx (rs6000_stack_t *info,
+rs6000_emit_savres_rtx (rs6000_stack_t *info,
rtx frame_reg_rtx, int save_area_offset,
enum machine_mode reg_mode,
bool savep, bool gpr, bool lr)
@@ -19742,6 +19778,7 @@ rs6000_make_savres_rtx (rs6000_stack_t *
int reg_size = GET_MODE_SIZE (reg_mode);
rtx sym;
rtvec p;
+ rtx par, insn;
offset = 0;
start_reg = (gpr
@@ -19752,7 +19789,7 @@ rs6000_make_savres_rtx (rs6000_stack_t *
p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
if (!savep && lr)
- RTVEC_ELT (p, offset++) = ret_rtx;
+ RTVEC_ELT (p, offset++) = simple_return_rtx;
RTVEC_ELT (p, offset++)
= gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
@@ -19788,7 +19825,16 @@ rs6000_make_savres_rtx (rs6000_stack_t *
RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
}
- return gen_rtx_PARALLEL (VOIDmode, p);
+ par = gen_rtx_PARALLEL (VOIDmode, p);
+
+ if (!savep && lr)
+ {
+ insn = emit_jump_insn (par);
+ JUMP_LABEL (insn) = simple_return_rtx;
+ }
+ else
+ insn = emit_insn (par);
+ return insn;
}
/* Determine whether the gp REG is really used. */
@@ -20087,16 +20133,13 @@ rs6000_emit_prologue (void)
}
else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
{
- rtx par;
-
- par = rs6000_make_savres_rtx (info, frame_reg_rtx,
- info->fp_save_offset + sp_offset,
- DFmode,
- /*savep=*/true, /*gpr=*/false,
- /*lr=*/(strategy
- & SAVE_NOINLINE_FPRS_SAVES_LR)
- != 0);
- insn = emit_insn (par);
+ insn = rs6000_emit_savres_rtx (info, frame_reg_rtx,
+ info->fp_save_offset + sp_offset,
+ DFmode,
+ /*savep=*/true, /*gpr=*/false,
+ /*lr=*/((strategy
+ & SAVE_NOINLINE_FPRS_SAVES_LR)
+ != 0));
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
NULL_RTX, NULL_RTX);
}
@@ -20186,13 +20229,10 @@ rs6000_emit_prologue (void)
}
else
{
- rtx par;
-
- par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
- 0, reg_mode,
- /*savep=*/true, /*gpr=*/true,
- /*lr=*/false);
- insn = emit_insn (par);
+ insn = rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11),
+ 0, reg_mode,
+ /*savep=*/true, /*gpr=*/true,
+ /*lr=*/false);
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
NULL_RTX, NULL_RTX);
}
@@ -20204,8 +20244,6 @@ rs6000_emit_prologue (void)
}
else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
{
- rtx par;
-
/* Need to adjust r11 (r12) if we saved any FPRs. */
if (info->first_fp_reg_save != 64)
{
@@ -20216,14 +20254,13 @@ rs6000_emit_prologue (void)
emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
}
- par = rs6000_make_savres_rtx (info, frame_reg_rtx,
- info->gp_save_offset + sp_offset,
- reg_mode,
- /*savep=*/true, /*gpr=*/true,
- /*lr=*/(strategy
- & SAVE_NOINLINE_GPRS_SAVES_LR)
- != 0);
- insn = emit_insn (par);
+ insn = rs6000_emit_savres_rtx (info, frame_reg_rtx,
+ info->gp_save_offset + sp_offset,
+ reg_mode,
+ /*savep=*/true, /*gpr=*/true,
+ /*lr=*/((strategy
+ & SAVE_NOINLINE_GPRS_SAVES_LR)
+ != 0));
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
NULL_RTX, NULL_RTX);
}
@@ -20750,7 +20805,7 @@ rs6000_emit_epilogue (int sibcall)
alloc_rname = ggc_strdup (rname);
j = 0;
- RTVEC_ELT (p, j++) = ret_rtx;
+ RTVEC_ELT (p, j++) = simple_return_rtx;
RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
gen_rtx_REG (Pmode,
LR_REGNO));
@@ -21165,13 +21214,11 @@ rs6000_emit_epilogue (int sibcall)
}
else
{
- rtx par;
+ rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11),
+ 0, reg_mode,
+ /*savep=*/false, /*gpr=*/true,
+ /*lr=*/true);
- par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
- 0, reg_mode,
- /*savep=*/false, /*gpr=*/true,
- /*lr=*/true);
- emit_jump_insn (par);
/* We don't want anybody else emitting things after we jumped
back. */
return;
@@ -21181,12 +21228,22 @@ rs6000_emit_epilogue (int sibcall)
{
/* We are jumping to an out-of-line function. */
bool can_use_exit = info->first_fp_reg_save == 64;
- rtx par;
/* Emit stack reset code if we need it. */
if (can_use_exit)
- rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
- sp_offset, can_use_exit);
+ {
+ rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
+ sp_offset, can_use_exit);
+ if (info->cr_save_p)
+ {
+ rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
+ if (DEFAULT_ABI == ABI_V4)
+ cfa_restores
+ = alloc_reg_note (REG_CFA_RESTORE,
+ gen_rtx_REG (SImode, CR2_REGNO),
+ cfa_restores);
+ }
+ }
else
{
emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
@@ -21197,31 +21254,18 @@ rs6000_emit_epilogue (int sibcall)
sp_offset += info->fp_size;
}
- par = rs6000_make_savres_rtx (info, frame_reg_rtx,
- info->gp_save_offset, reg_mode,
- /*savep=*/false, /*gpr=*/true,
- /*lr=*/can_use_exit);
+ insn = rs6000_emit_savres_rtx (info, frame_reg_rtx,
+ info->gp_save_offset, reg_mode,
+ /*savep=*/false, /*gpr=*/true,
+ /*lr=*/can_use_exit);
if (can_use_exit)
{
- if (info->cr_save_p)
- {
- rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
- if (DEFAULT_ABI == ABI_V4)
- cfa_restores
- = alloc_reg_note (REG_CFA_RESTORE,
- gen_rtx_REG (SImode, CR2_REGNO),
- cfa_restores);
- }
-
- emit_jump_insn (par);
-
/* We don't want anybody else emitting things after we jumped
back. */
return;
}
- insn = emit_insn (par);
if (DEFAULT_ABI == ABI_V4)
{
if (frame_pointer_needed)
@@ -21366,7 +21410,7 @@ rs6000_emit_epilogue (int sibcall)
else
p = rtvec_alloc (2);
- RTVEC_ELT (p, 0) = ret_rtx;
+ RTVEC_ELT (p, 0) = simple_return_rtx;
RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
: gen_rtx_CLOBBER (VOIDmode,
@@ -21768,7 +21812,7 @@ rs6000_output_mi_thunk (FILE *file, tree
gen_rtx_USE (VOIDmode,
gen_rtx_REG (SImode,
LR_REGNO)),
- ret_rtx)));
+ simple_return_rtx)));
SIBLING_CALL_P (insn) = 1;
emit_barrier ();
@@ -306,7 +306,7 @@
(define_insn "*restore_world"
[(match_parallel 0 "restore_world_operation"
- [(return)
+ [(simple_return)
(use (reg:SI 65))
(use (match_operand:SI 1 "call_operand" "s"))
(clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])]
@@ -264,6 +265,12 @@
; Iterator for just SF/DF
(define_mode_iterator SFDF [SF DF])
+; Conditional returns.
+(define_code_iterator any_return [return simple_return])
+(define_code_attr return_pred [(return "direct_return ()")
+ (simple_return "")])
+(define_code_attr return_str [(return "") (simple_return "simple_")])
+
; Various instructions that come in SI and DI forms.
; A generic w/d attribute, for things like cmpw/cmpd.
(define_mode_attr wd [(QI "b") (HI "h") (SI "w") (DI "d")])
@@ -12814,7 +12831,7 @@
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(use (reg:SI LR_REGNO))
- (return)])]
+ (simple_return)])]
""
"
{
@@ -12838,7 +12855,7 @@
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(use (reg:SI LR_REGNO))
- (return)]
+ (simple_return)]
"(INTVAL (operands[2]) & CALL_LONG) == 0"
"*
{
@@ -12858,7 +12875,7 @@
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(use (reg:SI LR_REGNO))
- (return)]
+ (simple_return)]
"TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
{
@@ -12879,7 +12896,7 @@
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(use (reg:SI LR_REGNO))
- (return)]
+ (simple_return)]
"(INTVAL (operands[3]) & CALL_LONG) == 0"
"*
{
@@ -12901,7 +12918,7 @@
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(use (reg:SI LR_REGNO))
- (return)]
+ (simple_return)]
"TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
{
@@ -12921,7 +12938,7 @@
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,O"))
(use (reg:SI LR_REGNO))
- (return)]
+ (simple_return)]
"DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands[2]) & CALL_LONG) == 0"
"@
@@ -12936,7 +12953,7 @@
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,O"))
(use (reg:SI LR_REGNO))
- (return)]
+ (simple_return)]
"DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands[3]) & CALL_LONG) == 0"
"@
@@ -12950,7 +12967,7 @@
(match_operand 1 "" ""))
(use (match_operand 2 "immediate_operand" "O,n,O,n"))
(use (reg:SI LR_REGNO))
- (return)]
+ (simple_return)]
"(DEFAULT_ABI == ABI_DARWIN
|| DEFAULT_ABI == ABI_V4)
&& (INTVAL (operands[2]) & CALL_LONG) == 0"
@@ -12981,7 +12998,7 @@
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(use (reg:SI LR_REGNO))
- (return)])]
+ (simple_return)])]
""
"
{
@@ -13002,7 +13019,7 @@
(match_operand 2 "" "")))
(use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
(use (reg:SI LR_REGNO))
- (return)]
+ (simple_return)]
"(DEFAULT_ABI == ABI_DARWIN
|| DEFAULT_ABI == ABI_V4)
&& (INTVAL (operands[3]) & CALL_LONG) == 0"
@@ -15328,9 +15345,9 @@
[(match_operand 1
"cc_reg_operand" "y")
(const_int 0)])
- (return)
+ (any_return)
(pc)))]
- "direct_return ()"
+ "<return_pred>"
"*
{
return output_cbranch (operands[0], NULL, 0, insn);
@@ -15360,8 +15377,8 @@
"cc_reg_operand" "y")
(const_int 0)])
(pc)
- (return)))]
- "direct_return ()"
+ (any_return)))]
+ "<return_pred>"
"*
{
return output_cbranch (operands[0], NULL, 1, insn);
@@ -15491,9 +15508,9 @@
"b %l0"
[(set_attr "type" "branch")])
-(define_insn "return"
- [(return)]
- "direct_return ()"
+(define_insn "<return_str>return"
+ [(any_return)]
+ "<return_pred>"
"{br|blr}"
[(set_attr "type" "jmpreg")])
@@ -16015,7 +16032,7 @@
(set_attr "cell_micro" "always")])
(define_insn "*return_internal_<mode>"
- [(return)
+ [(simple_return)
(use (match_operand:P 0 "register_operand" "lc"))]
""
"b%T0"
@@ -16077,7 +16094,7 @@
(define_insn "*return_and_restore_gpregs_<mode>_r11"
[(match_parallel 0 "any_parallel_operand"
- [(return)
+ [(simple_return)
(clobber (match_operand:P 1 "register_operand" "=l"))
(use (match_operand:P 2 "symbol_ref_operand" "s"))
(use (reg:P 11))
@@ -16090,7 +16107,7 @@
(define_insn "*return_and_restore_gpregs_<mode>_r12"
[(match_parallel 0 "any_parallel_operand"
- [(return)
+ [(simple_return)
(clobber (match_operand:P 1 "register_operand" "=l"))
(use (match_operand:P 2 "symbol_ref_operand" "s"))
(use (reg:P 12))
@@ -16103,7 +16120,7 @@
(define_insn "*return_and_restore_gpregs_<mode>_r1"
[(match_parallel 0 "any_parallel_operand"
- [(return)
+ [(simple_return)
(clobber (match_operand:P 1 "register_operand" "=l"))
(use (match_operand:P 2 "symbol_ref_operand" "s"))
(use (reg:P 1))
@@ -16116,7 +16133,7 @@
(define_insn "*return_and_restore_fpregs_<mode>_r11"
[(match_parallel 0 "any_parallel_operand"
- [(return)
+ [(simple_return)
(clobber (match_operand:P 1 "register_operand" "=l"))
(use (match_operand:P 2 "symbol_ref_operand" "s"))
(use (reg:P 11))
@@ -16129,7 +16146,7 @@
(define_insn "*return_and_restore_fpregs_<mode>_r12"
[(match_parallel 0 "any_parallel_operand"
- [(return)
+ [(simple_return)
(clobber (match_operand:P 1 "register_operand" "=l"))
(use (match_operand:P 2 "symbol_ref_operand" "s"))
(use (reg:P 12))
@@ -16142,7 +16159,7 @@
(define_insn "*return_and_restore_fpregs_<mode>_r1"
[(match_parallel 0 "any_parallel_operand"
- [(return)
+ [(simple_return)
(clobber (match_operand:P 1 "register_operand" "=l"))
(use (match_operand:P 2 "symbol_ref_operand" "s"))
(use (reg:P 1))
@@ -16155,7 +16172,7 @@
(define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
[(match_parallel 0 "any_parallel_operand"
- [(return)
+ [(simple_return)
(use (match_operand:P 1 "register_operand" "l"))
(use (match_operand:P 2 "symbol_ref_operand" "s"))
(use (reg:P 11))
@@ -16168,7 +16185,7 @@
(define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
[(match_parallel 0 "any_parallel_operand"
- [(return)
+ [(simple_return)
(use (match_operand:P 1 "register_operand" "l"))
(use (match_operand:P 2 "symbol_ref_operand" "s"))
(use (reg:P 1))
@@ -3178,7 +3178,7 @@
(define_insn "*return_and_restore_gpregs_spe"
[(match_parallel 0 "any_parallel_operand"
- [(return)
+ [(simple_return)
(clobber (reg:P 65))
(use (match_operand:P 1 "symbol_ref_operand" "s"))
(use (reg:P 11))