diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2da6dab388159a684b920dcdc476db2e394e0ee0..ab6777a97b01c60aa1022e8fed4a304f38666a1b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2006-11-30  Janis Johnson  <janis187@us.ibm.com>
+
+	* config/dfp-bit.c (DFP_TO_INT): Use wider precision.
+
 2006-11-30  Jan Hubicka  <jh@suse.cz>
 
 	* tree-ssa-operands.h (struct ssa_operands): New.
diff --git a/gcc/config/dfp-bit.c b/gcc/config/dfp-bit.c
index 0d4308efc85388c97cc1455fc4b97ca121b02351..0ee2083e835b7f0bf43392f08fab5edb016ecd2b 100644
--- a/gcc/config/dfp-bit.c
+++ b/gcc/config/dfp-bit.c
@@ -392,7 +392,8 @@ DFP_TO_INT (DFP_C_TYPE x)
   decNumber qval, n1, n2;
   decContext context;
 
-  decContextDefault (&context, CONTEXT_INIT);
+  /* Use a large context to avoid losing precision.  */
+  decContextDefault (&context, DEC_INIT_DECIMAL128);
   /* Need non-default rounding mode here.  */
   context.round = DEC_ROUND_DOWN;
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dc05938ab5de972c85892f190b3feb796e2de8b5..3535260897f5785b1f124718532e5c2cb7088b58 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-11-30  Janis Johnson  <janis187@us.ibm.com>
+
+	* gcc.dg/dfp/convert-int-max.c: New test.
+	* gcc.dg/dfp/convert-int-max-fold.c: New test.
+
 2006-11-30  Richard Guenther  <rguenther@suse.de>
 
 	* gcc.dg/vect/vect-pow-1.c: Rename ...
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-int-max-fold.c b/gcc/testsuite/gcc.dg/dfp/convert-int-max-fold.c
new file mode 100644
index 0000000000000000000000000000000000000000..7e016918ad23b27443c0b104ab136fd5b98e4ad0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/convert-int-max-fold.c
@@ -0,0 +1,146 @@
+/* { dg-options "-std=gnu99 -O2" } */
+
+/* N1150 5.1 Conversions from decimal float to integer.  */
+
+/* Test decimal float to integer conversions for values at the limit of
+   what will fit into the destination type.  This assumes 32-bit int and
+   64-bit long long (there's a check for that below).  This version tests
+   conversions during compilation.  */
+
+extern void link_error (void);
+
+void
+doit ()
+{
+  _Decimal32 d32;
+  _Decimal64 d64;
+  _Decimal128 d128;
+  int si;
+  unsigned int ui;
+  long long sll;
+  unsigned long long ull;
+
+  /* _Decimal32 to int.  */
+
+  d32 = 2147483.E3DF;
+  si = d32;
+  if (si != 2147483000)
+    link_error ();
+
+  d32 = -2147483.E3DF;
+  si = d32;
+  if (si != -2147483000)
+    link_error ();
+
+  /* _Decimal32 to unsigned int.  */
+
+  d32 = 4.294967E9DF;
+  ui = d32;
+  if (ui != 4294967000U)
+    link_error ();
+
+  /* _Decimal32 to long long.  */
+
+  d32 = 922.3372E16DF;
+  sll = d32;
+  if (sll != 9223372000000000000LL)
+    link_error ();
+
+  d32 = -92233.72E14DF;
+  sll = d32;
+  if (sll != -9223372000000000000LL)
+    link_error ();
+
+  /* _Decimal32 to unsigned long long.  */
+
+  d32 = 0.1844674E20DF;
+  ull = d32;
+  if (ull != 18446740000000000000ULL)
+    link_error ();
+
+  /* _Decimal64 to int.  */
+
+  d64 = 2.147483647E9DD;
+  si = d64;
+  if (si != 2147483647)
+    link_error ();
+
+  d64 = -2147483648.DD;
+  si = d64;
+  if (si != -2147483648)
+    link_error ();
+
+  /* _Decimal64 to unsigned int.  */
+
+  d64 = 42949.67295E5DD;
+  ui = d64;
+  if (ui != 4294967295)
+    link_error ();
+
+  /* _Decimal64 to long long.  */
+
+  d64 = 9.223372036854775E18DD;
+  sll = d64;
+  if (sll != 9223372036854775000LL)
+    link_error (); 
+
+  d64 = -92233720.36854775E11DD;
+  sll = d64;
+  if (sll != -9223372036854775000LL)
+    link_error ();
+
+  /* _Decimal64 to unsigned long long.  */
+  d64 = 1844674407370955.E4DD;
+  ull = d64;
+  if (ull != 18446744073709550000ULL)
+    link_error ();
+
+  /* _Decimal128 to int.  */
+
+  d128 = 2.147483647E9DL;
+  si = d128;
+  if (si != 2147483647)
+    link_error ();
+
+  d128 = -2147483648.DL;
+  si = d128;
+  if (si != -2147483648)
+    link_error ();
+
+  /* _Decimal128 to unsigned int.  */
+
+  d128 = 4294.967295E6DL;
+  ui = d128;
+  if (ui != 4294967295)
+    link_error ();
+
+  /* _Decimal128 to long long.  */
+
+  d128 = 9223372036854775807.DL;
+  sll = d128;
+  if (sll != 9223372036854775807LL)
+    link_error (); 
+
+  d128 = -9.223372036854775808E19DL;
+  sll = d128;
+  if (sll != -9223372036854775807LL - 1LL)
+    link_error ();
+
+  /* _Decimal128 to unsigned long long.  */
+  d128 = 18446744073709551615.DL;
+  ull = d128;
+  if (ull != 18446744073709551615ULL)
+    link_error ();
+}
+
+int
+main ()
+{
+  /* This test assumes 32-bit int and 64-bit long long.  */
+
+  if (sizeof (int) != 4 || sizeof (long long) != 8)
+    return 0;
+
+  doit ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-int-max.c b/gcc/testsuite/gcc.dg/dfp/convert-int-max.c
new file mode 100644
index 0000000000000000000000000000000000000000..2f494323984e530b90de051001299e68b21d015c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/convert-int-max.c
@@ -0,0 +1,145 @@
+/* { dg-options "-std=gnu99 -O0" } */
+
+/* N1150 5.1 Conversions from decimal float to integer.  */
+
+/* Test decimal float to integer conversions for values at the limit of
+   what will fit into the destination type.  This assumes 32-bit int and
+   64-bit long long (there's a check for that below).  */
+
+extern void abort (void);
+
+volatile _Decimal32 d32;
+volatile _Decimal64 d64;
+volatile _Decimal128 d128;
+volatile int si;
+volatile unsigned int ui;
+volatile long long sll;
+volatile unsigned long long ull;
+
+void
+doit ()
+{
+  /* _Decimal32 to int.  */
+
+  d32 = 2147483.E3DF;
+  si = d32;
+  if (si != 2147483000)
+    abort ();
+
+  d32 = -2147483.E3DF;
+  si = d32;
+  if (si != -2147483000)
+    abort ();
+
+  /* _Decimal32 to unsigned int.  */
+
+  d32 = 4.294967E9DF;
+  ui = d32;
+  if (ui != 4294967000U)
+    abort ();
+
+  /* _Decimal32 to long long.  */
+
+  d32 = 922.3372E16DF;
+  sll = d32;
+  if (sll != 9223372000000000000LL)
+    abort ();
+
+  d32 = -92233.72E14DF;
+  sll = d32;
+  if (sll != -9223372000000000000LL)
+    abort ();
+
+  /* _Decimal32 to unsigned long long.  */
+
+  d32 = 0.1844674E20DF;
+  ull = d32;
+  if (ull != 18446740000000000000ULL)
+    abort ();
+
+  /* _Decimal64 to int.  */
+
+  d64 = 2.147483647E9DD;
+  si = d64;
+  if (si != 2147483647)
+    abort ();
+
+  d64 = -2147483648.DD;
+  si = d64;
+  if (si != -2147483648)
+    abort ();
+
+  /* _Decimal64 to unsigned int.  */
+
+  d64 = 42949.67295E5DD;
+  ui = d64;
+  if (ui != 4294967295)
+    abort ();
+
+  /* _Decimal64 to long long.  */
+
+  d64 = 9.223372036854775E18DD;
+  sll = d64;
+  if (sll != 9223372036854775000LL)
+    abort (); 
+
+  d64 = -92233720.36854775E11DD;
+  sll = d64;
+  if (sll != -9223372036854775000LL)
+    abort ();
+
+  /* _Decimal64 to unsigned long long.  */
+  d64 = 1844674407370955.E4DD;
+  ull = d64;
+  if (ull != 18446744073709550000ULL)
+    abort ();
+
+  /* _Decimal128 to int.  */
+
+  d128 = 2.147483647E9DL;
+  si = d128;
+  if (si != 2147483647)
+    abort ();
+
+  d128 = -2147483648.DL;
+  si = d128;
+  if (si != -2147483648)
+    abort ();
+
+  /* _Decimal128 to unsigned int.  */
+
+  d128 = 4294.967295E6DL;
+  ui = d128;
+  if (ui != 4294967295)
+    abort ();
+
+  /* _Decimal128 to long long.  */
+
+  d128 = 9223372036854775807.DL;
+  sll = d128;
+  if (sll != 9223372036854775807LL)
+    abort (); 
+
+  d128 = -9.223372036854775808E19DL;
+  sll = d128;
+  if (sll != -9223372036854775807LL - 1LL)
+    abort ();
+
+  /* _Decimal128 to unsigned long long.  */
+  d128 = 18446744073709551615.DL;
+  ull = d128;
+  if (ull != 18446744073709551615ULL)
+    abort ();
+}
+
+int
+main ()
+{
+  /* This test assumes 32-bit int and 64-bit long long.  */
+
+  if (sizeof (int) != 4 || sizeof (long long) != 8)
+    return 0;
+
+  doit ();
+  return 0;
+}