OSDN Git Service

* rtl.h (rtx_def): Update documentation.
[pf3gnuchains/gcc-fork.git] / gcc / optabs.c
index 8f4a640..83235f7 100644 (file)
@@ -1,5 +1,5 @@
 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
-   Copyright (C) 1987, 88, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 92-98, 1999 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
@@ -119,6 +119,13 @@ 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;
@@ -203,6 +210,15 @@ 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.  */
 
@@ -235,7 +251,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
 \f
 /* 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
@@ -280,13 +298,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;
 }
@@ -317,13 +335,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;
 }
@@ -617,7 +635,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;
 
@@ -736,7 +755,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;
 
@@ -850,7 +869,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;
 
@@ -899,7 +918,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++)
@@ -921,12 +940,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)
@@ -945,11 +963,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,
@@ -965,13 +983,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
@@ -1145,12 +1167,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;
            }
        }
@@ -1368,7 +1394,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.  */
@@ -1484,7 +1509,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;
          
@@ -1501,7 +1527,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;
@@ -1531,7 +1556,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;
     }
@@ -1675,7 +1700,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.  */
@@ -1945,7 +1970,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;
     }
 
@@ -1989,7 +2015,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;
     }
 
@@ -1997,7 +2024,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 ();
@@ -2011,7 +2037,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;
     }
@@ -2307,7 +2333,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 ();
@@ -2321,7 +2346,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;
     }
@@ -2383,9 +2408,10 @@ emit_unop_insn (icode, target, op0, code)
 
   op0 = protect_from_queue (op0, 0);
 
-  /* Sign 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)
+  /* 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.  */
@@ -2496,7 +2522,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)
     {
@@ -2504,12 +2530,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
@@ -2518,7 +2544,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 ();
@@ -2529,9 +2555,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;
 }
@@ -2570,6 +2596,21 @@ emit_libcall_block (insns, target, result, equiv)
 {
   rtx prev, next, first, last, insn;
 
+  /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
+     reg note to indicate that this call cannot throw. (Unless there is
+     already a REG_EH_REGION note.) */
+
+  for (insn = insns; insn; insn = NEXT_INSN (insn))
+    {
+      if (GET_CODE (insn) == CALL_INSN)
+        {
+          rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+          if (note == NULL_RTX)
+            REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (0),
+                                                  REG_NOTES (insn));
+        }
+    }
+
   /* First emit all insns that set pseudos.  Remove them from the list as
      we go.  Avoid insns that set pseudos which were referenced in previous
      insns.  These can be generated by move_by_pieces, for example,
@@ -2614,8 +2655,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 ();
@@ -2623,9 +2666,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));
 }
 \f
 /* Generate code to store zero in X.  */
@@ -2694,6 +2737,14 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
   if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
     y = force_reg (mode, y);
 
+#ifdef HAVE_cc0
+  /* Abort if we have a non-canonical comparison.  The RTL documentation
+     states that canonical comparisons are required only for targets which
+     have cc0.  */
+  if (CONSTANT_P (x) && ! CONSTANT_P (y))
+    abort();
+#endif
+
   /* Don't let both operands fail to indicate the mode.  */
   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
     x = force_reg (mode, x);
@@ -2885,6 +2936,52 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
     abort ();
 }
 
+/* Generate code to compare X with Y so that the condition codes are
+   set and to jump to LABEL if the condition is true.  If X is a
+   constant and Y is not a constant, then the comparison is swapped to
+   ensure that the comparison RTL has the canonical form.
+
+   MODE is the mode of the inputs (in case they are const_int).
+   UNSIGNEDP nonzero says that X and Y are unsigned;
+   this matters if they need to be widened.
+
+   If they have mode BLKmode, then SIZE specifies the size of both X and Y,
+   and ALIGN specifies the known shared alignment of X and Y.
+
+   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
+   It is ignored for fixed-point and block comparisons;
+   it is used only for floating-point comparisons.  */
+
+void
+emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
+     rtx x, y;
+     enum rtx_code comparison;
+     rtx size;
+     enum machine_mode mode;
+     int unsignedp;
+     int align;
+     rtx label;
+{
+  rtx op0;
+  rtx op1;
+         
+  if (CONSTANT_P (x))
+    {
+      /* Swap operands and condition to ensure canonical RTL.  */
+      op0 = y;
+      op1 = x;
+      comparison = swap_condition (comparison);
+    }
+  else
+    {
+      op0 = x;
+      op1 = y;
+    }
+  emit_cmp_insn (op0, op1, comparison, size, mode, unsignedp, align);
+  emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
+}
+
+
 /* Nonzero if a compare of mode MODE can be done straightforwardly
    (without splitting it into pieces).  */
 
@@ -2940,6 +3037,9 @@ emit_float_lib_cmp (x, y, comparison)
       case LE:
        libfunc = lehf2_libfunc;
        break;
+
+      default:
+       break;
       }
   else if (mode == SFmode)
     switch (comparison)
@@ -2967,6 +3067,9 @@ emit_float_lib_cmp (x, y, comparison)
       case LE:
        libfunc = lesf2_libfunc;
        break;
+
+      default:
+       break;
       }
   else if (mode == DFmode)
     switch (comparison)
@@ -2994,6 +3097,9 @@ emit_float_lib_cmp (x, y, comparison)
       case LE:
        libfunc = ledf2_libfunc;
        break;
+
+      default:
+       break;
       }
   else if (mode == XFmode)
     switch (comparison)
@@ -3021,6 +3127,9 @@ emit_float_lib_cmp (x, y, comparison)
       case LE:
        libfunc = lexf2_libfunc;
        break;
+
+      default:
+       break;
       }
   else if (mode == TFmode)
     switch (comparison)
@@ -3048,6 +3157,9 @@ emit_float_lib_cmp (x, y, comparison)
       case LE:
        libfunc = letf2_libfunc;
        break;
+
+      default:
+       break;
       }
   else
     {
@@ -3146,15 +3258,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);
     }
 
@@ -3345,20 +3456,18 @@ 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);
+             MEM_COPY_ATTRIBUTES (x, x1);
              copy_replacements (x1, x);
            }
 
          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);
+             MEM_COPY_ATTRIBUTES (y, y1);
              copy_replacements (y1, y);
            }
        }
@@ -3683,7 +3792,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:
@@ -3824,13 +3933,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
@@ -3912,8 +4026,8 @@ 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 (target != to)
@@ -3988,11 +4102,11 @@ init_libfuncs (optable, first_mode, last_mode, opname, suffix)
       for (q = opname; *q; )
        *p++ = *q++;
       for (q = mname; *q; q++)
-       *p++ = tolower (*q);
+       *p++ = tolower ((unsigned char)*q);
       *p++ = suffix;
       *p++ = '\0';
       optable->handlers[(int) mode].libfunc
-       = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
+       = gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
     }
 }
 
@@ -4024,19 +4138,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.  */
@@ -4044,7 +4145,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.  */
@@ -4182,164 +4287,193 @@ 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");
-
-  throw_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__throw");
-
-  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");
+  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");
+#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 (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");
+
+  /* For function entry/exit instrumentation.  */
+  profile_function_entry_libfunc
+    = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_enter");
+  profile_function_exit_libfunc
+    = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_exit");
+
+#ifdef HAVE_conditional_trap
+  init_traps ();
+#endif
 
 #ifdef INIT_TARGET_OPTABS
   /* Allow the target to add more libcalls or rename some, etc.  */
@@ -4363,3 +4497,49 @@ ldexp(x,n)
   return x;
 }
 #endif /* BROKEN_LDEXP */
+\f
+#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 ATTRIBUTE_UNUSED;
+  rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
+{
+  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;
+}