diff options
author | obrien <obrien@FreeBSD.org> | 1999-08-26 09:30:50 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 1999-08-26 09:30:50 +0000 |
commit | 0bedf4fb30066e5e1d4342a1d3914dae7d37cba7 (patch) | |
tree | 68d8110b41afd0ebbf39167b1a4918eea667a7c5 /contrib/gcc/optabs.c | |
parent | d4db5fb866b7ad5216abd5047774a3973b9901a9 (diff) | |
download | FreeBSD-src-0bedf4fb30066e5e1d4342a1d3914dae7d37cba7.zip FreeBSD-src-0bedf4fb30066e5e1d4342a1d3914dae7d37cba7.tar.gz |
Virgin import of gcc from EGCS 1.1.2
Diffstat (limited to 'contrib/gcc/optabs.c')
-rw-r--r-- | contrib/gcc/optabs.c | 591 |
1 files changed, 368 insertions, 223 deletions
diff --git a/contrib/gcc/optabs.c b/contrib/gcc/optabs.c index 2732ebe..4b31fe0 100644 --- a/contrib/gcc/optabs.c +++ b/contrib/gcc/optabs.c @@ -1,5 +1,5 @@ /* Expand the basic unary and binary arithmetic operations, for GNU compiler. - Copyright (C) 1987, 88, 92, 93, 94, 1995 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc. This file is part of GNU CC. @@ -20,6 +20,7 @@ Boston, MA 02111-1307, USA. */ #include "config.h" +#include "system.h" #include "rtl.h" #include "tree.h" #include "flags.h" @@ -29,7 +30,6 @@ Boston, MA 02111-1307, USA. */ #include "insn-config.h" #include "recog.h" #include "reload.h" -#include <ctype.h> /* Each optab contains info on how this target machine can perform a particular operation @@ -88,7 +88,7 @@ optab strlen_optab; /* Tables of patterns for extending one integer mode to another. */ enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2]; -/* Tables of patterns for converting between fixed and floating point. */ +/* Tables of patterns for converting between fixed and floating point. */ enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; @@ -118,6 +118,13 @@ rtx bcmp_libfunc; rtx memset_libfunc; rtx bzero_libfunc; +rtx throw_libfunc; +rtx sjthrow_libfunc; +rtx sjpopnthrow_libfunc; +rtx terminate_libfunc; +rtx setjmp_libfunc; +rtx longjmp_libfunc; + rtx eqhf2_libfunc; rtx nehf2_libfunc; rtx gthf2_libfunc; @@ -201,6 +208,12 @@ 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; + /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...) gives the gen_function to make a branch to test that condition. */ @@ -233,7 +246,9 @@ static optab init_optab PROTO((enum rtx_code)); static void init_libfuncs PROTO((optab, int, int, char *, int)); static void init_integral_libfuncs PROTO((optab, char *, int)); static void init_floating_libfuncs PROTO((optab, char *, int)); -static void init_complex_libfuncs PROTO((optab, char *, int)); +#ifdef HAVE_conditional_trap +static void init_traps PROTO((void)); +#endif /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to the result of operation CODE applied to OP0 (and OP1 if it is a binary @@ -278,13 +293,13 @@ add_equal_note (seq, target, code, op0, op1) return 0; if (GET_RTX_CLASS (code) == '1') - note = gen_rtx (code, GET_MODE (target), copy_rtx (op0)); + note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0)); else - note = gen_rtx (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1)); + note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1)); REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)) - = gen_rtx (EXPR_LIST, REG_EQUAL, note, - REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))); + = gen_rtx_EXPR_LIST (REG_EQUAL, note, + REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))); return 1; } @@ -315,13 +330,13 @@ widen_operand (op, mode, oldmode, unsignedp, no_extend) /* If MODE is no wider than a single word, we return a paradoxical SUBREG. */ if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) - return gen_rtx (SUBREG, mode, force_reg (GET_MODE (op), op), 0); + return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0); /* Otherwise, get an object of MODE, clobber it, and set the low-order part to OP. */ result = gen_reg_rtx (mode); - emit_insn (gen_rtx (CLOBBER, VOIDmode, result)); + emit_insn (gen_rtx_CLOBBER (VOIDmode, result)); emit_move_insn (gen_lowpart (GET_MODE (op), result), op); return result; } @@ -438,7 +453,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) temp = gen_reg_rtx (mode); /* If it is a commutative operator and the modes would match - if we would swap the operands, we can save the conversions. */ + if we would swap the operands, we can save the conversions. */ if (commutative_op) { if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1 @@ -615,7 +630,8 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) { if (binoptab->code != UNKNOWN) equiv_value - = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1)); + = gen_rtx_fmt_ee (binoptab->code, mode, + copy_rtx (op0), copy_rtx (op1)); else equiv_value = 0; @@ -734,7 +750,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) if (inter != 0) { if (binoptab->code != UNKNOWN) - equiv_value = gen_rtx (binoptab->code, mode, op0, op1); + equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1); else equiv_value = 0; @@ -848,7 +864,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) if (inter != 0) { if (binoptab->code != UNKNOWN) - equiv_value = gen_rtx (binoptab->code, mode, op0, op1); + equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1); else equiv_value = 0; @@ -897,7 +913,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) /* Indicate for flow that the entire target reg is being set. */ if (GET_CODE (target) == REG) - emit_insn (gen_rtx (CLOBBER, VOIDmode, target)); + emit_insn (gen_rtx_CLOBBER (VOIDmode, target)); /* Do the actual arithmetic. */ for (i = 0; i < nwords; i++) @@ -919,12 +935,11 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) { /* Store carry from main add/subtract. */ carry_out = gen_reg_rtx (word_mode); - carry_out = emit_store_flag (carry_out, - binoptab == add_optab ? LTU : GTU, - x, op0_piece, - word_mode, 1, normalizep); - if (carry_out == 0) - break; + carry_out = emit_store_flag_force (carry_out, + (binoptab == add_optab + ? LTU : GTU), + x, op0_piece, + word_mode, 1, normalizep); } if (i > 0) @@ -943,11 +958,11 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) { /* THIS CODE HAS NOT BEEN TESTED. */ /* Get out carry from adding/subtracting carry in. */ - carry_tmp = emit_store_flag (carry_tmp, - binoptab == add_optab - ? LTU : GTU, - x, carry_in, - word_mode, 1, normalizep); + carry_tmp = emit_store_flag_force (carry_tmp, + binoptab == add_optab + ? LTU : GTU, + x, carry_in, + word_mode, 1, normalizep); /* Logical-ior the two poss. carry together. */ carry_out = expand_binop (word_mode, ior_optab, @@ -963,13 +978,17 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD) { - rtx temp = emit_move_insn (target, target); - - REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL, - gen_rtx (binoptab->code, mode, - copy_rtx (xop0), - copy_rtx (xop1)), - REG_NOTES (temp)); + if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) + { + rtx temp = emit_move_insn (target, target); + + REG_NOTES (temp) + = gen_rtx_EXPR_LIST (REG_EQUAL, + gen_rtx_fmt_ee (binoptab->code, mode, + copy_rtx (xop0), + copy_rtx (xop1)), + REG_NOTES (temp)); + } return target; } else @@ -1143,12 +1162,16 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) if (temp != 0) { - temp = emit_move_insn (product, product); - REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL, - gen_rtx (MULT, mode, copy_rtx (op0), - copy_rtx (op1)), - REG_NOTES (temp)); - + if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) + { + temp = emit_move_insn (product, product); + REG_NOTES (temp) + = gen_rtx_EXPR_LIST (REG_EQUAL, + gen_rtx_fmt_ee (MULT, mode, + copy_rtx (op0), + copy_rtx (op1)), + REG_NOTES (temp)); + } return product; } } @@ -1366,7 +1389,6 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) X/(a+ib) */ rtx divisor; rtx real_t, imag_t; - rtx lhs, rhs; rtx temp1, temp2; /* Don't fetch these from memory more than once. */ @@ -1482,7 +1504,8 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) { if (binoptab->code != UNKNOWN) equiv_value - = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1)); + = gen_rtx_fmt_ee (binoptab->code, mode, + copy_rtx (op0), copy_rtx (op1)); else equiv_value = 0; @@ -1499,7 +1522,6 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN)) { rtx insns; - rtx funexp = binoptab->handlers[(int) mode].libfunc; rtx op1x = op1; enum machine_mode op1_mode = mode; rtx value; @@ -1529,7 +1551,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) target = gen_reg_rtx (mode); emit_libcall_block (insns, target, value, - gen_rtx (binoptab->code, mode, op0, op1)); + gen_rtx_fmt_ee (binoptab->code, mode, op0, op1)); return target; } @@ -1673,7 +1695,7 @@ sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods) [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))]. Either TARG0 or TARG1 may be zero, but what that means is that - that result is not actually wanted. We will generate it into + the result is not actually wanted. We will generate it into a dummy pseudo-reg and discard it. They may not both be zero. Returns 1 if this operation can be performed; 0 if not. */ @@ -1943,7 +1965,8 @@ expand_unop (mode, unoptab, op0, target, unsignedp) end_sequence (); emit_no_conflict_block (insns, target, op0, NULL_RTX, - gen_rtx (unoptab->code, mode, copy_rtx (op0))); + gen_rtx_fmt_e (unoptab->code, mode, + copy_rtx (op0))); return target; } @@ -1987,7 +2010,8 @@ expand_unop (mode, unoptab, op0, target, unsignedp) end_sequence (); emit_no_conflict_block (seq, target, op0, 0, - gen_rtx (unoptab->code, mode, copy_rtx (op0))); + gen_rtx_fmt_e (unoptab->code, mode, + copy_rtx (op0))); return target; } @@ -1995,7 +2019,6 @@ expand_unop (mode, unoptab, op0, target, unsignedp) if (unoptab->handlers[(int) mode].libfunc) { rtx insns; - rtx funexp = unoptab->handlers[(int) mode].libfunc; rtx value; start_sequence (); @@ -2009,7 +2032,7 @@ expand_unop (mode, unoptab, op0, target, unsignedp) target = gen_reg_rtx (mode); emit_libcall_block (insns, target, value, - gen_rtx (unoptab->code, mode, op0)); + gen_rtx_fmt_e (unoptab->code, mode, op0)); return target; } @@ -2116,6 +2139,13 @@ expand_abs (mode, op0, target, unsignedp, safe) } /* If that does not win, use conditional jump and negate. */ + + /* It is safe to use the target if it is the same + as the source if this is also a pseudo register */ + if (op0 == target && GET_CODE (op0) == REG + && REGNO (op0) >= FIRST_PSEUDO_REGISTER) + safe = 1; + op1 = gen_label_rtx (); if (target == 0 || ! safe || GET_MODE (target) != mode @@ -2298,7 +2328,6 @@ expand_complex_abs (mode, op0, target, unsignedp) if (abs_optab->handlers[(int) mode].libfunc) { rtx insns; - rtx funexp = abs_optab->handlers[(int) mode].libfunc; rtx value; start_sequence (); @@ -2312,7 +2341,7 @@ expand_complex_abs (mode, op0, target, unsignedp) target = gen_reg_rtx (submode); emit_libcall_block (insns, target, value, - gen_rtx (abs_optab->code, mode, op0)); + gen_rtx_fmt_e (abs_optab->code, mode, op0)); return target; } @@ -2374,7 +2403,10 @@ emit_unop_insn (icode, target, op0, code) op0 = protect_from_queue (op0, 0); - if (flag_force_mem) + /* Sign and zero extension from memory is often done specially on + RISC machines, so forcing into a register here can pessimize + code. */ + if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND) op0 = force_not_mem (op0); /* Now, if insn does not accept our operands, put them into pseudos. */ @@ -2485,7 +2517,7 @@ emit_no_conflict_block (insns, target, op0, op1, equiv) /* Now write the CLOBBER of the output, followed by the setting of each of the words, followed by the final copy. */ if (target != op0 && target != op1) - emit_insn (gen_rtx (CLOBBER, VOIDmode, target)); + emit_insn (gen_rtx_CLOBBER (VOIDmode, target)); for (insn = insns; insn; insn = next) { @@ -2493,12 +2525,12 @@ emit_no_conflict_block (insns, target, op0, op1, equiv) add_insn (insn); if (op1 && GET_CODE (op1) == REG) - REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1, - REG_NOTES (insn)); + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1, + REG_NOTES (insn)); if (op0 && GET_CODE (op0) == REG) - REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0, - REG_NOTES (insn)); + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0, + REG_NOTES (insn)); } if (mov_optab->handlers[(int) GET_MODE (target)].insn_code @@ -2507,7 +2539,7 @@ emit_no_conflict_block (insns, target, op0, op1, equiv) last = emit_move_insn (target, target); if (equiv) REG_NOTES (last) - = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last)); + = gen_rtx_EXPR_LIST (REG_EQUAL, equiv, REG_NOTES (last)); } else last = get_last_insn (); @@ -2518,9 +2550,9 @@ emit_no_conflict_block (insns, target, op0, op1, equiv) first = NEXT_INSN (prev); /* Encapsulate the block so it gets manipulated as a unit. */ - REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last, - REG_NOTES (first)); - REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last)); + REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, + REG_NOTES (first)); + REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); return last; } @@ -2603,8 +2635,10 @@ emit_libcall_block (insns, target, result, equiv) } last = emit_move_insn (target, result); - REG_NOTES (last) = gen_rtx (EXPR_LIST, - REG_EQUAL, copy_rtx (equiv), REG_NOTES (last)); + if (mov_optab->handlers[(int) GET_MODE (target)].insn_code + != CODE_FOR_nothing) + REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (equiv), + REG_NOTES (last)); if (prev == 0) first = get_insns (); @@ -2612,9 +2646,9 @@ emit_libcall_block (insns, target, result, equiv) first = NEXT_INSN (prev); /* Encapsulate the block so it gets manipulated as a unit. */ - REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last, - REG_NOTES (first)); - REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last)); + REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, + REG_NOTES (first)); + REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); } /* Generate code to store zero in X. */ @@ -2741,18 +2775,32 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align) else #endif { + rtx result; + #ifdef TARGET_MEM_FUNCTIONS emit_library_call (memcmp_libfunc, 0, TYPE_MODE (integer_type_node), 3, XEXP (x, 0), Pmode, XEXP (y, 0), Pmode, - size, Pmode); + convert_to_mode (TYPE_MODE (sizetype), size, + TREE_UNSIGNED (sizetype)), + TYPE_MODE (sizetype)); #else emit_library_call (bcmp_libfunc, 0, TYPE_MODE (integer_type_node), 3, XEXP (x, 0), Pmode, XEXP (y, 0), Pmode, - size, Pmode); + convert_to_mode (TYPE_MODE (integer_type_node), + size, + TREE_UNSIGNED (integer_type_node)), + TYPE_MODE (integer_type_node)); #endif - emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)), + + /* Immediately move the result of the libcall into a pseudo + register so reload doesn't clobber the value if it needs + the return register for a spill reg. */ + result = gen_reg_rtx (TYPE_MODE (integer_type_node)); + emit_move_insn (result, + hard_libcall_value (TYPE_MODE (integer_type_node))); + emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX, TYPE_MODE (integer_type_node), 0, 0); } @@ -2829,6 +2877,8 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align) && class != MODE_FLOAT) { rtx libfunc = cmp_optab->handlers[(int) mode].libfunc; + rtx result; + /* If we want unsigned, and this mode has a distinct unsigned comparison routine, use that. */ if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc) @@ -2837,11 +2887,16 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align) emit_library_call (libfunc, 1, word_mode, 2, x, mode, y, mode); + /* Immediately move the result of the libcall into a pseudo + register so reload doesn't clobber the value if it needs + the return register for a spill reg. */ + result = gen_reg_rtx (word_mode); + emit_move_insn (result, hard_libcall_value (word_mode)); + /* Integer comparison returns a result that must be compared against 1, so that even if we do an unsigned compare afterward, there is still a value that can represent the result "less than". */ - - emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx, + emit_cmp_insn (result, const1_rtx, comparison, NULL_RTX, word_mode, unsignedp, 0); return; } @@ -2880,6 +2935,7 @@ emit_float_lib_cmp (x, y, comparison) { enum machine_mode mode = GET_MODE (x); rtx libfunc = 0; + rtx result; if (mode == HFmode) switch (comparison) @@ -2907,6 +2963,9 @@ emit_float_lib_cmp (x, y, comparison) case LE: libfunc = lehf2_libfunc; break; + + default: + break; } else if (mode == SFmode) switch (comparison) @@ -2934,6 +2993,9 @@ emit_float_lib_cmp (x, y, comparison) case LE: libfunc = lesf2_libfunc; break; + + default: + break; } else if (mode == DFmode) switch (comparison) @@ -2961,6 +3023,9 @@ emit_float_lib_cmp (x, y, comparison) case LE: libfunc = ledf2_libfunc; break; + + default: + break; } else if (mode == XFmode) switch (comparison) @@ -2988,6 +3053,9 @@ emit_float_lib_cmp (x, y, comparison) case LE: libfunc = lexf2_libfunc; break; + + default: + break; } else if (mode == TFmode) switch (comparison) @@ -3015,6 +3083,9 @@ emit_float_lib_cmp (x, y, comparison) case LE: libfunc = letf2_libfunc; break; + + default: + break; } else { @@ -3044,7 +3115,13 @@ emit_float_lib_cmp (x, y, comparison) emit_library_call (libfunc, 1, word_mode, 2, x, mode, y, mode); - emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison, + /* Immediately move the result of the libcall into a pseudo + register so reload doesn't clobber the value if it needs + the return register for a spill reg. */ + result = gen_reg_rtx (word_mode); + emit_move_insn (result, hard_libcall_value (word_mode)); + + emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX, word_mode, 0, 0); } @@ -3107,15 +3184,14 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode, if (cmode == VOIDmode) cmode = GET_MODE (op0); - if ((CONSTANT_P (op2) && ! CONSTANT_P (op3)) - || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT)) + if (((CONSTANT_P (op2) && ! CONSTANT_P (op3)) + || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT)) + && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT + || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math)) { tem = op2; op2 = op3; op3 = tem; - /* ??? This may not be appropriate (consider IEEE). Perhaps we should - call can_reverse_comparison_p here and bail out if necessary. - It's not clear whether we need to do this canonicalization though. */ code = reverse_condition (code); } @@ -3306,7 +3382,7 @@ gen_move_insn (x, y) x = gen_lowpart_common (tmode, x1); if (x == 0 && GET_CODE (x1) == MEM) { - x = gen_rtx (MEM, tmode, XEXP (x1, 0)); + x = gen_rtx_MEM (tmode, XEXP (x1, 0)); RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1); MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1); MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1); @@ -3316,7 +3392,7 @@ gen_move_insn (x, y) y = gen_lowpart_common (tmode, y1); if (y == 0 && GET_CODE (y1) == MEM) { - y = gen_rtx (MEM, tmode, XEXP (y1, 0)); + y = gen_rtx_MEM (tmode, XEXP (y1, 0)); RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1); MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1); MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1); @@ -3487,7 +3563,7 @@ expand_float (to, from, unsignedp) /* There is no such mode. Pretend the target is wide enough. */ fmode = GET_MODE (to); - /* Avoid double-rounding when TO is narrower than FROM. */ + /* Avoid double-rounding when TO is narrower than FROM. */ if ((significand_size (fmode) + 1) < GET_MODE_BITSIZE (GET_MODE (from))) { @@ -3644,7 +3720,7 @@ expand_float (to, from, unsignedp) end_sequence (); emit_libcall_block (insns, target, value, - gen_rtx (FLOAT, GET_MODE (to), from)); + gen_rtx_FLOAT (GET_MODE (to), from)); } done: @@ -3785,13 +3861,18 @@ expand_fix (to, from, unsignedp) emit_label (lab2); - /* Make a place for a REG_NOTE and add it. */ - insn = emit_move_insn (to, to); - REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, - gen_rtx (UNSIGNED_FIX, GET_MODE (to), - copy_rtx (from)), - REG_NOTES (insn)); - + if (mov_optab->handlers[(int) GET_MODE (to)].insn_code + != CODE_FOR_nothing) + { + /* Make a place for a REG_NOTE and add it. */ + insn = emit_move_insn (to, to); + REG_NOTES (insn) + = gen_rtx_EXPR_LIST (REG_EQUAL, + gen_rtx_fmt_e (UNSIGNED_FIX, + GET_MODE (to), + copy_rtx (from)), + REG_NOTES (insn)); + } return; } #endif @@ -3873,14 +3954,17 @@ expand_fix (to, from, unsignedp) end_sequence (); emit_libcall_block (insns, target, value, - gen_rtx (unsignedp ? UNSIGNED_FIX : FIX, - GET_MODE (to), from)); + gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX, + GET_MODE (to), from)); } - if (GET_MODE (to) == GET_MODE (target)) - emit_move_insn (to, target); - else - convert_move (to, target, 0); + if (target != to) + { + if (GET_MODE (to) == GET_MODE (target)) + emit_move_insn (to, target); + else + convert_move (to, target, 0); + } } static optab @@ -3950,7 +4034,7 @@ init_libfuncs (optable, first_mode, last_mode, opname, suffix) *p++ = suffix; *p++ = '\0'; optable->handlers[(int) mode].libfunc - = gen_rtx (SYMBOL_REF, Pmode, libfunc_name); + = gen_rtx_SYMBOL_REF (Pmode, libfunc_name); } } @@ -3982,19 +4066,6 @@ init_floating_libfuncs (optable, opname, suffix) init_libfuncs (optable, SFmode, TFmode, opname, suffix); } -/* Initialize the libfunc fields of an entire group of entries in some - optab which correspond to all complex floating modes. The parameters - have the same meaning as similarly named ones for the `init_libfuncs' - routine. (See above). */ - -static void -init_complex_libfuncs (optable, opname, suffix) - register optab optable; - register char *opname; - register int suffix; -{ - init_libfuncs (optable, SCmode, TCmode, opname, suffix); -} /* Call this once to initialize the contents of the optabs appropriately for the current target machine. */ @@ -4002,7 +4073,11 @@ init_complex_libfuncs (optable, opname, suffix) void init_optabs () { - int i, j; + int i; +#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC + int j; +#endif + enum insn_code *p; /* Start by initializing all tables to contain CODE_FOR_nothing. */ @@ -4079,6 +4154,7 @@ init_optabs () for (i = 0; i < NUM_MACHINE_MODES; i++) { movstr_optab[i] = CODE_FOR_nothing; + clrstr_optab[i] = CODE_FOR_nothing; #ifdef HAVE_SECONDARY_RELOADS reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing; @@ -4139,162 +4215,185 @@ init_optabs () #ifdef MULSI3_LIBCALL smul_optab->handlers[(int) SImode].libfunc - = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL); + = gen_rtx_SYMBOL_REF (Pmode, MULSI3_LIBCALL); #endif #ifdef MULDI3_LIBCALL smul_optab->handlers[(int) DImode].libfunc - = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL); + = gen_rtx_SYMBOL_REF (Pmode, MULDI3_LIBCALL); #endif #ifdef DIVSI3_LIBCALL sdiv_optab->handlers[(int) SImode].libfunc - = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL); + = gen_rtx_SYMBOL_REF (Pmode, DIVSI3_LIBCALL); #endif #ifdef DIVDI3_LIBCALL sdiv_optab->handlers[(int) DImode].libfunc - = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL); + = gen_rtx_SYMBOL_REF (Pmode, DIVDI3_LIBCALL); #endif #ifdef UDIVSI3_LIBCALL udiv_optab->handlers[(int) SImode].libfunc - = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL); + = gen_rtx_SYMBOL_REF (Pmode, UDIVSI3_LIBCALL); #endif #ifdef UDIVDI3_LIBCALL udiv_optab->handlers[(int) DImode].libfunc - = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL); + = gen_rtx_SYMBOL_REF (Pmode, UDIVDI3_LIBCALL); #endif #ifdef MODSI3_LIBCALL smod_optab->handlers[(int) SImode].libfunc - = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL); + = gen_rtx_SYMBOL_REF (Pmode, MODSI3_LIBCALL); #endif #ifdef MODDI3_LIBCALL smod_optab->handlers[(int) DImode].libfunc - = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL); + = gen_rtx_SYMBOL_REF (Pmode, MODDI3_LIBCALL); #endif #ifdef UMODSI3_LIBCALL umod_optab->handlers[(int) SImode].libfunc - = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL); + = gen_rtx_SYMBOL_REF (Pmode, UMODSI3_LIBCALL); #endif #ifdef UMODDI3_LIBCALL umod_optab->handlers[(int) DImode].libfunc - = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL); + = gen_rtx_SYMBOL_REF (Pmode, 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"); + = gen_rtx_SYMBOL_REF (Pmode, "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"); - - 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"); + = 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"); + sjthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjthrow"); + sjpopnthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjpopnthrow"); + terminate_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__terminate"); +#ifndef DONT_USE_BUILTIN_SETJMP + setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_setjmp"); + longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_longjmp"); +#else + setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "setjmp"); + longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "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"); + + /* For check-memory-usage. */ + chkr_check_addr_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_check_addr"); + chkr_set_right_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_set_right"); + chkr_copy_bitmap_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_copy_bitmap"); + chkr_check_exec_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_check_exec"); + chkr_check_str_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_check_str"); + +#ifdef HAVE_conditional_trap + init_traps (); +#endif #ifdef INIT_TARGET_OPTABS /* Allow the target to add more libcalls or rename some, etc. */ @@ -4304,7 +4403,7 @@ init_optabs () #ifdef BROKEN_LDEXP -/* SCO 3.2 apparently has a broken ldexp. */ +/* SCO 3.2 apparently has a broken ldexp. */ double ldexp(x,n) @@ -4318,3 +4417,49 @@ ldexp(x,n) return x; } #endif /* BROKEN_LDEXP */ + +#ifdef HAVE_conditional_trap +/* 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. */ +static rtx trap_rtx; + +static void +init_traps () +{ + if (HAVE_conditional_trap) + trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX); +} +#endif + +/* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition + CODE. Return 0 on failure. */ + +rtx +gen_cond_trap (code, op1, op2, tcode) + enum rtx_code code; + rtx op1, op2, tcode; +{ + enum machine_mode mode = GET_MODE (op1); + + if (mode == VOIDmode) + return 0; + +#ifdef HAVE_conditional_trap + if (HAVE_conditional_trap + && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) + { + rtx insn; + 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; + } +#endif + + return 0; +} |