diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 5d60240..439b0cb 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -58,6 +58,9 @@ typedef const struct rtx_def *const_rtx;
 struct rtvec_def;
 typedef struct rtvec_def *rtvec;
 typedef const struct rtvec_def *const_rtvec;
+struct hwivec_def;
+typedef struct hwivec_def *hwivec;
+typedef const struct hwivec_def *const_hwivec;
 union tree_node;
 typedef union tree_node *tree;
 typedef const union tree_node *const_tree;
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index bc6a3af..bbd8be0 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -692,88 +692,39 @@ stabstr_U (unsigned HOST_WIDE_INT num)
 static void
 stabstr_O (tree cst)
 {
-  unsigned HOST_WIDE_INT high = TREE_INT_CST_HIGH (cst);
-  unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (cst);
-
-  char buf[128];
-  char *p = buf + sizeof buf;
-
-  /* GDB wants constants with no extra leading "1" bits, so
-     we need to remove any sign-extension that might be
-     present.  */
-  {
-    const unsigned int width = TYPE_PRECISION (TREE_TYPE (cst));
-    if (width == HOST_BITS_PER_DOUBLE_INT)
-      ;
-    else if (width > HOST_BITS_PER_WIDE_INT)
-      high &= (((HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT)) - 1);
-    else if (width == HOST_BITS_PER_WIDE_INT)
-      high = 0;
-    else
-      high = 0, low &= (((HOST_WIDE_INT) 1 << width) - 1);
-  }
+  int prec = TYPE_PRECISION (TREE_TYPE (cst));
+  int res_pres = prec % 3;
+  int i;
+  unsigned int digit;
 
   /* Leading zero for base indicator.  */
   stabstr_C ('0');
 
   /* If the value is zero, the base indicator will serve as the value
      all by itself.  */
-  if (high == 0 && low == 0)
+  if (wi::eq_p (cst, 0))
     return;
 
-  /* If the high half is zero, we need only print the low half normally.  */
-  if (high == 0)
-    NUMBER_FMT_LOOP (p, low, 8);
-  else
+  /* GDB wants constants with no extra leading "1" bits, so
+     we need to remove any sign-extension that might be
+     present.  */
+  if (res_pres == 1)
     {
-      /* When high != 0, we need to print enough zeroes from low to
-	 give the digits from high their proper place-values.  Hence
-	 NUMBER_FMT_LOOP cannot be used.  */
-      const int n_digits = HOST_BITS_PER_WIDE_INT / 3;
-      int i;
-
-      for (i = 1; i <= n_digits; i++)
-	{
-	  unsigned int digit = low % 8;
-	  low /= 8;
-	  *--p = '0' + digit;
-	}
-
-      /* Octal digits carry exactly three bits of information.  The
-	 width of a HOST_WIDE_INT is not normally a multiple of three.
-	 Therefore, the next digit printed probably needs to carry
-	 information from both low and high.  */
-      if (HOST_BITS_PER_WIDE_INT % 3 != 0)
-	{
-	  const int n_leftover_bits = HOST_BITS_PER_WIDE_INT % 3;
-	  const int n_bits_from_high = 3 - n_leftover_bits;
-
-	  const unsigned HOST_WIDE_INT
-	    low_mask = (((unsigned HOST_WIDE_INT)1) << n_leftover_bits) - 1;
-	  const unsigned HOST_WIDE_INT
-	    high_mask = (((unsigned HOST_WIDE_INT)1) << n_bits_from_high) - 1;
-
-	  unsigned int digit;
-
-	  /* At this point, only the bottom n_leftover_bits bits of low
-	     should be set.  */
-	  gcc_assert (!(low & ~low_mask));
-
-	  digit = (low | ((high & high_mask) << n_leftover_bits));
-	  high >>= n_bits_from_high;
-
-	  *--p = '0' + digit;
-	}
-
-      /* Now we can format high in the normal manner.  However, if
-	 the only bits of high that were set were handled by the
-	 digit split between low and high, high will now be zero, and
-	 we don't want to print extra digits in that case.  */
-      if (high)
-	NUMBER_FMT_LOOP (p, high, 8);
+      digit = wi::extract_uhwi (cst, prec - 1, 1);
+      stabstr_C ('0' + digit);
+    }
+  else if (res_pres == 2)
+    {
+      digit = wi::extract_uhwi (cst, prec - 2, 2);
+      stabstr_C ('0' + digit);
     }
 
-  obstack_grow (&stabstr_ob, p, (buf + sizeof buf) - p);
+  prec -= res_pres;
+  for (i = prec - 3; i <= 0; i = i - 3)
+    {
+      digit = wi::extract_uhwi (cst, i, 3);
+      stabstr_C ('0' + digit);
+    }
 }
 
 /* Called whenever it is safe to break a stabs string into multiple
@@ -2301,10 +2252,7 @@ dbxout_type (tree type, int full)
           if (TREE_CODE (value) == CONST_DECL)
             value = DECL_INITIAL (value);
 
-	  if (TREE_INT_CST_HIGH (value) == 0)
-	    stabstr_D (TREE_INT_CST_LOW (value));
-	  else if (TREE_INT_CST_HIGH (value) == -1
-		   && (HOST_WIDE_INT) TREE_INT_CST_LOW (value) < 0)
+	  if (cst_and_fits_in_hwi (value))
 	    stabstr_D (TREE_INT_CST_LOW (value));
 	  else
 	    stabstr_O (value);
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 37e8a08..0c69918 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1392,6 +1392,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define SWITCHABLE_TARGET 0
 #endif
 
+/* If the target supports integers that are wider than two
+   HOST_WIDE_INTs on the host compiler, then the target should define
+   TARGET_SUPPORTS_WIDE_INT and make the appropriate fixups.
+   Otherwise the compiler really is not robust.  */
+#ifndef TARGET_SUPPORTS_WIDE_INT
+#define TARGET_SUPPORTS_WIDE_INT 0
+#endif
+
 #endif /* GCC_INSN_FLAGS_H  */
 
 #endif  /* ! GCC_DEFAULTS_H */
diff --git a/gcc/double-int.h b/gcc/double-int.h
index 650520b..50ca182 100644
--- a/gcc/double-int.h
+++ b/gcc/double-int.h
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef DOUBLE_INT_H
 #define DOUBLE_INT_H
 
+#include "wide-int.h"
+
 /* A large integer is currently represented as a pair of HOST_WIDE_INTs.
    It therefore represents a number with precision of
    2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the
@@ -435,4 +437,36 @@ void mpz_set_double_int (mpz_t, double_int, bool);
 double_int mpz_get_double_int (const_tree, mpz_t, bool);
 #endif
 
+namespace wi
+{
+  template <>
+  struct int_traits <double_int>
+  {
+    static const enum precision_type precision_type = CONST_PRECISION;
+    static const bool host_dependent_precision = true;
+    static const unsigned int precision = HOST_BITS_PER_DOUBLE_INT;
+    static unsigned int get_precision (const double_int &);
+    static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int,
+				      const double_int &);
+  };
+}
+
+inline unsigned int
+wi::int_traits <double_int>::get_precision (const double_int &)
+{
+  return precision;
+}
+
+inline wi::storage_ref
+wi::int_traits <double_int>::decompose (HOST_WIDE_INT *scratch, unsigned int p,
+					const double_int &x)
+{
+  gcc_checking_assert (precision == p);
+  scratch[0] = x.low;
+  if ((x.high == 0 && scratch[0] >= 0) || (x.high == -1 && scratch[0] < 0))
+    return wi::storage_ref (scratch, 1, precision);
+  scratch[1] = x.high;
+  return wi::storage_ref (scratch, 2, precision);
+}
+
 #endif /* DOUBLE_INT_H */
diff --git a/gcc/fixed-value.c b/gcc/fixed-value.c
index 91ec588..03fd599 100644
--- a/gcc/fixed-value.c
+++ b/gcc/fixed-value.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "diagnostic-core.h"
+#include "wide-int.h"
 
 /* Compare two fixed objects for bitwise identity.  */
 
@@ -113,6 +114,7 @@ fixed_from_string (FIXED_VALUE_TYPE *f, const char *str, enum machine_mode mode)
   REAL_VALUE_TYPE real_value, fixed_value, base_value;
   unsigned int fbit;
   enum fixed_value_range_code temp;
+  bool fail;
 
   f->mode = mode;
   fbit = GET_MODE_FBIT (mode);
@@ -127,8 +129,10 @@ fixed_from_string (FIXED_VALUE_TYPE *f, const char *str, enum machine_mode mode)
 	     "large fixed-point constant implicitly truncated to fixed-point type");
   real_2expN (&base_value, fbit, mode);
   real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value);
-  real_to_integer2 ((HOST_WIDE_INT *)&f->data.low, &f->data.high,
-		    &fixed_value);
+  wide_int w = real_to_integer (&fixed_value, &fail,
+				GET_MODE_PRECISION (mode));
+  f->data.low = w.elt (0);
+  f->data.high = w.elt (1);
 
   if (temp == FIXED_MAX_EPS && ALL_FRACT_MODE_P (f->mode))
     {
@@ -153,9 +157,12 @@ fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *f_orig,
 {
   REAL_VALUE_TYPE real_value, base_value, fixed_value;
 
+  signop sgn = UNSIGNED_FIXED_POINT_MODE_P (f_orig->mode) ? UNSIGNED : SIGNED;
   real_2expN (&base_value, GET_MODE_FBIT (f_orig->mode), f_orig->mode);
-  real_from_integer (&real_value, VOIDmode, f_orig->data.low, f_orig->data.high,
-		     UNSIGNED_FIXED_POINT_MODE_P (f_orig->mode));
+  real_from_integer (&real_value, VOIDmode,
+		     wide_int::from (f_orig->data,
+				     GET_MODE_PRECISION (f_orig->mode), sgn),
+		     sgn);
   real_arithmetic (&fixed_value, RDIV_EXPR, &real_value, &base_value);
   real_to_decimal (str, &fixed_value, buf_size, 0, 1);
 }
@@ -1041,12 +1048,17 @@ fixed_convert_from_real (FIXED_VALUE_TYPE *f, enum machine_mode mode,
   int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode);
   unsigned int fbit = GET_MODE_FBIT (mode);
   enum fixed_value_range_code temp;
+  bool fail;
 
   real_value = *a;
   f->mode = mode;
   real_2expN (&base_value, fbit, mode);
   real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value);
-  real_to_integer2 ((HOST_WIDE_INT *)&f->data.low, &f->data.high, &fixed_value);
+
+  wide_int w = real_to_integer (&fixed_value, &fail,
+				GET_MODE_PRECISION (mode));
+  f->data.low = w.elt (0);
+  f->data.high = w.elt (1);
   temp = check_real_for_fixed_mode (&real_value, mode);
   if (temp == FIXED_UNDERFLOW) /* Minimum.  */
     {
@@ -1091,9 +1103,11 @@ real_convert_from_fixed (REAL_VALUE_TYPE *r, enum machine_mode mode,
 {
   REAL_VALUE_TYPE base_value, fixed_value, real_value;
 
+  signop sgn = UNSIGNED_FIXED_POINT_MODE_P (f->mode) ? UNSIGNED : SIGNED;
   real_2expN (&base_value, GET_MODE_FBIT (f->mode), f->mode);
-  real_from_integer (&fixed_value, VOIDmode, f->data.low, f->data.high,
-		     UNSIGNED_FIXED_POINT_MODE_P (f->mode));
+  real_from_integer (&fixed_value, VOIDmode,
+		     wide_int::from (f->data, GET_MODE_PRECISION (f->mode),
+				     sgn), sgn);
   real_arithmetic (&real_value, RDIV_EXPR, &fixed_value, &base_value);
   real_convert (r, mode, &real_value);
 }
diff --git a/gcc/predict.c b/gcc/predict.c
index 919dbe9..afe78c6 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -1310,76 +1310,58 @@ predict_iv_comparison (struct loop *loop, basic_block bb,
       && tree_fits_shwi_p (compare_base))
     {
       int probability;
-      bool of, overflow = false;
-      double_int mod, compare_count, tem, loop_count;
+      bool overflow, overall_overflow = false;
+      widest_int compare_count, tem;
 
-      double_int loop_bound = tree_to_double_int (loop_bound_var);
-      double_int compare_bound = tree_to_double_int (compare_var);
-      double_int base = tree_to_double_int (compare_base);
-      double_int compare_step = tree_to_double_int (compare_step_var);
+      widest_int loop_bound = wi::to_widest (loop_bound_var);
+      widest_int compare_bound = wi::to_widest (compare_var);
+      widest_int base = wi::to_widest (compare_base);
+      widest_int compare_step = wi::to_widest (compare_step_var);
 
       /* (loop_bound - base) / compare_step */
-      tem = loop_bound.sub_with_overflow (base, &of);
-      overflow |= of;
-      loop_count = tem.divmod_with_overflow (compare_step,
-					      0, TRUNC_DIV_EXPR,
-					      &mod, &of);
-      overflow |= of;
-
-      if ((!compare_step.is_negative ())
+      tem = wi::sub (loop_bound, base, SIGNED, &overflow);
+      overall_overflow |= overflow;
+      widest_int loop_count = wi::div_trunc (tem, compare_step, SIGNED,
+					     &overflow);
+      overall_overflow |= overflow;
+
+      if (!wi::neg_p (compare_step)
           ^ (compare_code == LT_EXPR || compare_code == LE_EXPR))
 	{
 	  /* (loop_bound - compare_bound) / compare_step */
-	  tem = loop_bound.sub_with_overflow (compare_bound, &of);
-	  overflow |= of;
-	  compare_count = tem.divmod_with_overflow (compare_step,
-						     0, TRUNC_DIV_EXPR,
-						     &mod, &of);
-	  overflow |= of;
+	  tem = wi::sub (loop_bound, compare_bound, SIGNED, &overflow);
+	  overall_overflow |= overflow;
+	  compare_count = wi::div_trunc (tem, compare_step, SIGNED, &overflow);
+	  overall_overflow |= overflow;
 	}
       else
         {
 	  /* (compare_bound - base) / compare_step */
-	  tem = compare_bound.sub_with_overflow (base, &of);
-	  overflow |= of;
-          compare_count = tem.divmod_with_overflow (compare_step,
-						     0, TRUNC_DIV_EXPR,
-						     &mod, &of);
-	  overflow |= of;
+	  tem = wi::sub (compare_bound, base, SIGNED, &overflow);
+	  overall_overflow |= overflow;
+          compare_count = wi::div_trunc (tem, compare_step, SIGNED, &overflow);
+	  overall_overflow |= overflow;
 	}
       if (compare_code == LE_EXPR || compare_code == GE_EXPR)
 	++compare_count;
       if (loop_bound_code == LE_EXPR || loop_bound_code == GE_EXPR)
 	++loop_count;
-      if (compare_count.is_negative ())
-        compare_count = double_int_zero;
-      if (loop_count.is_negative ())
-        loop_count = double_int_zero;
-      if (loop_count.is_zero ())
+      if (wi::neg_p (compare_count))
+        compare_count = 0;
+      if (wi::neg_p (loop_count))
+        loop_count = 0;
+      if (loop_count == 0)
 	probability = 0;
-      else if (compare_count.scmp (loop_count) == 1)
+      else if (wi::cmps (compare_count, loop_count) == 1)
 	probability = REG_BR_PROB_BASE;
       else
         {
-	  /* If loop_count is too big, such that REG_BR_PROB_BASE * loop_count
-	     could overflow, shift both loop_count and compare_count right
-	     a bit so that it doesn't overflow.  Note both counts are known not
-	     to be negative at this point.  */
-	  int clz_bits = clz_hwi (loop_count.high);
-	  gcc_assert (REG_BR_PROB_BASE < 32768);
-	  if (clz_bits < 16)
-	    {
-	      loop_count.arshift (16 - clz_bits, HOST_BITS_PER_DOUBLE_INT);
-	      compare_count.arshift (16 - clz_bits, HOST_BITS_PER_DOUBLE_INT);
-	    }
-	  tem = compare_count.mul_with_sign (double_int::from_shwi
-					    (REG_BR_PROB_BASE), true, &of);
-	  gcc_assert (!of);
-	  tem = tem.divmod (loop_count, true, TRUNC_DIV_EXPR, &mod);
+	  tem = compare_count * REG_BR_PROB_BASE;
+	  tem = wi::udiv_trunc (tem, loop_count);
 	  probability = tem.to_uhwi ();
 	}
 
-      if (!overflow)
+      if (!overall_overflow)
         predict_edge (then_edge, PRED_LOOP_IV_COMPARE, probability);
 
       return;
diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h
index a60be32..0003f28 100644
--- a/gcc/pretty-print.h
+++ b/gcc/pretty-print.h
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "obstack.h"
 #include "input.h"
+#include "wide-int-print.h"
 
 /* Maximum number of format string arguments.  */
 #define PP_NL_ARGMAX   30
@@ -261,6 +262,13 @@ pp_get_prefix (const pretty_printer *pp) { return pp->prefix; }
 #define pp_decimal_int(PP, I)  pp_scalar (PP, "%d", I)
 #define pp_unsigned_wide_integer(PP, I) \
    pp_scalar (PP, HOST_WIDE_INT_PRINT_UNSIGNED, (unsigned HOST_WIDE_INT) I)
+#define pp_wide_int(PP, W, SGN)					\
+  do								\
+    {								\
+      print_dec (W, pp_buffer (PP)->digit_buffer, SGN);		\
+      pp_string (PP, pp_buffer (PP)->digit_buffer);		\
+    }								\
+  while (0)
 #define pp_wide_integer(PP, I) \
    pp_scalar (PP, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) I)
 #define pp_widest_integer(PP, I) \
diff --git a/gcc/signop.h b/gcc/signop.h
new file mode 100644
index 0000000..05dac90
--- /dev/null
+++ b/gcc/signop.h
@@ -0,0 +1,35 @@
+/* Operations with SIGNED and UNSIGNED.  -*- C++ -*-
+   Copyright (C) 2012-2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef SIGNOP_H
+#define SIGNOP_H
+
+/* This type is used for the large number of functions that produce
+   different results depending on if the operands are signed types or
+   unsigned types.  The signedness of a tree type can be found by
+   using the TYPE_SIGN macro.  */
+
+enum signop_e {
+  SIGNED,
+  UNSIGNED
+};
+
+typedef enum signop_e signop;
+
+#endif
diff --git a/gcc/system.h b/gcc/system.h
index 87ebe3c..adc9703 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -711,6 +711,16 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
 #define gcc_unreachable() (fancy_abort (__FILE__, __LINE__, __FUNCTION__))
 #endif
 
+#if GCC_VERSION >= 3001
+#define STATIC_CONSTANT_P(X) (__builtin_constant_p (X) && (X))
+#else
+#define STATIC_CONSTANT_P(X) (false && (X))
+#endif
+
+/* Until we can use STATIC_ASSERT.  */
+#define STATIC_ASSERT(X) \
+  typedef int assertion1[(X) ? 1 : -1] ATTRIBUTE_UNUSED
+
 /* Provide a fake boolean type.  We make no attempt to use the
    C99 _Bool, as it may not be available in the bootstrap compiler,
    and even if it is, it is liable to be buggy.
diff --git a/gcc/target.def b/gcc/target.def
index f6e42a1..de75e8d 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -3610,9 +3610,9 @@ loop is only entered from the top.\n\
 This hook is only used if @code{doloop_end} is available.  The default\n\
 implementation returns true.  You can use @code{can_use_doloop_if_innermost}\n\
 if the loop must be the innermost, and if there are no other restrictions.",
- bool, (double_int iterations, double_int iterations_max,
+ bool, (const widest_int &iterations, const widest_int &iterations_max,
 	unsigned int loop_depth, bool entered_at_top),
- hook_bool_dint_dint_uint_bool_true)
+ hook_bool_wint_wint_uint_bool_true)
 
 /* Returns NULL if target supports the insn within a doloop block,
    otherwise it returns an error message.  */
diff --git a/gcc/target.h b/gcc/target.h
index 12249ec..19522e2 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -50,7 +50,7 @@
 
 #include "insn-modes.h"
 #include "insn-codes.h"
-#include "double-int.h"
+#include "wide-int.h"
 
 #ifdef ENABLE_CHECKING
 
