#include "insn-config.h"
#include "rtl.h"
#include "tree.h"
+#include "tm_p.h"
#include "flags.h"
#include "insn-flags.h"
#include "insn-codes.h"
#include "expr.h"
#include "recog.h"
#include "reload.h"
+#include "ggc.h"
/* Each optab contains info on how this target machine
can perform a particular operation
See expr.h for documentation of these optabs. */
-optab add_optab;
-optab sub_optab;
-optab smul_optab;
-optab smul_highpart_optab;
-optab umul_highpart_optab;
-optab smul_widen_optab;
-optab umul_widen_optab;
-optab sdiv_optab;
-optab sdivmod_optab;
-optab udiv_optab;
-optab udivmod_optab;
-optab smod_optab;
-optab umod_optab;
-optab flodiv_optab;
-optab ftrunc_optab;
-optab and_optab;
-optab ior_optab;
-optab xor_optab;
-optab ashl_optab;
-optab lshr_optab;
-optab ashr_optab;
-optab rotl_optab;
-optab rotr_optab;
-optab smin_optab;
-optab smax_optab;
-optab umin_optab;
-optab umax_optab;
-
-optab mov_optab;
-optab movstrict_optab;
-
-optab neg_optab;
-optab abs_optab;
-optab one_cmpl_optab;
-optab ffs_optab;
-optab sqrt_optab;
-optab sin_optab;
-optab cos_optab;
-
-optab cmp_optab;
-optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
-optab tst_optab;
-
-optab strlen_optab;
+optab optab_table[OTI_MAX];
+
+rtx libfunc_table[LTI_MAX];
/* Tables of patterns for extending one integer mode to another. */
enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
/* Contains the optab used for each rtx code. */
optab code_to_optab[NUM_RTX_CODE + 1];
-/* SYMBOL_REF rtx's for the library functions that are called
- implicitly and not via optabs. */
-
-rtx extendsfdf2_libfunc;
-rtx extendsfxf2_libfunc;
-rtx extendsftf2_libfunc;
-rtx extenddfxf2_libfunc;
-rtx extenddftf2_libfunc;
-
-rtx truncdfsf2_libfunc;
-rtx truncxfsf2_libfunc;
-rtx trunctfsf2_libfunc;
-rtx truncxfdf2_libfunc;
-rtx trunctfdf2_libfunc;
-
-rtx memcpy_libfunc;
-rtx bcopy_libfunc;
-rtx memcmp_libfunc;
-rtx bcmp_libfunc;
-rtx memset_libfunc;
-rtx bzero_libfunc;
-
-rtx throw_libfunc;
-rtx rethrow_libfunc;
-rtx sjthrow_libfunc;
-rtx sjpopnthrow_libfunc;
-rtx terminate_libfunc;
-rtx setjmp_libfunc;
-rtx longjmp_libfunc;
-rtx eh_rtime_match_libfunc;
-
-rtx eqhf2_libfunc;
-rtx nehf2_libfunc;
-rtx gthf2_libfunc;
-rtx gehf2_libfunc;
-rtx lthf2_libfunc;
-rtx lehf2_libfunc;
-
-rtx eqsf2_libfunc;
-rtx nesf2_libfunc;
-rtx gtsf2_libfunc;
-rtx gesf2_libfunc;
-rtx ltsf2_libfunc;
-rtx lesf2_libfunc;
-
-rtx eqdf2_libfunc;
-rtx nedf2_libfunc;
-rtx gtdf2_libfunc;
-rtx gedf2_libfunc;
-rtx ltdf2_libfunc;
-rtx ledf2_libfunc;
-
-rtx eqxf2_libfunc;
-rtx nexf2_libfunc;
-rtx gtxf2_libfunc;
-rtx gexf2_libfunc;
-rtx ltxf2_libfunc;
-rtx lexf2_libfunc;
-
-rtx eqtf2_libfunc;
-rtx netf2_libfunc;
-rtx gttf2_libfunc;
-rtx getf2_libfunc;
-rtx lttf2_libfunc;
-rtx letf2_libfunc;
-
-rtx floatsisf_libfunc;
-rtx floatdisf_libfunc;
-rtx floattisf_libfunc;
-
-rtx floatsidf_libfunc;
-rtx floatdidf_libfunc;
-rtx floattidf_libfunc;
-
-rtx floatsixf_libfunc;
-rtx floatdixf_libfunc;
-rtx floattixf_libfunc;
-
-rtx floatsitf_libfunc;
-rtx floatditf_libfunc;
-rtx floattitf_libfunc;
-
-rtx fixsfsi_libfunc;
-rtx fixsfdi_libfunc;
-rtx fixsfti_libfunc;
-
-rtx fixdfsi_libfunc;
-rtx fixdfdi_libfunc;
-rtx fixdfti_libfunc;
-
-rtx fixxfsi_libfunc;
-rtx fixxfdi_libfunc;
-rtx fixxfti_libfunc;
-
-rtx fixtfsi_libfunc;
-rtx fixtfdi_libfunc;
-rtx fixtfti_libfunc;
-
-rtx fixunssfsi_libfunc;
-rtx fixunssfdi_libfunc;
-rtx fixunssfti_libfunc;
-
-rtx fixunsdfsi_libfunc;
-rtx fixunsdfdi_libfunc;
-rtx fixunsdfti_libfunc;
-
-rtx fixunsxfsi_libfunc;
-rtx fixunsxfdi_libfunc;
-rtx fixunsxfti_libfunc;
-
-rtx fixunstfsi_libfunc;
-rtx fixunstfdi_libfunc;
-rtx fixunstfti_libfunc;
-
-rtx chkr_check_addr_libfunc;
-rtx chkr_set_right_libfunc;
-rtx chkr_copy_bitmap_libfunc;
-rtx chkr_check_exec_libfunc;
-rtx chkr_check_str_libfunc;
-
-rtx profile_function_entry_libfunc;
-rtx profile_function_exit_libfunc;
-
/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
gives the gen_function to make a branch to test that condition. */
#ifdef HAVE_conditional_trap
static void init_traps PROTO((void));
#endif
-static int cmp_available_p PROTO((enum machine_mode, enum rtx_code, int));
static void emit_cmp_and_jump_insn_1 PROTO((rtx, rtx, enum machine_mode,
enum rtx_code, int, rtx));
-static void prepare_cmp_insn PROTO((rtx *, rtx *, enum rtx_code, rtx,
- enum machine_mode *, int *, int));
-static rtx prepare_operand PROTO((int, rtx, int, enum machine_mode,
- enum machine_mode, int));
-static void prepare_float_lib_cmp PROTO((rtx *, rtx *, enum rtx_code,
+static void prepare_float_lib_cmp PROTO((rtx *, rtx *, enum rtx_code *,
enum machine_mode *, int *));
\f
/* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
&& binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
int icode = (int) binoptab->handlers[(int) mode].insn_code;
- enum machine_mode mode0 = insn_operand_mode[icode][1];
- enum machine_mode mode1 = insn_operand_mode[icode][2];
+ enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+ enum machine_mode mode1 = insn_data[icode].operand[2].mode;
rtx pat;
rtx xop0 = op0, xop1 = op1;
/* Now, if insn's predicates don't allow our operands, put them into
pseudo regs. */
- if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
+ if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)
&& mode0 != VOIDmode)
xop0 = copy_to_mode_reg (mode0, xop0);
- if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
+ if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
&& mode1 != VOIDmode)
xop1 = copy_to_mode_reg (mode1, xop1);
- if (! (*insn_operand_predicate[icode][0]) (temp, mode))
+ if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
temp = gen_reg_rtx (mode);
pat = GEN_FCN (icode) (temp, xop0, xop1);
copy_rtx (xop0),
copy_rtx (xop1)));
}
+
return target;
}
+
else
delete_insns_since (last);
}
copy_rtx (op0),
copy_rtx (op1)));
}
+
return product;
}
}
if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
int icode = (int) binoptab->handlers[(int) mode].insn_code;
- enum machine_mode mode0 = insn_operand_mode[icode][1];
- enum machine_mode mode1 = insn_operand_mode[icode][2];
+ enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+ enum machine_mode mode1 = insn_data[icode].operand[2].mode;
rtx pat;
rtx xop0 = op0, xop1 = op1;
xop1 = convert_to_mode (mode1, xop1, unsignedp);
/* Now, if insn doesn't accept these operands, put them into pseudos. */
- if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
+ if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
xop0 = copy_to_mode_reg (mode0, xop0);
- if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
+ if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
xop1 = copy_to_mode_reg (mode1, xop1);
/* We could handle this, but we should always be called with a pseudo
for our targets and all insns should take them as outputs. */
- if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
- || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
+ if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
+ || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
abort ();
pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
int icode = (int) unoptab->handlers[(int) mode].insn_code;
- enum machine_mode mode0 = insn_operand_mode[icode][1];
+ enum machine_mode mode0 = insn_data[icode].operand[1].mode;
rtx xop0 = op0;
if (target)
/* Now, if insn doesn't accept our operand, put it into a pseudo. */
- if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
+ if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
xop0 = copy_to_mode_reg (mode0, xop0);
- if (! (*insn_operand_predicate[icode][0]) (temp, mode))
+ if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
temp = gen_reg_rtx (mode);
pat = GEN_FCN (icode) (temp, xop0);
if (temp != 0)
return temp;
+ /* If we have a MAX insn, we can do this as MAX (x, -x). */
+ if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
+ {
+ rtx last = get_last_insn ();
+
+ temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
+ if (temp != 0)
+ temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
+ OPTAB_WIDEN);
+
+ if (temp != 0)
+ return temp;
+
+ delete_insns_since (last);
+ }
+
/* If this machine has expensive jumps, we can do integer absolute
value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
- where W is the width of MODE. */
+ where W is the width of MODE. But don't do this if the machine has
+ conditional arithmetic since the branches will be converted into
+ a conditional negation insn. */
+#ifndef HAVE_conditional_arithmetic
if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
{
rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
if (temp != 0)
return temp;
}
+#endif
/* If that does not win, use conditional jump and negate. */
/* If this mode is an integer too wide to compare properly,
compare word by word. Rely on CSE to optimize constant cases. */
- if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
+ if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode, ccp_jump))
do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
NULL_RTX, op1);
else
if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
int icode = (int) abs_optab->handlers[(int) mode].insn_code;
- enum machine_mode mode0 = insn_operand_mode[icode][1];
+ enum machine_mode mode0 = insn_data[icode].operand[1].mode;
rtx xop0 = op0;
if (target)
/* Now, if insn doesn't accept our operand, put it into a pseudo. */
- if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
+ if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
xop0 = copy_to_mode_reg (mode0, xop0);
- if (! (*insn_operand_predicate[icode][0]) (temp, submode))
+ if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
temp = gen_reg_rtx (submode);
pat = GEN_FCN (icode) (temp, xop0);
enum rtx_code code;
{
register rtx temp;
- enum machine_mode mode0 = insn_operand_mode[icode][1];
+ enum machine_mode mode0 = insn_data[icode].operand[1].mode;
rtx pat;
temp = target = protect_from_queue (target, 1);
/* Now, if insn does not accept our operands, put them into pseudos. */
- if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
op0 = copy_to_mode_reg (mode0, op0);
- if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
+ if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
|| (flag_force_mem && GET_CODE (temp) == MEM))
temp = gen_reg_rtx (GET_MODE (temp));
next = NEXT_INSN (insn);
- if (GET_CODE (PATTERN (insn)) == SET)
+ if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
set = PATTERN (insn);
else if (GET_CODE (PATTERN (insn)) == PARALLEL)
{
emit_move_insn (x, const1_rtx);
}
-/* Nonzero if we can perform a comparison of mode MODE for a conditional jump
- straightforwardly. */
-
-static int
-cmp_available_p (mode, code, can_use_tst_p)
+/* Nonzero if we can perform a comparison of mode MODE straightforwardly.
+ If FOR_JUMP is nonzero, we will be generating a jump based on this
+ comparison, otherwise a store-flags operation. */
+
+int
+can_compare_p (mode, purpose)
enum machine_mode mode;
- enum rtx_code code;
- int can_use_tst_p;
+ enum can_compare_purpose purpose;
{
do
{
- if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing
- || (can_use_tst_p
- && tst_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing))
+ if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
+ return 1;
+ if (purpose == ccp_jump
+ && cbranch_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
+ return 1;
+ if (purpose == ccp_cmov
+ && cmov_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
return 1;
+ if (purpose == ccp_store_flag
+ && cstore_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
+ return 1;
+
mode = GET_MODE_WIDER_MODE (mode);
- } while (mode != VOIDmode);
+ }
+ while (mode != VOIDmode);
return 0;
}
should perform the comparison on the modified values. */
void
-prepare_cmp_insn (px, py, comparison, size, pmode, punsignedp, align)
+prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
+ purpose)
rtx *px, *py;
- enum rtx_code comparison;
+ enum rtx_code *pcomparison;
rtx size;
enum machine_mode *pmode;
int *punsignedp;
int align;
+ enum can_compare_purpose purpose;
{
enum machine_mode mode = *pmode;
rtx x = *px, y = *py;
&& GET_CODE (size) == CONST_INT
&& INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
{
- result_mode = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
+ result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
result = gen_reg_rtx (result_mode);
emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
}
&& GET_CODE (size) == CONST_INT
&& INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
{
- result_mode = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
+ result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
result = gen_reg_rtx (result_mode);
emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
}
#ifdef HAVE_cmpstrsi
if (HAVE_cmpstrsi)
{
- result_mode = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
+ result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
result = gen_reg_rtx (result_mode);
size = protect_from_queue (size, 0);
emit_insn (gen_cmpstrsi (result, x, y,
*px = x;
*py = y;
- if (cmp_available_p (mode, comparison, y == CONST0_RTX (mode)))
+ if (can_compare_p (mode, purpose))
return;
/* Handle a lib call just for the mode we are using. */
}
if (class == MODE_FLOAT)
- prepare_float_lib_cmp (px, py, comparison, pmode, punsignedp);
+ prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
else
abort ();
to be used for operand OPNUM of the insn, is converted from mode MODE to
WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
that it is accepted by the operand predicate. Return the new value. */
-static rtx
+rtx
prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
int icode;
rtx x;
if (mode != wider_mode)
x = convert_modes (wider_mode, mode, x, unsignedp);
- if (! (*insn_operand_predicate[icode][opnum])
- (x, insn_operand_mode[icode][opnum]))
- x = copy_to_mode_reg (insn_operand_mode[icode][opnum], x);
+ if (! (*insn_data[icode].operand[opnum].predicate)
+ (x, insn_data[icode].operand[opnum].mode))
+ x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
return x;
}
enum insn_code icode;
PUT_MODE (test, wider_mode);
+ if (label)
+ {
+ icode = cbranch_optab->handlers[(int)wider_mode].insn_code;
+
+ if (icode != CODE_FOR_nothing
+ && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
+ {
+ x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
+ y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
+ emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
+ return;
+ }
+ }
+
/* Handle some compares against zero. */
icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
rtx op0;
rtx op1;
- if (CONSTANT_P (x))
+ if ((CONSTANT_P (x) && ! CONSTANT_P (y))
+ || (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT))
{
/* Swap operands and condition to ensure canonical RTL. */
op0 = y;
emit_queue ();
if (unsignedp)
comparison = unsigned_condition (comparison);
- prepare_cmp_insn (&op0, &op1, comparison, size, &mode, &unsignedp, align);
+ prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp, align,
+ ccp_jump);
emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
}
{
emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, 0);
}
-
-
-/* Nonzero if a compare of mode MODE can be done straightforwardly
- (without splitting it into pieces). */
-
-int
-can_compare_p (mode)
- enum machine_mode mode;
-{
- do
- {
- if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
- return 1;
- mode = GET_MODE_WIDER_MODE (mode);
- } while (mode != VOIDmode);
-
- return 0;
-}
\f
/* Emit a library call comparison between floating point X and Y.
COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
-void
-prepare_float_lib_cmp (px, py, comparison, pmode, punsignedp)
+static void
+prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
rtx *px, *py;
- enum rtx_code comparison;
+ enum rtx_code *pcomparison;
enum machine_mode *pmode;
int *punsignedp;
{
+ enum rtx_code comparison = *pcomparison;
rtx x = *px, y = *py;
enum machine_mode mode = GET_MODE (x);
rtx libfunc = 0;
y = protect_from_queue (y, 0);
*px = convert_to_mode (wider_mode, x, 0);
*py = convert_to_mode (wider_mode, y, 0);
- prepare_float_lib_cmp (px, py, comparison, pmode, punsignedp);
+ prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
return;
}
}
*px = result;
*py = const0_rtx;
*pmode = word_mode;
+#ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
+ if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
+ *pcomparison = NE;
+#endif
*punsignedp = 0;
}
\f
emit_indirect_jump (loc)
rtx loc;
{
- if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
+ if (! ((*insn_data[(int)CODE_FOR_indirect_jump].operand[0].predicate)
(loc, Pmode)))
loc = copy_to_mode_reg (Pmode, loc);
code = swap_condition (code);
}
+ /* get_condition will prefer to generate LT and GT even if the old
+ comparison was against zero, so undo that canonicalization here since
+ comparisons against zero are cheaper. */
+ if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
+ code = LE, op1 = const0_rtx;
+ else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
+ code = GE, op1 = const0_rtx;
+
if (cmode == VOIDmode)
cmode = GET_MODE (op0);
/* If the insn doesn't accept these operands, put them in pseudos. */
- if (! (*insn_operand_predicate[icode][0])
- (subtarget, insn_operand_mode[icode][0]))
- subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
+ if (! (*insn_data[icode].operand[0].predicate)
+ (subtarget, insn_data[icode].operand[0].mode))
+ subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
- if (! (*insn_operand_predicate[icode][2])
- (op2, insn_operand_mode[icode][2]))
- op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
+ if (! (*insn_data[icode].operand[2].predicate)
+ (op2, insn_data[icode].operand[2].mode))
+ op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
- if (! (*insn_operand_predicate[icode][3])
- (op3, insn_operand_mode[icode][3]))
- op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
+ if (! (*insn_data[icode].operand[3].predicate)
+ (op3, insn_data[icode].operand[3].mode))
+ op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
/* Everything should now be in the suitable form, so emit the compare insn
and then the conditional move. */
{
int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
- if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
- || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
- || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
+ if (! ((*insn_data[icode].operand[0].predicate)
+ (x, insn_data[icode].operand[0].mode))
+ || ! ((*insn_data[icode].operand[1].predicate)
+ (x, insn_data[icode].operand[1].mode))
+ || ! ((*insn_data[icode].operand[2].predicate)
+ (y, insn_data[icode].operand[2].mode)))
abort ();
return (GEN_FCN (icode) (x, x, y));
{
int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
- if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
- || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
- || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
+ if (! ((*insn_data[icode].operand[0].predicate)
+ (x, insn_data[icode].operand[0].mode))
+ || ! ((*insn_data[icode].operand[1].predicate)
+ (x, insn_data[icode].operand[1].mode))
+ || ! ((*insn_data[icode].operand[2].predicate)
+ (y, insn_data[icode].operand[2].mode)))
abort ();
return (GEN_FCN (icode) (x, x, y));
do_pending_stack_adjust ();
/* Test whether the sign bit is set. */
- emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
- emit_jump_insn (gen_blt (neglabel));
+ emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
+ 0, 0, neglabel);
/* The sign bit is not set. Convert as signed. */
expand_float (target, from, 0);
GET_MODE (to),
copy_rtx (from)));
}
+
return;
}
#endif
for (mode = first_mode; (int) mode <= (int) last_mode;
mode = (enum machine_mode) ((int) mode + 1))
{
- register char *mname = mode_name[(int) mode];
+ register const char *mname = GET_MODE_NAME(mode);
register unsigned mname_len = strlen (mname);
register char *libfunc_name
- = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
+ = ggc_alloc_string (NULL, 2 + opname_len + mname_len + 1 + 1);
register char *p;
register const char *q;
for (q = opname; *q; )
*p++ = *q++;
for (q = mname; *q; q++)
- *p++ = tolower ((unsigned char)*q);
+ *p++ = TOLOWER (*q);
*p++ = suffix;
*p++ = '\0';
+
optable->handlers[(int) mode].libfunc
= gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
}
init_libfuncs (optable, SFmode, TFmode, opname, suffix);
}
+rtx
+init_one_libfunc (name)
+ register const char *name;
+{
+ if (ggc_p)
+ name = ggc_alloc_string (name, -1);
+ return gen_rtx_SYMBOL_REF (Pmode, name);
+}
+
+/* Mark ARG (which is really an OPTAB *) for GC. */
+
+void
+mark_optab (arg)
+ void *arg;
+{
+ optab o = *(optab *) arg;
+ int i;
+
+ for (i = 0; i < NUM_MACHINE_MODES; ++i)
+ ggc_mark_rtx (o->handlers[i].libfunc);
+}
/* Call this once to initialize the contents of the optabs
appropriately for the current target machine. */
sin_optab = init_optab (UNKNOWN);
cos_optab = init_optab (UNKNOWN);
strlen_optab = init_optab (UNKNOWN);
+ cbranch_optab = init_optab (UNKNOWN);
+ cmov_optab = init_optab (UNKNOWN);
+ cstore_optab = init_optab (UNKNOWN);
for (i = 0; i < NUM_MACHINE_MODES; i++)
{
fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
#endif
-#ifdef EXTRA_CC_MODES
- init_mov_optab ();
-#endif
-
/* Initialize the optabs with the names of the library functions. */
init_integral_libfuncs (add_optab, "add", '3');
init_floating_libfuncs (add_optab, "add", '3');
#ifdef MULSI3_LIBCALL
smul_optab->handlers[(int) SImode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, MULSI3_LIBCALL);
+ = init_one_libfunc (MULSI3_LIBCALL);
#endif
#ifdef MULDI3_LIBCALL
smul_optab->handlers[(int) DImode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, MULDI3_LIBCALL);
+ = init_one_libfunc (MULDI3_LIBCALL);
#endif
#ifdef DIVSI3_LIBCALL
sdiv_optab->handlers[(int) SImode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, DIVSI3_LIBCALL);
+ = init_one_libfunc (DIVSI3_LIBCALL);
#endif
#ifdef DIVDI3_LIBCALL
sdiv_optab->handlers[(int) DImode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, DIVDI3_LIBCALL);
+ = init_one_libfunc (DIVDI3_LIBCALL);
#endif
#ifdef UDIVSI3_LIBCALL
udiv_optab->handlers[(int) SImode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, UDIVSI3_LIBCALL);
+ = init_one_libfunc (UDIVSI3_LIBCALL);
#endif
#ifdef UDIVDI3_LIBCALL
udiv_optab->handlers[(int) DImode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, UDIVDI3_LIBCALL);
+ = init_one_libfunc (UDIVDI3_LIBCALL);
#endif
#ifdef MODSI3_LIBCALL
smod_optab->handlers[(int) SImode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, MODSI3_LIBCALL);
+ = init_one_libfunc (MODSI3_LIBCALL);
#endif
#ifdef MODDI3_LIBCALL
smod_optab->handlers[(int) DImode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, MODDI3_LIBCALL);
+ = init_one_libfunc (MODDI3_LIBCALL);
#endif
#ifdef UMODSI3_LIBCALL
umod_optab->handlers[(int) SImode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, UMODSI3_LIBCALL);
+ = init_one_libfunc (UMODSI3_LIBCALL);
#endif
#ifdef UMODDI3_LIBCALL
umod_optab->handlers[(int) DImode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, UMODDI3_LIBCALL);
+ = init_one_libfunc (UMODDI3_LIBCALL);
#endif
/* Use cabs for DC complex abs, since systems generally have cabs.
Don't define any libcall for SCmode, so that cabs will be used. */
abs_optab->handlers[(int) DCmode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, "cabs");
+ = init_one_libfunc ("cabs");
/* The ffs function operates on `int'. */
#ifndef INT_TYPE_SIZE
#define INT_TYPE_SIZE BITS_PER_WORD
#endif
- ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
- = gen_rtx_SYMBOL_REF (Pmode, "ffs");
-
- extendsfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfdf2");
- extendsfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfxf2");
- extendsftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsftf2");
- extenddfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddfxf2");
- extenddftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddftf2");
-
- truncdfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncdfsf2");
- truncxfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfsf2");
- trunctfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfsf2");
- truncxfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfdf2");
- trunctfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfdf2");
-
- memcpy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcpy");
- bcopy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bcopy");
- memcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcmp");
- bcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gcc_bcmp");
- memset_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memset");
- bzero_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bzero");
-
- throw_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__throw");
- rethrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__rethrow");
- sjthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjthrow");
- sjpopnthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjpopnthrow");
- terminate_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__terminate");
- eh_rtime_match_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eh_rtime_match");
+ ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
+ = init_one_libfunc ("ffs");
+
+ extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
+ extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
+ extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
+ extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
+ extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
+
+ truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
+ truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
+ trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
+ truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
+ trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
+
+ memcpy_libfunc = init_one_libfunc ("memcpy");
+ bcopy_libfunc = init_one_libfunc ("bcopy");
+ memcmp_libfunc = init_one_libfunc ("memcmp");
+ bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
+ memset_libfunc = init_one_libfunc ("memset");
+ bzero_libfunc = init_one_libfunc ("bzero");
+
+ throw_libfunc = init_one_libfunc ("__throw");
+ rethrow_libfunc = init_one_libfunc ("__rethrow");
+ sjthrow_libfunc = init_one_libfunc ("__sjthrow");
+ sjpopnthrow_libfunc = init_one_libfunc ("__sjpopnthrow");
+ terminate_libfunc = init_one_libfunc ("__terminate");
+ eh_rtime_match_libfunc = init_one_libfunc ("__eh_rtime_match");
#ifndef DONT_USE_BUILTIN_SETJMP
- setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_setjmp");
- longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_longjmp");
+ setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
+ longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
#else
- setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "setjmp");
- longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "longjmp");
+ setjmp_libfunc = init_one_libfunc ("setjmp");
+ longjmp_libfunc = init_one_libfunc ("longjmp");
#endif
- eqhf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqhf2");
- nehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nehf2");
- gthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gthf2");
- gehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gehf2");
- lthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lthf2");
- lehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lehf2");
-
- eqsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqsf2");
- nesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nesf2");
- gtsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtsf2");
- gesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gesf2");
- ltsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltsf2");
- lesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lesf2");
-
- eqdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqdf2");
- nedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nedf2");
- gtdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtdf2");
- gedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gedf2");
- ltdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltdf2");
- ledf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ledf2");
-
- eqxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqxf2");
- nexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nexf2");
- gtxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtxf2");
- gexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gexf2");
- ltxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltxf2");
- lexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lexf2");
-
- eqtf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqtf2");
- netf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__netf2");
- gttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gttf2");
- getf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__getf2");
- lttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lttf2");
- letf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__letf2");
-
- floatsisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsisf");
- floatdisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdisf");
- floattisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattisf");
-
- floatsidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsidf");
- floatdidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdidf");
- floattidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattidf");
-
- floatsixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsixf");
- floatdixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdixf");
- floattixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattixf");
-
- floatsitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsitf");
- floatditf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatditf");
- floattitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattitf");
-
- fixsfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfsi");
- fixsfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfdi");
- fixsfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfti");
-
- fixdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfsi");
- fixdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfdi");
- fixdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfti");
-
- fixxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfsi");
- fixxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfdi");
- fixxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfti");
-
- fixtfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfsi");
- fixtfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfdi");
- fixtfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfti");
-
- fixunssfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfsi");
- fixunssfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfdi");
- fixunssfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfti");
-
- fixunsdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfsi");
- fixunsdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfdi");
- fixunsdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfti");
-
- fixunsxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfsi");
- fixunsxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfdi");
- fixunsxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfti");
-
- fixunstfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfsi");
- fixunstfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfdi");
- fixunstfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfti");
+ eqhf2_libfunc = init_one_libfunc ("__eqhf2");
+ nehf2_libfunc = init_one_libfunc ("__nehf2");
+ gthf2_libfunc = init_one_libfunc ("__gthf2");
+ gehf2_libfunc = init_one_libfunc ("__gehf2");
+ lthf2_libfunc = init_one_libfunc ("__lthf2");
+ lehf2_libfunc = init_one_libfunc ("__lehf2");
+
+ eqsf2_libfunc = init_one_libfunc ("__eqsf2");
+ nesf2_libfunc = init_one_libfunc ("__nesf2");
+ gtsf2_libfunc = init_one_libfunc ("__gtsf2");
+ gesf2_libfunc = init_one_libfunc ("__gesf2");
+ ltsf2_libfunc = init_one_libfunc ("__ltsf2");
+ lesf2_libfunc = init_one_libfunc ("__lesf2");
+
+ eqdf2_libfunc = init_one_libfunc ("__eqdf2");
+ nedf2_libfunc = init_one_libfunc ("__nedf2");
+ gtdf2_libfunc = init_one_libfunc ("__gtdf2");
+ gedf2_libfunc = init_one_libfunc ("__gedf2");
+ ltdf2_libfunc = init_one_libfunc ("__ltdf2");
+ ledf2_libfunc = init_one_libfunc ("__ledf2");
+
+ eqxf2_libfunc = init_one_libfunc ("__eqxf2");
+ nexf2_libfunc = init_one_libfunc ("__nexf2");
+ gtxf2_libfunc = init_one_libfunc ("__gtxf2");
+ gexf2_libfunc = init_one_libfunc ("__gexf2");
+ ltxf2_libfunc = init_one_libfunc ("__ltxf2");
+ lexf2_libfunc = init_one_libfunc ("__lexf2");
+
+ eqtf2_libfunc = init_one_libfunc ("__eqtf2");
+ netf2_libfunc = init_one_libfunc ("__netf2");
+ gttf2_libfunc = init_one_libfunc ("__gttf2");
+ getf2_libfunc = init_one_libfunc ("__getf2");
+ lttf2_libfunc = init_one_libfunc ("__lttf2");
+ letf2_libfunc = init_one_libfunc ("__letf2");
+
+ floatsisf_libfunc = init_one_libfunc ("__floatsisf");
+ floatdisf_libfunc = init_one_libfunc ("__floatdisf");
+ floattisf_libfunc = init_one_libfunc ("__floattisf");
+
+ floatsidf_libfunc = init_one_libfunc ("__floatsidf");
+ floatdidf_libfunc = init_one_libfunc ("__floatdidf");
+ floattidf_libfunc = init_one_libfunc ("__floattidf");
+
+ floatsixf_libfunc = init_one_libfunc ("__floatsixf");
+ floatdixf_libfunc = init_one_libfunc ("__floatdixf");
+ floattixf_libfunc = init_one_libfunc ("__floattixf");
+
+ floatsitf_libfunc = init_one_libfunc ("__floatsitf");
+ floatditf_libfunc = init_one_libfunc ("__floatditf");
+ floattitf_libfunc = init_one_libfunc ("__floattitf");
+
+ fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
+ fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
+ fixsfti_libfunc = init_one_libfunc ("__fixsfti");
+
+ fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
+ fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
+ fixdfti_libfunc = init_one_libfunc ("__fixdfti");
+
+ fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
+ fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
+ fixxfti_libfunc = init_one_libfunc ("__fixxfti");
+
+ fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
+ fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
+ fixtfti_libfunc = init_one_libfunc ("__fixtfti");
+
+ fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
+ fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
+ fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
+
+ fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
+ fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
+ fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
+
+ fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
+ fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
+ fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
+
+ fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
+ fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
+ fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
/* For check-memory-usage. */
- chkr_check_addr_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_addr");
- chkr_set_right_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_set_right");
- chkr_copy_bitmap_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_copy_bitmap");
- chkr_check_exec_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_exec");
- chkr_check_str_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_str");
+ chkr_check_addr_libfunc = init_one_libfunc ("chkr_check_addr");
+ chkr_set_right_libfunc = init_one_libfunc ("chkr_set_right");
+ chkr_copy_bitmap_libfunc = init_one_libfunc ("chkr_copy_bitmap");
+ chkr_check_exec_libfunc = init_one_libfunc ("chkr_check_exec");
+ chkr_check_str_libfunc = init_one_libfunc ("chkr_check_str");
/* For function entry/exit instrumentation. */
profile_function_entry_libfunc
- = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_enter");
+ = init_one_libfunc ("__cyg_profile_func_enter");
profile_function_exit_libfunc
- = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_exit");
+ = init_one_libfunc ("__cyg_profile_func_exit");
#ifdef HAVE_conditional_trap
init_traps ();
/* Allow the target to add more libcalls or rename some, etc. */
INIT_TARGET_OPTABS;
#endif
+
+ /* Add these GC roots. */
+ ggc_add_root (optab_table, OTI_MAX, sizeof(optab), mark_optab);
+ ggc_add_rtx_root (libfunc_table, LTI_MAX);
}
\f
#ifdef BROKEN_LDEXP
/* The insn generating function can not take an rtx_code argument.
TRAP_RTX is used as an rtx argument. Its code is replaced with
the code to be used in the trap insn and all other fields are
- ignored.
-
- ??? Will need to change to support garbage collection. */
+ ignored. */
static rtx trap_rtx;
static void
init_traps ()
{
if (HAVE_conditional_trap)
- trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
+ {
+ trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
+ ggc_add_rtx_root (&trap_rtx, 1);
+ }
}
#endif
&& cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
rtx insn;
+ start_sequence();
emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
PUT_CODE (trap_rtx, code);
insn = gen_conditional_trap (trap_rtx, tcode);
if (insn)
- return insn;
+ {
+ emit_insn (insn);
+ insn = gen_sequence ();
+ }
+ end_sequence();
+ return insn;
}
#endif