ia64-protos.h: Update.

* config/ia64/ia64-protos.h: Update.
        * config/ia64/ia64.c (call_multiple_values_operation): Remove.
        (ia64_expand_call): New.
        (ia64_expand_prologue): Emit an alloc if we need extra input
        registers.
        (ia64_expand_epilogue): New arg sibcall_p; don't emit the return
        instruction if true.
        (struct reg_flags): Add is_sibcall.
        (rtx_needs_barrier): A sibcall does not use CFM et al.  Ignore USEs.
        (emit_insn_group_barriers): Set flags.is_sibcall.  Remove hacks
        for CODE_FOR_gr_spill_internal/CODE_FOR_gr_restore_internal.
        * config/ia64/ia64.h (PREDICATE_CODES): Update.
        * config/ia64/ia64.md (call): Use ia64_expand_call.
        (call_value): Likewise.
        (sibcall, sibcall_value): New.
        (call patterns): Remove extra expanders; tidy.
        (sibcall_epilogue): New.
        (set_bsp): Remove the extra USE.  Put the operand inside the UNSPEC.

From-SVN: r36597
This commit is contained in:
Richard Henderson 2000-09-24 16:58:24 -07:00 committed by Richard Henderson
parent fd442cef30
commit 2ed4af6f2d
5 changed files with 212 additions and 304 deletions

View File

@ -1,3 +1,24 @@
2000-09-24 Richard Henderson <rth@cygnus.com>
* config/ia64/ia64-protos.h: Update.
* config/ia64/ia64.c (call_multiple_values_operation): Remove.
(ia64_expand_call): New.
(ia64_expand_prologue): Emit an alloc if we need extra input
registers.
(ia64_expand_epilogue): New arg sibcall_p; don't emit the return
instruction if true.
(struct reg_flags): Add is_sibcall.
(rtx_needs_barrier): A sibcall does not use CFM et al. Ignore USEs.
(emit_insn_group_barriers): Set flags.is_sibcall. Remove hacks
for CODE_FOR_gr_spill_internal/CODE_FOR_gr_restore_internal.
* config/ia64/ia64.h (PREDICATE_CODES): Update.
* config/ia64/ia64.md (call): Use ia64_expand_call.
(call_value): Likewise.
(sibcall, sibcall_value): New.
(call patterns): Remove extra expanders; tidy.
(sibcall_epilogue): New.
(set_bsp): Remove the extra USE. Put the operand inside the UNSPEC.
2000-09-24 Richard Henderson <rth@cygnus.com>
* emit-rtl.c (gen_lowpart_common): Use trunc_int_for_mode.

View File

@ -57,7 +57,6 @@ extern int fr_reg_or_fp01_operand PARAMS((rtx, enum machine_mode));
extern int normal_comparison_operator PARAMS((rtx, enum machine_mode));
extern int adjusted_comparison_operator PARAMS((rtx, enum machine_mode));
extern int signed_inequality_operator PARAMS((rtx, enum machine_mode));
extern int call_multiple_values_operation PARAMS((rtx, enum machine_mode));
extern int destination_operand PARAMS((rtx, enum machine_mode));
extern int not_postinc_memory_operand PARAMS((rtx, enum machine_mode));
extern int predicate_operator PARAMS((rtx, enum machine_mode));
@ -73,10 +72,11 @@ extern rtx ia64_gp_save_reg PARAMS((int));
extern rtx ia64_split_timode PARAMS((rtx[], rtx, rtx));
extern rtx spill_tfmode_operand PARAMS((rtx, int));
extern rtx ia64_expand_compare PARAMS((enum rtx_code, enum machine_mode));
extern void ia64_expand_call PARAMS((rtx, rtx, rtx, int));
extern HOST_WIDE_INT ia64_initial_elimination_offset PARAMS((int, int));
extern void ia64_expand_prologue PARAMS((void));
extern void ia64_expand_epilogue PARAMS((void));
extern void ia64_expand_epilogue PARAMS((int));
extern void ia64_function_prologue PARAMS((FILE *, int));
extern void ia64_function_epilogue PARAMS((FILE *, int));

View File

@ -676,41 +676,6 @@ signed_inequality_operator (op, mode)
|| code == LE || code == LT));
}
/* Return 1 if OP is a call returning an HFA. It is known to be a PARALLEL
and the first section has already been tested. */
int
call_multiple_values_operation (op, mode)
rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
int count = XVECLEN (op, 0) - 2;
int i;
unsigned int dest_regno;
/* Perform a quick check so we don't block up below. */
if (count <= 1
|| GET_CODE (XVECEXP (op, 0, 0)) != SET
|| GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
|| GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != CALL)
return 0;
dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
for (i = 1; i < count; i++)
{
rtx elt = XVECEXP (op, 0, i + 2);
if (GET_CODE (elt) != SET
|| GET_CODE (SET_SRC (elt)) != CALL
|| GET_CODE (SET_DEST (elt)) != REG
|| REGNO (SET_DEST (elt)) != dest_regno + i)
return 0;
}
return 1;
}
/* Return 1 if this operator is valid for predication. */
int
@ -1044,6 +1009,98 @@ ia64_expand_compare (code, mode)
return gen_rtx_fmt_ee (code, mode, cmp, const0_rtx);
}
/* Emit the appropriate sequence for a call. */
void
ia64_expand_call (retval, addr, nextarg, sibcall_p)
rtx retval;
rtx addr;
rtx nextarg;
int sibcall_p;
{
rtx insn, b0, gp_save, narg_rtx;
int narg;
addr = XEXP (addr, 0);
b0 = gen_rtx_REG (DImode, R_BR (0));
if (! nextarg)
narg = 0;
else if (IN_REGNO_P (REGNO (nextarg)))
narg = REGNO (nextarg) - IN_REG (0);
else
narg = REGNO (nextarg) - OUT_REG (0);
narg_rtx = GEN_INT (narg);
if (TARGET_NO_PIC || TARGET_AUTO_PIC)
{
if (sibcall_p)
insn = gen_sibcall_nopic (addr, narg_rtx, b0);
else if (! retval)
insn = gen_call_nopic (addr, narg_rtx, b0);
else
insn = gen_call_value_nopic (retval, addr, narg_rtx, b0);
emit_call_insn (insn);
return;
}
if (sibcall_p)
gp_save = NULL_RTX;
else
gp_save = ia64_gp_save_reg (setjmp_operand (addr, VOIDmode));
/* If this is an indirect call, then we have the address of a descriptor. */
if (! symbolic_operand (addr, VOIDmode))
{
rtx dest;
if (! sibcall_p)
emit_move_insn (gp_save, pic_offset_table_rtx);
dest = force_reg (DImode, gen_rtx_MEM (DImode, addr));
emit_move_insn (pic_offset_table_rtx,
gen_rtx_MEM (DImode, plus_constant (addr, 8)));
if (sibcall_p)
insn = gen_sibcall_pic (dest, narg_rtx, b0);
else if (! retval)
insn = gen_call_pic (dest, narg_rtx, b0);
else
insn = gen_call_value_pic (retval, dest, narg_rtx, b0);
emit_call_insn (insn);
if (! sibcall_p)
emit_move_insn (pic_offset_table_rtx, gp_save);
}
else if (TARGET_CONST_GP)
{
if (sibcall_p)
insn = gen_sibcall_nopic (addr, narg_rtx, b0);
else if (! retval)
insn = gen_call_nopic (addr, narg_rtx, b0);
else
insn = gen_call_value_nopic (retval, addr, narg_rtx, b0);
emit_call_insn (insn);
}
else
{
if (sibcall_p)
emit_call_insn (gen_sibcall_pic (addr, narg_rtx, b0));
else
{
emit_move_insn (gp_save, pic_offset_table_rtx);
if (! retval)
insn = gen_call_pic (addr, narg_rtx, b0);
else
insn = gen_call_value_pic (retval, addr, narg_rtx, b0);
emit_call_insn (insn);
emit_move_insn (pic_offset_table_rtx, gp_save);
}
}
}
/* Begin the assembly file. */
@ -1819,7 +1876,8 @@ ia64_expand_prologue ()
/* We don't need an alloc instruction if we've used no outputs or locals. */
if (current_frame_info.n_local_regs == 0
&& current_frame_info.n_output_regs == 0)
&& current_frame_info.n_output_regs == 0
&& current_frame_info.n_input_regs <= current_function_args_info.words)
{
/* If there is no alloc, but there are input registers used, then we
need a .regstk directive. */
@ -2090,7 +2148,8 @@ ia64_expand_prologue ()
insn to prevent such scheduling. */
void
ia64_expand_epilogue ()
ia64_expand_epilogue (sibcall_p)
int sibcall_p;
{
rtx insn, reg, alt_reg, ar_unat_save_reg;
int regno, alt_regno, cfa_off;
@ -2303,7 +2362,8 @@ ia64_expand_epilogue ()
if (cfun->machine->ia64_eh_epilogue_bsp)
emit_insn (gen_set_bsp (cfun->machine->ia64_eh_epilogue_bsp));
emit_jump_insn (gen_return_internal (gen_rtx_REG (DImode, BR_REG (0))));
if (! sibcall_p)
emit_jump_insn (gen_return_internal (gen_rtx_REG (DImode, BR_REG (0))));
}
/* Return 1 if br.ret can do all the work required to return from a
@ -3642,6 +3702,7 @@ struct reg_flags
unsigned int is_branch : 1; /* Is register used as part of a branch? */
unsigned int is_and : 1; /* Is register used as part of and.orcm? */
unsigned int is_or : 1; /* Is register used as part of or.andcm? */
unsigned int is_sibcall : 1; /* Is this a sibling or normal call? */
};
static void rws_update PARAMS ((struct reg_write_state *, int,
@ -3935,9 +3996,7 @@ rtx_needs_barrier (x, flags, pred)
/* Avoid multiple register writes, in case this is a pattern with
multiple CALL rtx. This avoids an abort in rws_access_reg. */
/* ??? This assumes that no rtx other than CALL/RETURN sets REG_AR_CFM,
and that we don't have predicated calls/returns. */
if (! rws_insn[REG_AR_CFM].write_count)
if (! flags.is_sibcall && ! rws_insn[REG_AR_CFM].write_count)
{
new_flags.is_write = 1;
need_barrier |= rws_access_regno (REG_RP, new_flags, pred);
@ -3968,12 +4027,7 @@ rtx_needs_barrier (x, flags, pred)
return need_barrier;
case CLOBBER:
#if 0
case USE:
/* We must handle USE here in case it occurs within a PARALLEL.
For instance, the mov ar.pfs= instruction has a USE which requires
a barrier between it and an immediately preceeding alloc. */
#endif
/* Clobber & use are for earlier compiler-phases only. */
break;
@ -4096,6 +4150,7 @@ rtx_needs_barrier (x, flags, pred)
break;
case 7: /* pred_rel_mutex */
case 9: /* pic call */
case 12: /* mf */
case 19: /* fetchadd_acq */
case 20: /* mov = ar.bsp */
@ -4185,6 +4240,7 @@ rtx_needs_barrier (x, flags, pred)
default:
abort ();
}
break;
}
return need_barrier;
}
@ -4229,6 +4285,7 @@ emit_insn_group_barriers (insns)
case CALL_INSN:
flags.is_branch = 1;
flags.is_sibcall = SIBLING_CALL_P (insn);
memset (rws_insn, 0, sizeof (rws_insn));
need_barrier = rtx_needs_barrier (PATTERN (insn), flags, 0);
@ -4300,18 +4357,6 @@ emit_insn_group_barriers (insns)
pat = XVECEXP (pat, 0, 1);
break;
/* We include ar.unat in the rtl pattern so that sched2
does not move the ar.unat save/restore after/before
a gr spill/fill. However, we special case these
insns based on their unspec number so as to model
their precise ar.unat bit operations. If we pass on
the use/clobber of the whole ar.unat register we'll
waste this effort. */
case CODE_FOR_gr_spill_internal:
case CODE_FOR_gr_restore_internal:
pat = XVECEXP (pat, 0, 0);
break;
/* Doesn't generate code. */
case CODE_FOR_pred_rel_mutex:
continue;

View File

@ -2697,7 +2697,6 @@ do { \
{ "normal_comparison_operator", {EQ, NE, GT, LE, GTU, LEU}}, \
{ "adjusted_comparison_operator", {LT, GE, LTU, GEU}}, \
{ "signed_inequality_operator", {GE, GT, LE, LT}}, \
{ "call_multiple_values_operation", {PARALLEL}}, \
{ "predicate_operator", {NE, EQ}}, \
{ "ar_lc_reg_operand", {REG}}, \
{ "ar_ccv_reg_operand", {REG}}, \

View File

@ -62,6 +62,7 @@
;; 5 recip_approx
;; 7 pred_rel_mutex
;; 8 popcnt
;; 9 pic call
;; 12 mf
;; 13 cmpxchg_acq
;; 19 fetchadd_acq
@ -4708,82 +4709,27 @@
""
"
{
/* ??? Stripping off the MEM isn't correct. Will lose alias info. */
rtx addr = XEXP (operands[0], 0);
enum machine_mode mode = GET_MODE (addr);
if (TARGET_NO_PIC || TARGET_AUTO_PIC)
emit_call_insn (gen_call_internal (addr, operands[1],
gen_rtx_REG (DImode, R_BR (0))));
/* If this is an indirect call, then we have the address of a descriptor. */
else if (! symbolic_operand (addr, mode))
emit_insn (gen_indirect_call_pic (addr, operands[1]));
else if (TARGET_CONST_GP)
emit_call_insn (gen_call_internal (addr, operands[1],
gen_rtx_REG (DImode, R_BR (0))));
else
emit_insn (gen_call_pic (addr, operands[1]));
ia64_expand_call (NULL_RTX, operands[0], operands[2], 0);
DONE;
}")
(define_expand "indirect_call_pic"
[(set (match_dup 2) (reg:DI 1))
(set (match_dup 3) (mem:DI (match_operand 0 "" "")))
(set (match_dup 4) (plus:DI (match_dup 0) (const_int 8)))
(set (reg:DI 1) (mem:DI (match_dup 4)))
(parallel [(call (mem:DI (match_dup 3)) (match_operand 1 "" ""))
(use (reg:DI 1))
(clobber (reg:DI 320))])
(set (reg:DI 1) (match_dup 2))]
(define_expand "sibcall"
[(use (match_operand:DI 0 "" ""))
(use (match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(use (match_operand 3 "" ""))]
""
"
{
operands[2] = ia64_gp_save_reg (0);
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
ia64_expand_call (NULL_RTX, operands[0], operands[2], 1);
DONE;
}")
;; ??? Saving/restoring the GP register is not needed if we are calling
;; a function in the same module.
(define_expand "call_pic"
[(set (match_dup 2) (reg:DI 1))
(parallel [(call (mem:DI (match_operand 0 "" "")) (match_operand 1 "" ""))
(use (reg:DI 1))
(clobber (reg:DI 320))])
(set (reg:DI 1) (match_dup 2))]
""
"
{
/* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
operands[2] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[0], 0),
VOIDmode));
}")
(define_insn "call_internal"
[(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
(match_operand 1 "" ""))
(clobber (match_operand:DI 2 "register_operand" "=b"))]
""
"br.call%+.many %2 = %0"
[(set_attr "type" "B")])
(define_insn "*call_internal1"
[(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
(match_operand 1 "" ""))
(use (reg:DI 1))
(clobber (match_operand:DI 2 "register_operand" "=b"))]
""
"br.call%+.many %2 = %0"
[(set_attr "type" "B")])
;; Subroutine call instruction returning a value. Operand 0 is the hard
;; register in which the value is returned. There are three more operands, the
;; same as the three operands of the `call' instruction (but with numbers
;; register in which the value is returned. There are three more operands,
;; the same as the three operands of the `call' instruction (but with numbers
;; increased by one).
;;
;; Subroutines that return `BLKmode' objects use the `call' insn.
(define_expand "call_value"
@ -4795,187 +4741,23 @@
""
"
{
/* ??? Stripping off the MEM isn't correct. Will lose alias info. */
rtx addr = XEXP (operands[1], 0);
enum machine_mode mode = GET_MODE (addr);
if (TARGET_NO_PIC || TARGET_AUTO_PIC)
emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
gen_rtx_REG (DImode, R_BR (0))));
/* If this is an indirect call, then we have the address of a descriptor. */
else if (! symbolic_operand (addr, mode))
{
/* This is for HFA returns. */
if (GET_CODE (operands[0]) == PARALLEL)
emit_insn (gen_indirect_call_multiple_values_pic (operands[0], addr,
operands[2]));
else
emit_insn (gen_indirect_call_value_pic (operands[0], addr,
operands[2]));
}
else if (TARGET_CONST_GP)
emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
gen_rtx_REG (DImode, R_BR (0))));
/* This is for HFA returns. */
else if (GET_CODE (operands[0]) == PARALLEL)
emit_insn (gen_call_multiple_values_pic (operands[0], addr, operands[2]));
else
emit_insn (gen_call_value_pic (operands[0], addr, operands[2]));
ia64_expand_call (operands[0], operands[1], operands[3], 0);
DONE;
}")
(define_expand "indirect_call_value_pic"
[(set (match_dup 3) (reg:DI 1))
(set (match_dup 4) (mem:DI (match_operand 1 "" "")))
(set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
(set (reg:DI 1) (mem:DI (match_dup 5)))
(parallel [(set (match_operand 0 "" "")
(call (mem:DI (match_dup 4)) (match_operand 2 "" "")))
(use (reg:DI 1))
(clobber (reg:DI 320))])
(set (reg:DI 1) (match_dup 3))]
(define_expand "sibcall_value"
[(use (match_operand 0 "" ""))
(use (match_operand:DI 1 "" ""))
(use (match_operand 2 "" ""))
(use (match_operand 3 "" ""))
(use (match_operand 4 "" ""))]
""
"
{
operands[3] = ia64_gp_save_reg (0);
operands[4] = gen_reg_rtx (DImode);
operands[5] = gen_reg_rtx (DImode);
ia64_expand_call (operands[0], operands[1], operands[3], 1);
DONE;
}")
(define_expand "indirect_call_multiple_values_pic"
[(set (match_dup 3) (reg:DI 1))
(set (match_dup 4) (mem:DI (match_operand 1 "" "")))
(set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
(set (reg:DI 1) (mem:DI (match_dup 5)))
(match_par_dup 6 [(set (match_operand 0 "" "")
(call (mem:DI (match_dup 4))
(match_operand 2 "" "")))
(use (reg:DI 1))
(clobber (reg:DI 320))])
(set (reg:DI 1) (match_dup 3))]
""
"
{
int count;
int i;
rtx call;
operands[3] = ia64_gp_save_reg (0);
operands[4] = gen_reg_rtx (DImode);
operands[5] = gen_reg_rtx (DImode);
/* This code is the same as the code in call_multiple_values_pic, except
that op3 was replaced with op6 and op1 was replaced with op4. */
call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[4]),
operands[2]);
count = XVECLEN (operands[0], 0);
operands[6] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
XVECEXP (operands[6], 0, 0)
= gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
XVECEXP (operands[6], 0, 1)
= gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
XVECEXP (operands[6], 0, 2)
= gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
for (i = 1; i < count; i++)
XVECEXP (operands[6], 0, i + 2)
= gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
}")
;; ??? Saving/restoring the GP register is not needed if we are calling
;; a function in the same module.
(define_expand "call_value_pic"
[(set (match_dup 3) (reg:DI 1))
(parallel [(set (match_operand 0 "" "")
(call (mem:DI (match_operand 1 "" ""))
(match_operand 2 "" "")))
(use (reg:DI 1))
(clobber (reg:DI 320))])
(set (reg:DI 1) (match_dup 3))]
""
"
{
/* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
operands[3] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[1], 0),
VOIDmode));
}")
;; ??? Saving/restoring the GP register is not needed if we are calling
;; a function in the same module.
(define_expand "call_multiple_values_pic"
[(set (match_dup 4) (reg:DI 1))
(match_par_dup 3 [(set (match_operand 0 "" "")
(call (mem:DI (match_operand 1 "" ""))
(match_operand 2 "" "")))
(use (reg:DI 1))
(clobber (reg:DI 320))])
(set (reg:DI 1) (match_dup 4))]
""
"
{
int count;
int i;
rtx call;
operands[4] = ia64_gp_save_reg (0);
call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[1]),
operands[2]);
count = XVECLEN (operands[0], 0);
operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
XVECEXP (operands[3], 0, 0)
= gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
XVECEXP (operands[3], 0, 1)
= gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
XVECEXP (operands[3], 0, 2)
= gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
for (i = 1; i < count; i++)
XVECEXP (operands[3], 0, i + 2)
= gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
}")
(define_insn "call_value_internal"
[(set (match_operand 0 "register_operand" "=rf")
(call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
(match_operand 2 "" "")))
(clobber (match_operand:DI 3 "register_operand" "=b"))]
""
"br.call%+.many %3 = %1"
[(set_attr "type" "B")])
(define_insn "*call_value_internal1"
[(set (match_operand 0 "register_operand" "=rf")
(call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
(match_operand 2 "" "")))
(use (reg:DI 1))
(clobber (match_operand:DI 3 "register_operand" "=b"))]
""
"br.call%+.many %3 = %1"
[(set_attr "type" "B")])
(define_insn "*call_multiple_values_internal1"
[(match_parallel 0 "call_multiple_values_operation"
[(set (match_operand 1 "register_operand" "=rf")
(call (mem:DI (match_operand:DI 2 "call_operand" "bi"))
(match_operand 3 "" "")))
(use (reg:DI 1))
(clobber (match_operand:DI 4 "register_operand" "=b"))])]
""
"br.call%+.many %4 = %2"
[(set_attr "type" "B")])
;; Call subroutine returning any type.
(define_expand "untyped_call"
@ -5005,6 +4787,59 @@
DONE;
}")
(define_insn "call_nopic"
[(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
(match_operand 1 "" ""))
(clobber (match_operand:DI 2 "register_operand" "=b"))]
""
"br.call%+.many %2 = %0"
[(set_attr "type" "B")])
(define_insn "call_value_nopic"
[(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
(match_operand 2 "" "")))
(clobber (match_operand:DI 3 "register_operand" "=b"))]
""
"br.call%+.many %3 = %1"
[(set_attr "type" "B")])
(define_insn "sibcall_nopic"
[(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
(match_operand 1 "" ""))
(use (match_operand:DI 2 "register_operand" "=b"))]
""
"br%+.many %0"
[(set_attr "type" "B")])
(define_insn "call_pic"
[(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
(match_operand 1 "" ""))
(use (unspec [(reg:DI 1)] 9))
(clobber (match_operand:DI 2 "register_operand" "=b"))]
""
"br.call%+.many %2 = %0"
[(set_attr "type" "B")])
(define_insn "call_value_pic"
[(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
(match_operand 2 "" "")))
(use (unspec [(reg:DI 1)] 9))
(clobber (match_operand:DI 3 "register_operand" "=b"))]
""
"br.call%+.many %3 = %1"
[(set_attr "type" "B")])
(define_insn "sibcall_pic"
[(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
(match_operand 1 "" ""))
(use (unspec [(reg:DI 1)] 9))
(use (match_operand:DI 2 "register_operand" "=b"))]
""
"br%+.many %0"
[(set_attr "type" "B")])
(define_insn "return_internal"
[(return)
(use (match_operand:DI 0 "register_operand" "b"))]
@ -5093,11 +4928,20 @@
}")
(define_expand "epilogue"
[(const_int 2)]
[(return)]
""
"
{
ia64_expand_epilogue ();
ia64_expand_epilogue (0);
DONE;
}")
(define_expand "sibcall_epilogue"
[(return)]
""
"
{
ia64_expand_epilogue (1);
DONE;
}")
@ -5200,8 +5044,7 @@
[(set_attr "type" "I")])
(define_insn "set_bsp"
[(unspec_volatile [(const_int 0)] 5)
(use (match_operand:DI 0 "register_operand" "r"))]
[(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 5)]
""
"flushrs\;mov r19=ar.rsc\;;;\;and r19=0x1c,r19\;;;\;mov ar.rsc=r19\;;;\;mov ar.bspstore=%0\;;;\;or r19=0x3,r19\;;;\;loadrs\;invala\;;;\;mov ar.rsc=r19"
[(set_attr "type" "unknown")