public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PATCH: Enable TFmode for x86
@ 2008-06-29 17:43 H.J. Lu
  2008-06-29 18:37 ` Joseph S. Myers
  2008-06-30  5:43 ` H.J. Lu
  0 siblings, 2 replies; 32+ messages in thread
From: H.J. Lu @ 2008-06-29 17:43 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Uros Bizjak, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 610 bytes --]

I am enclosing 3 patches to enable TFmode for x86:

1. gcc-float128-3.patch. Support TFmode in x86 backend.
2. gcc-quad-1.patch. Add x86 support to soft-fp.
3. gcc-quadtest-2.patch. Enable __float80/__float128 tests for
x86.

I added x86 soft-fp support to libgcc. But I didn't move soft-fp to
libgcc since it involves too many parts of gcc.  I will look into 
supporting __builtin_fabsq and __builtin_copysignq for x86 when
SSE2 is enabled after __float128 support for x86 is checked in.
I am testing them on Linux/ia32, Linux/ia64 and Linux/x86-64. OK
to install if there are no regressions?

Thanks.


H.J.

[-- Attachment #2: gcc-float128-3.patch --]
[-- Type: text/plain, Size: 20203 bytes --]

2008-06-28  H.J. Lu  <hongjiu.lu@intel.com>

	* config/i386/i386.c (contains_aligned_value_p): Return true
	for __float128.
	(ix86_function_arg_boundary): Return its natural boundary for
	for __float128.
	(return_in_memory_32): Don't check TDmode.
	(ix86_split_to_parts): Support splitting
	into 4 parts and support TFmode for 32bit target.
	(ix86_split_long_move): Support splitting into 4 parts.
	(bdesc_args): Enable IX86_BUILTIN_FABSQ and IX86_BUILTIN_COPYSIGNQ
	for SSE2.
	(ix86_init_mmx_sse_builtins): Move __float80 and __float128
	to ...
	(ix86_init_builtins): Here.
	(ix86_scalar_mode_supported_p): Always return true for TFmode.
	(ix86_c_mode_for_suffix): Always return 'q' for TFmode.

	* config/i386/i386.md (movtf): Check TARGET_SSE2 instead of
	TARGET_64BIT.
	(movtf_internal): Likewise.
	(<code>tf2): Likewise.
	(*absnegtf2_sse): Likewise.
	(copysign<mode>3): Likewise.
	(copysign<mode>3_const): Likewise.
	(copysign<mode>3_var): Likewise.
	(define_split UNSPEC_COPYSIGN): Likewise.
	* config/i386/sse.md (*nandtf3): Likewise.
	(<code>tf3): Likewise.
	(*<code>tf3): Likewise.

--- gcc/config/i386/i386.c.float128	2008-06-27 18:43:05.000000000 -0700
+++ gcc/config/i386/i386.c	2008-06-28 15:40:33.000000000 -0700
@@ -4744,7 +4744,9 @@ static bool
 contains_aligned_value_p (tree type)
 {
   enum machine_mode mode = TYPE_MODE (type);
-  if (((TARGET_SSE && SSE_REG_MODE_P (mode)) || mode == TDmode)
+  if (((TARGET_SSE && SSE_REG_MODE_P (mode))
+       || mode == TDmode
+       || mode == TFmode)
       && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
     return true;
   if (TYPE_ALIGN (type) < 128)
@@ -4803,8 +4805,9 @@ ix86_function_arg_boundary (enum machine
     align = GET_MODE_ALIGNMENT (mode);
   if (align < PARM_BOUNDARY)
     align = PARM_BOUNDARY;
-  /* In 32bit, only _Decimal128 is aligned to its natural boundary.  */
-  if (!TARGET_64BIT && mode != TDmode)
+  /* In 32bit, only _Decimal128 and __float128 are aligned to their
+     natural boundaries.  */
+  if (!TARGET_64BIT && mode != TDmode && mode != TFmode)
     {
       /* i386 ABI defines all arguments to be 4 byte aligned.  We have to
 	 make an exception for SSE modes since these require 128bit
@@ -4815,7 +4818,7 @@ ix86_function_arg_boundary (enum machine
 	 to 8 byte boundaries.  */
       if (!type)
 	{
-	  if (!(TARGET_SSE && SSE_REG_MODE_P (mode)) && mode != TDmode)
+	  if (!(TARGET_SSE && SSE_REG_MODE_P (mode)))
 	    align = PARM_BOUNDARY;
 	}
       else
@@ -5041,9 +5044,6 @@ return_in_memory_32 (const_tree type, en
   if (mode == XFmode)
     return 0;
 
-  if (mode == TDmode)
-    return 1;
-
   if (size > 12)
     return 1;
   return 0;
@@ -14122,7 +14122,7 @@ ix86_split_to_parts (rtx operand, rtx *p
     size = (GET_MODE_SIZE (mode) + 4) / 8;
 
   gcc_assert (!REG_P (operand) || !MMX_REGNO_P (REGNO (operand)));
-  gcc_assert (size >= 2 && size <= 3);
+  gcc_assert (size >= 2 && size <= 4);
 
   /* Optimize constant pool reference to immediates.  This is used by fp
      moves, that force all constants to memory to allow combining.  */
@@ -14142,7 +14142,7 @@ ix86_split_to_parts (rtx operand, rtx *p
 
       operand = copy_rtx (operand);
       PUT_MODE (operand, Pmode);
-      parts[0] = parts[1] = parts[2] = operand;
+      parts[0] = parts[1] = parts[2] = parts[3] = operand;
       return size;
     }
 
@@ -14163,21 +14163,20 @@ ix86_split_to_parts (rtx operand, rtx *p
 	split_di (&operand, 1, &parts[0], &parts[1]);
       else
 	{
+	  int i;
+
 	  if (REG_P (operand))
 	    {
 	      gcc_assert (reload_completed);
-	      parts[0] = gen_rtx_REG (SImode, REGNO (operand) + 0);
-	      parts[1] = gen_rtx_REG (SImode, REGNO (operand) + 1);
-	      if (size == 3)
-		parts[2] = gen_rtx_REG (SImode, REGNO (operand) + 2);
+	      for (i = 0; i < size; i++)
+		parts[i] = gen_rtx_REG (SImode, REGNO (operand) + i);
 	    }
 	  else if (offsettable_memref_p (operand))
 	    {
 	      operand = adjust_address (operand, SImode, 0);
 	      parts[0] = operand;
-	      parts[1] = adjust_address (operand, SImode, 4);
-	      if (size == 3)
-		parts[2] = adjust_address (operand, SImode, 8);
+	      for (i = 1; i < size; i++)
+		parts[i] = adjust_address (operand, SImode, 4 * i);
 	    }
 	  else if (GET_CODE (operand) == CONST_DOUBLE)
 	    {
@@ -14187,6 +14186,11 @@ ix86_split_to_parts (rtx operand, rtx *p
 	      REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
 	      switch (mode)
 		{
+		case TFmode:
+		  real_to_target (l, &r, mode);
+		  parts[3] = gen_int_mode (l[3], SImode);
+		  parts[2] = gen_int_mode (l[2], SImode);
+		  break;
 		case XFmode:
 		  REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
 		  parts[2] = gen_int_mode (l[2], SImode);
@@ -14260,7 +14264,7 @@ ix86_split_to_parts (rtx operand, rtx *p
   return size;
 }
 
-/* Emit insns to perform a move or push of DI, DF, and XF values.
+/* Emit insns to perform a move or push of DI, DF, XF, and TF values.
    Return false when normal moves are needed; true when all required
    insns have been emitted.  Operands 2-4 contain the input values
    int the correct order; operands 5-7 contain the output values.  */
@@ -14268,11 +14272,12 @@ ix86_split_to_parts (rtx operand, rtx *p
 void
 ix86_split_long_move (rtx operands[])
 {
-  rtx part[2][3];
-  int nparts;
+  rtx part[2][4];
+  int nparts, i, j;
   int push = 0;
   int collisions = 0;
   enum machine_mode mode = GET_MODE (operands[0]);
+  bool collisionparts[4];
 
   /* The DFmode expanders may ask us to move double.
      For 64bit target this is single move.  By hiding the fact
@@ -14311,34 +14316,46 @@ ix86_split_long_move (rtx operands[])
   /* When emitting push, take care for source operands on the stack.  */
   if (push && MEM_P (operands[1])
       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
-    {
-      if (nparts == 3)
-	part[1][1] = change_address (part[1][1], GET_MODE (part[1][1]),
-				     XEXP (part[1][2], 0));
-      part[1][0] = change_address (part[1][0], GET_MODE (part[1][0]),
-				   XEXP (part[1][1], 0));
-    }
+    for (i = 0; i < nparts - 1; i++)
+      part[1][i] = change_address (part[1][i],
+				   GET_MODE (part[1][i]),
+				   XEXP (part[1][i + 1], 0));
 
   /* We need to do copy in the right order in case an address register
      of the source overlaps the destination.  */
   if (REG_P (part[0][0]) && MEM_P (part[1][0]))
     {
-      if (reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0)))
-	collisions++;
-      if (reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
-	collisions++;
-      if (nparts == 3
-	  && reg_overlap_mentioned_p (part[0][2], XEXP (part[1][0], 0)))
-	collisions++;
+      rtx tmp;
+
+      for (i = 0; i < nparts; i++)
+	{
+	  collisionparts[i]
+	    = reg_overlap_mentioned_p (part[0][i], XEXP (part[1][0], 0));
+	  if (collisionparts[i])
+	    collisions++;
+	}
 
       /* Collision in the middle part can be handled by reordering.  */
-      if (collisions == 1 && nparts == 3
-	  && reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
+      if (collisions == 1 && nparts == 3 && collisionparts [1])
 	{
-	  rtx tmp;
 	  tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp;
 	  tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp;
 	}
+      else if (collisions == 1
+	       && nparts == 4
+	       && (collisionparts [1] || collisionparts [2]))
+	{
+	  if (collisionparts [1])
+	    {
+	      tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp;
+	      tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp;
+	    }
+	  else
+	    {
+	      tmp = part[0][2]; part[0][2] = part[0][3]; part[0][3] = tmp;
+	      tmp = part[1][2]; part[1][2] = part[1][3]; part[1][3] = tmp;
+	    }
+	}
 
       /* If there are more collisions, we can't handle it by reordering.
 	 Do an lea to the last part and use only one colliding move.  */
@@ -14357,11 +14374,11 @@ ix86_split_long_move (rtx operands[])
 
 	  emit_insn (gen_rtx_SET (VOIDmode, base, XEXP (part[1][0], 0)));
 	  part[1][0] = replace_equiv_address (part[1][0], base);
-	  part[1][1] = replace_equiv_address (part[1][1],
-				      plus_constant (base, UNITS_PER_WORD));
-	  if (nparts == 3)
-	    part[1][2] = replace_equiv_address (part[1][2],
-				      plus_constant (base, 8));
+	  for (i = 1; i < nparts; i++)
+	    {
+	      tmp = plus_constant (base, UNITS_PER_WORD * i);
+	      part[1][i] = replace_equiv_address (part[1][i], tmp);
+	    }
 	}
     }
 
@@ -14375,6 +14392,11 @@ ix86_split_long_move (rtx operands[])
                 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4)));
 	      emit_move_insn (part[0][2], part[1][2]);
 	    }
+	  else if (nparts == 4)
+	    {
+	      emit_move_insn (part[0][3], part[1][3]);
+	      emit_move_insn (part[0][2], part[1][2]);
+	    }
 	}
       else
 	{
@@ -14412,77 +14434,42 @@ ix86_split_long_move (rtx operands[])
        && REG_P (part[1][1])
        && (REGNO (part[0][0]) == REGNO (part[1][1])
 	   || (nparts == 3
-	       && REGNO (part[0][0]) == REGNO (part[1][2]))))
+	       && REGNO (part[0][0]) == REGNO (part[1][2]))
+	   || (nparts == 4
+	       && REGNO (part[0][0]) == REGNO (part[1][3]))))
       || (collisions > 0
 	  && reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0))))
     {
-      if (nparts == 3)
-	{
-	  operands[2] = part[0][2];
-	  operands[3] = part[0][1];
-	  operands[4] = part[0][0];
-	  operands[5] = part[1][2];
-	  operands[6] = part[1][1];
-	  operands[7] = part[1][0];
-	}
-      else
+      for (i = 0, j = nparts - 1; i < nparts; i++, j--)
 	{
-	  operands[2] = part[0][1];
-	  operands[3] = part[0][0];
-	  operands[5] = part[1][1];
-	  operands[6] = part[1][0];
+	  operands[2 + i] = part[0][j];
+	  operands[6 + i] = part[1][j];
 	}
     }
   else
     {
-      if (nparts == 3)
-	{
-	  operands[2] = part[0][0];
-	  operands[3] = part[0][1];
-	  operands[4] = part[0][2];
-	  operands[5] = part[1][0];
-	  operands[6] = part[1][1];
-	  operands[7] = part[1][2];
-	}
-      else
+      for (i = 0; i < nparts; i++)
 	{
-	  operands[2] = part[0][0];
-	  operands[3] = part[0][1];
-	  operands[5] = part[1][0];
-	  operands[6] = part[1][1];
+	  operands[2 + i] = part[0][i];
+	  operands[6 + i] = part[1][i];
 	}
     }
 
   /* If optimizing for size, attempt to locally unCSE nonzero constants.  */
   if (optimize_size)
     {
-      if (CONST_INT_P (operands[5])
-	  && operands[5] != const0_rtx
-	  && REG_P (operands[2]))
-	{
-	  if (CONST_INT_P (operands[6])
-	      && INTVAL (operands[6]) == INTVAL (operands[5]))
-	    operands[6] = operands[2];
-
-	  if (nparts == 3
-	      && CONST_INT_P (operands[7])
-	      && INTVAL (operands[7]) == INTVAL (operands[5]))
-	    operands[7] = operands[2];
-	}
-
-      if (nparts == 3
-	  && CONST_INT_P (operands[6])
-	  && operands[6] != const0_rtx
-	  && REG_P (operands[3])
-	  && CONST_INT_P (operands[7])
-	  && INTVAL (operands[7]) == INTVAL (operands[6]))
-	operands[7] = operands[3];
-    }
-
-  emit_move_insn (operands[2], operands[5]);
-  emit_move_insn (operands[3], operands[6]);
-  if (nparts == 3)
-    emit_move_insn (operands[4], operands[7]);
+      for (j = 0; j < nparts - 1; j++)
+	if (CONST_INT_P (operands[6 + j])
+	    && operands[6 + j] != const0_rtx
+	    && REG_P (operands[2 + j]))
+	  for (i = j; i < nparts - 1; i++)
+	    if (CONST_INT_P (operands[7 + i])
+		&& INTVAL (operands[7 + i]) == INTVAL (operands[6 + j]))
+	      operands[7 + i] = operands[2 + j];
+    }
+
+  for (i = 0; i < nparts; i++)
+    emit_move_insn (operands[2 + i], operands[6 + i]);
 
   return;
 }
@@ -18674,6 +18661,9 @@ static const struct builtin_description 
 
   { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmsqrtv2df2, "__builtin_ia32_sqrtsd", IX86_BUILTIN_SQRTSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_VEC_MERGE },
 
+  { OPTION_MASK_ISA_SSE2, CODE_FOR_abstf2, 0, IX86_BUILTIN_FABSQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128 },
+  { OPTION_MASK_ISA_SSE2, CODE_FOR_copysigntf3, 0, IX86_BUILTIN_COPYSIGNQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128_FLOAT128 },
+
   /* SSE2 MMX */
   { OPTION_MASK_ISA_SSE2, CODE_FOR_mmx_addv1di3, "__builtin_ia32_paddq", IX86_BUILTIN_PADDQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI },
   { OPTION_MASK_ISA_SSE2, CODE_FOR_mmx_subv1di3, "__builtin_ia32_psubq", IX86_BUILTIN_PSUBQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI },
@@ -18799,10 +18789,6 @@ static const struct builtin_description 
 
   /* PCLMUL */
   { OPTION_MASK_ISA_SSE2, CODE_FOR_pclmulqdq, 0, IX86_BUILTIN_PCLMULQDQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT },
-
-   /* 64bit */
-  { OPTION_MASK_ISA_64BIT, CODE_FOR_abstf2, 0, IX86_BUILTIN_FABSQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128 },
-  { OPTION_MASK_ISA_64BIT, CODE_FOR_copysigntf3, 0, IX86_BUILTIN_COPYSIGNQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128_FLOAT128 },
 };
 
 /* SSE5 */
@@ -19600,47 +19586,6 @@ ix86_init_mmx_sse_builtins (void)
 
   tree ftype;
 
-  /* The __float80 type.  */
-  if (TYPE_MODE (long_double_type_node) == XFmode)
-    (*lang_hooks.types.register_builtin_type) (long_double_type_node,
-					       "__float80");
-  else
-    {
-      /* The __float80 type.  */
-      tree float80_type_node = make_node (REAL_TYPE);
-
-      TYPE_PRECISION (float80_type_node) = 80;
-      layout_type (float80_type_node);
-      (*lang_hooks.types.register_builtin_type) (float80_type_node,
-						 "__float80");
-    }
-
-  if (TARGET_64BIT)
-    {
-      tree float128_type_node = make_node (REAL_TYPE);
-
-      TYPE_PRECISION (float128_type_node) = 128;
-      layout_type (float128_type_node);
-      (*lang_hooks.types.register_builtin_type) (float128_type_node,
-						 "__float128");
-
-      /* TFmode support builtins.  */
-      ftype = build_function_type (float128_type_node,
-				   void_list_node);
-      def_builtin (OPTION_MASK_ISA_64BIT, "__builtin_infq", ftype, IX86_BUILTIN_INFQ);
-
-      ftype = build_function_type_list (float128_type_node,
-					float128_type_node,
-					NULL_TREE);
-      def_builtin_const (OPTION_MASK_ISA_64BIT, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
-
-      ftype = build_function_type_list (float128_type_node,
-					float128_type_node,
-					float128_type_node,
-					NULL_TREE);
-      def_builtin_const (OPTION_MASK_ISA_64BIT, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
-    }
-
   /* Add all special builtins with variable number of operands.  */
   for (i = 0, d = bdesc_special_args;
        i < ARRAY_SIZE (bdesc_special_args);
@@ -20246,6 +20191,52 @@ ix86_init_mmx_sse_builtins (void)
 static void
 ix86_init_builtins (void)
 {
+  tree float128_type_node = make_node (REAL_TYPE);
+  tree ftype, decl;
+
+  /* The __float80 type.  */
+  if (TYPE_MODE (long_double_type_node) == XFmode)
+    (*lang_hooks.types.register_builtin_type) (long_double_type_node,
+					       "__float80");
+  else
+    {
+      /* The __float80 type.  */
+      tree float80_type_node = make_node (REAL_TYPE);
+
+      TYPE_PRECISION (float80_type_node) = 80;
+      layout_type (float80_type_node);
+      (*lang_hooks.types.register_builtin_type) (float80_type_node,
+						 "__float80");
+    }
+
+  /* The __float128 type.  */
+  TYPE_PRECISION (float128_type_node) = 128;
+  layout_type (float128_type_node);
+  (*lang_hooks.types.register_builtin_type) (float128_type_node,
+					     "__float128");
+
+  /* TFmode support builtins.  */
+  ftype = build_function_type (float128_type_node, void_list_node);
+  decl = add_builtin_function ("__builtin_infq", ftype,
+			       IX86_BUILTIN_INFQ, BUILT_IN_MD,
+			       NULL, NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_INFQ] = decl;
+
+  if (HOST_BITS_PER_WIDE_INT >= 64)
+    {
+      /* Those builtins need TImode to compile.  */
+      ftype = build_function_type_list (float128_type_node,
+					float128_type_node,
+					NULL_TREE);
+      def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
+
+      ftype = build_function_type_list (float128_type_node,
+					float128_type_node,
+					float128_type_node,
+					NULL_TREE);
+      def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
+    }
+
   if (TARGET_MMX)
     ix86_init_mmx_sse_builtins ();
 }
@@ -24702,7 +24693,7 @@ ix86_scalar_mode_supported_p (enum machi
   if (DECIMAL_FLOAT_MODE_P (mode))
     return true;
   else if (mode == TFmode)
-    return TARGET_64BIT;
+    return true;
   else
     return default_scalar_mode_supported_p (mode);
 }
@@ -24726,7 +24717,7 @@ ix86_vector_mode_supported_p (enum machi
 static enum machine_mode
 ix86_c_mode_for_suffix (char suffix)
 {
-  if (TARGET_64BIT && suffix == 'q')
+  if (suffix == 'q')
     return TFmode;
   if (TARGET_MMX && suffix == 'w')
     return XFmode;
--- gcc/config/i386/i386.md.float128	2008-06-27 18:43:05.000000000 -0700
+++ gcc/config/i386/i386.md	2008-06-28 08:21:28.000000000 -0700
@@ -3261,7 +3261,7 @@
 (define_expand "movtf"
   [(set (match_operand:TF 0 "nonimmediate_operand" "")
 	(match_operand:TF 1 "nonimmediate_operand" ""))]
-  "TARGET_64BIT"
+  "TARGET_SSE2"
 {
   ix86_expand_move (TFmode, operands);
   DONE;
@@ -3270,7 +3270,7 @@
 (define_insn "*movtf_internal"
   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
 	(match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
-  "TARGET_64BIT
+  "TARGET_SSE2
    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
 {
   switch (which_alternative)
@@ -10375,7 +10375,7 @@
 (define_expand "<code>tf2"
   [(set (match_operand:TF 0 "register_operand" "")
 	(absneg:TF (match_operand:TF 1 "register_operand" "")))]
-  "TARGET_64BIT"
+  "TARGET_SSE2"
   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
 
 (define_insn "*absnegtf2_sse"
@@ -10384,7 +10384,7 @@
 	  [(match_operand:TF 1 "register_operand" "0,x")]))
    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT"
+  "TARGET_SSE2"
   "#")
 
 ;; Splitters for fp abs and neg.
@@ -10563,7 +10563,7 @@
    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
    (match_operand:CSGNMODE 2 "register_operand" "")]
   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
-   || (TARGET_64BIT && (<MODE>mode == TFmode))"
+   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
 {
   ix86_expand_copysign (operands);
   DONE;
@@ -10577,7 +10577,7 @@
 	   (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
 	  UNSPEC_COPYSIGN))]
   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
-   || (TARGET_64BIT && (<MODE>mode == TFmode))"
+   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
   "#"
   "&& reload_completed"
   [(const_int 0)]
@@ -10596,7 +10596,7 @@
 	  UNSPEC_COPYSIGN))
    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
-   || (TARGET_64BIT && (<MODE>mode == TFmode))"
+   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
   "#")
 
 (define_split
@@ -10609,7 +10609,7 @@
 	  UNSPEC_COPYSIGN))
    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
-    || (TARGET_64BIT && (<MODE>mode == TFmode)))
+    || (TARGET_SSE2 && (<MODE>mode == TFmode)))
    && reload_completed"
   [(const_int 0)]
 {
--- gcc/config/i386/sse.md.float128	2008-05-21 22:30:20.000000000 -0700
+++ gcc/config/i386/sse.md	2008-06-28 08:21:28.000000000 -0700
@@ -3895,7 +3895,7 @@
 	(and:TF
 	  (not:TF (match_operand:TF 1 "register_operand" "0"))
 	  (match_operand:TF 2 "nonimmediate_operand" "xm")))]
-  "TARGET_64BIT"
+  "TARGET_SSE2"
   "pandn\t{%2, %0|%0, %2}"
   [(set_attr "type" "sselog")
    (set_attr "prefix_data16" "1")
@@ -3936,7 +3936,7 @@
 	(plogic:TF
 	  (match_operand:TF 1 "nonimmediate_operand" "")
 	  (match_operand:TF 2 "nonimmediate_operand" "")))]
-  "TARGET_64BIT"
+  "TARGET_SSE2"
   "ix86_fixup_binary_operands_no_copy (<CODE>, TFmode, operands);")
 
 (define_insn "*<code>tf3"
@@ -3944,7 +3944,7 @@
 	(plogic:TF
 	  (match_operand:TF 1 "nonimmediate_operand" "%0")
 	  (match_operand:TF 2 "nonimmediate_operand" "xm")))]
-  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, TFmode, operands)"
+  "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, TFmode, operands)"
   "p<plogicprefix>\t{%2, %0|%0, %2}"
   [(set_attr "type" "sselog")
    (set_attr "prefix_data16" "1")

[-- Attachment #3: gcc-quad-1.patch --]
[-- Type: text/plain, Size: 22786 bytes --]

gcc/

2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.  Add
	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
	x86_64-*-linux*. 

	* config/i386/sfp-machine.h: Moved to libgcc.

	* config/i386/sfp-machine.h: New.

	* config/i386/t-darwin: Remove softfp_wrap_start and
	softfp_wrap_end.
	* config/i386/t-darwin64: Likewise.
	* config/i386/t-linux64: Likewise.

	* config/i386/t-fprules-softfp64: Renamed to ...
	* config/i386/t-fprules-softfp: This.

libgcc/

2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>

	* config.host: Add i386/${host_address}/t-fprules-softfp to
	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*. 

	* configure.ac: Set host_address to 64 or 32 for x86.
	* configure: Regenerated.

	* config/i386/32/sfp-machine.h: New.
	* config/i386/32/t-fprules-softfp: Likewise.
	* config/i386/64/sfp-machine.h: New. Moved from gcc.

--- gcc/gcc/config.gcc.quad	2008-06-27 18:43:07.000000000 -0700
+++ gcc/gcc/config.gcc	2008-06-29 07:25:20.000000000 -0700
@@ -1006,11 +1006,11 @@ i[34567]86-*-darwin*)
 	# then this file using that to set --with-cpu=i386 which has no -m64
 	# support.
 	with_cpu=${with_cpu:-generic}
-	tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 x86_64-*-darwin*)
 	with_cpu=${with_cpu:-generic}
-	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
 	tm_file="${tm_file} ${cpu_type}/darwin64.h"
 	;;
 i[34567]86-*-elf*)
@@ -1069,7 +1069,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
-			tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
+			tmake_file="${tmake_file} i386/t-linux64"
 			need_64bit_hwint=yes
 			case X"${with_cpu}" in
 			Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
@@ -1101,7 +1101,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
+	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-*-gnu*)
 	;;
@@ -2973,6 +2973,11 @@ case ${target} in
 		fi
 		;;
 
+	i[34567]86-*-darwin* | x86_64-*-darwin* | \
+	  i[34567]86-*-linux* | x86_64-*-linux*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+		;;
+
 	mips*-*-*)
 		if test x$gnu_ld = xyes
 		then
--- gcc/gcc/config/i386/sfp-machine.h.quad	2008-02-19 20:52:26.000000000 -0800
+++ gcc/gcc/config/i386/sfp-machine.h	2008-06-29 07:52:03.000000000 -0700
@@ -1,143 +1,5 @@
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-typedef int TItype __attribute__ ((mode (TI)));
-typedef unsigned int UTItype __attribute__ ((mode (TI)));
-
-#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
-
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
-#define _FP_MUL_MEAT_Q(R,X,Y)                           \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D
-#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_E		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID		0x01
-#define FP_EX_DENORM		0x02
-#define FP_EX_DIVZERO		0x04
-#define FP_EX_OVERFLOW		0x08
-#define FP_EX_UNDERFLOW		0x10
-#define FP_EX_INEXACT		0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS						\
-  do {									\
-    if (_fex & FP_EX_INVALID)						\
-      {									\
-	float f = 0.0;							\
-	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
-      }									\
-    if (_fex & FP_EX_DIVZERO)						\
-      {									\
-	float f = 1.0, g = 0.0;						\
-	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
-      }									\
-    if (_fex & FP_EX_OVERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_OVERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_UNDERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_UNDERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_INEXACT)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_INEXACT;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-  } while (0)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		0xc00
-#define FP_RND_PINF		0x800
-#define FP_RND_MINF		0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE			\
-  do {						\
-    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
-  } while (0)
-
-#define FP_ROUNDMODE		(_fcw & 0xc00)
-
-#define	__LITTLE_ENDIAN	1234
-#define	__BIG_ENDIAN	4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#ifdef __x86_64__
+#include "config/i386/64/sfp-machine.h"
 #else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#include "config/i386/32/sfp-machine.h"
 #endif
--- gcc/gcc/config/i386/t-darwin.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin	2008-06-29 07:08:22.000000000 -0700
@@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
 MULTILIB_DIRNAMES = x86_64
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-darwin64.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin64	2008-06-29 07:08:26.000000000 -0700
@@ -1,5 +1,2 @@
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-fprules-softfp.quad	2008-06-29 07:25:58.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp	2008-06-29 07:34:08.000000000 -0700
@@ -0,0 +1,6 @@
+softfp_float_modes := tf
+softfp_int_modes := si di ti
+softfp_extensions := sftf dftf xftf
+softfp_truncations := tfsf tfdf tfxf
+softfp_machine_header := i386/sfp-machine.h
+softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-fprules-softfp64.quad	2007-05-18 07:10:43.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp64	2008-06-29 10:13:33.000000000 -0700
@@ -1,6 +0,0 @@
-softfp_float_modes := tf
-softfp_int_modes := si di ti
-softfp_extensions := sftf dftf xftf
-softfp_truncations := tfsf tfdf tfxf
-softfp_machine_header := i386/sfp-machine.h
-softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-linux64.quad	2007-09-29 07:58:28.000000000 -0700
+++ gcc/gcc/config/i386/t-linux64	2008-06-29 07:08:31.000000000 -0700
@@ -21,6 +21,3 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
 		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
 		     crtfastmath.o
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/libgcc/config.host.quad	2008-06-08 08:48:36.000000000 -0700
+++ gcc/libgcc/config.host	2008-06-29 10:04:21.000000000 -0700
@@ -578,3 +578,12 @@ i[34567]86-*-linux* | x86_64-*-linux*)
 	tmake_file="${tmake_file} t-tls"
 	;;
 esac
+
+case ${host} in
+i[34567]86-*-darwin* | x86_64-*-darwin* | \
+  i[34567]86-*-linux* | x86_64-*-linux*)
+	if test "${host_address}" = 32; then
+		tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	fi
+	;;
+esac
--- gcc/libgcc/config/i386/32/sfp-machine.h.quad	2008-06-29 10:11:58.000000000 -0700
+++ gcc/libgcc/config/i386/32/sfp-machine.h	2008-06-29 09:18:56.000000000 -0700
@@ -0,0 +1,187 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl)				\
+  __asm__("addl %5,%1; adcl %3,%0"					\
+	  : "=r"(rh), "=r"(rl)						\
+	  : "%0"(xh), "g"(yh), "%1"(xl), "g"(yl)			\
+	  : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  do { 									\
+    __asm__ volatile("addl %5,%1; adcl %3,%0"				\
+		     : "=r"(r1), "=r"(r0)				\
+		     : "%0"(x1), "g"(y1), "%1"(x0), "g"(y0)		\
+		     : "cc");						\
+    __asm__ volatile("adcl %5,%1; adcl %3,%0"				\
+		     : "=r"(r3), "=r"(r2)				\
+		     : "%0"(x3), "g"(y3), "%1"(x2), "g"(y2)		\
+		     : "cc");						\
+  } while (0)
+
+#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl)				\
+  __asm__("subl %5,%1; sbbl %4,%0"					\
+	  : "=r"(rh), "=r"(rl)						\
+	  : "0"(xh), "1"(xl), "g"(yh), "g"(yl)				\
+	  : "cc")
+
+#define __FP_CLZ(r, x)							\
+  do {									\
+    __asm__("bsrl %1,%0" : "=r"(r) : "g"(x) : "cc");			\
+    r ^= 31;								\
+  } while (0)
+
+#define _i386_mul_32_64(rh, rl, x, y)					\
+  __asm__("mull %2" : "=d"(rh), "=a"(rl) : "%g"(x), "1"(y) : "cc")
+
+#define _i386_div_64_32(q, r, nh, nl, d)				\
+  __asm__ ("divl %4" : "=a"(q), "=d"(r) : "0"(nl), "1"(nh), "g"(d) : "cc")
+
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,_i386_mul_32_64)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,_i386_mul_32_64)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
+   emulation is done in 16byte.  */
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0, 0, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	double d;							\
+	__asm__ __volatile__ ("fldz");					\
+	__asm__ __volatile__ ("fdiv %%st, %%st(0)" : "=t" (d));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	double d;							\
+	__asm__ __volatile__ ("fldz; fld1");				\
+	__asm__ __volatile__ ("fdivp %%st, %%st(1)" : "=t" (d));	\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/32/t-fprules-softfp.quad	2008-06-29 10:13:31.000000000 -0700
+++ gcc/libgcc/config/i386/32/t-fprules-softfp	2008-06-29 08:32:04.000000000 -0700
@@ -0,0 +1,5 @@
+# Filter out TImode functions
+tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
--- gcc/libgcc/config/i386/64/sfp-machine.h.quad	2008-06-29 10:12:22.000000000 -0700
+++ gcc/libgcc/config/i386/64/sfp-machine.h	2008-06-29 06:31:46.000000000 -0700
@@ -0,0 +1,143 @@
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y)                           \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f = 0.0;							\
+	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/configure.ac.quad	2008-06-21 07:10:37.000000000 -0700
+++ gcc/libgcc/configure.ac	2008-06-29 06:55:16.000000000 -0700
@@ -153,6 +153,21 @@ AC_CACHE_CHECK([whether fixed-point is s
 fixed_point=$libgcc_cv_fixed_point
 AC_SUBST(fixed_point)
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i[34567]86-*-* | x86_64-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/configure.quad	2008-06-21 07:10:37.000000000 -0700
+++ gcc/libgcc/configure	2008-06-29 06:55:19.000000000 -0700
@@ -3402,6 +3402,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >
 fixed_point=$libgcc_cv_fixed_point
 
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i3456786-*-* | x86_64-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 

[-- Attachment #4: gcc-quadtest-2.patch --]
[-- Type: text/plain, Size: 5107 bytes --]

2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>

	* g++.dg/abi/mangle24.C: Remove -mmmx.
	* gcc.dg/const-float80-ped.c: Likewise.
	* gcc.dg/const-float80.c: Likewise.
	* gcc.dg/torture/fp-int-convert-float80.c: Likewise.

	* g++.dg/abi/mangle25.C: Enable x86.
	* gcc.dg/const-float128-ped.c: Likewise.
	* gcc.dg/const-float128.c: Likewise.
	* gcc.dg/torture/fp-int-convert-float128.c: Likewise.
	* gcc.target/i386/pr32268.c: Likewise.

--- gcc/testsuite/g++.dg/abi/mangle24.C.quadtest	2006-09-27 22:35:18.000000000 -0700
+++ gcc/testsuite/g++.dg/abi/mangle24.C	2008-06-29 09:59:42.000000000 -0700
@@ -5,7 +5,6 @@
 // Origin: Joseph Myers <joseph@codesourcery.com>
 // { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
 // { dg-options "" } */
-// { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 // { dg-final { scan-assembler "_Z1fe" { target i?86-*-* x86_64-*-* } } } */
 // { dg-final { scan-assembler "_Z1fe" { target { ia64-*-* && { ! "ia64-*-hpux*" } } } } } */
 // { dg-final { scan-assembler "_Z1fu9__float80" { target ia64-*-hpux* } } } */
--- gcc/testsuite/g++.dg/abi/mangle25.C.quadtest	2006-09-27 22:35:18.000000000 -0700
+++ gcc/testsuite/g++.dg/abi/mangle25.C	2008-06-28 16:59:46.000000000 -0700
@@ -4,7 +4,7 @@
 // ia64-hpux where "long double" is "e" and __float128 is synonymous with
 // "long double".
 // Origin: Joseph Myers <joseph@codesourcery.com>
-// { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-*} && lp64 } } } }
+// { dg-do compile { target { ia64-*-* || { i?86-*-* x86_64-*-* } } } }
 // { dg-options "" } */
 // { dg-final { scan-assembler "_Z1fg" { target i?86-*-* x86_64-*-* } } } */
 // { dg-final { scan-assembler "_Z1fg" { target { ia64-*-* && { ! "ia64-*-hpux*" } } } } } */
--- gcc/testsuite/gcc.dg/const-float128-ped.c.quadtest	2007-08-29 08:49:56.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float128-ped.c	2008-06-28 16:57:53.000000000 -0700
@@ -1,5 +1,5 @@
 /* Test 'q' suffix with -pedantic on __float128 type constants.  */
-/* { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-* } && lp64 } } } } */
+/* { dg-do compile { target { ia64-*-* || { i?86-*-* x86_64-*-* } } } */
 /* { dg-options "-pedantic" } */
 
 __float128 a = 123.456789q; /* { dg-warning "non-standard suffix on floating constant" } */
--- gcc/testsuite/gcc.dg/const-float128.c.quadtest	2007-08-29 08:49:56.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float128.c	2008-06-28 16:58:06.000000000 -0700
@@ -1,5 +1,5 @@
 /* Test 'q' and 'Q' suffixes on __float128 type constants.  */
-/* { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-* } && lp64 } } } } */
+/* { dg-do compile { target { ia64-*-* || { i?86-*-* x86_64-*-* } } } */
 /* { dg-options "" } */
 
 __float128 a = 123.456789q;
--- gcc/testsuite/gcc.dg/const-float80-ped.c.quadtest	2007-07-03 06:45:52.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float80-ped.c	2008-06-29 09:58:50.000000000 -0700
@@ -1,6 +1,5 @@
 /* Test 'w' suffix with -pedantic on __float80 type constants.  */
 /* { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
 /* { dg-options "-pedantic" } */
-/* { dg-options "-mmmx -pedantic" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 __float80 a = 123.456789w;  /* { dg-warning "non-standard suffix on floating constant" } */
--- gcc/testsuite/gcc.dg/const-float80.c.quadtest	2007-07-03 06:45:52.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float80.c	2008-06-29 09:58:05.000000000 -0700
@@ -1,7 +1,6 @@
 /* Test 'w' and 'W' suffixes on __float80 type constants.  */
 /* { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
 /* { dg-options "" } */
-/* { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 __float80 a = 123.456789W;
 __float80 b = 123.456789w;
--- gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c.quadtest	2007-05-18 07:10:39.000000000 -0700
+++ gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c	2008-06-28 17:08:53.000000000 -0700
@@ -1,6 +1,6 @@
 /* Test floating-point conversions.  __float128 type.  */
 /* Origin: Joseph Myers <joseph@codesourcery.com> */
-/* { dg-do run { target { ia64-*-* || { { i?86-*-* x86_64-*-*} && lp64 } } } } */
+/* { dg-do run { target { ia64-*-* || { i?86-*-* x86_64-*-* } } } } */
 /* { dg-options "" } */
 
 #include "fp-int-convert.h"
--- gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c.quadtest	2006-09-27 22:34:04.000000000 -0700
+++ gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c	2008-06-29 09:58:26.000000000 -0700
@@ -2,7 +2,6 @@
 /* Origin: Joseph Myers <joseph@codesourcery.com> */
 /* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
 /* { dg-options "" } */
-/* { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 #include "fp-int-convert.h"
 
--- gcc/testsuite/gcc.target/i386/pr32268.c.quadtest	2008-02-17 07:27:09.000000000 -0800
+++ gcc/testsuite/gcc.target/i386/pr32268.c	2008-06-28 16:58:48.000000000 -0700
@@ -1,5 +1,4 @@
 /* { dg-do run { target *-*-linux* } } */
-/* { dg-require-effective-target lp64 } */
 /* { dg-options "-O2" } */
 
 extern void abort(void);

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-29 17:43 PATCH: Enable TFmode for x86 H.J. Lu
@ 2008-06-29 18:37 ` Joseph S. Myers
  2008-06-29 19:23   ` H.J. Lu
  2008-06-30  5:43 ` H.J. Lu
  1 sibling, 1 reply; 32+ messages in thread
From: Joseph S. Myers @ 2008-06-29 18:37 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Uros Bizjak, GCC Patches

On Sun, 29 Jun 2008, H.J. Lu wrote:

> I am enclosing 3 patches to enable TFmode for x86:
> 
> 1. gcc-float128-3.patch. Support TFmode in x86 backend.
> 2. gcc-quad-1.patch. Add x86 support to soft-fp.
> 3. gcc-quadtest-2.patch. Enable __float80/__float128 tests for
> x86.

I don't see anything here to handle symbol versioning.  
libgcc-x86_64-glibc.ver arranges appropriate GCC_4.3.0 versions for the 
TFmode symbols for x86_64.  For 32-bit, they should presumably get 
GCC_4.4.0 versions since that's the version for which these symbols are 
introduced.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-29 18:37 ` Joseph S. Myers
@ 2008-06-29 19:23   ` H.J. Lu
  2008-06-29 20:04     ` H.J. Lu
  2008-06-29 20:18     ` Joseph S. Myers
  0 siblings, 2 replies; 32+ messages in thread
From: H.J. Lu @ 2008-06-29 19:23 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Uros Bizjak, GCC Patches

On Sun, Jun 29, 2008 at 06:10:56PM +0000, Joseph S. Myers wrote:
> On Sun, 29 Jun 2008, H.J. Lu wrote:
> 
> > I am enclosing 3 patches to enable TFmode for x86:
> > 
> > 1. gcc-float128-3.patch. Support TFmode in x86 backend.
> > 2. gcc-quad-1.patch. Add x86 support to soft-fp.
> > 3. gcc-quadtest-2.patch. Enable __float80/__float128 tests for
> > x86.
> 
> I don't see anything here to handle symbol versioning.  
> libgcc-x86_64-glibc.ver arranges appropriate GCC_4.3.0 versions for the 
> TFmode symbols for x86_64.  For 32-bit, they should presumably get 
> GCC_4.4.0 versions since that's the version for which these symbols are 
> introduced.
> 

Here is the updated soft-fp patch to put 32bit __float128 functions
in GCC_4.4.0.  I am testing it on Linux/ia32, Linux/x86-64 and
Linux/ia64. OK for trunk if all pass?

Thanks.


H.J.
--- 
gcc/

2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.  Add
	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
	i[34567]86-*-linux*, x86_64-*-linux*.

	* config/i386/libgcc-glibc.ver: New.
	* config/i386/t-linux: Likewise.

	* config/i386/libgcc-x86_64-glibc.ver: Removed.

	* config/i386/sfp-machine.h: Moved to libgcc.

	* config/i386/sfp-machine.h: New.

	* config/i386/t-darwin: Remove softfp_wrap_start and
	softfp_wrap_end.
	* config/i386/t-darwin64: Likewise.

	* config/i386/t-fprules-softfp64: Renamed to ...
	* config/i386/t-fprules-softfp: This.

	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
	and softfp_wrap_end.

libgcc/

2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>

	* config.host: Add i386/${host_address}/t-fprules-softfp to
	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*. 

	* configure.ac: Set host_address to 64 or 32 for x86.
	* configure: Regenerated.

	* config/i386/32/sfp-machine.h: New.
	* config/i386/32/t-fprules-softfp: Likewise.
	* config/i386/64/sfp-machine.h: New. Moved from gcc.

--- gcc/gcc/config.gcc.quad	2008-06-27 18:43:07.000000000 -0700
+++ gcc/gcc/config.gcc	2008-06-29 12:04:42.000000000 -0700
@@ -1006,11 +1006,11 @@ i[34567]86-*-darwin*)
 	# then this file using that to set --with-cpu=i386 which has no -m64
 	# support.
 	with_cpu=${with_cpu:-generic}
-	tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 x86_64-*-darwin*)
 	with_cpu=${with_cpu:-generic}
-	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
 	tm_file="${tm_file} ${cpu_type}/darwin64.h"
 	;;
 i[34567]86-*-elf*)
@@ -1069,7 +1069,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
-			tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
+			tmake_file="${tmake_file} i386/t-linux64"
 			need_64bit_hwint=yes
 			case X"${with_cpu}" in
 			Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
@@ -1101,7 +1101,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
+	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-*-gnu*)
 	;;
@@ -2973,6 +2973,13 @@ case ${target} in
 		fi
 		;;
 
+	i[34567]86-*-darwin* | x86_64-*-darwin*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+		;;
+	i[34567]86-*-linux* | x86_64-*-linux*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
+		;;
+
 	mips*-*-*)
 		if test x$gnu_ld = xyes
 		then
--- gcc/gcc/config/i386/libgcc-glibc.ver.quad	2008-06-29 12:04:42.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-glibc.ver	2008-06-29 12:09:25.000000000 -0700
@@ -0,0 +1,135 @@
+# In order to work around the very problems that force us to now generally
+# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
+# By now choosing the same version tags for these specific routines, we
+# maintain enough binary compatibility to allow future versions of glibc
+# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
+
+%ifndef __x86_64__
+%inherit GCC_3.0 GLIBC_2.0
+GLIBC_2.0 {
+  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+
+  # Exception handling support functions used by most everyone.
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+%endif
+
+% 128 bit long double support was introduced with GCC 4.3.0 to 64bit
+% and with GCC 4.4.0 to 32bit.  These lines make the symbols to get
+% a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
+
+%ifdef __x86_64__
+%exclude {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __letf2
+  __multf3
+  __negtf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __unordtf2
+}
+
+GCC_4.3.0 {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __letf2
+  __multf3
+  __negtf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __unordtf2
+}
+%else
+%exclude {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __letf2
+  __multf3
+  __negtf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __unordtf2
+}
+
+GCC_4.4.0 {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __letf2
+  __multf3
+  __negtf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __unordtf2
+}
+%endif
--- gcc/gcc/config/i386/libgcc-x86_64-glibc.ver.quad	2007-05-18 07:10:43.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-x86_64-glibc.ver	2008-06-29 12:09:58.000000000 -0700
@@ -1,86 +0,0 @@
-# In order to work around the very problems that force us to now generally
-# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
-# By now choosing the same version tags for these specific routines, we
-# maintain enough binary compatibility to allow future versions of glibc
-# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
-
-%ifndef __x86_64__
-%inherit GCC_3.0 GLIBC_2.0
-GLIBC_2.0 {
-  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
-  __divdi3
-  __moddi3
-  __udivdi3
-  __umoddi3
-
-  # Exception handling support functions used by most everyone.
-  __register_frame
-  __register_frame_table
-  __deregister_frame
-  __register_frame_info
-  __deregister_frame_info
-  __frame_state_for
-  __register_frame_info_table
-}
-%endif
-
-% 128 bit long double support was introduced with GCC 4.3.0.
-% These lines make the symbols to get a @@GCC_4.3.0 attached.
-
-%ifdef __x86_64__
-%exclude {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-
-GCC_4.3.0 {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-%endif
--- gcc/gcc/config/i386/sfp-machine.h.quad	2008-02-19 20:52:26.000000000 -0800
+++ gcc/gcc/config/i386/sfp-machine.h	2008-06-29 12:04:42.000000000 -0700
@@ -1,143 +1,5 @@
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-typedef int TItype __attribute__ ((mode (TI)));
-typedef unsigned int UTItype __attribute__ ((mode (TI)));
-
-#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
-
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
-#define _FP_MUL_MEAT_Q(R,X,Y)                           \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D
-#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_E		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID		0x01
-#define FP_EX_DENORM		0x02
-#define FP_EX_DIVZERO		0x04
-#define FP_EX_OVERFLOW		0x08
-#define FP_EX_UNDERFLOW		0x10
-#define FP_EX_INEXACT		0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS						\
-  do {									\
-    if (_fex & FP_EX_INVALID)						\
-      {									\
-	float f = 0.0;							\
-	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
-      }									\
-    if (_fex & FP_EX_DIVZERO)						\
-      {									\
-	float f = 1.0, g = 0.0;						\
-	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
-      }									\
-    if (_fex & FP_EX_OVERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_OVERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_UNDERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_UNDERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_INEXACT)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_INEXACT;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-  } while (0)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		0xc00
-#define FP_RND_PINF		0x800
-#define FP_RND_MINF		0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE			\
-  do {						\
-    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
-  } while (0)
-
-#define FP_ROUNDMODE		(_fcw & 0xc00)
-
-#define	__LITTLE_ENDIAN	1234
-#define	__BIG_ENDIAN	4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#ifdef __x86_64__
+#include "config/i386/64/sfp-machine.h"
 #else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#include "config/i386/32/sfp-machine.h"
 #endif
--- gcc/gcc/config/i386/t-darwin.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin	2008-06-29 12:04:42.000000000 -0700
@@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
 MULTILIB_DIRNAMES = x86_64
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-darwin64.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin64	2008-06-29 12:04:42.000000000 -0700
@@ -1,5 +1,2 @@
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-fprules-softfp.quad	2008-06-29 12:04:42.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp	2008-06-29 12:04:42.000000000 -0700
@@ -0,0 +1,6 @@
+softfp_float_modes := tf
+softfp_int_modes := si di ti
+softfp_extensions := sftf dftf xftf
+softfp_truncations := tfsf tfdf tfxf
+softfp_machine_header := i386/sfp-machine.h
+softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-fprules-softfp64.quad	2007-05-18 07:10:43.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp64	2008-06-29 12:09:58.000000000 -0700
@@ -1,6 +0,0 @@
-softfp_float_modes := tf
-softfp_int_modes := si di ti
-softfp_extensions := sftf dftf xftf
-softfp_truncations := tfsf tfdf tfxf
-softfp_machine_header := i386/sfp-machine.h
-softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-linux.quad	2008-06-29 12:04:42.000000000 -0700
+++ gcc/gcc/config/i386/t-linux	2008-06-29 12:04:42.000000000 -0700
@@ -0,0 +1,5 @@
+# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
+# Need to support TImode for x86.  Override the settings from
+# t-slibgcc-elf-ver and t-linux
+SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
+		 $(srcdir)/config/i386/libgcc-glibc.ver
--- gcc/gcc/config/i386/t-linux64.quad	2008-06-29 12:02:20.000000000 -0700
+++ gcc/gcc/config/i386/t-linux64	2008-06-29 12:04:42.000000000 -0700
@@ -1,9 +1,3 @@
-# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
-# override the settings
-# from t-slibgcc-elf-ver and t-linux
-SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
-		 $(srcdir)/config/i386/libgcc-x86_64-glibc.ver
-
 # On Debian, Ubuntu and other derivative distributions, the 32bit libraries
 # are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to
 # /lib and /usr/lib, while other distributions install libraries into /lib64
@@ -21,6 +15,3 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
 		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
 		     crtfastmath.o
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/libgcc/config.host.quad	2008-06-08 08:48:36.000000000 -0700
+++ gcc/libgcc/config.host	2008-06-29 12:04:42.000000000 -0700
@@ -578,3 +578,12 @@ i[34567]86-*-linux* | x86_64-*-linux*)
 	tmake_file="${tmake_file} t-tls"
 	;;
 esac
+
+case ${host} in
+i[34567]86-*-darwin* | x86_64-*-darwin* | \
+  i[34567]86-*-linux* | x86_64-*-linux*)
+	if test "${host_address}" = 32; then
+		tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	fi
+	;;
+esac
--- gcc/libgcc/config/i386/32/sfp-machine.h.quad	2008-06-29 12:04:42.000000000 -0700
+++ gcc/libgcc/config/i386/32/sfp-machine.h	2008-06-29 12:04:42.000000000 -0700
@@ -0,0 +1,187 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl)				\
+  __asm__("addl %5,%1; adcl %3,%0"					\
+	  : "=r"(rh), "=r"(rl)						\
+	  : "%0"(xh), "g"(yh), "%1"(xl), "g"(yl)			\
+	  : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  do { 									\
+    __asm__ volatile("addl %5,%1; adcl %3,%0"				\
+		     : "=r"(r1), "=r"(r0)				\
+		     : "%0"(x1), "g"(y1), "%1"(x0), "g"(y0)		\
+		     : "cc");						\
+    __asm__ volatile("adcl %5,%1; adcl %3,%0"				\
+		     : "=r"(r3), "=r"(r2)				\
+		     : "%0"(x3), "g"(y3), "%1"(x2), "g"(y2)		\
+		     : "cc");						\
+  } while (0)
+
+#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl)				\
+  __asm__("subl %5,%1; sbbl %4,%0"					\
+	  : "=r"(rh), "=r"(rl)						\
+	  : "0"(xh), "1"(xl), "g"(yh), "g"(yl)				\
+	  : "cc")
+
+#define __FP_CLZ(r, x)							\
+  do {									\
+    __asm__("bsrl %1,%0" : "=r"(r) : "g"(x) : "cc");			\
+    r ^= 31;								\
+  } while (0)
+
+#define _i386_mul_32_64(rh, rl, x, y)					\
+  __asm__("mull %2" : "=d"(rh), "=a"(rl) : "%g"(x), "1"(y) : "cc")
+
+#define _i386_div_64_32(q, r, nh, nl, d)				\
+  __asm__ ("divl %4" : "=a"(q), "=d"(r) : "0"(nl), "1"(nh), "g"(d) : "cc")
+
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,_i386_mul_32_64)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,_i386_mul_32_64)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
+   emulation is done in 16byte.  */
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0, 0, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	double d;							\
+	__asm__ __volatile__ ("fldz");					\
+	__asm__ __volatile__ ("fdiv %%st, %%st(0)" : "=t" (d));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	double d;							\
+	__asm__ __volatile__ ("fldz; fld1");				\
+	__asm__ __volatile__ ("fdivp %%st, %%st(1)" : "=t" (d));	\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/32/t-fprules-softfp.quad	2008-06-29 12:04:42.000000000 -0700
+++ gcc/libgcc/config/i386/32/t-fprules-softfp	2008-06-29 12:04:42.000000000 -0700
@@ -0,0 +1,5 @@
+# Filter out TImode functions
+tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
--- gcc/libgcc/config/i386/64/sfp-machine.h.quad	2008-06-29 12:04:42.000000000 -0700
+++ gcc/libgcc/config/i386/64/sfp-machine.h	2008-06-29 12:04:42.000000000 -0700
@@ -0,0 +1,143 @@
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y)                           \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f = 0.0;							\
+	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/configure.ac.quad	2008-06-21 07:10:37.000000000 -0700
+++ gcc/libgcc/configure.ac	2008-06-29 12:04:42.000000000 -0700
@@ -153,6 +153,21 @@ AC_CACHE_CHECK([whether fixed-point is s
 fixed_point=$libgcc_cv_fixed_point
 AC_SUBST(fixed_point)
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/configure.quad	2008-06-21 07:10:37.000000000 -0700
+++ gcc/libgcc/configure	2008-06-29 12:04:42.000000000 -0700
@@ -3402,6 +3402,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >
 fixed_point=$libgcc_cv_fixed_point
 
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-29 19:23   ` H.J. Lu
@ 2008-06-29 20:04     ` H.J. Lu
  2008-06-29 20:10       ` Joseph S. Myers
  2008-06-29 20:18     ` Joseph S. Myers
  1 sibling, 1 reply; 32+ messages in thread
From: H.J. Lu @ 2008-06-29 20:04 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Uros Bizjak, GCC Patches

On Sun, Jun 29, 2008 at 12:10:54PM -0700, H.J. Lu wrote:
> On Sun, Jun 29, 2008 at 06:10:56PM +0000, Joseph S. Myers wrote:
> > On Sun, 29 Jun 2008, H.J. Lu wrote:
> > 
> > > I am enclosing 3 patches to enable TFmode for x86:
> > > 
> > > 1. gcc-float128-3.patch. Support TFmode in x86 backend.
> > > 2. gcc-quad-1.patch. Add x86 support to soft-fp.
> > > 3. gcc-quadtest-2.patch. Enable __float80/__float128 tests for
> > > x86.
> > 
> > I don't see anything here to handle symbol versioning.  
> > libgcc-x86_64-glibc.ver arranges appropriate GCC_4.3.0 versions for the 
> > TFmode symbols for x86_64.  For 32-bit, they should presumably get 
> > GCC_4.4.0 versions since that's the version for which these symbols are 
> > introduced.
> > 
> 
> Here is the updated soft-fp patch to put 32bit __float128 functions
> in GCC_4.4.0.  I am testing it on Linux/ia32, Linux/x86-64 and
> Linux/ia64. OK for trunk if all pass?
> 

Some __float128 functions are leaked into @@GCC_3.0:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36669

Here is the updated patch to put them in @@GCC_4.3.0.

I will provide a backport to gcc 4.3 for it after it is fixed
in 4.4.

Thanks.


H.J.
---
gcc/

2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.  Add
	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
	i[34567]86-*-linux*, x86_64-*-linux*.

	PR target/36669
	* config/i386/libgcc-glibc.ver: New.

	* config/i386/t-linux: New.

	* config/i386/libgcc-x86_64-glibc.ver: Removed.

	* config/i386/sfp-machine.h: Moved to libgcc.

	* config/i386/sfp-machine.h: New.

	* config/i386/t-darwin: Remove softfp_wrap_start and
	softfp_wrap_end.
	* config/i386/t-darwin64: Likewise.

	* config/i386/t-fprules-softfp64: Renamed to ...
	* config/i386/t-fprules-softfp: This.

	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
	and softfp_wrap_end.

libgcc/

2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>

	* config.host: Add i386/${host_address}/t-fprules-softfp to
	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*. 

	* configure.ac: Set host_address to 64 or 32 for x86.
	* configure: Regenerated.

	* config/i386/32/sfp-machine.h: New.
	* config/i386/32/t-fprules-softfp: Likewise.
	* config/i386/64/sfp-machine.h: New. Moved from gcc.

--- gcc/gcc/config.gcc.quad	2008-06-29 12:12:15.000000000 -0700
+++ gcc/gcc/config.gcc	2008-06-29 12:12:16.000000000 -0700
@@ -1010,11 +1010,11 @@ i[34567]86-*-darwin*)
 	# then this file using that to set --with-cpu=i386 which has no -m64
 	# support.
 	with_cpu=${with_cpu:-generic}
-	tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 x86_64-*-darwin*)
 	with_cpu=${with_cpu:-generic}
-	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
 	tm_file="${tm_file} ${cpu_type}/darwin64.h"
 	;;
 i[34567]86-*-elf*)
@@ -1073,7 +1073,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
-			tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
+			tmake_file="${tmake_file} i386/t-linux64"
 			need_64bit_hwint=yes
 			case X"${with_cpu}" in
 			Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
@@ -1105,7 +1105,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
+	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-*-gnu*)
 	;;
@@ -2977,6 +2977,13 @@ case ${target} in
 		fi
 		;;
 
+	i[34567]86-*-darwin* | x86_64-*-darwin*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+		;;
+	i[34567]86-*-linux* | x86_64-*-linux*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
+		;;
+
 	mips*-*-*)
 		if test x$gnu_ld = xyes
 		then
--- gcc/gcc/config/i386/libgcc-glibc.ver.quad	2008-06-29 12:12:16.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-glibc.ver	2008-06-29 12:36:36.000000000 -0700
@@ -0,0 +1,154 @@
+# In order to work around the very problems that force us to now generally
+# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
+# By now choosing the same version tags for these specific routines, we
+# maintain enough binary compatibility to allow future versions of glibc
+# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
+
+%ifndef __x86_64__
+%inherit GCC_3.0 GLIBC_2.0
+GLIBC_2.0 {
+  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+
+  # Exception handling support functions used by most everyone.
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+%endif
+
+% 128 bit long double support was introduced with GCC 4.3.0 to 64bit
+% and with GCC 4.4.0 to 32bit.  These lines make the symbols to get
+% a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
+
+%ifdef __x86_64__
+%exclude {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+GCC_4.3.0 {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%else
+%exclude {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2;
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+GCC_4.4.0 {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%endif
--- gcc/gcc/config/i386/libgcc-x86_64-glibc.ver.quad	2007-05-16 15:15:40.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-x86_64-glibc.ver	2008-06-29 12:37:48.000000000 -0700
@@ -1,86 +0,0 @@
-# In order to work around the very problems that force us to now generally
-# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
-# By now choosing the same version tags for these specific routines, we
-# maintain enough binary compatibility to allow future versions of glibc
-# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
-
-%ifndef __x86_64__
-%inherit GCC_3.0 GLIBC_2.0
-GLIBC_2.0 {
-  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
-  __divdi3
-  __moddi3
-  __udivdi3
-  __umoddi3
-
-  # Exception handling support functions used by most everyone.
-  __register_frame
-  __register_frame_table
-  __deregister_frame
-  __register_frame_info
-  __deregister_frame_info
-  __frame_state_for
-  __register_frame_info_table
-}
-%endif
-
-% 128 bit long double support was introduced with GCC 4.3.0.
-% These lines make the symbols to get a @@GCC_4.3.0 attached.
-
-%ifdef __x86_64__
-%exclude {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-
-GCC_4.3.0 {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-%endif
--- gcc/gcc/config/i386/sfp-machine.h.quad	2008-02-19 11:30:00.000000000 -0800
+++ gcc/gcc/config/i386/sfp-machine.h	2008-06-29 12:12:16.000000000 -0700
@@ -1,143 +1,5 @@
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-typedef int TItype __attribute__ ((mode (TI)));
-typedef unsigned int UTItype __attribute__ ((mode (TI)));
-
-#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
-
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
-#define _FP_MUL_MEAT_Q(R,X,Y)                           \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D
-#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_E		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID		0x01
-#define FP_EX_DENORM		0x02
-#define FP_EX_DIVZERO		0x04
-#define FP_EX_OVERFLOW		0x08
-#define FP_EX_UNDERFLOW		0x10
-#define FP_EX_INEXACT		0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS						\
-  do {									\
-    if (_fex & FP_EX_INVALID)						\
-      {									\
-	float f = 0.0;							\
-	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
-      }									\
-    if (_fex & FP_EX_DIVZERO)						\
-      {									\
-	float f = 1.0, g = 0.0;						\
-	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
-      }									\
-    if (_fex & FP_EX_OVERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_OVERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_UNDERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_UNDERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_INEXACT)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_INEXACT;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-  } while (0)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		0xc00
-#define FP_RND_PINF		0x800
-#define FP_RND_MINF		0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE			\
-  do {						\
-    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
-  } while (0)
-
-#define FP_ROUNDMODE		(_fcw & 0xc00)
-
-#define	__LITTLE_ENDIAN	1234
-#define	__BIG_ENDIAN	4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#ifdef __x86_64__
+#include "config/i386/64/sfp-machine.h"
 #else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#include "config/i386/32/sfp-machine.h"
 #endif
--- gcc/gcc/config/i386/t-darwin.quad	2007-05-27 08:09:00.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin	2008-06-29 12:12:16.000000000 -0700
@@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
 MULTILIB_DIRNAMES = x86_64
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-darwin64.quad	2007-05-27 08:09:00.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin64	2008-06-29 12:12:16.000000000 -0700
@@ -1,5 +1,2 @@
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-fprules-softfp.quad	2008-06-29 12:12:16.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp	2008-06-29 12:12:16.000000000 -0700
@@ -0,0 +1,6 @@
+softfp_float_modes := tf
+softfp_int_modes := si di ti
+softfp_extensions := sftf dftf xftf
+softfp_truncations := tfsf tfdf tfxf
+softfp_machine_header := i386/sfp-machine.h
+softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-fprules-softfp64.quad	2007-05-16 15:15:40.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp64	2008-06-29 12:37:48.000000000 -0700
@@ -1,6 +0,0 @@
-softfp_float_modes := tf
-softfp_int_modes := si di ti
-softfp_extensions := sftf dftf xftf
-softfp_truncations := tfsf tfdf tfxf
-softfp_machine_header := i386/sfp-machine.h
-softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-linux.quad	2008-06-29 12:12:16.000000000 -0700
+++ gcc/gcc/config/i386/t-linux	2008-06-29 12:12:16.000000000 -0700
@@ -0,0 +1,5 @@
+# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
+# Need to support TImode for x86.  Override the settings from
+# t-slibgcc-elf-ver and t-linux
+SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
+		 $(srcdir)/config/i386/libgcc-glibc.ver
--- gcc/gcc/config/i386/t-linux64.quad	2007-09-29 07:59:53.000000000 -0700
+++ gcc/gcc/config/i386/t-linux64	2008-06-29 12:12:16.000000000 -0700
@@ -1,9 +1,3 @@
-# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
-# override the settings
-# from t-slibgcc-elf-ver and t-linux
-SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
-		 $(srcdir)/config/i386/libgcc-x86_64-glibc.ver
-
 # On Debian, Ubuntu and other derivative distributions, the 32bit libraries
 # are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to
 # /lib and /usr/lib, while other distributions install libraries into /lib64
@@ -21,6 +15,3 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
 		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
 		     crtfastmath.o
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/libgcc/config.host.quad	2008-06-08 19:30:32.000000000 -0700
+++ gcc/libgcc/config.host	2008-06-29 12:12:16.000000000 -0700
@@ -578,3 +578,12 @@ i[34567]86-*-linux* | x86_64-*-linux*)
 	tmake_file="${tmake_file} t-tls"
 	;;
 esac
+
+case ${host} in
+i[34567]86-*-darwin* | x86_64-*-darwin* | \
+  i[34567]86-*-linux* | x86_64-*-linux*)
+	if test "${host_address}" = 32; then
+		tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	fi
+	;;
+esac
--- gcc/libgcc/config/i386/32/sfp-machine.h.quad	2008-06-29 12:12:16.000000000 -0700
+++ gcc/libgcc/config/i386/32/sfp-machine.h	2008-06-29 12:12:16.000000000 -0700
@@ -0,0 +1,187 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl)				\
+  __asm__("addl %5,%1; adcl %3,%0"					\
+	  : "=r"(rh), "=r"(rl)						\
+	  : "%0"(xh), "g"(yh), "%1"(xl), "g"(yl)			\
+	  : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  do { 									\
+    __asm__ volatile("addl %5,%1; adcl %3,%0"				\
+		     : "=r"(r1), "=r"(r0)				\
+		     : "%0"(x1), "g"(y1), "%1"(x0), "g"(y0)		\
+		     : "cc");						\
+    __asm__ volatile("adcl %5,%1; adcl %3,%0"				\
+		     : "=r"(r3), "=r"(r2)				\
+		     : "%0"(x3), "g"(y3), "%1"(x2), "g"(y2)		\
+		     : "cc");						\
+  } while (0)
+
+#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl)				\
+  __asm__("subl %5,%1; sbbl %4,%0"					\
+	  : "=r"(rh), "=r"(rl)						\
+	  : "0"(xh), "1"(xl), "g"(yh), "g"(yl)				\
+	  : "cc")
+
+#define __FP_CLZ(r, x)							\
+  do {									\
+    __asm__("bsrl %1,%0" : "=r"(r) : "g"(x) : "cc");			\
+    r ^= 31;								\
+  } while (0)
+
+#define _i386_mul_32_64(rh, rl, x, y)					\
+  __asm__("mull %2" : "=d"(rh), "=a"(rl) : "%g"(x), "1"(y) : "cc")
+
+#define _i386_div_64_32(q, r, nh, nl, d)				\
+  __asm__ ("divl %4" : "=a"(q), "=d"(r) : "0"(nl), "1"(nh), "g"(d) : "cc")
+
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,_i386_mul_32_64)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,_i386_mul_32_64)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
+   emulation is done in 16byte.  */
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0, 0, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	double d;							\
+	__asm__ __volatile__ ("fldz");					\
+	__asm__ __volatile__ ("fdiv %%st, %%st(0)" : "=t" (d));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	double d;							\
+	__asm__ __volatile__ ("fldz; fld1");				\
+	__asm__ __volatile__ ("fdivp %%st, %%st(1)" : "=t" (d));	\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/32/t-fprules-softfp.quad	2008-06-29 12:12:16.000000000 -0700
+++ gcc/libgcc/config/i386/32/t-fprules-softfp	2008-06-29 12:12:16.000000000 -0700
@@ -0,0 +1,5 @@
+# Filter out TImode functions
+tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
--- gcc/libgcc/config/i386/64/sfp-machine.h.quad	2008-06-29 12:12:16.000000000 -0700
+++ gcc/libgcc/config/i386/64/sfp-machine.h	2008-06-29 12:12:16.000000000 -0700
@@ -0,0 +1,143 @@
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y)                           \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f = 0.0;							\
+	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/configure.ac.quad	2008-06-29 12:12:15.000000000 -0700
+++ gcc/libgcc/configure.ac	2008-06-29 12:12:16.000000000 -0700
@@ -155,6 +155,21 @@ AC_CACHE_CHECK([whether fixed-point is s
 fixed_point=$libgcc_cv_fixed_point
 AC_SUBST(fixed_point)
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/configure.quad	2008-06-18 05:03:33.000000000 -0700
+++ gcc/libgcc/configure	2008-06-29 12:12:25.000000000 -0700
@@ -272,7 +272,7 @@ PACKAGE_STRING='GNU C Runtime Library 1.
 PACKAGE_BUGREPORT=''
 
 ac_unique_file="static-object.mk"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float enable_decimal_float fixed_point vis_hide set_have_cc_tls tmake_file extra_parts asm_hidden_op LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float enable_decimal_float fixed_point vis_hide set_have_cc_tls tmake_file extra_parts asm_hidden_op extra_ldflags_libgcc LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 ac_pwd=`pwd`
 
@@ -1432,6 +1432,7 @@ fi;
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # OS/2's system install, which has a completely different semantic
 # ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
 echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
 if test -z "$INSTALL"; then
@@ -1465,8 +1466,18 @@ case $as_dir/ in
 	    # program-specific install script used by HP pwplus--don't use.
 	    :
 	  else
-	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
-	    break 3
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
 	  fi
 	fi
       done
@@ -1475,15 +1486,16 @@ case $as_dir/ in
 esac
 done
 
+rm -rf conftest.one conftest.two conftest.dir
 
 fi
   if test "${ac_cv_path_install+set}" = set; then
     INSTALL=$ac_cv_path_install
   else
-    # As a last resort, use the slow shell script.  We don't cache a
-    # path for INSTALL within a source directory, because that will
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
     # break other packages using the cache if that directory is
-    # removed, or if the path is relative.
+    # removed, or if the value is a relative name.
     INSTALL=$ac_install_sh
   fi
 fi
@@ -3402,6 +3414,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >
 fixed_point=$libgcc_cv_fixed_point
 
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
@@ -3523,6 +3550,48 @@ tmake_file="${tmake_file_}"
 
 
 
+# Substitute GNU linker -Bsymbolic-functions
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${acl_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  acl_cv_prog_gnu_ld=yes
+else
+  acl_cv_prog_gnu_ld=no
+fi
+fi
+echo "$as_me:$LINENO: result: $acl_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$acl_cv_prog_gnu_ld" >&6
+with_gnu_ld=$acl_cv_prog_gnu_ld
+
+echo "$as_me:$LINENO: checking if the GNU linker ($LD) supports -Bsymbolic-functions" >&5
+echo $ECHO_N "checking if the GNU linker ($LD) supports -Bsymbolic-functions... $ECHO_C" >&6
+if test "${acl_cv_prog_gnu_ld_symbolic+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+acl_cv_prog_gnu_ld_symbolic=no
+
+if test x"$with_gnu_ld" = x"yes"; then
+  if $LD --help 2>&1 </dev/null | grep Bsymbolic-functions 1>&5; then
+    acl_cv_prog_gnu_ld_symbolic=yes
+  fi
+fi
+fi
+echo "$as_me:$LINENO: result: $acl_cv_prog_gnu_ld_symbolic" >&5
+echo "${ECHO_T}$acl_cv_prog_gnu_ld_symbolic" >&6
+if test x"$acl_cv_prog_gnu_ld_symbolic" = x"yes"; then
+  SYMBOLIC_LDFLAGS="-Wl,-Bsymbolic-functions"
+else
+  SYMBOLIC_LDFLAGS=''
+fi
+
+extra_ldflags_libgcc=$SYMBOLIC_LDFLAGS
+
+
 # We need multilib support.
           ac_config_files="$ac_config_files Makefile"
 
@@ -4230,6 +4299,7 @@ s,@set_have_cc_tls@,$set_have_cc_tls,;t 
 s,@tmake_file@,$tmake_file,;t t
 s,@extra_parts@,$extra_parts,;t t
 s,@asm_hidden_op@,$asm_hidden_op,;t t
+s,@extra_ldflags_libgcc@,$extra_ldflags_libgcc,;t t
 s,@LIBOBJS@,$LIBOBJS,;t t
 s,@LTLIBOBJS@,$LTLIBOBJS,;t t
 CEOF

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-29 20:04     ` H.J. Lu
@ 2008-06-29 20:10       ` Joseph S. Myers
  2008-06-29 20:57         ` H.J. Lu
  0 siblings, 1 reply; 32+ messages in thread
From: Joseph S. Myers @ 2008-06-29 20:10 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Uros Bizjak, GCC Patches

On Sun, 29 Jun 2008, H.J. Lu wrote:

> Some __float128 functions are leaked into @@GCC_3.0:
> 
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36669
> 
> Here is the updated patch to put them in @@GCC_4.3.0.

I'm not convinced changing versions after they've been in a release is a 
good idea (even if the versions are abstractly "wrong"), but if they are 
changed I think the new version should be 4.3.2, given that's the first 
GCC version that would have them at the new symbol version.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-29 19:23   ` H.J. Lu
  2008-06-29 20:04     ` H.J. Lu
@ 2008-06-29 20:18     ` Joseph S. Myers
  2008-06-29 21:07       ` H.J. Lu
  1 sibling, 1 reply; 32+ messages in thread
From: Joseph S. Myers @ 2008-06-29 20:18 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Uros Bizjak, GCC Patches

I think you should have

%inherit GCC_4.4.0 GCC_4.3.0
GCC_4.4.0 {
}

in libgcc-std.ver - at least, that's present for the 4.1.0 version that 
has no target-independent symbols.  Or similar with both 4.3.2 and 4.4.0 
versions if some symbols end up in 4.3.2.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-29 20:10       ` Joseph S. Myers
@ 2008-06-29 20:57         ` H.J. Lu
  0 siblings, 0 replies; 32+ messages in thread
From: H.J. Lu @ 2008-06-29 20:57 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Uros Bizjak, GCC Patches

On Sun, Jun 29, 2008 at 1:02 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> On Sun, 29 Jun 2008, H.J. Lu wrote:
>
>> Some __float128 functions are leaked into @@GCC_3.0:
>>
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36669
>>
>> Here is the updated patch to put them in @@GCC_4.3.0.
>
> I'm not convinced changing versions after they've been in a release is a
> good idea (even if the versions are abstractly "wrong"), but if they are
> changed I think the new version should be 4.3.2, given that's the first
> GCC version that would have them at the new symbol version.
>

We have changed _Decimal128 psABI between gcc 4.3.0 and 4.3.1.
This is no worse than it. I can leave out that part of the patch if it
is preferred.

-- 
H.J.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-29 20:18     ` Joseph S. Myers
@ 2008-06-29 21:07       ` H.J. Lu
  2008-06-29 22:44         ` Joseph S. Myers
  0 siblings, 1 reply; 32+ messages in thread
From: H.J. Lu @ 2008-06-29 21:07 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Uros Bizjak, GCC Patches

On Sun, Jun 29, 2008 at 1:10 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> I think you should have
>
> %inherit GCC_4.4.0 GCC_4.3.0
> GCC_4.4.0 {
> }
>
> in libgcc-std.ver - at least, that's present for the 4.1.0 version that
> has no target-independent symbols.  Or similar with both 4.3.2 and 4.4.0
> versions if some symbols end up in 4.3.2.
>

I followed __float128 GCC_4.3.0 versioning in the old libgcc-x86_64-glibc.ver
where there is no

%inherit GCC_4.3.0 GCC_4.2.0

before

GCC_4.3.0 {


-- 
H.J.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-29 21:07       ` H.J. Lu
@ 2008-06-29 22:44         ` Joseph S. Myers
  2008-06-30  1:14           ` H.J. Lu
  0 siblings, 1 reply; 32+ messages in thread
From: Joseph S. Myers @ 2008-06-29 22:44 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Uros Bizjak, GCC Patches

On Sun, 29 Jun 2008, H.J. Lu wrote:

> On Sun, Jun 29, 2008 at 1:10 PM, Joseph S. Myers
> <joseph@codesourcery.com> wrote:
> > I think you should have
> >
> > %inherit GCC_4.4.0 GCC_4.3.0
> > GCC_4.4.0 {
> > }
> >
> > in libgcc-std.ver - at least, that's present for the 4.1.0 version that
> > has no target-independent symbols.  Or similar with both 4.3.2 and 4.4.0
> > versions if some symbols end up in 4.3.2.
> >
> 
> I followed __float128 GCC_4.3.0 versioning in the old libgcc-x86_64-glibc.ver
> where there is no

The %inherit goes in the target-independent libgcc-std.ver, not the 
version scripts for individual targets.  Again, see the example of 4.1.0 
where there is a target-independent %inherit though all the symbols are 
target-dependent.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-29 22:44         ` Joseph S. Myers
@ 2008-06-30  1:14           ` H.J. Lu
  2008-06-30  7:26             ` Uros Bizjak
                               ` (2 more replies)
  0 siblings, 3 replies; 32+ messages in thread
From: H.J. Lu @ 2008-06-30  1:14 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Uros Bizjak, GCC Patches

On Sun, Jun 29, 2008 at 09:54:30PM +0000, Joseph S. Myers wrote:
> On Sun, 29 Jun 2008, H.J. Lu wrote:
> 
> > On Sun, Jun 29, 2008 at 1:10 PM, Joseph S. Myers
> > <joseph@codesourcery.com> wrote:
> > > I think you should have
> > >
> > > %inherit GCC_4.4.0 GCC_4.3.0
> > > GCC_4.4.0 {
> > > }
> > >
> > > in libgcc-std.ver - at least, that's present for the 4.1.0 version that
> > > has no target-independent symbols.  Or similar with both 4.3.2 and 4.4.0
> > > versions if some symbols end up in 4.3.2.
> > >
> > 
> > I followed __float128 GCC_4.3.0 versioning in the old libgcc-x86_64-glibc.ver
> > where there is no
> 
> The %inherit goes in the target-independent libgcc-std.ver, not the 
> version scripts for individual targets.  Again, see the example of 4.1.0 
> where there is a target-independent %inherit though all the symbols are 
> target-dependent.
> 

Here is the updated patch.

Thanks.

H.J.
----
gcc/

2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.  Add
	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
	i[34567]86-*-linux*, x86_64-*-linux*.

	PR target/36669
	* config/i386/libgcc-glibc.ver: New.

	* config/i386/t-linux: New.

	* config/i386/libgcc-x86_64-glibc.ver: Removed.

	* config/i386/sfp-machine.h: Moved to libgcc.

	* config/i386/sfp-machine.h: New.

	* config/i386/t-darwin: Remove softfp_wrap_start and
	softfp_wrap_end.
	* config/i386/t-darwin64: Likewise.

	* config/i386/t-fprules-softfp64: Renamed to ...
	* config/i386/t-fprules-softfp: This.

	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
	and softfp_wrap_end.

libgcc/

2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>

	* config.host: Add i386/${host_address}/t-fprules-softfp to
	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*. 

	* configure.ac: Set host_address to 64 or 32 for x86.
	* configure: Regenerated.

	* config/i386/32/sfp-machine.h: New.
	* config/i386/32/t-fprules-softfp: Likewise.
	* config/i386/64/sfp-machine.h: New. Moved from gcc.

--- gcc/gcc/config.gcc.quad	2008-06-29 14:00:00.000000000 -0700
+++ gcc/gcc/config.gcc	2008-06-29 14:00:00.000000000 -0700
@@ -1010,11 +1010,11 @@ i[34567]86-*-darwin*)
 	# then this file using that to set --with-cpu=i386 which has no -m64
 	# support.
 	with_cpu=${with_cpu:-generic}
-	tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 x86_64-*-darwin*)
 	with_cpu=${with_cpu:-generic}
-	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
 	tm_file="${tm_file} ${cpu_type}/darwin64.h"
 	;;
 i[34567]86-*-elf*)
@@ -1073,7 +1073,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
-			tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
+			tmake_file="${tmake_file} i386/t-linux64"
 			need_64bit_hwint=yes
 			case X"${with_cpu}" in
 			Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
@@ -1105,7 +1105,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
+	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-*-gnu*)
 	;;
@@ -2977,6 +2977,13 @@ case ${target} in
 		fi
 		;;
 
+	i[34567]86-*-darwin* | x86_64-*-darwin*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+		;;
+	i[34567]86-*-linux* | x86_64-*-linux*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
+		;;
+
 	mips*-*-*)
 		if test x$gnu_ld = xyes
 		then
--- gcc/gcc/config/i386/libgcc-glibc.ver.quad	2008-06-29 14:00:00.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-glibc.ver	2008-06-29 17:05:37.000000000 -0700
@@ -0,0 +1,155 @@
+# In order to work around the very problems that force us to now generally
+# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
+# By now choosing the same version tags for these specific routines, we
+# maintain enough binary compatibility to allow future versions of glibc
+# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
+
+%ifndef __x86_64__
+%inherit GCC_3.0 GLIBC_2.0
+GLIBC_2.0 {
+  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+
+  # Exception handling support functions used by most everyone.
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+%endif
+
+% 128 bit long double support was introduced with GCC 4.3.0 to 64bit
+% and with GCC 4.4.0 to 32bit.  These lines make the symbols to get
+% a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
+
+%ifdef __x86_64__
+%exclude {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+GCC_4.3.0 {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%else
+%exclude {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2;
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+%inherit GCC_4.4.0 GCC_4.3.0
+GCC_4.4.0 {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%endif
--- gcc/gcc/config/i386/libgcc-x86_64-glibc.ver.quad	2007-05-18 07:10:43.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-x86_64-glibc.ver	2008-06-29 17:06:56.000000000 -0700
@@ -1,86 +0,0 @@
-# In order to work around the very problems that force us to now generally
-# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
-# By now choosing the same version tags for these specific routines, we
-# maintain enough binary compatibility to allow future versions of glibc
-# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
-
-%ifndef __x86_64__
-%inherit GCC_3.0 GLIBC_2.0
-GLIBC_2.0 {
-  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
-  __divdi3
-  __moddi3
-  __udivdi3
-  __umoddi3
-
-  # Exception handling support functions used by most everyone.
-  __register_frame
-  __register_frame_table
-  __deregister_frame
-  __register_frame_info
-  __deregister_frame_info
-  __frame_state_for
-  __register_frame_info_table
-}
-%endif
-
-% 128 bit long double support was introduced with GCC 4.3.0.
-% These lines make the symbols to get a @@GCC_4.3.0 attached.
-
-%ifdef __x86_64__
-%exclude {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-
-GCC_4.3.0 {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-%endif
--- gcc/gcc/config/i386/sfp-machine.h.quad	2008-02-19 20:52:26.000000000 -0800
+++ gcc/gcc/config/i386/sfp-machine.h	2008-06-29 14:00:00.000000000 -0700
@@ -1,143 +1,5 @@
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-typedef int TItype __attribute__ ((mode (TI)));
-typedef unsigned int UTItype __attribute__ ((mode (TI)));
-
-#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
-
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
-#define _FP_MUL_MEAT_Q(R,X,Y)                           \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D
-#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_E		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID		0x01
-#define FP_EX_DENORM		0x02
-#define FP_EX_DIVZERO		0x04
-#define FP_EX_OVERFLOW		0x08
-#define FP_EX_UNDERFLOW		0x10
-#define FP_EX_INEXACT		0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS						\
-  do {									\
-    if (_fex & FP_EX_INVALID)						\
-      {									\
-	float f = 0.0;							\
-	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
-      }									\
-    if (_fex & FP_EX_DIVZERO)						\
-      {									\
-	float f = 1.0, g = 0.0;						\
-	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
-      }									\
-    if (_fex & FP_EX_OVERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_OVERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_UNDERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_UNDERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_INEXACT)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_INEXACT;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-  } while (0)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		0xc00
-#define FP_RND_PINF		0x800
-#define FP_RND_MINF		0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE			\
-  do {						\
-    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
-  } while (0)
-
-#define FP_ROUNDMODE		(_fcw & 0xc00)
-
-#define	__LITTLE_ENDIAN	1234
-#define	__BIG_ENDIAN	4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#ifdef __x86_64__
+#include "config/i386/64/sfp-machine.h"
 #else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#include "config/i386/32/sfp-machine.h"
 #endif
--- gcc/gcc/config/i386/t-darwin.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin	2008-06-29 14:00:00.000000000 -0700
@@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
 MULTILIB_DIRNAMES = x86_64
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-darwin64.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin64	2008-06-29 14:00:00.000000000 -0700
@@ -1,5 +1,2 @@
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-fprules-softfp.quad	2008-06-29 14:00:00.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp	2008-06-29 14:00:00.000000000 -0700
@@ -0,0 +1,6 @@
+softfp_float_modes := tf
+softfp_int_modes := si di ti
+softfp_extensions := sftf dftf xftf
+softfp_truncations := tfsf tfdf tfxf
+softfp_machine_header := i386/sfp-machine.h
+softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-fprules-softfp64.quad	2007-05-18 07:10:43.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp64	2008-06-29 17:06:56.000000000 -0700
@@ -1,6 +0,0 @@
-softfp_float_modes := tf
-softfp_int_modes := si di ti
-softfp_extensions := sftf dftf xftf
-softfp_truncations := tfsf tfdf tfxf
-softfp_machine_header := i386/sfp-machine.h
-softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-linux.quad	2008-06-29 14:00:00.000000000 -0700
+++ gcc/gcc/config/i386/t-linux	2008-06-29 14:00:00.000000000 -0700
@@ -0,0 +1,5 @@
+# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
+# Need to support TImode for x86.  Override the settings from
+# t-slibgcc-elf-ver and t-linux
+SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
+		 $(srcdir)/config/i386/libgcc-glibc.ver
--- gcc/gcc/config/i386/t-linux64.quad	2008-06-29 12:02:20.000000000 -0700
+++ gcc/gcc/config/i386/t-linux64	2008-06-29 14:00:00.000000000 -0700
@@ -1,9 +1,3 @@
-# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
-# override the settings
-# from t-slibgcc-elf-ver and t-linux
-SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
-		 $(srcdir)/config/i386/libgcc-x86_64-glibc.ver
-
 # On Debian, Ubuntu and other derivative distributions, the 32bit libraries
 # are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to
 # /lib and /usr/lib, while other distributions install libraries into /lib64
@@ -21,6 +15,3 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
 		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
 		     crtfastmath.o
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/libgcc/config.host.quad	2008-06-08 08:48:36.000000000 -0700
+++ gcc/libgcc/config.host	2008-06-29 14:00:00.000000000 -0700
@@ -578,3 +578,12 @@ i[34567]86-*-linux* | x86_64-*-linux*)
 	tmake_file="${tmake_file} t-tls"
 	;;
 esac
+
+case ${host} in
+i[34567]86-*-darwin* | x86_64-*-darwin* | \
+  i[34567]86-*-linux* | x86_64-*-linux*)
+	if test "${host_address}" = 32; then
+		tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	fi
+	;;
+esac
--- gcc/libgcc/config/i386/32/sfp-machine.h.quad	2008-06-29 14:00:00.000000000 -0700
+++ gcc/libgcc/config/i386/32/sfp-machine.h	2008-06-29 14:00:00.000000000 -0700
@@ -0,0 +1,187 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl)				\
+  __asm__("addl %5,%1; adcl %3,%0"					\
+	  : "=r"(rh), "=r"(rl)						\
+	  : "%0"(xh), "g"(yh), "%1"(xl), "g"(yl)			\
+	  : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  do { 									\
+    __asm__ volatile("addl %5,%1; adcl %3,%0"				\
+		     : "=r"(r1), "=r"(r0)				\
+		     : "%0"(x1), "g"(y1), "%1"(x0), "g"(y0)		\
+		     : "cc");						\
+    __asm__ volatile("adcl %5,%1; adcl %3,%0"				\
+		     : "=r"(r3), "=r"(r2)				\
+		     : "%0"(x3), "g"(y3), "%1"(x2), "g"(y2)		\
+		     : "cc");						\
+  } while (0)
+
+#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl)				\
+  __asm__("subl %5,%1; sbbl %4,%0"					\
+	  : "=r"(rh), "=r"(rl)						\
+	  : "0"(xh), "1"(xl), "g"(yh), "g"(yl)				\
+	  : "cc")
+
+#define __FP_CLZ(r, x)							\
+  do {									\
+    __asm__("bsrl %1,%0" : "=r"(r) : "g"(x) : "cc");			\
+    r ^= 31;								\
+  } while (0)
+
+#define _i386_mul_32_64(rh, rl, x, y)					\
+  __asm__("mull %2" : "=d"(rh), "=a"(rl) : "%g"(x), "1"(y) : "cc")
+
+#define _i386_div_64_32(q, r, nh, nl, d)				\
+  __asm__ ("divl %4" : "=a"(q), "=d"(r) : "0"(nl), "1"(nh), "g"(d) : "cc")
+
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,_i386_mul_32_64)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,_i386_mul_32_64)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
+   emulation is done in 16byte.  */
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0, 0, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	double d;							\
+	__asm__ __volatile__ ("fldz");					\
+	__asm__ __volatile__ ("fdiv %%st, %%st(0)" : "=t" (d));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	double d;							\
+	__asm__ __volatile__ ("fldz; fld1");				\
+	__asm__ __volatile__ ("fdivp %%st, %%st(1)" : "=t" (d));	\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/32/t-fprules-softfp.quad	2008-06-29 14:00:00.000000000 -0700
+++ gcc/libgcc/config/i386/32/t-fprules-softfp	2008-06-29 14:00:00.000000000 -0700
@@ -0,0 +1,5 @@
+# Filter out TImode functions
+tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
--- gcc/libgcc/config/i386/64/sfp-machine.h.quad	2008-06-29 14:00:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/sfp-machine.h	2008-06-29 14:00:00.000000000 -0700
@@ -0,0 +1,143 @@
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y)                           \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f = 0.0;							\
+	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/configure.ac.quad	2008-06-29 14:00:00.000000000 -0700
+++ gcc/libgcc/configure.ac	2008-06-29 14:00:00.000000000 -0700
@@ -155,6 +155,21 @@ AC_CACHE_CHECK([whether fixed-point is s
 fixed_point=$libgcc_cv_fixed_point
 AC_SUBST(fixed_point)
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/configure.quad	2008-06-21 07:10:37.000000000 -0700
+++ gcc/libgcc/configure	2008-06-29 14:00:09.000000000 -0700
@@ -272,7 +272,7 @@ PACKAGE_STRING='GNU C Runtime Library 1.
 PACKAGE_BUGREPORT=''
 
 ac_unique_file="static-object.mk"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float enable_decimal_float fixed_point vis_hide set_have_cc_tls tmake_file extra_parts asm_hidden_op LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float enable_decimal_float fixed_point vis_hide set_have_cc_tls tmake_file extra_parts asm_hidden_op extra_ldflags_libgcc LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 ac_pwd=`pwd`
 
@@ -1432,6 +1432,7 @@ fi;
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # OS/2's system install, which has a completely different semantic
 # ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
 echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
 if test -z "$INSTALL"; then
@@ -1465,8 +1466,18 @@ case $as_dir/ in
 	    # program-specific install script used by HP pwplus--don't use.
 	    :
 	  else
-	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
-	    break 3
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
 	  fi
 	fi
       done
@@ -1475,15 +1486,16 @@ case $as_dir/ in
 esac
 done
 
+rm -rf conftest.one conftest.two conftest.dir
 
 fi
   if test "${ac_cv_path_install+set}" = set; then
     INSTALL=$ac_cv_path_install
   else
-    # As a last resort, use the slow shell script.  We don't cache a
-    # path for INSTALL within a source directory, because that will
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
     # break other packages using the cache if that directory is
-    # removed, or if the path is relative.
+    # removed, or if the value is a relative name.
     INSTALL=$ac_install_sh
   fi
 fi
@@ -3402,6 +3414,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >
 fixed_point=$libgcc_cv_fixed_point
 
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
@@ -3523,6 +3550,48 @@ tmake_file="${tmake_file_}"
 
 
 
+# Substitute GNU linker -Bsymbolic-functions
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${acl_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  acl_cv_prog_gnu_ld=yes
+else
+  acl_cv_prog_gnu_ld=no
+fi
+fi
+echo "$as_me:$LINENO: result: $acl_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$acl_cv_prog_gnu_ld" >&6
+with_gnu_ld=$acl_cv_prog_gnu_ld
+
+echo "$as_me:$LINENO: checking if the GNU linker ($LD) supports -Bsymbolic-functions" >&5
+echo $ECHO_N "checking if the GNU linker ($LD) supports -Bsymbolic-functions... $ECHO_C" >&6
+if test "${acl_cv_prog_gnu_ld_symbolic+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+acl_cv_prog_gnu_ld_symbolic=no
+
+if test x"$with_gnu_ld" = x"yes"; then
+  if $LD --help 2>&1 </dev/null | grep Bsymbolic-functions 1>&5; then
+    acl_cv_prog_gnu_ld_symbolic=yes
+  fi
+fi
+fi
+echo "$as_me:$LINENO: result: $acl_cv_prog_gnu_ld_symbolic" >&5
+echo "${ECHO_T}$acl_cv_prog_gnu_ld_symbolic" >&6
+if test x"$acl_cv_prog_gnu_ld_symbolic" = x"yes"; then
+  SYMBOLIC_LDFLAGS="-Wl,-Bsymbolic-functions"
+else
+  SYMBOLIC_LDFLAGS=''
+fi
+
+extra_ldflags_libgcc=$SYMBOLIC_LDFLAGS
+
+
 # We need multilib support.
           ac_config_files="$ac_config_files Makefile"
 
@@ -4230,6 +4299,7 @@ s,@set_have_cc_tls@,$set_have_cc_tls,;t 
 s,@tmake_file@,$tmake_file,;t t
 s,@extra_parts@,$extra_parts,;t t
 s,@asm_hidden_op@,$asm_hidden_op,;t t
+s,@extra_ldflags_libgcc@,$extra_ldflags_libgcc,;t t
 s,@LIBOBJS@,$LIBOBJS,;t t
 s,@LTLIBOBJS@,$LTLIBOBJS,;t t
 CEOF

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-29 17:43 PATCH: Enable TFmode for x86 H.J. Lu
  2008-06-29 18:37 ` Joseph S. Myers
@ 2008-06-30  5:43 ` H.J. Lu
  2008-07-02 18:49   ` Uros Bizjak
  1 sibling, 1 reply; 32+ messages in thread
From: H.J. Lu @ 2008-06-30  5:43 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Uros Bizjak, GCC Patches

On Sun, Jun 29, 2008 at 10:36:40AM -0700, H.J. Lu wrote:
> I am enclosing 3 patches to enable TFmode for x86:
> 
> 1. gcc-float128-3.patch. Support TFmode in x86 backend.
> 2. gcc-quad-1.patch. Add x86 support to soft-fp.
> 3. gcc-quadtest-2.patch. Enable __float80/__float128 tests for
> x86.
> 

Here is the updated patch for testcases with simplified targets.
OK for trunk?

Thanks.


H.J.
----
2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>

	* g++.dg/abi/mangle24.C: Remove -mmmx.
	* gcc.dg/const-float80-ped.c: Likewise.
	* gcc.dg/const-float80.c: Likewise.
	* gcc.dg/torture/fp-int-convert-float80.c: Likewise.

	* g++.dg/abi/mangle25.C: Enable x86.
	* gcc.dg/const-float128-ped.c: Likewise.
	* gcc.dg/const-float128.c: Likewise.
	* gcc.dg/torture/fp-int-convert-float128.c: Likewise.
	* gcc.target/i386/pr32268.c: Likewise.

--- gcc/testsuite/g++.dg/abi/mangle24.C.quadtest	2006-09-27 22:35:18.000000000 -0700
+++ gcc/testsuite/g++.dg/abi/mangle24.C	2008-06-29 17:16:10.000000000 -0700
@@ -5,7 +5,6 @@
 // Origin: Joseph Myers <joseph@codesourcery.com>
 // { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
 // { dg-options "" } */
-// { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 // { dg-final { scan-assembler "_Z1fe" { target i?86-*-* x86_64-*-* } } } */
 // { dg-final { scan-assembler "_Z1fe" { target { ia64-*-* && { ! "ia64-*-hpux*" } } } } } */
 // { dg-final { scan-assembler "_Z1fu9__float80" { target ia64-*-hpux* } } } */
--- gcc/testsuite/g++.dg/abi/mangle25.C.quadtest	2006-09-27 22:35:18.000000000 -0700
+++ gcc/testsuite/g++.dg/abi/mangle25.C	2008-06-29 22:27:10.000000000 -0700
@@ -4,7 +4,7 @@
 // ia64-hpux where "long double" is "e" and __float128 is synonymous with
 // "long double".
 // Origin: Joseph Myers <joseph@codesourcery.com>
-// { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-*} && lp64 } } } }
+// { dg-do compile { target ia64-*-* i?86-*-* x86_64-*-* } }
 // { dg-options "" } */
 // { dg-final { scan-assembler "_Z1fg" { target i?86-*-* x86_64-*-* } } } */
 // { dg-final { scan-assembler "_Z1fg" { target { ia64-*-* && { ! "ia64-*-hpux*" } } } } } */
--- gcc/testsuite/gcc.dg/const-float128-ped.c.quadtest	2007-08-29 08:49:56.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float128-ped.c	2008-06-29 22:27:27.000000000 -0700
@@ -1,5 +1,5 @@
 /* Test 'q' suffix with -pedantic on __float128 type constants.  */
-/* { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-* } && lp64 } } } } */
+/* { dg-do compile { target ia64-*-* i?86-*-* x86_64-*-* } } */
 /* { dg-options "-pedantic" } */
 
 __float128 a = 123.456789q; /* { dg-warning "non-standard suffix on floating constant" } */
--- gcc/testsuite/gcc.dg/const-float128.c.quadtest	2007-08-29 08:49:56.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float128.c	2008-06-29 22:27:37.000000000 -0700
@@ -1,5 +1,5 @@
 /* Test 'q' and 'Q' suffixes on __float128 type constants.  */
-/* { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-* } && lp64 } } } } */
+/* { dg-do compile { target ia64-*-* i?86-*-* x86_64-*-* } } */
 /* { dg-options "" } */
 
 __float128 a = 123.456789q;
--- gcc/testsuite/gcc.dg/const-float80-ped.c.quadtest	2007-07-03 06:45:52.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float80-ped.c	2008-06-29 17:16:10.000000000 -0700
@@ -1,6 +1,5 @@
 /* Test 'w' suffix with -pedantic on __float80 type constants.  */
 /* { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
 /* { dg-options "-pedantic" } */
-/* { dg-options "-mmmx -pedantic" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 __float80 a = 123.456789w;  /* { dg-warning "non-standard suffix on floating constant" } */
--- gcc/testsuite/gcc.dg/const-float80.c.quadtest	2007-07-03 06:45:52.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float80.c	2008-06-29 17:16:10.000000000 -0700
@@ -1,7 +1,6 @@
 /* Test 'w' and 'W' suffixes on __float80 type constants.  */
 /* { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
 /* { dg-options "" } */
-/* { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 __float80 a = 123.456789W;
 __float80 b = 123.456789w;
--- gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c.quadtest	2007-05-18 07:10:39.000000000 -0700
+++ gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c	2008-06-29 22:27:47.000000000 -0700
@@ -1,6 +1,6 @@
 /* Test floating-point conversions.  __float128 type.  */
 /* Origin: Joseph Myers <joseph@codesourcery.com> */
-/* { dg-do run { target { ia64-*-* || { { i?86-*-* x86_64-*-*} && lp64 } } } } */
+/* { dg-do run { target ia64-*-* i?86-*-* x86_64-*-* } } */
 /* { dg-options "" } */
 
 #include "fp-int-convert.h"
--- gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c.quadtest	2006-09-27 22:34:04.000000000 -0700
+++ gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c	2008-06-29 17:16:10.000000000 -0700
@@ -2,7 +2,6 @@
 /* Origin: Joseph Myers <joseph@codesourcery.com> */
 /* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
 /* { dg-options "" } */
-/* { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 #include "fp-int-convert.h"
 
--- gcc/testsuite/gcc.target/i386/pr32268.c.quadtest	2008-02-17 07:27:09.000000000 -0800
+++ gcc/testsuite/gcc.target/i386/pr32268.c	2008-06-29 17:16:10.000000000 -0700
@@ -1,5 +1,4 @@
 /* { dg-do run { target *-*-linux* } } */
-/* { dg-require-effective-target lp64 } */
 /* { dg-options "-O2" } */
 
 extern void abort(void);

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-30  1:14           ` H.J. Lu
@ 2008-06-30  7:26             ` Uros Bizjak
  2008-06-30 10:28             ` Joseph S. Myers
  2008-06-30 12:52             ` Uros Bizjak
  2 siblings, 0 replies; 32+ messages in thread
From: Uros Bizjak @ 2008-06-30  7:26 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Joseph S. Myers, GCC Patches

On Mon, Jun 30, 2008 at 2:09 AM, H.J. Lu <hjl.tools@gmail.com> wrote:

>
> Here is the updated patch.

> --- gcc/libgcc/config/i386/32/sfp-machine.h.quad        2008-06-29 14:00:00.000000000 -0700
> +++ gcc/libgcc/config/i386/32/sfp-machine.h     2008-06-29 14:00:00.000000000 -0700
> @@ -0,0 +1,187 @@
> +#define _FP_W_TYPE_SIZE                32
> +#define _FP_W_TYPE             unsigned int
> +#define _FP_WS_TYPE            signed int
> +#define _FP_I_TYPE             int
> +
> +/* The type of the result of a floating point comparison.  This must
> +   match `__libgcc_cmp_return__' in GCC for the target.  */
> +typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
> +#define CMPtype __gcc_CMPtype
> +
> +#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl)                                \
> +  __asm__("addl %5,%1; adcl %3,%0"                                     \
> +         : "=r"(rh), "=r"(rl)                                          \
> +         : "%0"(xh), "g"(yh), "%1"(xl), "g"(yl)                        \
> +         : "cc")

You can remove __FP_FRAC_ADD_2 define, since it will pick add_ssaaaa
from longlong.h anyway.

> +
> +#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
> +  do {                                                                         \
> +    __asm__ volatile("addl %5,%1; adcl %3,%0"                          \
> +                    : "=r"(r1), "=r"(r0)                               \
> +                    : "%0"(x1), "g"(y1), "%1"(x0), "g"(y0)             \
> +                    : "cc");                                           \
> +    __asm__ volatile("adcl %5,%1; adcl %3,%0"                          \
> +                    : "=r"(r3), "=r"(r2)                               \
> +                    : "%0"(x3), "g"(y3), "%1"(x2), "g"(y2)             \
> +                    : "cc");                                           \
> +  } while (0)

This needs to have Intel asm dialect alternative template, please see
longlong.h for examples. Also, you can provide __FP_FRAC_ADD_3, with
one adcl less.

> +
> +#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl)                                \
> +  __asm__("subl %5,%1; sbbl %4,%0"                                     \
> +         : "=r"(rh), "=r"(rl)                                          \
> +         : "0"(xh), "1"(xl), "g"(yh), "g"(yl)                          \
> +         : "cc")

You can remove __FP_FRAC_SUB_2 (it is defined as sub_ddmmss in
longlong.h) and provide __PF_FRAC_SUB_{3,4}, in the same way as
__FP_FRAC_ADD_*  above.

> +
> +#define __FP_CLZ(r, x)                                                 \
> +  do {                                                                 \
> +    __asm__("bsrl %1,%0" : "=r"(r) : "g"(x) : "cc");                   \
> +    r ^= 31;                                                           \
> +  } while (0)

Remove definition of __FP_CLZ.

> +
> +#define _i386_mul_32_64(rh, rl, x, y)                                  \
> +  __asm__("mull %2" : "=d"(rh), "=a"(rl) : "%g"(x), "1"(y) : "cc")

This is umul_ppmm from longlong.h. Please remove it and substitute its
uses with umul_ppmm.

> +
> +#define _i386_div_64_32(q, r, nh, nl, d)                               \
> +  __asm__ ("divl %4" : "=a"(q), "=d"(r) : "0"(nl), "1"(nh), "g"(d) : "cc")
> +
> +
> +#define _FP_MUL_MEAT_S(R,X,Y)                                  \
> +  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,_i386_mul_32_64)
> +#define _FP_MUL_MEAT_D(R,X,Y)                                  \
> +  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,_i386_mul_32_64)

Use umul_ppmm in the above definitions.

> +#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
> +  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
> +
> +#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_udiv(S,R,X,Y)
> +#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_2_udiv(D,R,X,Y)
> +#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
> +
> +#define _FP_NANFRAC_S          _FP_QNANBIT_S
> +#define _FP_NANFRAC_D          _FP_QNANBIT_D, 0
> +/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
> +   emulation is done in 16byte.  */
> +#define _FP_NANFRAC_E          _FP_QNANBIT_E, 0, 0, 0
> +#define _FP_NANFRAC_Q          _FP_QNANBIT_Q, 0, 0, 0
> +#define _FP_NANSIGN_S          1
> +#define _FP_NANSIGN_D          1
> +#define _FP_NANSIGN_E          1
> +#define _FP_NANSIGN_Q          1
> +
> +#define _FP_KEEPNANFRACP 1
> +
> +/* Here is something Intel misdesigned: the specs don't define
> +   the case where we have two NaNs with same mantissas, but
> +   different sign. Different operations pick up different NaNs.  */
> +#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
> +  do {                                                         \
> +    if (_FP_FRAC_GT_##wc(X, Y)                                 \
> +       || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
> +      {                                                                \
> +       R##_s = X##_s;                                          \
> +        _FP_FRAC_COPY_##wc(R,X);                               \
> +      }                                                                \
> +    else                                                       \
> +      {                                                                \
> +       R##_s = Y##_s;                                          \
> +        _FP_FRAC_COPY_##wc(R,Y);                               \
> +      }                                                                \
> +    R##_c = FP_CLS_NAN;                                                \
> +  } while (0)
> +
> +#define FP_EX_INVALID          0x01
> +#define FP_EX_DENORM           0x02
> +#define FP_EX_DIVZERO          0x04
> +#define FP_EX_OVERFLOW         0x08
> +#define FP_EX_UNDERFLOW                0x10
> +#define FP_EX_INEXACT          0x20
> +
> +struct fenv
> +{
> +  unsigned short int __control_word;
> +  unsigned short int __unused1;
> +  unsigned short int __status_word;
> +  unsigned short int __unused2;
> +  unsigned short int __tags;
> +  unsigned short int __unused3;
> +  unsigned int __eip;
> +  unsigned short int __cs_selector;
> +  unsigned int __opcode:11;
> +  unsigned int __unused4:5;
> +  unsigned int __data_offset;
> +  unsigned short int __data_selector;
> +  unsigned short int __unused5;
> +};
> +
> +#define FP_HANDLE_EXCEPTIONS                                           \
> +  do {                                                                 \
> +    if (_fex & FP_EX_INVALID)                                          \
> +      {                                                                        \
> +       double d;                                                       \
> +       __asm__ __volatile__ ("fldz");                                  \
> +       __asm__ __volatile__ ("fdiv %%st, %%st(0)" : "=t" (d));         \
> +       __asm__ __volatile__ ("fwait");                                 \
> +      }                                                                        \

This should be written as:
{
  float f = 0.0;
  __asm__ __volatile__ ("fdiv %0": "+t" (f));
  __asm__ __volatile__ ("fwait");
}

> +    if (_fex & FP_EX_DIVZERO)                                          \
> +      {                                                                        \
> +       double d;                                                       \
> +       __asm__ __volatile__ ("fldz; fld1");                            \
> +       __asm__ __volatile__ ("fdivp %%st, %%st(1)" : "=t" (d));        \
> +       __asm__ __volatile__ ("fwait");                                 \
> +      }                                                                        \

And this as:
{
  float f = 1.0, g = 0.0;
  __asm__ __volatile__ ("fdivp"
			: "=t" (f) : "0" (f), "u" (g) : "st(1)");
  __asm__ __volatile__ ("fwait");
}

Uros.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-30  1:14           ` H.J. Lu
  2008-06-30  7:26             ` Uros Bizjak
@ 2008-06-30 10:28             ` Joseph S. Myers
  2008-06-30 12:52             ` Uros Bizjak
  2 siblings, 0 replies; 32+ messages in thread
From: Joseph S. Myers @ 2008-06-30 10:28 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Uros Bizjak, GCC Patches

On Sun, 29 Jun 2008, H.J. Lu wrote:

> On Sun, Jun 29, 2008 at 09:54:30PM +0000, Joseph S. Myers wrote:

> > > > I think you should have
> > > >
> > > > %inherit GCC_4.4.0 GCC_4.3.0
> > > > GCC_4.4.0 {
> > > > }

> > The %inherit goes in the target-independent libgcc-std.ver, not the 
> > version scripts for individual targets.  Again, see the example of 4.1.0 
> > where there is a target-independent %inherit though all the symbols are 
> > target-dependent.
> > 
> 
> Here is the updated patch.

This patch still does not follow the description I gave above, whereby the 
%inherit goes in libgcc-std.ver (which has an empty set of symbols at the 
4.4.0 version for now), not in config/i386/libgcc-glibc.ver.  I'm not sure 
what difference it makes, but it's what's been done so far for previous 
symbol versions.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-30  1:14           ` H.J. Lu
  2008-06-30  7:26             ` Uros Bizjak
  2008-06-30 10:28             ` Joseph S. Myers
@ 2008-06-30 12:52             ` Uros Bizjak
  2008-06-30 15:22               ` H.J. Lu
  2 siblings, 1 reply; 32+ messages in thread
From: Uros Bizjak @ 2008-06-30 12:52 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Joseph S. Myers, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1444 bytes --]

On Mon, Jun 30, 2008 at 2:09 AM, H.J. Lu <hjl.tools@gmail.com> wrote:

> Here is the updated patch.

> +#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
> +  do {                                                                         \
> +    __asm__ volatile("addl %5,%1; adcl %3,%0"                          \
> +                    : "=r"(r1), "=r"(r0)                               \
> +                    : "%0"(x1), "g"(y1), "%1"(x0), "g"(y0)             \
> +                    : "cc");                                           \
> +    __asm__ volatile("adcl %5,%1; adcl %3,%0"                          \
> +                    : "=r"(r3), "=r"(r2)                               \
> +                    : "%0"(x3), "g"(y3), "%1"(x2), "g"(y2)             \
> +                    : "cc");                                           \
> +  } while (0)

This is wrong, carry flag propagation is broken between these two asm
insns. Also, clobbers should be added (please look at attached
source).

> +#define _i386_div_64_32(q, r, nh, nl, d)                               \
> +  __asm__ ("divl %4" : "=a"(q), "=d"(r) : "0"(nl), "1"(nh), "g"(d) : "cc")

The definition above is also unused and should be removed. udiv_qrnnd
from longlong.h is used by default through soft-fp sources.

Attached to this message, please find definitions of
__FP_FRAC_{ADD,SUB}_{3,4} macros, together with a test application.

Uros.

[-- Attachment #2: frac.c --]
[-- Type: application/octet-stream, Size: 5919 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned int USItype __attribute__ ((mode(SI)));

#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
  __asm__ ("add{l} {%11,%3|%3,%11}\n\t"					\
	   "adc{l} {%9,%2|%2,%9}\n\t"					\
	   "adc{l} {%7,%1|%1,%7}\n\t"					\
	   "adc{l} {%5,%0|%0,%5}"					\
	   : "=r" ((USItype) (r3)),					\
	     "=&r" ((USItype) (r2)),					\
	     "=&r" ((USItype) (r1)),					\
	     "=&r" ((USItype) (r0))					\
	   : "%0" ((USItype) (x3)),					\
	     "g" ((USItype) (y3)),					\
	     "%1" ((USItype) (x2)),					\
	     "g" ((USItype) (y2)),					\
	     "%2" ((USItype) (x1)),					\
	     "g" ((USItype) (y1)),					\
	     "%3" ((USItype) (x0)),					\
	     "g" ((USItype) (y0)))

#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
  __asm__ ("add{l} {%8,%2|%2,%8}\n\t"					\
	   "adc{l} {%6,%1|%1,%6}\n\t"					\
	   "adc{l} {%4,%0|%0,%4}"					\
	   : "=r" ((USItype) (r2)),					\
	     "=&r" ((USItype) (r1)),					\
	     "=&r" ((USItype) (r0))					\
	   : "%0" ((USItype) (x2)),					\
	     "g" ((USItype) (y2)),					\
	     "%1" ((USItype) (x1)),					\
	     "g" ((USItype) (y1)),					\
	     "%2" ((USItype) (x0)),					\
	     "g" ((USItype) (y0)))

#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
  __asm__ ("sub{l} {%11,%3|%3,%11}\n\t"					\
	   "sbb{l} {%9,%2|%2,%9}\n\t"					\
	   "sbb{l} {%7,%1|%1,%7}\n\t"					\
	   "sbb{l} {%5,%0|%0,%5}"					\
	   : "=r" ((USItype) (r3)),					\
	     "=&r" ((USItype) (r2)),					\
	     "=&r" ((USItype) (r1)),					\
	     "=&r" ((USItype) (r0))					\
	   : "0" ((USItype) (x3)),					\
	     "g" ((USItype) (y3)),					\
	     "1" ((USItype) (x2)),					\
	     "g" ((USItype) (y2)),					\
	     "2" ((USItype) (x1)),					\
	     "g" ((USItype) (y1)),					\
	     "3" ((USItype) (x0)),					\
	     "g" ((USItype) (y0)))

#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
  __asm__ ("sub{l} {%8,%2|%2,%8}\n\t"					\
	   "sbb{l} {%6,%1|%1,%6}\n\t"					\
	   "sbb{l} {%4,%0|%0,%4}"					\
	   : "=r" ((USItype) (r2)),					\
	     "=&r" ((USItype) (r1)),					\
	     "=&r" ((USItype) (r0))					\
	   : "0" ((USItype) (x2)),					\
	     "g" ((USItype) (y2)),					\
	     "1" ((USItype) (x1)),					\
	     "g" ((USItype) (y1)),					\
	     "2" ((USItype) (x0)),					\
	     "g" ((USItype) (y0)))

void __attribute__ ((noinline))
test_4_add (unsigned int *r, unsigned int *x, unsigned int *y)
{
  __FP_FRAC_ADD_4(r[3],r[2],r[1],r[0],
		  x[3],x[2],x[1],x[0],
		  y[3],y[2],y[1],y[0]);
}

void __attribute__ ((noinline))
test_3_add (unsigned int *r, unsigned int *x, unsigned int *y)
{
  __FP_FRAC_ADD_3(r[2],r[1],r[0],
		  x[2],x[1],x[0],
		  y[2],y[1],y[0]);
}

void __attribute__ ((noinline))
test_4_sub (unsigned int *r, unsigned int *x, unsigned int *y)
{
  __FP_FRAC_SUB_4(r[3],r[2],r[1],r[0],
		  x[3],x[2],x[1],x[0],
		  y[3],y[2],y[1],y[0]);
}

void __attribute__ ((noinline))
test_3_sub (unsigned int *r, unsigned int *x, unsigned int *y)
{
  __FP_FRAC_SUB_3(r[2],r[1],r[0],
		  x[2],x[1],x[0],
		  y[2],y[1],y[0]);
}


#define __FP_FRAC_ADD_3_ref(r2,r1,r0,x2,x1,x0,y2,y1,y0)		\
  do {								\
    USItype _c1, _c2;						\
    r0 = x0 + y0;						\
    _c1 = r0 < x0;						\
    r1 = x1 + y1;						\
    _c2 = r1 < x1;						\
    r1 += _c1;							\
    _c2 |= r1 < _c1;						\
    r2 = x2 + y2 + _c2;						\
  } while (0)

#define __FP_FRAC_ADD_4_ref(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)	\
  do {								\
    USItype _c1, _c2, _c3;					\
    r0 = x0 + y0;						\
    _c1 = r0 < x0;						\
    r1 = x1 + y1;						\
    _c2 = r1 < x1;						\
    r1 += _c1;							\
    _c2 |= r1 < _c1;						\
    r2 = x2 + y2;						\
    _c3 = r2 < x2;						\
    r2 += _c2;							\
    _c3 |= r2 < _c2;						\
    r3 = x3 + y3 + _c3;						\
  } while (0)

#define __FP_FRAC_SUB_3_ref(r2,r1,r0,x2,x1,x0,y2,y1,y0)		\
  do {								\
    USItype _c1, _c2;						\
    r0 = x0 - y0;						\
    _c1 = r0 > x0;						\
    r1 = x1 - y1;						\
    _c2 = r1 > x1;						\
    r1 -= _c1;							\
    _c2 |= _c1 && (y1 == x1);					\
    r2 = x2 - y2 - _c2;						\
  } while (0)

#define __FP_FRAC_SUB_4_ref(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)	\
  do {								\
    USItype _c1, _c2, _c3;					\
    r0 = x0 - y0;						\
    _c1 = r0 > x0;						\
    r1 = x1 - y1;						\
    _c2 = r1 > x1;						\
    r1 -= _c1;							\
    _c2 |= _c1 && (y1 == x1);					\
    r2 = x2 - y2;						\
    _c3 = r2 > x2;						\
    r2 -= _c2;							\
    _c3 |= _c2 && (y2 == x2);					\
    r3 = x3 - y3 - _c3;						\
  } while (0)

void __attribute__ ((noinline))
ref_4_add (unsigned int *r, unsigned int *x, unsigned int *y)
{
  __FP_FRAC_ADD_4_ref(r[3],r[2],r[1],r[0],
		      x[3],x[2],x[1],x[0],
		      y[3],y[2],y[1],y[0]);
}

void __attribute__ ((noinline))
ref_3_add (unsigned int *r, unsigned int *x, unsigned int *y)
{
  __FP_FRAC_ADD_3_ref(r[2],r[1],r[0],
		      x[2],x[1],x[0],
		      y[2],y[1],y[0]);
}

void __attribute__ ((noinline))
ref_4_sub (unsigned int *r, unsigned int *x, unsigned int *y)
{
  __FP_FRAC_SUB_4_ref(r[3],r[2],r[1],r[0],
		      x[3],x[2],x[1],x[0],
		      y[3],y[2],y[1],y[0]);
}

void __attribute__ ((noinline))
ref_3_sub (unsigned int *r, unsigned int *x, unsigned int *y)
{
  __FP_FRAC_SUB_3_ref(r[2],r[1],r[0],
		      x[2],x[1],x[0],
		      y[2],y[1],y[0]);
}


int main()
{
  unsigned int r[4], r_ref[4], x[4], y[4];

  int i;

  while (1)
    {
      for (i = 0; i < 4; i++)
	{
	  x[i] = (unsigned) mrand48();
	  y[i] = (unsigned) mrand48();
	}

      test_4_add (r, x, y);
      ref_4_add (r_ref, x, y);

      if (memcmp (r, r_ref, 4))
	abort ();

      test_4_sub (r, x, y);
      ref_4_sub (r_ref, x, y);

      if (memcmp (r, r_ref, 4))
	abort ();

      test_3_add (r, x, y);
      ref_3_add (r_ref, x, y);

      if (memcmp (r, r_ref, 3))
	abort ();

      test_3_sub (r, x, y);
      ref_3_sub (r_ref, x, y);

      if (memcmp (r, r_ref, 3))
	abort ();
    }

  return 0;
}

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-30 12:52             ` Uros Bizjak
@ 2008-06-30 15:22               ` H.J. Lu
  2008-06-30 16:22                 ` Uros Bizjak
  2008-06-30 19:33                 ` Uros Bizjak
  0 siblings, 2 replies; 32+ messages in thread
From: H.J. Lu @ 2008-06-30 15:22 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: Joseph S. Myers, GCC Patches

On Mon, Jun 30, 2008 at 02:47:11PM +0200, Uros Bizjak wrote:
> On Mon, Jun 30, 2008 at 2:09 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> 
> This is wrong, carry flag propagation is broken between these two asm
> insns. Also, clobbers should be added (please look at attached
> source).
> 
> Attached to this message, please find definitions of
> __FP_FRAC_{ADD,SUB}_{3,4} macros, together with a test application.
> 

Here is the updated patch. I had to comment out __FP_FRAC_SUB_4
since I got

/export/gnu/src/gcc/gcc/libgcc/../gcc/config/soft-fp/divtf3.c:44:
error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
/export/gnu/src/gcc/gcc/libgcc/../gcc/config/soft-fp/divtf3.c:44: error: ‘asm’ operand has impossible constraints

OK for trunk?  Thanks.


H.J.
----
gcc/

2008-06-30  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.  Add
	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
	i[34567]86-*-linux*, x86_64-*-linux*.

	* libgcc-std.ver: Add empty GCC_4.4.0.

	PR target/36669
	* config/i386/libgcc-glibc.ver: New.

	* config/i386/t-linux: New.

	* config/i386/libgcc-x86_64-glibc.ver: Removed.

	* config/i386/sfp-machine.h: Moved to libgcc.

	* config/i386/sfp-machine.h: New.

	* config/i386/t-darwin: Remove softfp_wrap_start and
	softfp_wrap_end.
	* config/i386/t-darwin64: Likewise.

	* config/i386/t-fprules-softfp64: Renamed to ...
	* config/i386/t-fprules-softfp: This.

	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
	and softfp_wrap_end.

libgcc/

2008-06-30  H.J. Lu  <hongjiu.lu@intel.com>

	* config.host: Add i386/${host_address}/t-fprules-softfp to
	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*. 

	* configure.ac: Set host_address to 64 or 32 for x86.
	* configure: Regenerated.

	* config/i386/32/t-fprules-softfp: New.

	* config/i386/64/sfp-machine.h: New. Moved from gcc.

2008-06-30  H.J. Lu  <hongjiu.lu@intel.com>
	    Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/32/sfp-machine.h: New.

--- gcc/gcc/config.gcc.quad	2008-06-29 17:16:09.000000000 -0700
+++ gcc/gcc/config.gcc	2008-06-29 17:16:10.000000000 -0700
@@ -1010,11 +1010,11 @@ i[34567]86-*-darwin*)
 	# then this file using that to set --with-cpu=i386 which has no -m64
 	# support.
 	with_cpu=${with_cpu:-generic}
-	tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 x86_64-*-darwin*)
 	with_cpu=${with_cpu:-generic}
-	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
 	tm_file="${tm_file} ${cpu_type}/darwin64.h"
 	;;
 i[34567]86-*-elf*)
@@ -1073,7 +1073,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
-			tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
+			tmake_file="${tmake_file} i386/t-linux64"
 			need_64bit_hwint=yes
 			case X"${with_cpu}" in
 			Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
@@ -1105,7 +1105,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
+	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-*-gnu*)
 	;;
@@ -2977,6 +2977,13 @@ case ${target} in
 		fi
 		;;
 
+	i[34567]86-*-darwin* | x86_64-*-darwin*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+		;;
+	i[34567]86-*-linux* | x86_64-*-linux*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
+		;;
+
 	mips*-*-*)
 		if test x$gnu_ld = xyes
 		then
--- gcc/gcc/config/i386/libgcc-glibc.ver.quad	2008-06-29 17:16:10.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-glibc.ver	2008-06-30 06:40:48.000000000 -0700
@@ -0,0 +1,154 @@
+# In order to work around the very problems that force us to now generally
+# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
+# By now choosing the same version tags for these specific routines, we
+# maintain enough binary compatibility to allow future versions of glibc
+# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
+
+%ifndef __x86_64__
+%inherit GCC_3.0 GLIBC_2.0
+GLIBC_2.0 {
+  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+
+  # Exception handling support functions used by most everyone.
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+%endif
+
+% 128 bit long double support was introduced with GCC 4.3.0 to 64bit
+% and with GCC 4.4.0 to 32bit.  These lines make the symbols to get
+% a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
+
+%ifdef __x86_64__
+%exclude {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+GCC_4.3.0 {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%else
+%exclude {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2;
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+GCC_4.4.0 {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%endif
--- gcc/gcc/config/i386/libgcc-x86_64-glibc.ver.quad	2007-05-18 07:10:43.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-x86_64-glibc.ver	2008-06-30 07:03:09.000000000 -0700
@@ -1,86 +0,0 @@
-# In order to work around the very problems that force us to now generally
-# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
-# By now choosing the same version tags for these specific routines, we
-# maintain enough binary compatibility to allow future versions of glibc
-# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
-
-%ifndef __x86_64__
-%inherit GCC_3.0 GLIBC_2.0
-GLIBC_2.0 {
-  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
-  __divdi3
-  __moddi3
-  __udivdi3
-  __umoddi3
-
-  # Exception handling support functions used by most everyone.
-  __register_frame
-  __register_frame_table
-  __deregister_frame
-  __register_frame_info
-  __deregister_frame_info
-  __frame_state_for
-  __register_frame_info_table
-}
-%endif
-
-% 128 bit long double support was introduced with GCC 4.3.0.
-% These lines make the symbols to get a @@GCC_4.3.0 attached.
-
-%ifdef __x86_64__
-%exclude {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-
-GCC_4.3.0 {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-%endif
--- gcc/gcc/config/i386/sfp-machine.h.quad	2008-02-19 20:52:26.000000000 -0800
+++ gcc/gcc/config/i386/sfp-machine.h	2008-06-29 17:16:10.000000000 -0700
@@ -1,143 +1,5 @@
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-typedef int TItype __attribute__ ((mode (TI)));
-typedef unsigned int UTItype __attribute__ ((mode (TI)));
-
-#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
-
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
-#define _FP_MUL_MEAT_Q(R,X,Y)                           \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D
-#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_E		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID		0x01
-#define FP_EX_DENORM		0x02
-#define FP_EX_DIVZERO		0x04
-#define FP_EX_OVERFLOW		0x08
-#define FP_EX_UNDERFLOW		0x10
-#define FP_EX_INEXACT		0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS						\
-  do {									\
-    if (_fex & FP_EX_INVALID)						\
-      {									\
-	float f = 0.0;							\
-	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
-      }									\
-    if (_fex & FP_EX_DIVZERO)						\
-      {									\
-	float f = 1.0, g = 0.0;						\
-	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
-      }									\
-    if (_fex & FP_EX_OVERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_OVERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_UNDERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_UNDERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_INEXACT)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_INEXACT;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-  } while (0)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		0xc00
-#define FP_RND_PINF		0x800
-#define FP_RND_MINF		0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE			\
-  do {						\
-    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
-  } while (0)
-
-#define FP_ROUNDMODE		(_fcw & 0xc00)
-
-#define	__LITTLE_ENDIAN	1234
-#define	__BIG_ENDIAN	4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#ifdef __x86_64__
+#include "config/i386/64/sfp-machine.h"
 #else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#include "config/i386/32/sfp-machine.h"
 #endif
--- gcc/gcc/config/i386/t-darwin.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin	2008-06-29 17:16:10.000000000 -0700
@@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
 MULTILIB_DIRNAMES = x86_64
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-darwin64.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin64	2008-06-29 17:16:10.000000000 -0700
@@ -1,5 +1,2 @@
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-fprules-softfp.quad	2008-06-29 17:16:10.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp	2008-06-29 17:16:10.000000000 -0700
@@ -0,0 +1,6 @@
+softfp_float_modes := tf
+softfp_int_modes := si di ti
+softfp_extensions := sftf dftf xftf
+softfp_truncations := tfsf tfdf tfxf
+softfp_machine_header := i386/sfp-machine.h
+softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-fprules-softfp64.quad	2007-05-18 07:10:43.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp64	2008-06-30 07:03:09.000000000 -0700
@@ -1,6 +0,0 @@
-softfp_float_modes := tf
-softfp_int_modes := si di ti
-softfp_extensions := sftf dftf xftf
-softfp_truncations := tfsf tfdf tfxf
-softfp_machine_header := i386/sfp-machine.h
-softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-linux.quad	2008-06-29 17:16:10.000000000 -0700
+++ gcc/gcc/config/i386/t-linux	2008-06-29 17:16:10.000000000 -0700
@@ -0,0 +1,5 @@
+# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
+# Need to support TImode for x86.  Override the settings from
+# t-slibgcc-elf-ver and t-linux
+SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
+		 $(srcdir)/config/i386/libgcc-glibc.ver
--- gcc/gcc/config/i386/t-linux64.quad	2008-06-29 12:02:20.000000000 -0700
+++ gcc/gcc/config/i386/t-linux64	2008-06-29 17:16:10.000000000 -0700
@@ -1,9 +1,3 @@
-# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
-# override the settings
-# from t-slibgcc-elf-ver and t-linux
-SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
-		 $(srcdir)/config/i386/libgcc-x86_64-glibc.ver
-
 # On Debian, Ubuntu and other derivative distributions, the 32bit libraries
 # are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to
 # /lib and /usr/lib, while other distributions install libraries into /lib64
@@ -21,6 +15,3 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
 		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
 		     crtfastmath.o
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/libgcc-std.ver.quad	2007-09-29 07:58:29.000000000 -0700
+++ gcc/gcc/libgcc-std.ver	2008-06-30 06:41:54.000000000 -0700
@@ -1800,3 +1800,7 @@ GCC_4.3.0 {
   __satfractunstiuda
   __satfractunstiuta
 }
+
+%inherit GCC_4.4.0 GCC_4.3.0
+GCC_4.4.0 {
+}
--- gcc/libgcc/config.host.quad	2008-06-08 08:48:36.000000000 -0700
+++ gcc/libgcc/config.host	2008-06-29 17:16:10.000000000 -0700
@@ -578,3 +578,12 @@ i[34567]86-*-linux* | x86_64-*-linux*)
 	tmake_file="${tmake_file} t-tls"
 	;;
 esac
+
+case ${host} in
+i[34567]86-*-darwin* | x86_64-*-darwin* | \
+  i[34567]86-*-linux* | x86_64-*-linux*)
+	if test "${host_address}" = 32; then
+		tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	fi
+	;;
+esac
--- gcc/libgcc/config/i386/32/sfp-machine.h.quad	2008-06-29 17:16:10.000000000 -0700
+++ gcc/libgcc/config/i386/32/sfp-machine.h	2008-06-30 07:02:36.000000000 -0700
@@ -0,0 +1,218 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("add{l} {%11,%3|%3,%11}\n\t"					\
+	   "adc{l} {%9,%2|%2,%9}\n\t"					\
+	   "adc{l} {%7,%1|%1,%7}\n\t"					\
+	   "adc{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "%1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%3" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("add{l} {%8,%2|%2,%8}\n\t"					\
+	   "adc{l} {%6,%1|%1,%6}\n\t"					\
+	   "adc{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+#if 0
+/* FIXME: Reload doesn't work with it.  */
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("sub{l} {%11,%3|%3,%11}\n\t"					\
+	   "sbb{l} {%9,%2|%2,%9}\n\t"					\
+	   "sbb{l} {%7,%1|%1,%7}\n\t"					\
+	   "sbb{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "3" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+#endif
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("sub{l} {%8,%2|%2,%8}\n\t"					\
+	   "sbb{l} {%6,%1|%1,%6}\n\t"					\
+	   "sbb{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
+   emulation is done in 16byte.  */
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0, 0, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f;							\
+	__asm__ __volatile__ ("fdiv %0" : "+t" (f));			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("fdivp" : "=t" (f)			\
+			      	      : "0" (f), "u" (g)		\
+				      : "st(1)");			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/32/t-fprules-softfp.quad	2008-06-29 17:16:10.000000000 -0700
+++ gcc/libgcc/config/i386/32/t-fprules-softfp	2008-06-29 17:16:10.000000000 -0700
@@ -0,0 +1,5 @@
+# Filter out TImode functions
+tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
--- gcc/libgcc/config/i386/64/sfp-machine.h.quad	2008-06-29 17:16:10.000000000 -0700
+++ gcc/libgcc/config/i386/64/sfp-machine.h	2008-06-29 17:16:10.000000000 -0700
@@ -0,0 +1,143 @@
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y)                           \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f = 0.0;							\
+	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/configure.ac.quad	2008-06-29 17:16:10.000000000 -0700
+++ gcc/libgcc/configure.ac	2008-06-29 17:16:10.000000000 -0700
@@ -155,6 +155,21 @@ AC_CACHE_CHECK([whether fixed-point is s
 fixed_point=$libgcc_cv_fixed_point
 AC_SUBST(fixed_point)
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/configure.quad	2008-06-21 07:10:37.000000000 -0700
+++ gcc/libgcc/configure	2008-06-29 17:16:21.000000000 -0700
@@ -272,7 +272,7 @@ PACKAGE_STRING='GNU C Runtime Library 1.
 PACKAGE_BUGREPORT=''
 
 ac_unique_file="static-object.mk"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float enable_decimal_float fixed_point vis_hide set_have_cc_tls tmake_file extra_parts asm_hidden_op LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float enable_decimal_float fixed_point vis_hide set_have_cc_tls tmake_file extra_parts asm_hidden_op extra_ldflags_libgcc LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 ac_pwd=`pwd`
 
@@ -1432,6 +1432,7 @@ fi;
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # OS/2's system install, which has a completely different semantic
 # ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
 echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
 if test -z "$INSTALL"; then
@@ -1465,8 +1466,18 @@ case $as_dir/ in
 	    # program-specific install script used by HP pwplus--don't use.
 	    :
 	  else
-	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
-	    break 3
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
 	  fi
 	fi
       done
@@ -1475,15 +1486,16 @@ case $as_dir/ in
 esac
 done
 
+rm -rf conftest.one conftest.two conftest.dir
 
 fi
   if test "${ac_cv_path_install+set}" = set; then
     INSTALL=$ac_cv_path_install
   else
-    # As a last resort, use the slow shell script.  We don't cache a
-    # path for INSTALL within a source directory, because that will
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
     # break other packages using the cache if that directory is
-    # removed, or if the path is relative.
+    # removed, or if the value is a relative name.
     INSTALL=$ac_install_sh
   fi
 fi
@@ -3402,6 +3414,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >
 fixed_point=$libgcc_cv_fixed_point
 
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
@@ -3523,6 +3550,48 @@ tmake_file="${tmake_file_}"
 
 
 
+# Substitute GNU linker -Bsymbolic-functions
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${acl_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  acl_cv_prog_gnu_ld=yes
+else
+  acl_cv_prog_gnu_ld=no
+fi
+fi
+echo "$as_me:$LINENO: result: $acl_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$acl_cv_prog_gnu_ld" >&6
+with_gnu_ld=$acl_cv_prog_gnu_ld
+
+echo "$as_me:$LINENO: checking if the GNU linker ($LD) supports -Bsymbolic-functions" >&5
+echo $ECHO_N "checking if the GNU linker ($LD) supports -Bsymbolic-functions... $ECHO_C" >&6
+if test "${acl_cv_prog_gnu_ld_symbolic+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+acl_cv_prog_gnu_ld_symbolic=no
+
+if test x"$with_gnu_ld" = x"yes"; then
+  if $LD --help 2>&1 </dev/null | grep Bsymbolic-functions 1>&5; then
+    acl_cv_prog_gnu_ld_symbolic=yes
+  fi
+fi
+fi
+echo "$as_me:$LINENO: result: $acl_cv_prog_gnu_ld_symbolic" >&5
+echo "${ECHO_T}$acl_cv_prog_gnu_ld_symbolic" >&6
+if test x"$acl_cv_prog_gnu_ld_symbolic" = x"yes"; then
+  SYMBOLIC_LDFLAGS="-Wl,-Bsymbolic-functions"
+else
+  SYMBOLIC_LDFLAGS=''
+fi
+
+extra_ldflags_libgcc=$SYMBOLIC_LDFLAGS
+
+
 # We need multilib support.
           ac_config_files="$ac_config_files Makefile"
 
@@ -4230,6 +4299,7 @@ s,@set_have_cc_tls@,$set_have_cc_tls,;t 
 s,@tmake_file@,$tmake_file,;t t
 s,@extra_parts@,$extra_parts,;t t
 s,@asm_hidden_op@,$asm_hidden_op,;t t
+s,@extra_ldflags_libgcc@,$extra_ldflags_libgcc,;t t
 s,@LIBOBJS@,$LIBOBJS,;t t
 s,@LTLIBOBJS@,$LTLIBOBJS,;t t
 CEOF

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-30 15:22               ` H.J. Lu
@ 2008-06-30 16:22                 ` Uros Bizjak
  2008-06-30 17:53                   ` H.J. Lu
  2008-06-30 19:33                 ` Uros Bizjak
  1 sibling, 1 reply; 32+ messages in thread
From: Uros Bizjak @ 2008-06-30 16:22 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Joseph S. Myers, GCC Patches, Ian Lance Taylor

H.J. Lu wrote:
> On Mon, Jun 30, 2008 at 02:47:11PM +0200, Uros Bizjak wrote:
>   
>> On Mon, Jun 30, 2008 at 2:09 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>
>> This is wrong, carry flag propagation is broken between these two asm
>> insns. Also, clobbers should be added (please look at attached
>> source).
>>
>> Attached to this message, please find definitions of
>> __FP_FRAC_{ADD,SUB}_{3,4} macros, together with a test application.
>>
>>     
>
> Here is the updated patch. I had to comment out __FP_FRAC_SUB_4
> since I got
>
> /export/gnu/src/gcc/gcc/libgcc/../gcc/config/soft-fp/divtf3.c:44:
> error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
> /export/gnu/src/gcc/gcc/libgcc/../gcc/config/soft-fp/divtf3.c:44: error: ‘asm’ operand has impossible constraints
>
> OK for trunk?  Thanks.
>   

This is OK for mainline, but please resolve with Joseph about libgcc 
versioning issues. Also, please wait a couple of hours for possible 
Ian's comments (CC'd; he is libgcc maintainer, so he has the last say on 
this matter.).

Thanks,
Uros.

>
> H.J.
> ----
> gcc/
>
> 2008-06-30  H.J. Lu  <hongjiu.lu@intel.com>
>
> 	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
> 	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
> 	i[34567]86-*-linux*, x86_64-*-linux*.  Add
> 	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
> 	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
> 	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
> 	i[34567]86-*-linux*, x86_64-*-linux*.
>
> 	* libgcc-std.ver: Add empty GCC_4.4.0.
>
> 	PR target/36669
> 	* config/i386/libgcc-glibc.ver: New.
>
> 	* config/i386/t-linux: New.
>
> 	* config/i386/libgcc-x86_64-glibc.ver: Removed.
>
> 	* config/i386/sfp-machine.h: Moved to libgcc.
>
> 	* config/i386/sfp-machine.h: New.
>
> 	* config/i386/t-darwin: Remove softfp_wrap_start and
> 	softfp_wrap_end.
> 	* config/i386/t-darwin64: Likewise.
>
> 	* config/i386/t-fprules-softfp64: Renamed to ...
> 	* config/i386/t-fprules-softfp: This.
>
> 	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
> 	and softfp_wrap_end.
>
> libgcc/
>
> 2008-06-30  H.J. Lu  <hongjiu.lu@intel.com>
>
> 	* config.host: Add i386/${host_address}/t-fprules-softfp to
> 	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
> 	i[34567]86-*-linux*, x86_64-*-linux*. 
>
> 	* configure.ac: Set host_address to 64 or 32 for x86.
> 	* configure: Regenerated.
>
> 	* config/i386/32/t-fprules-softfp: New.
>
> 	* config/i386/64/sfp-machine.h: New. Moved from gcc.
>
> 2008-06-30  H.J. Lu  <hongjiu.lu@intel.com>
> 	    Uros Bizjak  <ubizjak@gmail.com>
>
> 	* config/i386/32/sfp-machine.h: New.
>
> --- gcc/gcc/config.gcc.quad	2008-06-29 17:16:09.000000000 -0700
> +++ gcc/gcc/config.gcc	2008-06-29 17:16:10.000000000 -0700
> @@ -1010,11 +1010,11 @@ i[34567]86-*-darwin*)
>  	# then this file using that to set --with-cpu=i386 which has no -m64
>  	# support.
>  	with_cpu=${with_cpu:-generic}
> -	tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
> +	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
>  	;;
>  x86_64-*-darwin*)
>  	with_cpu=${with_cpu:-generic}
> -	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
> +	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
>  	tm_file="${tm_file} ${cpu_type}/darwin64.h"
>  	;;
>  i[34567]86-*-elf*)
> @@ -1073,7 +1073,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
>  		if test x$enable_targets = xall; then
>  			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
>  			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
> -			tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
> +			tmake_file="${tmake_file} i386/t-linux64"
>  			need_64bit_hwint=yes
>  			case X"${with_cpu}" in
>  			Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
> @@ -1105,7 +1105,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu
>  	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
>  	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
>  	esac
> -	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
> +	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
>  	;;
>  i[34567]86-*-gnu*)
>  	;;
> @@ -2977,6 +2977,13 @@ case ${target} in
>  		fi
>  		;;
>  
> +	i[34567]86-*-darwin* | x86_64-*-darwin*)
> +		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
> +		;;
> +	i[34567]86-*-linux* | x86_64-*-linux*)
> +		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
> +		;;
> +
>  	mips*-*-*)
>  		if test x$gnu_ld = xyes
>  		then
> --- gcc/gcc/config/i386/libgcc-glibc.ver.quad	2008-06-29 17:16:10.000000000 -0700
> +++ gcc/gcc/config/i386/libgcc-glibc.ver	2008-06-30 06:40:48.000000000 -0700
> @@ -0,0 +1,154 @@
> +# In order to work around the very problems that force us to now generally
> +# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
> +# By now choosing the same version tags for these specific routines, we
> +# maintain enough binary compatibility to allow future versions of glibc
> +# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
> +
> +%ifndef __x86_64__
> +%inherit GCC_3.0 GLIBC_2.0
> +GLIBC_2.0 {
> +  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
> +  __divdi3
> +  __moddi3
> +  __udivdi3
> +  __umoddi3
> +
> +  # Exception handling support functions used by most everyone.
> +  __register_frame
> +  __register_frame_table
> +  __deregister_frame
> +  __register_frame_info
> +  __deregister_frame_info
> +  __frame_state_for
> +  __register_frame_info_table
> +}
> +%endif
> +
> +% 128 bit long double support was introduced with GCC 4.3.0 to 64bit
> +% and with GCC 4.4.0 to 32bit.  These lines make the symbols to get
> +% a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
> +
> +%ifdef __x86_64__
> +%exclude {
> +  __addtf3
> +  __divtf3
> +  __eqtf2
> +  __extenddftf2
> +  __extendsftf2
> +  __extendxftf2
> +  __fixtfdi
> +  __fixtfsi
> +  __fixtfti
> +  __fixunstfdi
> +  __fixunstfsi
> +  __fixunstfti
> +  __floatditf
> +  __floatsitf
> +  __floattitf
> +  __floatunditf
> +  __floatunsitf
> +  __floatuntitf
> +  __getf2
> +  __gttf2
> +  __letf2
> +  __lttf2
> +  __multf3
> +  __negtf2
> +  __netf2
> +  __subtf3
> +  __trunctfdf2
> +  __trunctfsf2
> +  __trunctfxf2
> +  __unordtf2
> +}
> +
> +GCC_4.3.0 {
> +  __addtf3
> +  __divtf3
> +  __eqtf2
> +  __extenddftf2
> +  __extendsftf2
> +  __extendxftf2
> +  __fixtfdi
> +  __fixtfsi
> +  __fixtfti
> +  __fixunstfdi
> +  __fixunstfsi
> +  __fixunstfti
> +  __floatditf
> +  __floatsitf
> +  __floattitf
> +  __floatunditf
> +  __floatunsitf
> +  __floatuntitf
> +  __getf2
> +  __gttf2
> +  __letf2
> +  __lttf2
> +  __multf3
> +  __negtf2
> +  __netf2
> +  __subtf3
> +  __trunctfdf2
> +  __trunctfsf2
> +  __trunctfxf2
> +  __unordtf2
> +}
> +%else
> +%exclude {
> +  __addtf3
> +  __divtf3
> +  __eqtf2
> +  __extenddftf2
> +  __extendsftf2
> +  __extendxftf2
> +  __fixtfdi
> +  __fixtfsi
> +  __fixunstfdi
> +  __fixunstfsi
> +  __floatditf
> +  __floatsitf
> +  __floatunditf
> +  __floatunsitf
> +  __getf2
> +  __gttf2
> +  __letf2
> +  __lttf2
> +  __multf3
> +  __negtf2
> +  __netf2;
> +  __subtf3
> +  __trunctfdf2
> +  __trunctfsf2
> +  __trunctfxf2
> +  __unordtf2
> +}
> +
> +GCC_4.4.0 {
> +  __addtf3
> +  __divtf3
> +  __eqtf2
> +  __extenddftf2
> +  __extendsftf2
> +  __fixtfdi
> +  __fixtfsi
> +  __fixunstfdi
> +  __fixunstfsi
> +  __floatditf
> +  __floatsitf
> +  __floatunditf
> +  __floatunsitf
> +  __getf2
> +  __gttf2
> +  __letf2
> +  __lttf2
> +  __multf3
> +  __negtf2
> +  __netf2
> +  __subtf3
> +  __trunctfdf2
> +  __trunctfsf2
> +  __trunctfxf2
> +  __unordtf2
> +}
> +%endif
> --- gcc/gcc/config/i386/libgcc-x86_64-glibc.ver.quad	2007-05-18 07:10:43.000000000 -0700
> +++ gcc/gcc/config/i386/libgcc-x86_64-glibc.ver	2008-06-30 07:03:09.000000000 -0700
> @@ -1,86 +0,0 @@
> -# In order to work around the very problems that force us to now generally
> -# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
> -# By now choosing the same version tags for these specific routines, we
> -# maintain enough binary compatibility to allow future versions of glibc
> -# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
> -
> -%ifndef __x86_64__
> -%inherit GCC_3.0 GLIBC_2.0
> -GLIBC_2.0 {
> -  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
> -  __divdi3
> -  __moddi3
> -  __udivdi3
> -  __umoddi3
> -
> -  # Exception handling support functions used by most everyone.
> -  __register_frame
> -  __register_frame_table
> -  __deregister_frame
> -  __register_frame_info
> -  __deregister_frame_info
> -  __frame_state_for
> -  __register_frame_info_table
> -}
> -%endif
> -
> -% 128 bit long double support was introduced with GCC 4.3.0.
> -% These lines make the symbols to get a @@GCC_4.3.0 attached.
> -
> -%ifdef __x86_64__
> -%exclude {
> -  __addtf3
> -  __divtf3
> -  __eqtf2
> -  __extenddftf2
> -  __extendsftf2
> -  __fixtfdi
> -  __fixtfsi
> -  __fixtfti
> -  __fixunstfdi
> -  __fixunstfsi
> -  __fixunstfti
> -  __floatditf
> -  __floatsitf
> -  __floattitf
> -  __floatunditf
> -  __floatunsitf
> -  __floatuntitf
> -  __getf2
> -  __letf2
> -  __multf3
> -  __negtf2
> -  __subtf3
> -  __trunctfdf2
> -  __trunctfsf2
> -  __unordtf2
> -}
> -
> -GCC_4.3.0 {
> -  __addtf3
> -  __divtf3
> -  __eqtf2
> -  __extenddftf2
> -  __extendsftf2
> -  __fixtfdi
> -  __fixtfsi
> -  __fixtfti
> -  __fixunstfdi
> -  __fixunstfsi
> -  __fixunstfti
> -  __floatditf
> -  __floatsitf
> -  __floattitf
> -  __floatunditf
> -  __floatunsitf
> -  __floatuntitf
> -  __getf2
> -  __letf2
> -  __multf3
> -  __negtf2
> -  __subtf3
> -  __trunctfdf2
> -  __trunctfsf2
> -  __unordtf2
> -}
> -%endif
> --- gcc/gcc/config/i386/sfp-machine.h.quad	2008-02-19 20:52:26.000000000 -0800
> +++ gcc/gcc/config/i386/sfp-machine.h	2008-06-29 17:16:10.000000000 -0700
> @@ -1,143 +1,5 @@
> -#define _FP_W_TYPE_SIZE		64
> -#define _FP_W_TYPE		unsigned long
> -#define _FP_WS_TYPE		signed long
> -#define _FP_I_TYPE		long
> -
> -typedef int TItype __attribute__ ((mode (TI)));
> -typedef unsigned int UTItype __attribute__ ((mode (TI)));
> -
> -#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
> -
> -/* The type of the result of a floating point comparison.  This must
> -   match `__libgcc_cmp_return__' in GCC for the target.  */
> -typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
> -#define CMPtype __gcc_CMPtype
> -
> -#define _FP_MUL_MEAT_Q(R,X,Y)                           \
> -  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
> -
> -#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
> -
> -#define _FP_NANFRAC_S		_FP_QNANBIT_S
> -#define _FP_NANFRAC_D		_FP_QNANBIT_D
> -#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
> -#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
> -#define _FP_NANSIGN_S		1
> -#define _FP_NANSIGN_D		1
> -#define _FP_NANSIGN_E		1
> -#define _FP_NANSIGN_Q		1
> -
> -#define _FP_KEEPNANFRACP 1
> -
> -/* Here is something Intel misdesigned: the specs don't define
> -   the case where we have two NaNs with same mantissas, but
> -   different sign. Different operations pick up different NaNs.  */
> -#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
> -  do {								\
> -    if (_FP_FRAC_GT_##wc(X, Y)					\
> -	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
> -      {								\
> -	R##_s = X##_s;						\
> -        _FP_FRAC_COPY_##wc(R,X);				\
> -      }								\
> -    else							\
> -      {								\
> -	R##_s = Y##_s;						\
> -        _FP_FRAC_COPY_##wc(R,Y);				\
> -      }								\
> -    R##_c = FP_CLS_NAN;						\
> -  } while (0)
> -
> -#define FP_EX_INVALID		0x01
> -#define FP_EX_DENORM		0x02
> -#define FP_EX_DIVZERO		0x04
> -#define FP_EX_OVERFLOW		0x08
> -#define FP_EX_UNDERFLOW		0x10
> -#define FP_EX_INEXACT		0x20
> -
> -struct fenv
> -{
> -  unsigned short int __control_word;
> -  unsigned short int __unused1;
> -  unsigned short int __status_word;
> -  unsigned short int __unused2;
> -  unsigned short int __tags;
> -  unsigned short int __unused3;
> -  unsigned int __eip;
> -  unsigned short int __cs_selector;
> -  unsigned int __opcode:11;
> -  unsigned int __unused4:5;
> -  unsigned int __data_offset;
> -  unsigned short int __data_selector;
> -  unsigned short int __unused5;
> -};
> -
> -#define FP_HANDLE_EXCEPTIONS						\
> -  do {									\
> -    if (_fex & FP_EX_INVALID)						\
> -      {									\
> -	float f = 0.0;							\
> -	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
> -      }									\
> -    if (_fex & FP_EX_DIVZERO)						\
> -      {									\
> -	float f = 1.0, g = 0.0;						\
> -	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
> -      }									\
> -    if (_fex & FP_EX_OVERFLOW)						\
> -      {									\
> -	struct fenv temp;						\
> -	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
> -	temp.__status_word |= FP_EX_OVERFLOW;				\
> -	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
> -	__asm__ __volatile__ ("fwait");					\
> -      }									\
> -    if (_fex & FP_EX_UNDERFLOW)						\
> -      {									\
> -	struct fenv temp;						\
> -	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
> -	temp.__status_word |= FP_EX_UNDERFLOW;				\
> -	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
> -	__asm__ __volatile__ ("fwait");					\
> -      }									\
> -    if (_fex & FP_EX_INEXACT)						\
> -      {									\
> -	struct fenv temp;						\
> -	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
> -	temp.__status_word |= FP_EX_INEXACT;				\
> -	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
> -	__asm__ __volatile__ ("fwait");					\
> -      }									\
> -  } while (0)
> -
> -#define FP_RND_NEAREST		0
> -#define FP_RND_ZERO		0xc00
> -#define FP_RND_PINF		0x800
> -#define FP_RND_MINF		0x400
> -
> -#define _FP_DECL_EX \
> -  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
> -
> -#define FP_INIT_ROUNDMODE			\
> -  do {						\
> -    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
> -  } while (0)
> -
> -#define FP_ROUNDMODE		(_fcw & 0xc00)
> -
> -#define	__LITTLE_ENDIAN	1234
> -#define	__BIG_ENDIAN	4321
> -
> -#define __BYTE_ORDER __LITTLE_ENDIAN
> -
> -/* Define ALIASNAME as a strong alias for NAME.  */
> -#if defined __MACH__
> -/* Mach-O doesn't support aliasing.  If these functions ever return
> -   anything but CMPtype we need to revisit this... */
> -#define strong_alias(name, aliasname) \
> -  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
> +#ifdef __x86_64__
> +#include "config/i386/64/sfp-machine.h"
>  #else
> -# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
> -# define _strong_alias(name, aliasname) \
> -  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
> +#include "config/i386/32/sfp-machine.h"
>  #endif
> --- gcc/gcc/config/i386/t-darwin.quad	2007-05-26 07:35:21.000000000 -0700
> +++ gcc/gcc/config/i386/t-darwin	2008-06-29 17:16:10.000000000 -0700
> @@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
>  MULTILIB_DIRNAMES = x86_64
>  LIB2_SIDITI_CONV_FUNCS=yes
>  LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
> -
> -softfp_wrap_start := '\#ifdef __x86_64__'
> -softfp_wrap_end := '\#endif'
> --- gcc/gcc/config/i386/t-darwin64.quad	2007-05-26 07:35:21.000000000 -0700
> +++ gcc/gcc/config/i386/t-darwin64	2008-06-29 17:16:10.000000000 -0700
> @@ -1,5 +1,2 @@
>  LIB2_SIDITI_CONV_FUNCS=yes
>  LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
> -
> -softfp_wrap_start := '\#ifdef __x86_64__'
> -softfp_wrap_end := '\#endif'
> --- gcc/gcc/config/i386/t-fprules-softfp.quad	2008-06-29 17:16:10.000000000 -0700
> +++ gcc/gcc/config/i386/t-fprules-softfp	2008-06-29 17:16:10.000000000 -0700
> @@ -0,0 +1,6 @@
> +softfp_float_modes := tf
> +softfp_int_modes := si di ti
> +softfp_extensions := sftf dftf xftf
> +softfp_truncations := tfsf tfdf tfxf
> +softfp_machine_header := i386/sfp-machine.h
> +softfp_exclude_libgcc2 := n
> --- gcc/gcc/config/i386/t-fprules-softfp64.quad	2007-05-18 07:10:43.000000000 -0700
> +++ gcc/gcc/config/i386/t-fprules-softfp64	2008-06-30 07:03:09.000000000 -0700
> @@ -1,6 +0,0 @@
> -softfp_float_modes := tf
> -softfp_int_modes := si di ti
> -softfp_extensions := sftf dftf xftf
> -softfp_truncations := tfsf tfdf tfxf
> -softfp_machine_header := i386/sfp-machine.h
> -softfp_exclude_libgcc2 := n
> --- gcc/gcc/config/i386/t-linux.quad	2008-06-29 17:16:10.000000000 -0700
> +++ gcc/gcc/config/i386/t-linux	2008-06-29 17:16:10.000000000 -0700
> @@ -0,0 +1,5 @@
> +# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
> +# Need to support TImode for x86.  Override the settings from
> +# t-slibgcc-elf-ver and t-linux
> +SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
> +		 $(srcdir)/config/i386/libgcc-glibc.ver
> --- gcc/gcc/config/i386/t-linux64.quad	2008-06-29 12:02:20.000000000 -0700
> +++ gcc/gcc/config/i386/t-linux64	2008-06-29 17:16:10.000000000 -0700
> @@ -1,9 +1,3 @@
> -# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
> -# override the settings
> -# from t-slibgcc-elf-ver and t-linux
> -SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
> -		 $(srcdir)/config/i386/libgcc-x86_64-glibc.ver
> -
>  # On Debian, Ubuntu and other derivative distributions, the 32bit libraries
>  # are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to
>  # /lib and /usr/lib, while other distributions install libraries into /lib64
> @@ -21,6 +15,3 @@ INSTALL_LIBGCC = install-multilib
>  EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
>  		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
>  		     crtfastmath.o
> -
> -softfp_wrap_start := '\#ifdef __x86_64__'
> -softfp_wrap_end := '\#endif'
> --- gcc/gcc/libgcc-std.ver.quad	2007-09-29 07:58:29.000000000 -0700
> +++ gcc/gcc/libgcc-std.ver	2008-06-30 06:41:54.000000000 -0700
> @@ -1800,3 +1800,7 @@ GCC_4.3.0 {
>    __satfractunstiuda
>    __satfractunstiuta
>  }
> +
> +%inherit GCC_4.4.0 GCC_4.3.0
> +GCC_4.4.0 {
> +}
> --- gcc/libgcc/config.host.quad	2008-06-08 08:48:36.000000000 -0700
> +++ gcc/libgcc/config.host	2008-06-29 17:16:10.000000000 -0700
> @@ -578,3 +578,12 @@ i[34567]86-*-linux* | x86_64-*-linux*)
>  	tmake_file="${tmake_file} t-tls"
>  	;;
>  esac
> +
> +case ${host} in
> +i[34567]86-*-darwin* | x86_64-*-darwin* | \
> +  i[34567]86-*-linux* | x86_64-*-linux*)
> +	if test "${host_address}" = 32; then
> +		tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
> +	fi
> +	;;
> +esac
> --- gcc/libgcc/config/i386/32/sfp-machine.h.quad	2008-06-29 17:16:10.000000000 -0700
> +++ gcc/libgcc/config/i386/32/sfp-machine.h	2008-06-30 07:02:36.000000000 -0700
> @@ -0,0 +1,218 @@
> +#define _FP_W_TYPE_SIZE		32
> +#define _FP_W_TYPE		unsigned int
> +#define _FP_WS_TYPE		signed int
> +#define _FP_I_TYPE		int
> +
> +/* The type of the result of a floating point comparison.  This must
> +   match `__libgcc_cmp_return__' in GCC for the target.  */
> +typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
> +#define CMPtype __gcc_CMPtype
> +
> +#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
> +  __asm__ ("add{l} {%11,%3|%3,%11}\n\t"					\
> +	   "adc{l} {%9,%2|%2,%9}\n\t"					\
> +	   "adc{l} {%7,%1|%1,%7}\n\t"					\
> +	   "adc{l} {%5,%0|%0,%5}"					\
> +	   : "=r" ((USItype) (r3)),					\
> +	     "=&r" ((USItype) (r2)),					\
> +	     "=&r" ((USItype) (r1)),					\
> +	     "=&r" ((USItype) (r0))					\
> +	   : "%0" ((USItype) (x3)),					\
> +	     "g" ((USItype) (y3)),					\
> +	     "%1" ((USItype) (x2)),					\
> +	     "g" ((USItype) (y2)),					\
> +	     "%2" ((USItype) (x1)),					\
> +	     "g" ((USItype) (y1)),					\
> +	     "%3" ((USItype) (x0)),					\
> +	     "g" ((USItype) (y0)))
> +
> +#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
> +  __asm__ ("add{l} {%8,%2|%2,%8}\n\t"					\
> +	   "adc{l} {%6,%1|%1,%6}\n\t"					\
> +	   "adc{l} {%4,%0|%0,%4}"					\
> +	   : "=r" ((USItype) (r2)),					\
> +	     "=&r" ((USItype) (r1)),					\
> +	     "=&r" ((USItype) (r0))					\
> +	   : "%0" ((USItype) (x2)),					\
> +	     "g" ((USItype) (y2)),					\
> +	     "%1" ((USItype) (x1)),					\
> +	     "g" ((USItype) (y1)),					\
> +	     "%2" ((USItype) (x0)),					\
> +	     "g" ((USItype) (y0)))
> +
> +#if 0
> +/* FIXME: Reload doesn't work with it.  */
> +#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
> +  __asm__ ("sub{l} {%11,%3|%3,%11}\n\t"					\
> +	   "sbb{l} {%9,%2|%2,%9}\n\t"					\
> +	   "sbb{l} {%7,%1|%1,%7}\n\t"					\
> +	   "sbb{l} {%5,%0|%0,%5}"					\
> +	   : "=r" ((USItype) (r3)),					\
> +	     "=&r" ((USItype) (r2)),					\
> +	     "=&r" ((USItype) (r1)),					\
> +	     "=&r" ((USItype) (r0))					\
> +	   : "0" ((USItype) (x3)),					\
> +	     "g" ((USItype) (y3)),					\
> +	     "1" ((USItype) (x2)),					\
> +	     "g" ((USItype) (y2)),					\
> +	     "2" ((USItype) (x1)),					\
> +	     "g" ((USItype) (y1)),					\
> +	     "3" ((USItype) (x0)),					\
> +	     "g" ((USItype) (y0)))
> +#endif
> +
> +#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
> +  __asm__ ("sub{l} {%8,%2|%2,%8}\n\t"					\
> +	   "sbb{l} {%6,%1|%1,%6}\n\t"					\
> +	   "sbb{l} {%4,%0|%0,%4}"					\
> +	   : "=r" ((USItype) (r2)),					\
> +	     "=&r" ((USItype) (r1)),					\
> +	     "=&r" ((USItype) (r0))					\
> +	   : "0" ((USItype) (x2)),					\
> +	     "g" ((USItype) (y2)),					\
> +	     "1" ((USItype) (x1)),					\
> +	     "g" ((USItype) (y1)),					\
> +	     "2" ((USItype) (x0)),					\
> +	     "g" ((USItype) (y0)))
> +
> +
> +#define _FP_MUL_MEAT_S(R,X,Y)					\
> +  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
> +#define _FP_MUL_MEAT_D(R,X,Y)					\
> +  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
> +#define _FP_MUL_MEAT_Q(R,X,Y)					\
> +  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
> +
> +#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
> +#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
> +#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
> +
> +#define _FP_NANFRAC_S		_FP_QNANBIT_S
> +#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
> +/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
> +   emulation is done in 16byte.  */
> +#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0, 0, 0
> +#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
> +#define _FP_NANSIGN_S		1
> +#define _FP_NANSIGN_D		1
> +#define _FP_NANSIGN_E		1
> +#define _FP_NANSIGN_Q		1
> +
> +#define _FP_KEEPNANFRACP 1
> +
> +/* Here is something Intel misdesigned: the specs don't define
> +   the case where we have two NaNs with same mantissas, but
> +   different sign. Different operations pick up different NaNs.  */
> +#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
> +  do {								\
> +    if (_FP_FRAC_GT_##wc(X, Y)					\
> +	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
> +      {								\
> +	R##_s = X##_s;						\
> +        _FP_FRAC_COPY_##wc(R,X);				\
> +      }								\
> +    else							\
> +      {								\
> +	R##_s = Y##_s;						\
> +        _FP_FRAC_COPY_##wc(R,Y);				\
> +      }								\
> +    R##_c = FP_CLS_NAN;						\
> +  } while (0)
> +
> +#define FP_EX_INVALID		0x01
> +#define FP_EX_DENORM		0x02
> +#define FP_EX_DIVZERO		0x04
> +#define FP_EX_OVERFLOW		0x08
> +#define FP_EX_UNDERFLOW		0x10
> +#define FP_EX_INEXACT		0x20
> +
> +struct fenv
> +{
> +  unsigned short int __control_word;
> +  unsigned short int __unused1;
> +  unsigned short int __status_word;
> +  unsigned short int __unused2;
> +  unsigned short int __tags;
> +  unsigned short int __unused3;
> +  unsigned int __eip;
> +  unsigned short int __cs_selector;
> +  unsigned int __opcode:11;
> +  unsigned int __unused4:5;
> +  unsigned int __data_offset;
> +  unsigned short int __data_selector;
> +  unsigned short int __unused5;
> +};
> +
> +#define FP_HANDLE_EXCEPTIONS						\
> +  do {									\
> +    if (_fex & FP_EX_INVALID)						\
> +      {									\
> +	float f;							\
> +	__asm__ __volatile__ ("fdiv %0" : "+t" (f));			\
> +	__asm__ __volatile__ ("fwait");					\
> +      }									\
> +    if (_fex & FP_EX_DIVZERO)						\
> +      {									\
> +	float f = 1.0, g = 0.0;						\
> +	__asm__ __volatile__ ("fdivp" : "=t" (f)			\
> +			      	      : "0" (f), "u" (g)		\
> +				      : "st(1)");			\
> +	__asm__ __volatile__ ("fwait");					\
> +      }									\
> +    if (_fex & FP_EX_OVERFLOW)						\
> +      {									\
> +	struct fenv temp;						\
> +	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
> +	temp.__status_word |= FP_EX_OVERFLOW;				\
> +	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
> +	__asm__ __volatile__ ("fwait");					\
> +      }									\
> +    if (_fex & FP_EX_UNDERFLOW)						\
> +      {									\
> +	struct fenv temp;						\
> +	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
> +	temp.__status_word |= FP_EX_UNDERFLOW;				\
> +	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
> +	__asm__ __volatile__ ("fwait");					\
> +      }									\
> +    if (_fex & FP_EX_INEXACT)						\
> +      {									\
> +	struct fenv temp;						\
> +	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
> +	temp.__status_word |= FP_EX_INEXACT;				\
> +	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
> +	__asm__ __volatile__ ("fwait");					\
> +      }									\
> +  } while (0)
> +
> +#define FP_RND_NEAREST		0
> +#define FP_RND_ZERO		0xc00
> +#define FP_RND_PINF		0x800
> +#define FP_RND_MINF		0x400
> +
> +#define _FP_DECL_EX \
> +  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
> +
> +#define FP_INIT_ROUNDMODE			\
> +  do {						\
> +    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
> +  } while (0)
> +
> +#define FP_ROUNDMODE		(_fcw & 0xc00)
> +
> +#define	__LITTLE_ENDIAN	1234
> +#define	__BIG_ENDIAN	4321
> +
> +#define __BYTE_ORDER __LITTLE_ENDIAN
> +
> +/* Define ALIASNAME as a strong alias for NAME.  */
> +#if defined __MACH__
> +/* Mach-O doesn't support aliasing.  If these functions ever return
> +   anything but CMPtype we need to revisit this... */
> +#define strong_alias(name, aliasname) \
> +  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
> +#else
> +# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
> +# define _strong_alias(name, aliasname) \
> +  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
> +#endif
> --- gcc/libgcc/config/i386/32/t-fprules-softfp.quad	2008-06-29 17:16:10.000000000 -0700
> +++ gcc/libgcc/config/i386/32/t-fprules-softfp	2008-06-29 17:16:10.000000000 -0700
> @@ -0,0 +1,5 @@
> +# Filter out TImode functions
> +tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
> +tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
> +
> +LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
> --- gcc/libgcc/config/i386/64/sfp-machine.h.quad	2008-06-29 17:16:10.000000000 -0700
> +++ gcc/libgcc/config/i386/64/sfp-machine.h	2008-06-29 17:16:10.000000000 -0700
> @@ -0,0 +1,143 @@
> +#define _FP_W_TYPE_SIZE		64
> +#define _FP_W_TYPE		unsigned long
> +#define _FP_WS_TYPE		signed long
> +#define _FP_I_TYPE		long
> +
> +typedef int TItype __attribute__ ((mode (TI)));
> +typedef unsigned int UTItype __attribute__ ((mode (TI)));
> +
> +#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
> +
> +/* The type of the result of a floating point comparison.  This must
> +   match `__libgcc_cmp_return__' in GCC for the target.  */
> +typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
> +#define CMPtype __gcc_CMPtype
> +
> +#define _FP_MUL_MEAT_Q(R,X,Y)                           \
> +  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
> +
> +#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
> +
> +#define _FP_NANFRAC_S		_FP_QNANBIT_S
> +#define _FP_NANFRAC_D		_FP_QNANBIT_D
> +#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
> +#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
> +#define _FP_NANSIGN_S		1
> +#define _FP_NANSIGN_D		1
> +#define _FP_NANSIGN_E		1
> +#define _FP_NANSIGN_Q		1
> +
> +#define _FP_KEEPNANFRACP 1
> +
> +/* Here is something Intel misdesigned: the specs don't define
> +   the case where we have two NaNs with same mantissas, but
> +   different sign. Different operations pick up different NaNs.  */
> +#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
> +  do {								\
> +    if (_FP_FRAC_GT_##wc(X, Y)					\
> +	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
> +      {								\
> +	R##_s = X##_s;						\
> +        _FP_FRAC_COPY_##wc(R,X);				\
> +      }								\
> +    else							\
> +      {								\
> +	R##_s = Y##_s;						\
> +        _FP_FRAC_COPY_##wc(R,Y);				\
> +      }								\
> +    R##_c = FP_CLS_NAN;						\
> +  } while (0)
> +
> +#define FP_EX_INVALID		0x01
> +#define FP_EX_DENORM		0x02
> +#define FP_EX_DIVZERO		0x04
> +#define FP_EX_OVERFLOW		0x08
> +#define FP_EX_UNDERFLOW		0x10
> +#define FP_EX_INEXACT		0x20
> +
> +struct fenv
> +{
> +  unsigned short int __control_word;
> +  unsigned short int __unused1;
> +  unsigned short int __status_word;
> +  unsigned short int __unused2;
> +  unsigned short int __tags;
> +  unsigned short int __unused3;
> +  unsigned int __eip;
> +  unsigned short int __cs_selector;
> +  unsigned int __opcode:11;
> +  unsigned int __unused4:5;
> +  unsigned int __data_offset;
> +  unsigned short int __data_selector;
> +  unsigned short int __unused5;
> +};
> +
> +#define FP_HANDLE_EXCEPTIONS						\
> +  do {									\
> +    if (_fex & FP_EX_INVALID)						\
> +      {									\
> +	float f = 0.0;							\
> +	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
> +      }									\
> +    if (_fex & FP_EX_DIVZERO)						\
> +      {									\
> +	float f = 1.0, g = 0.0;						\
> +	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
> +      }									\
> +    if (_fex & FP_EX_OVERFLOW)						\
> +      {									\
> +	struct fenv temp;						\
> +	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
> +	temp.__status_word |= FP_EX_OVERFLOW;				\
> +	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
> +	__asm__ __volatile__ ("fwait");					\
> +      }									\
> +    if (_fex & FP_EX_UNDERFLOW)						\
> +      {									\
> +	struct fenv temp;						\
> +	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
> +	temp.__status_word |= FP_EX_UNDERFLOW;				\
> +	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
> +	__asm__ __volatile__ ("fwait");					\
> +      }									\
> +    if (_fex & FP_EX_INEXACT)						\
> +      {									\
> +	struct fenv temp;						\
> +	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
> +	temp.__status_word |= FP_EX_INEXACT;				\
> +	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
> +	__asm__ __volatile__ ("fwait");					\
> +      }									\
> +  } while (0)
> +
> +#define FP_RND_NEAREST		0
> +#define FP_RND_ZERO		0xc00
> +#define FP_RND_PINF		0x800
> +#define FP_RND_MINF		0x400
> +
> +#define _FP_DECL_EX \
> +  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
> +
> +#define FP_INIT_ROUNDMODE			\
> +  do {						\
> +    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
> +  } while (0)
> +
> +#define FP_ROUNDMODE		(_fcw & 0xc00)
> +
> +#define	__LITTLE_ENDIAN	1234
> +#define	__BIG_ENDIAN	4321
> +
> +#define __BYTE_ORDER __LITTLE_ENDIAN
> +
> +/* Define ALIASNAME as a strong alias for NAME.  */
> +#if defined __MACH__
> +/* Mach-O doesn't support aliasing.  If these functions ever return
> +   anything but CMPtype we need to revisit this... */
> +#define strong_alias(name, aliasname) \
> +  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
> +#else
> +# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
> +# define _strong_alias(name, aliasname) \
> +  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
> +#endif
> --- gcc/libgcc/configure.ac.quad	2008-06-29 17:16:10.000000000 -0700
> +++ gcc/libgcc/configure.ac	2008-06-29 17:16:10.000000000 -0700
> @@ -155,6 +155,21 @@ AC_CACHE_CHECK([whether fixed-point is s
>  fixed_point=$libgcc_cv_fixed_point
>  AC_SUBST(fixed_point)
>  
> +# Check 32bit or 64bit for x86.
> +case ${host} in
> +i?86*-*-* | x86_64*-*-*)
> +  cat > conftest.c <<EOF
> +#ifdef __x86_64__
> +host_address=64
> +#else
> +host_address=32
> +#endif
> +EOF
> +    eval `${CC-cc} -E conftest.c | grep host_address=`
> +    rm -f conftest.c
> +    ;;
> +esac
> +
>  # Collect host-machine-specific information.
>  . ${srcdir}/config.host
>  
> --- gcc/libgcc/configure.quad	2008-06-21 07:10:37.000000000 -0700
> +++ gcc/libgcc/configure	2008-06-29 17:16:21.000000000 -0700
> @@ -272,7 +272,7 @@ PACKAGE_STRING='GNU C Runtime Library 1.
>  PACKAGE_BUGREPORT=''
>  
>  ac_unique_file="static-object.mk"
> -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float enable_decimal_float fixed_point vis_hide set_have_cc_tls tmake_file extra_parts asm_hidden_op LIBOBJS LTLIBOBJS'
> +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float enable_decimal_float fixed_point vis_hide set_have_cc_tls tmake_file extra_parts asm_hidden_op extra_ldflags_libgcc LIBOBJS LTLIBOBJS'
>  ac_subst_files=''
>  ac_pwd=`pwd`
>  
> @@ -1432,6 +1432,7 @@ fi;
>  # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
>  # OS/2's system install, which has a completely different semantic
>  # ./install, which can be erroneously created by make from ./install.sh.
> +# Reject install programs that cannot install multiple files.
>  echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
>  echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
>  if test -z "$INSTALL"; then
> @@ -1465,8 +1466,18 @@ case $as_dir/ in
>  	    # program-specific install script used by HP pwplus--don't use.
>  	    :
>  	  else
> -	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
> -	    break 3
> +	    rm -rf conftest.one conftest.two conftest.dir
> +	    echo one > conftest.one
> +	    echo two > conftest.two
> +	    mkdir conftest.dir
> +	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
> +	      test -s conftest.one && test -s conftest.two &&
> +	      test -s conftest.dir/conftest.one &&
> +	      test -s conftest.dir/conftest.two
> +	    then
> +	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
> +	      break 3
> +	    fi
>  	  fi
>  	fi
>        done
> @@ -1475,15 +1486,16 @@ case $as_dir/ in
>  esac
>  done
>  
> +rm -rf conftest.one conftest.two conftest.dir
>  
>  fi
>    if test "${ac_cv_path_install+set}" = set; then
>      INSTALL=$ac_cv_path_install
>    else
> -    # As a last resort, use the slow shell script.  We don't cache a
> -    # path for INSTALL within a source directory, because that will
> +    # As a last resort, use the slow shell script.  Don't cache a
> +    # value for INSTALL within a source directory, because that will
>      # break other packages using the cache if that directory is
> -    # removed, or if the path is relative.
> +    # removed, or if the value is a relative name.
>      INSTALL=$ac_install_sh
>    fi
>  fi
> @@ -3402,6 +3414,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >
>  fixed_point=$libgcc_cv_fixed_point
>  
>  
> +# Check 32bit or 64bit for x86.
> +case ${host} in
> +i?86*-*-* | x86_64*-*-*)
> +  cat > conftest.c <<EOF
> +#ifdef __x86_64__
> +host_address=64
> +#else
> +host_address=32
> +#endif
> +EOF
> +    eval `${CC-cc} -E conftest.c | grep host_address=`
> +    rm -f conftest.c
> +    ;;
> +esac
> +
>  # Collect host-machine-specific information.
>  . ${srcdir}/config.host
>  
> @@ -3523,6 +3550,48 @@ tmake_file="${tmake_file_}"
>  
>  
>  
> +# Substitute GNU linker -Bsymbolic-functions
> +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
> +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
> +if test "${acl_cv_prog_gnu_ld+set}" = set; then
> +  echo $ECHO_N "(cached) $ECHO_C" >&6
> +else
> +  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
> +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
> +  acl_cv_prog_gnu_ld=yes
> +else
> +  acl_cv_prog_gnu_ld=no
> +fi
> +fi
> +echo "$as_me:$LINENO: result: $acl_cv_prog_gnu_ld" >&5
> +echo "${ECHO_T}$acl_cv_prog_gnu_ld" >&6
> +with_gnu_ld=$acl_cv_prog_gnu_ld
> +
> +echo "$as_me:$LINENO: checking if the GNU linker ($LD) supports -Bsymbolic-functions" >&5
> +echo $ECHO_N "checking if the GNU linker ($LD) supports -Bsymbolic-functions... $ECHO_C" >&6
> +if test "${acl_cv_prog_gnu_ld_symbolic+set}" = set; then
> +  echo $ECHO_N "(cached) $ECHO_C" >&6
> +else
> +
> +acl_cv_prog_gnu_ld_symbolic=no
> +
> +if test x"$with_gnu_ld" = x"yes"; then
> +  if $LD --help 2>&1 </dev/null | grep Bsymbolic-functions 1>&5; then
> +    acl_cv_prog_gnu_ld_symbolic=yes
> +  fi
> +fi
> +fi
> +echo "$as_me:$LINENO: result: $acl_cv_prog_gnu_ld_symbolic" >&5
> +echo "${ECHO_T}$acl_cv_prog_gnu_ld_symbolic" >&6
> +if test x"$acl_cv_prog_gnu_ld_symbolic" = x"yes"; then
> +  SYMBOLIC_LDFLAGS="-Wl,-Bsymbolic-functions"
> +else
> +  SYMBOLIC_LDFLAGS=''
> +fi
> +
> +extra_ldflags_libgcc=$SYMBOLIC_LDFLAGS
> +
> +
>  # We need multilib support.
>            ac_config_files="$ac_config_files Makefile"
>  
> @@ -4230,6 +4299,7 @@ s,@set_have_cc_tls@,$set_have_cc_tls,;t 
>  s,@tmake_file@,$tmake_file,;t t
>  s,@extra_parts@,$extra_parts,;t t
>  s,@asm_hidden_op@,$asm_hidden_op,;t t
> +s,@extra_ldflags_libgcc@,$extra_ldflags_libgcc,;t t
>  s,@LIBOBJS@,$LIBOBJS,;t t
>  s,@LTLIBOBJS@,$LTLIBOBJS,;t t
>  CEOF
>
>   

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-30 16:22                 ` Uros Bizjak
@ 2008-06-30 17:53                   ` H.J. Lu
  2008-06-30 18:10                     ` Uros Bizjak
  0 siblings, 1 reply; 32+ messages in thread
From: H.J. Lu @ 2008-06-30 17:53 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: Joseph S. Myers, GCC Patches, Ian Lance Taylor

On Mon, Jun 30, 2008 at 06:14:27PM +0200, Uros Bizjak wrote:
> H.J. Lu wrote:
>> On Mon, Jun 30, 2008 at 02:47:11PM +0200, Uros Bizjak wrote:
>>   
>>> On Mon, Jun 30, 2008 at 2:09 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>
>>> This is wrong, carry flag propagation is broken between these two asm
>>> insns. Also, clobbers should be added (please look at attached
>>> source).
>>>
>>> Attached to this message, please find definitions of
>>> __FP_FRAC_{ADD,SUB}_{3,4} macros, together with a test application.
>>>
>>>     
>>
>> Here is the updated patch. I had to comment out __FP_FRAC_SUB_4
>> since I got
>>
>> /export/gnu/src/gcc/gcc/libgcc/../gcc/config/soft-fp/divtf3.c:44:
>> error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
>> /export/gnu/src/gcc/gcc/libgcc/../gcc/config/soft-fp/divtf3.c:44: error: ‘asm’ operand has impossible constraints
>>
>> OK for trunk?  Thanks.
>>   
>
> This is OK for mainline, but please resolve with Joseph about libgcc  
> versioning issues. Also, please wait a couple of hours for possible  
> Ian's comments (CC'd; he is libgcc maintainer, so he has the last say on  
> this matter.).
>

Here is the updated x86 backend patch. Since __float80 is enabled
unconditionally, I changed ix86_c_mode_for_suffix to return XFmode
for 'w'.  OK for trunk?

Thanks.


H.J.
---
2008-06-28  H.J. Lu  <hongjiu.lu@intel.com>

	* config/i386/i386.c (contains_aligned_value_p): Return true
	for __float128.
	(ix86_function_arg_boundary): Return its natural boundary for
	for __float128.
	(return_in_memory_32): Don't check TDmode.
	(ix86_split_to_parts): Support splitting into 4 parts and
	support TFmode for 32bit target.
	(ix86_split_long_move): Support splitting into 4 parts.
	(bdesc_args): Enable IX86_BUILTIN_FABSQ and IX86_BUILTIN_COPYSIGNQ
	for SSE2.
	(ix86_init_mmx_sse_builtins): Move __float80 and __float128
	to ...
	(ix86_init_builtins): Here.
	(ix86_scalar_mode_supported_p): Always return true for TFmode.
	(ix86_c_mode_for_suffix): Always return TFmode and XFmode for
	'q' and 'w', respectively. 

	* config/i386/i386.md (movtf): Check TARGET_SSE2 instead of
	TARGET_64BIT.
	(movtf_internal): Likewise.
	(<code>tf2): Likewise.
	(*absnegtf2_sse): Likewise.
	(copysign<mode>3): Likewise.
	(copysign<mode>3_const): Likewise.
	(copysign<mode>3_var): Likewise.
	(define_split UNSPEC_COPYSIGN): Likewise.
	* config/i386/sse.md (*nandtf3): Likewise.
	(<code>tf3): Likewise.
	(*<code>tf3): Likewise.

--- gcc/config/i386/i386.c.float128	2008-06-30 07:13:07.000000000 -0700
+++ gcc/config/i386/i386.c	2008-06-30 10:21:53.000000000 -0700
@@ -4748,7 +4748,9 @@ static bool
 contains_aligned_value_p (tree type)
 {
   enum machine_mode mode = TYPE_MODE (type);
-  if (((TARGET_SSE && SSE_REG_MODE_P (mode)) || mode == TDmode)
+  if (((TARGET_SSE && SSE_REG_MODE_P (mode))
+       || mode == TDmode
+       || mode == TFmode)
       && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
     return true;
   if (TYPE_ALIGN (type) < 128)
@@ -4807,8 +4809,9 @@ ix86_function_arg_boundary (enum machine
     align = GET_MODE_ALIGNMENT (mode);
   if (align < PARM_BOUNDARY)
     align = PARM_BOUNDARY;
-  /* In 32bit, only _Decimal128 is aligned to its natural boundary.  */
-  if (!TARGET_64BIT && mode != TDmode)
+  /* In 32bit, only _Decimal128 and __float128 are aligned to their
+     natural boundaries.  */
+  if (!TARGET_64BIT && mode != TDmode && mode != TFmode)
     {
       /* i386 ABI defines all arguments to be 4 byte aligned.  We have to
 	 make an exception for SSE modes since these require 128bit
@@ -4819,7 +4822,7 @@ ix86_function_arg_boundary (enum machine
 	 to 8 byte boundaries.  */
       if (!type)
 	{
-	  if (!(TARGET_SSE && SSE_REG_MODE_P (mode)) && mode != TDmode)
+	  if (!(TARGET_SSE && SSE_REG_MODE_P (mode)))
 	    align = PARM_BOUNDARY;
 	}
       else
@@ -5045,9 +5048,6 @@ return_in_memory_32 (const_tree type, en
   if (mode == XFmode)
     return 0;
 
-  if (mode == TDmode)
-    return 1;
-
   if (size > 12)
     return 1;
   return 0;
@@ -14155,7 +14155,7 @@ ix86_split_to_parts (rtx operand, rtx *p
     size = (GET_MODE_SIZE (mode) + 4) / 8;
 
   gcc_assert (!REG_P (operand) || !MMX_REGNO_P (REGNO (operand)));
-  gcc_assert (size >= 2 && size <= 3);
+  gcc_assert (size >= 2 && size <= 4);
 
   /* Optimize constant pool reference to immediates.  This is used by fp
      moves, that force all constants to memory to allow combining.  */
@@ -14175,7 +14175,7 @@ ix86_split_to_parts (rtx operand, rtx *p
 
       operand = copy_rtx (operand);
       PUT_MODE (operand, Pmode);
-      parts[0] = parts[1] = parts[2] = operand;
+      parts[0] = parts[1] = parts[2] = parts[3] = operand;
       return size;
     }
 
@@ -14196,21 +14196,20 @@ ix86_split_to_parts (rtx operand, rtx *p
 	split_di (&operand, 1, &parts[0], &parts[1]);
       else
 	{
+	  int i;
+
 	  if (REG_P (operand))
 	    {
 	      gcc_assert (reload_completed);
-	      parts[0] = gen_rtx_REG (SImode, REGNO (operand) + 0);
-	      parts[1] = gen_rtx_REG (SImode, REGNO (operand) + 1);
-	      if (size == 3)
-		parts[2] = gen_rtx_REG (SImode, REGNO (operand) + 2);
+	      for (i = 0; i < size; i++)
+		parts[i] = gen_rtx_REG (SImode, REGNO (operand) + i);
 	    }
 	  else if (offsettable_memref_p (operand))
 	    {
 	      operand = adjust_address (operand, SImode, 0);
 	      parts[0] = operand;
-	      parts[1] = adjust_address (operand, SImode, 4);
-	      if (size == 3)
-		parts[2] = adjust_address (operand, SImode, 8);
+	      for (i = 1; i < size; i++)
+		parts[i] = adjust_address (operand, SImode, 4 * i);
 	    }
 	  else if (GET_CODE (operand) == CONST_DOUBLE)
 	    {
@@ -14220,6 +14219,11 @@ ix86_split_to_parts (rtx operand, rtx *p
 	      REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
 	      switch (mode)
 		{
+		case TFmode:
+		  real_to_target (l, &r, mode);
+		  parts[3] = gen_int_mode (l[3], SImode);
+		  parts[2] = gen_int_mode (l[2], SImode);
+		  break;
 		case XFmode:
 		  REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
 		  parts[2] = gen_int_mode (l[2], SImode);
@@ -14293,7 +14297,7 @@ ix86_split_to_parts (rtx operand, rtx *p
   return size;
 }
 
-/* Emit insns to perform a move or push of DI, DF, and XF values.
+/* Emit insns to perform a move or push of DI, DF, XF, and TF values.
    Return false when normal moves are needed; true when all required
    insns have been emitted.  Operands 2-4 contain the input values
    int the correct order; operands 5-7 contain the output values.  */
@@ -14301,11 +14305,12 @@ ix86_split_to_parts (rtx operand, rtx *p
 void
 ix86_split_long_move (rtx operands[])
 {
-  rtx part[2][3];
-  int nparts;
+  rtx part[2][4];
+  int nparts, i, j;
   int push = 0;
   int collisions = 0;
   enum machine_mode mode = GET_MODE (operands[0]);
+  bool collisionparts[4];
 
   /* The DFmode expanders may ask us to move double.
      For 64bit target this is single move.  By hiding the fact
@@ -14344,34 +14349,46 @@ ix86_split_long_move (rtx operands[])
   /* When emitting push, take care for source operands on the stack.  */
   if (push && MEM_P (operands[1])
       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
-    {
-      if (nparts == 3)
-	part[1][1] = change_address (part[1][1], GET_MODE (part[1][1]),
-				     XEXP (part[1][2], 0));
-      part[1][0] = change_address (part[1][0], GET_MODE (part[1][0]),
-				   XEXP (part[1][1], 0));
-    }
+    for (i = 0; i < nparts - 1; i++)
+      part[1][i] = change_address (part[1][i],
+				   GET_MODE (part[1][i]),
+				   XEXP (part[1][i + 1], 0));
 
   /* We need to do copy in the right order in case an address register
      of the source overlaps the destination.  */
   if (REG_P (part[0][0]) && MEM_P (part[1][0]))
     {
-      if (reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0)))
-	collisions++;
-      if (reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
-	collisions++;
-      if (nparts == 3
-	  && reg_overlap_mentioned_p (part[0][2], XEXP (part[1][0], 0)))
-	collisions++;
+      rtx tmp;
+
+      for (i = 0; i < nparts; i++)
+	{
+	  collisionparts[i]
+	    = reg_overlap_mentioned_p (part[0][i], XEXP (part[1][0], 0));
+	  if (collisionparts[i])
+	    collisions++;
+	}
 
       /* Collision in the middle part can be handled by reordering.  */
-      if (collisions == 1 && nparts == 3
-	  && reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
+      if (collisions == 1 && nparts == 3 && collisionparts [1])
 	{
-	  rtx tmp;
 	  tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp;
 	  tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp;
 	}
+      else if (collisions == 1
+	       && nparts == 4
+	       && (collisionparts [1] || collisionparts [2]))
+	{
+	  if (collisionparts [1])
+	    {
+	      tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp;
+	      tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp;
+	    }
+	  else
+	    {
+	      tmp = part[0][2]; part[0][2] = part[0][3]; part[0][3] = tmp;
+	      tmp = part[1][2]; part[1][2] = part[1][3]; part[1][3] = tmp;
+	    }
+	}
 
       /* If there are more collisions, we can't handle it by reordering.
 	 Do an lea to the last part and use only one colliding move.  */
@@ -14390,11 +14407,11 @@ ix86_split_long_move (rtx operands[])
 
 	  emit_insn (gen_rtx_SET (VOIDmode, base, XEXP (part[1][0], 0)));
 	  part[1][0] = replace_equiv_address (part[1][0], base);
-	  part[1][1] = replace_equiv_address (part[1][1],
-				      plus_constant (base, UNITS_PER_WORD));
-	  if (nparts == 3)
-	    part[1][2] = replace_equiv_address (part[1][2],
-				      plus_constant (base, 8));
+	  for (i = 1; i < nparts; i++)
+	    {
+	      tmp = plus_constant (base, UNITS_PER_WORD * i);
+	      part[1][i] = replace_equiv_address (part[1][i], tmp);
+	    }
 	}
     }
 
@@ -14408,6 +14425,11 @@ ix86_split_long_move (rtx operands[])
                 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4)));
 	      emit_move_insn (part[0][2], part[1][2]);
 	    }
+	  else if (nparts == 4)
+	    {
+	      emit_move_insn (part[0][3], part[1][3]);
+	      emit_move_insn (part[0][2], part[1][2]);
+	    }
 	}
       else
 	{
@@ -14445,77 +14467,42 @@ ix86_split_long_move (rtx operands[])
        && REG_P (part[1][1])
        && (REGNO (part[0][0]) == REGNO (part[1][1])
 	   || (nparts == 3
-	       && REGNO (part[0][0]) == REGNO (part[1][2]))))
+	       && REGNO (part[0][0]) == REGNO (part[1][2]))
+	   || (nparts == 4
+	       && REGNO (part[0][0]) == REGNO (part[1][3]))))
       || (collisions > 0
 	  && reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0))))
     {
-      if (nparts == 3)
-	{
-	  operands[2] = part[0][2];
-	  operands[3] = part[0][1];
-	  operands[4] = part[0][0];
-	  operands[5] = part[1][2];
-	  operands[6] = part[1][1];
-	  operands[7] = part[1][0];
-	}
-      else
+      for (i = 0, j = nparts - 1; i < nparts; i++, j--)
 	{
-	  operands[2] = part[0][1];
-	  operands[3] = part[0][0];
-	  operands[5] = part[1][1];
-	  operands[6] = part[1][0];
+	  operands[2 + i] = part[0][j];
+	  operands[6 + i] = part[1][j];
 	}
     }
   else
     {
-      if (nparts == 3)
-	{
-	  operands[2] = part[0][0];
-	  operands[3] = part[0][1];
-	  operands[4] = part[0][2];
-	  operands[5] = part[1][0];
-	  operands[6] = part[1][1];
-	  operands[7] = part[1][2];
-	}
-      else
+      for (i = 0; i < nparts; i++)
 	{
-	  operands[2] = part[0][0];
-	  operands[3] = part[0][1];
-	  operands[5] = part[1][0];
-	  operands[6] = part[1][1];
+	  operands[2 + i] = part[0][i];
+	  operands[6 + i] = part[1][i];
 	}
     }
 
   /* If optimizing for size, attempt to locally unCSE nonzero constants.  */
   if (optimize_size)
     {
-      if (CONST_INT_P (operands[5])
-	  && operands[5] != const0_rtx
-	  && REG_P (operands[2]))
-	{
-	  if (CONST_INT_P (operands[6])
-	      && INTVAL (operands[6]) == INTVAL (operands[5]))
-	    operands[6] = operands[2];
-
-	  if (nparts == 3
-	      && CONST_INT_P (operands[7])
-	      && INTVAL (operands[7]) == INTVAL (operands[5]))
-	    operands[7] = operands[2];
-	}
-
-      if (nparts == 3
-	  && CONST_INT_P (operands[6])
-	  && operands[6] != const0_rtx
-	  && REG_P (operands[3])
-	  && CONST_INT_P (operands[7])
-	  && INTVAL (operands[7]) == INTVAL (operands[6]))
-	operands[7] = operands[3];
-    }
-
-  emit_move_insn (operands[2], operands[5]);
-  emit_move_insn (operands[3], operands[6]);
-  if (nparts == 3)
-    emit_move_insn (operands[4], operands[7]);
+      for (j = 0; j < nparts - 1; j++)
+	if (CONST_INT_P (operands[6 + j])
+	    && operands[6 + j] != const0_rtx
+	    && REG_P (operands[2 + j]))
+	  for (i = j; i < nparts - 1; i++)
+	    if (CONST_INT_P (operands[7 + i])
+		&& INTVAL (operands[7 + i]) == INTVAL (operands[6 + j]))
+	      operands[7 + i] = operands[2 + j];
+    }
+
+  for (i = 0; i < nparts; i++)
+    emit_move_insn (operands[2 + i], operands[6 + i]);
 
   return;
 }
@@ -18707,6 +18694,9 @@ static const struct builtin_description 
 
   { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmsqrtv2df2, "__builtin_ia32_sqrtsd", IX86_BUILTIN_SQRTSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_VEC_MERGE },
 
+  { OPTION_MASK_ISA_SSE2, CODE_FOR_abstf2, 0, IX86_BUILTIN_FABSQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128 },
+  { OPTION_MASK_ISA_SSE2, CODE_FOR_copysigntf3, 0, IX86_BUILTIN_COPYSIGNQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128_FLOAT128 },
+
   /* SSE2 MMX */
   { OPTION_MASK_ISA_SSE2, CODE_FOR_mmx_addv1di3, "__builtin_ia32_paddq", IX86_BUILTIN_PADDQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI },
   { OPTION_MASK_ISA_SSE2, CODE_FOR_mmx_subv1di3, "__builtin_ia32_psubq", IX86_BUILTIN_PSUBQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI },
@@ -18832,10 +18822,6 @@ static const struct builtin_description 
 
   /* PCLMUL */
   { OPTION_MASK_ISA_SSE2, CODE_FOR_pclmulqdq, 0, IX86_BUILTIN_PCLMULQDQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT },
-
-   /* 64bit */
-  { OPTION_MASK_ISA_64BIT, CODE_FOR_abstf2, 0, IX86_BUILTIN_FABSQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128 },
-  { OPTION_MASK_ISA_64BIT, CODE_FOR_copysigntf3, 0, IX86_BUILTIN_COPYSIGNQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128_FLOAT128 },
 };
 
 /* SSE5 */
@@ -19633,47 +19619,6 @@ ix86_init_mmx_sse_builtins (void)
 
   tree ftype;
 
-  /* The __float80 type.  */
-  if (TYPE_MODE (long_double_type_node) == XFmode)
-    (*lang_hooks.types.register_builtin_type) (long_double_type_node,
-					       "__float80");
-  else
-    {
-      /* The __float80 type.  */
-      tree float80_type_node = make_node (REAL_TYPE);
-
-      TYPE_PRECISION (float80_type_node) = 80;
-      layout_type (float80_type_node);
-      (*lang_hooks.types.register_builtin_type) (float80_type_node,
-						 "__float80");
-    }
-
-  if (TARGET_64BIT)
-    {
-      tree float128_type_node = make_node (REAL_TYPE);
-
-      TYPE_PRECISION (float128_type_node) = 128;
-      layout_type (float128_type_node);
-      (*lang_hooks.types.register_builtin_type) (float128_type_node,
-						 "__float128");
-
-      /* TFmode support builtins.  */
-      ftype = build_function_type (float128_type_node,
-				   void_list_node);
-      def_builtin (OPTION_MASK_ISA_64BIT, "__builtin_infq", ftype, IX86_BUILTIN_INFQ);
-
-      ftype = build_function_type_list (float128_type_node,
-					float128_type_node,
-					NULL_TREE);
-      def_builtin_const (OPTION_MASK_ISA_64BIT, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
-
-      ftype = build_function_type_list (float128_type_node,
-					float128_type_node,
-					float128_type_node,
-					NULL_TREE);
-      def_builtin_const (OPTION_MASK_ISA_64BIT, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
-    }
-
   /* Add all special builtins with variable number of operands.  */
   for (i = 0, d = bdesc_special_args;
        i < ARRAY_SIZE (bdesc_special_args);
@@ -20279,6 +20224,52 @@ ix86_init_mmx_sse_builtins (void)
 static void
 ix86_init_builtins (void)
 {
+  tree float128_type_node = make_node (REAL_TYPE);
+  tree ftype, decl;
+
+  /* The __float80 type.  */
+  if (TYPE_MODE (long_double_type_node) == XFmode)
+    (*lang_hooks.types.register_builtin_type) (long_double_type_node,
+					       "__float80");
+  else
+    {
+      /* The __float80 type.  */
+      tree float80_type_node = make_node (REAL_TYPE);
+
+      TYPE_PRECISION (float80_type_node) = 80;
+      layout_type (float80_type_node);
+      (*lang_hooks.types.register_builtin_type) (float80_type_node,
+						 "__float80");
+    }
+
+  /* The __float128 type.  */
+  TYPE_PRECISION (float128_type_node) = 128;
+  layout_type (float128_type_node);
+  (*lang_hooks.types.register_builtin_type) (float128_type_node,
+					     "__float128");
+
+  /* TFmode support builtins.  */
+  ftype = build_function_type (float128_type_node, void_list_node);
+  decl = add_builtin_function ("__builtin_infq", ftype,
+			       IX86_BUILTIN_INFQ, BUILT_IN_MD,
+			       NULL, NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_INFQ] = decl;
+
+  if (HOST_BITS_PER_WIDE_INT >= 64)
+    {
+      /* Those builtins need TImode to compile.  */
+      ftype = build_function_type_list (float128_type_node,
+					float128_type_node,
+					NULL_TREE);
+      def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
+
+      ftype = build_function_type_list (float128_type_node,
+					float128_type_node,
+					float128_type_node,
+					NULL_TREE);
+      def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
+    }
+
   if (TARGET_MMX)
     ix86_init_mmx_sse_builtins ();
 }
@@ -24735,7 +24726,7 @@ ix86_scalar_mode_supported_p (enum machi
   if (DECIMAL_FLOAT_MODE_P (mode))
     return true;
   else if (mode == TFmode)
-    return TARGET_64BIT;
+    return true;
   else
     return default_scalar_mode_supported_p (mode);
 }
@@ -24759,9 +24750,9 @@ ix86_vector_mode_supported_p (enum machi
 static enum machine_mode
 ix86_c_mode_for_suffix (char suffix)
 {
-  if (TARGET_64BIT && suffix == 'q')
+  if (suffix == 'q')
     return TFmode;
-  if (TARGET_MMX && suffix == 'w')
+  if (suffix == 'w')
     return XFmode;
 
   return VOIDmode;
--- gcc/config/i386/i386.md.float128	2008-06-30 07:13:07.000000000 -0700
+++ gcc/config/i386/i386.md	2008-06-30 07:13:08.000000000 -0700
@@ -3261,7 +3261,7 @@
 (define_expand "movtf"
   [(set (match_operand:TF 0 "nonimmediate_operand" "")
 	(match_operand:TF 1 "nonimmediate_operand" ""))]
-  "TARGET_64BIT"
+  "TARGET_SSE2"
 {
   ix86_expand_move (TFmode, operands);
   DONE;
@@ -3270,7 +3270,7 @@
 (define_insn "*movtf_internal"
   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
 	(match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
-  "TARGET_64BIT
+  "TARGET_SSE2
    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
 {
   switch (which_alternative)
@@ -10348,7 +10348,7 @@
 (define_expand "<code>tf2"
   [(set (match_operand:TF 0 "register_operand" "")
 	(absneg:TF (match_operand:TF 1 "register_operand" "")))]
-  "TARGET_64BIT"
+  "TARGET_SSE2"
   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
 
 (define_insn "*absnegtf2_sse"
@@ -10357,7 +10357,7 @@
 	  [(match_operand:TF 1 "register_operand" "0,x")]))
    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT"
+  "TARGET_SSE2"
   "#")
 
 ;; Splitters for fp abs and neg.
@@ -10536,7 +10536,7 @@
    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
    (match_operand:CSGNMODE 2 "register_operand" "")]
   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
-   || (TARGET_64BIT && (<MODE>mode == TFmode))"
+   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
 {
   ix86_expand_copysign (operands);
   DONE;
@@ -10550,7 +10550,7 @@
 	   (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
 	  UNSPEC_COPYSIGN))]
   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
-   || (TARGET_64BIT && (<MODE>mode == TFmode))"
+   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
   "#"
   "&& reload_completed"
   [(const_int 0)]
@@ -10569,7 +10569,7 @@
 	  UNSPEC_COPYSIGN))
    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
-   || (TARGET_64BIT && (<MODE>mode == TFmode))"
+   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
   "#")
 
 (define_split
@@ -10582,7 +10582,7 @@
 	  UNSPEC_COPYSIGN))
    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
-    || (TARGET_64BIT && (<MODE>mode == TFmode)))
+    || (TARGET_SSE2 && (<MODE>mode == TFmode)))
    && reload_completed"
   [(const_int 0)]
 {
--- gcc/config/i386/sse.md.float128	2008-05-21 17:24:11.000000000 -0700
+++ gcc/config/i386/sse.md	2008-06-30 07:13:08.000000000 -0700
@@ -3895,7 +3895,7 @@
 	(and:TF
 	  (not:TF (match_operand:TF 1 "register_operand" "0"))
 	  (match_operand:TF 2 "nonimmediate_operand" "xm")))]
-  "TARGET_64BIT"
+  "TARGET_SSE2"
   "pandn\t{%2, %0|%0, %2}"
   [(set_attr "type" "sselog")
    (set_attr "prefix_data16" "1")
@@ -3936,7 +3936,7 @@
 	(plogic:TF
 	  (match_operand:TF 1 "nonimmediate_operand" "")
 	  (match_operand:TF 2 "nonimmediate_operand" "")))]
-  "TARGET_64BIT"
+  "TARGET_SSE2"
   "ix86_fixup_binary_operands_no_copy (<CODE>, TFmode, operands);")
 
 (define_insn "*<code>tf3"
@@ -3944,7 +3944,7 @@
 	(plogic:TF
 	  (match_operand:TF 1 "nonimmediate_operand" "%0")
 	  (match_operand:TF 2 "nonimmediate_operand" "xm")))]
-  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, TFmode, operands)"
+  "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, TFmode, operands)"
   "p<plogicprefix>\t{%2, %0|%0, %2}"
   [(set_attr "type" "sselog")
    (set_attr "prefix_data16" "1")

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-30 17:53                   ` H.J. Lu
@ 2008-06-30 18:10                     ` Uros Bizjak
  0 siblings, 0 replies; 32+ messages in thread
From: Uros Bizjak @ 2008-06-30 18:10 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Joseph S. Myers, GCC Patches, Ian Lance Taylor

H.J. Lu wrote:
> On Mon, Jun 30, 2008 at 06:14:27PM +0200, Uros Bizjak wrote:
>   
>> H.J. Lu wrote:
>>     
>>> On Mon, Jun 30, 2008 at 02:47:11PM +0200, Uros Bizjak wrote:
>>>   
>>>       
>>>> On Mon, Jun 30, 2008 at 2:09 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>>
>>>> This is wrong, carry flag propagation is broken between these two asm
>>>> insns. Also, clobbers should be added (please look at attached
>>>> source).
>>>>
>>>> Attached to this message, please find definitions of
>>>> __FP_FRAC_{ADD,SUB}_{3,4} macros, together with a test application.
>>>>
>>>>     
>>>>         
>>> Here is the updated patch. I had to comment out __FP_FRAC_SUB_4
>>> since I got
>>>
>>> /export/gnu/src/gcc/gcc/libgcc/../gcc/config/soft-fp/divtf3.c:44:
>>> error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
>>> /export/gnu/src/gcc/gcc/libgcc/../gcc/config/soft-fp/divtf3.c:44: error: ‘asm’ operand has impossible constraints
>>>
>>> OK for trunk?  Thanks.
>>>   
>>>       
>> This is OK for mainline, but please resolve with Joseph about libgcc  
>> versioning issues. Also, please wait a couple of hours for possible  
>> Ian's comments (CC'd; he is libgcc maintainer, so he has the last say on  
>> this matter.).
>>
>>     
>
> Here is the updated x86 backend patch. Since __float80 is enabled
> unconditionally, I changed ix86_c_mode_for_suffix to return XFmode
> for 'w'.  OK for trunk?
>   

Since this is now pure i386 patch, it is OK for mainline.

Thanks,
Uros.

> Thanks.
>
>
> H.J.
> ---
> 2008-06-28  H.J. Lu  <hongjiu.lu@intel.com>
>
> 	* config/i386/i386.c (contains_aligned_value_p): Return true
> 	for __float128.
> 	(ix86_function_arg_boundary): Return its natural boundary for
> 	for __float128.
> 	(return_in_memory_32): Don't check TDmode.
> 	(ix86_split_to_parts): Support splitting into 4 parts and
> 	support TFmode for 32bit target.
> 	(ix86_split_long_move): Support splitting into 4 parts.
> 	(bdesc_args): Enable IX86_BUILTIN_FABSQ and IX86_BUILTIN_COPYSIGNQ
> 	for SSE2.
> 	(ix86_init_mmx_sse_builtins): Move __float80 and __float128
> 	to ...
> 	(ix86_init_builtins): Here.
> 	(ix86_scalar_mode_supported_p): Always return true for TFmode.
> 	(ix86_c_mode_for_suffix): Always return TFmode and XFmode for
> 	'q' and 'w', respectively. 
>
> 	* config/i386/i386.md (movtf): Check TARGET_SSE2 instead of
> 	TARGET_64BIT.
> 	(movtf_internal): Likewise.
> 	(<code>tf2): Likewise.
> 	(*absnegtf2_sse): Likewise.
> 	(copysign<mode>3): Likewise.
> 	(copysign<mode>3_const): Likewise.
> 	(copysign<mode>3_var): Likewise.
> 	(define_split UNSPEC_COPYSIGN): Likewise.
> 	* config/i386/sse.md (*nandtf3): Likewise.
> 	(<code>tf3): Likewise.
> 	(*<code>tf3): Likewise.
>
> --- gcc/config/i386/i386.c.float128	2008-06-30 07:13:07.000000000 -0700
> +++ gcc/config/i386/i386.c	2008-06-30 10:21:53.000000000 -0700
> @@ -4748,7 +4748,9 @@ static bool
>  contains_aligned_value_p (tree type)
>  {
>    enum machine_mode mode = TYPE_MODE (type);
> -  if (((TARGET_SSE && SSE_REG_MODE_P (mode)) || mode == TDmode)
> +  if (((TARGET_SSE && SSE_REG_MODE_P (mode))
> +       || mode == TDmode
> +       || mode == TFmode)
>        && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
>      return true;
>    if (TYPE_ALIGN (type) < 128)
> @@ -4807,8 +4809,9 @@ ix86_function_arg_boundary (enum machine
>      align = GET_MODE_ALIGNMENT (mode);
>    if (align < PARM_BOUNDARY)
>      align = PARM_BOUNDARY;
> -  /* In 32bit, only _Decimal128 is aligned to its natural boundary.  */
> -  if (!TARGET_64BIT && mode != TDmode)
> +  /* In 32bit, only _Decimal128 and __float128 are aligned to their
> +     natural boundaries.  */
> +  if (!TARGET_64BIT && mode != TDmode && mode != TFmode)
>      {
>        /* i386 ABI defines all arguments to be 4 byte aligned.  We have to
>  	 make an exception for SSE modes since these require 128bit
> @@ -4819,7 +4822,7 @@ ix86_function_arg_boundary (enum machine
>  	 to 8 byte boundaries.  */
>        if (!type)
>  	{
> -	  if (!(TARGET_SSE && SSE_REG_MODE_P (mode)) && mode != TDmode)
> +	  if (!(TARGET_SSE && SSE_REG_MODE_P (mode)))
>  	    align = PARM_BOUNDARY;
>  	}
>        else
> @@ -5045,9 +5048,6 @@ return_in_memory_32 (const_tree type, en
>    if (mode == XFmode)
>      return 0;
>  
> -  if (mode == TDmode)
> -    return 1;
> -
>    if (size > 12)
>      return 1;
>    return 0;
> @@ -14155,7 +14155,7 @@ ix86_split_to_parts (rtx operand, rtx *p
>      size = (GET_MODE_SIZE (mode) + 4) / 8;
>  
>    gcc_assert (!REG_P (operand) || !MMX_REGNO_P (REGNO (operand)));
> -  gcc_assert (size >= 2 && size <= 3);
> +  gcc_assert (size >= 2 && size <= 4);
>  
>    /* Optimize constant pool reference to immediates.  This is used by fp
>       moves, that force all constants to memory to allow combining.  */
> @@ -14175,7 +14175,7 @@ ix86_split_to_parts (rtx operand, rtx *p
>  
>        operand = copy_rtx (operand);
>        PUT_MODE (operand, Pmode);
> -      parts[0] = parts[1] = parts[2] = operand;
> +      parts[0] = parts[1] = parts[2] = parts[3] = operand;
>        return size;
>      }
>  
> @@ -14196,21 +14196,20 @@ ix86_split_to_parts (rtx operand, rtx *p
>  	split_di (&operand, 1, &parts[0], &parts[1]);
>        else
>  	{
> +	  int i;
> +
>  	  if (REG_P (operand))
>  	    {
>  	      gcc_assert (reload_completed);
> -	      parts[0] = gen_rtx_REG (SImode, REGNO (operand) + 0);
> -	      parts[1] = gen_rtx_REG (SImode, REGNO (operand) + 1);
> -	      if (size == 3)
> -		parts[2] = gen_rtx_REG (SImode, REGNO (operand) + 2);
> +	      for (i = 0; i < size; i++)
> +		parts[i] = gen_rtx_REG (SImode, REGNO (operand) + i);
>  	    }
>  	  else if (offsettable_memref_p (operand))
>  	    {
>  	      operand = adjust_address (operand, SImode, 0);
>  	      parts[0] = operand;
> -	      parts[1] = adjust_address (operand, SImode, 4);
> -	      if (size == 3)
> -		parts[2] = adjust_address (operand, SImode, 8);
> +	      for (i = 1; i < size; i++)
> +		parts[i] = adjust_address (operand, SImode, 4 * i);
>  	    }
>  	  else if (GET_CODE (operand) == CONST_DOUBLE)
>  	    {
> @@ -14220,6 +14219,11 @@ ix86_split_to_parts (rtx operand, rtx *p
>  	      REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
>  	      switch (mode)
>  		{
> +		case TFmode:
> +		  real_to_target (l, &r, mode);
> +		  parts[3] = gen_int_mode (l[3], SImode);
> +		  parts[2] = gen_int_mode (l[2], SImode);
> +		  break;
>  		case XFmode:
>  		  REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
>  		  parts[2] = gen_int_mode (l[2], SImode);
> @@ -14293,7 +14297,7 @@ ix86_split_to_parts (rtx operand, rtx *p
>    return size;
>  }
>  
> -/* Emit insns to perform a move or push of DI, DF, and XF values.
> +/* Emit insns to perform a move or push of DI, DF, XF, and TF values.
>     Return false when normal moves are needed; true when all required
>     insns have been emitted.  Operands 2-4 contain the input values
>     int the correct order; operands 5-7 contain the output values.  */
> @@ -14301,11 +14305,12 @@ ix86_split_to_parts (rtx operand, rtx *p
>  void
>  ix86_split_long_move (rtx operands[])
>  {
> -  rtx part[2][3];
> -  int nparts;
> +  rtx part[2][4];
> +  int nparts, i, j;
>    int push = 0;
>    int collisions = 0;
>    enum machine_mode mode = GET_MODE (operands[0]);
> +  bool collisionparts[4];
>  
>    /* The DFmode expanders may ask us to move double.
>       For 64bit target this is single move.  By hiding the fact
> @@ -14344,34 +14349,46 @@ ix86_split_long_move (rtx operands[])
>    /* When emitting push, take care for source operands on the stack.  */
>    if (push && MEM_P (operands[1])
>        && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
> -    {
> -      if (nparts == 3)
> -	part[1][1] = change_address (part[1][1], GET_MODE (part[1][1]),
> -				     XEXP (part[1][2], 0));
> -      part[1][0] = change_address (part[1][0], GET_MODE (part[1][0]),
> -				   XEXP (part[1][1], 0));
> -    }
> +    for (i = 0; i < nparts - 1; i++)
> +      part[1][i] = change_address (part[1][i],
> +				   GET_MODE (part[1][i]),
> +				   XEXP (part[1][i + 1], 0));
>  
>    /* We need to do copy in the right order in case an address register
>       of the source overlaps the destination.  */
>    if (REG_P (part[0][0]) && MEM_P (part[1][0]))
>      {
> -      if (reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0)))
> -	collisions++;
> -      if (reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
> -	collisions++;
> -      if (nparts == 3
> -	  && reg_overlap_mentioned_p (part[0][2], XEXP (part[1][0], 0)))
> -	collisions++;
> +      rtx tmp;
> +
> +      for (i = 0; i < nparts; i++)
> +	{
> +	  collisionparts[i]
> +	    = reg_overlap_mentioned_p (part[0][i], XEXP (part[1][0], 0));
> +	  if (collisionparts[i])
> +	    collisions++;
> +	}
>  
>        /* Collision in the middle part can be handled by reordering.  */
> -      if (collisions == 1 && nparts == 3
> -	  && reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
> +      if (collisions == 1 && nparts == 3 && collisionparts [1])
>  	{
> -	  rtx tmp;
>  	  tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp;
>  	  tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp;
>  	}
> +      else if (collisions == 1
> +	       && nparts == 4
> +	       && (collisionparts [1] || collisionparts [2]))
> +	{
> +	  if (collisionparts [1])
> +	    {
> +	      tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp;
> +	      tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp;
> +	    }
> +	  else
> +	    {
> +	      tmp = part[0][2]; part[0][2] = part[0][3]; part[0][3] = tmp;
> +	      tmp = part[1][2]; part[1][2] = part[1][3]; part[1][3] = tmp;
> +	    }
> +	}
>  
>        /* If there are more collisions, we can't handle it by reordering.
>  	 Do an lea to the last part and use only one colliding move.  */
> @@ -14390,11 +14407,11 @@ ix86_split_long_move (rtx operands[])
>  
>  	  emit_insn (gen_rtx_SET (VOIDmode, base, XEXP (part[1][0], 0)));
>  	  part[1][0] = replace_equiv_address (part[1][0], base);
> -	  part[1][1] = replace_equiv_address (part[1][1],
> -				      plus_constant (base, UNITS_PER_WORD));
> -	  if (nparts == 3)
> -	    part[1][2] = replace_equiv_address (part[1][2],
> -				      plus_constant (base, 8));
> +	  for (i = 1; i < nparts; i++)
> +	    {
> +	      tmp = plus_constant (base, UNITS_PER_WORD * i);
> +	      part[1][i] = replace_equiv_address (part[1][i], tmp);
> +	    }
>  	}
>      }
>  
> @@ -14408,6 +14425,11 @@ ix86_split_long_move (rtx operands[])
>                  emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4)));
>  	      emit_move_insn (part[0][2], part[1][2]);
>  	    }
> +	  else if (nparts == 4)
> +	    {
> +	      emit_move_insn (part[0][3], part[1][3]);
> +	      emit_move_insn (part[0][2], part[1][2]);
> +	    }
>  	}
>        else
>  	{
> @@ -14445,77 +14467,42 @@ ix86_split_long_move (rtx operands[])
>         && REG_P (part[1][1])
>         && (REGNO (part[0][0]) == REGNO (part[1][1])
>  	   || (nparts == 3
> -	       && REGNO (part[0][0]) == REGNO (part[1][2]))))
> +	       && REGNO (part[0][0]) == REGNO (part[1][2]))
> +	   || (nparts == 4
> +	       && REGNO (part[0][0]) == REGNO (part[1][3]))))
>        || (collisions > 0
>  	  && reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0))))
>      {
> -      if (nparts == 3)
> -	{
> -	  operands[2] = part[0][2];
> -	  operands[3] = part[0][1];
> -	  operands[4] = part[0][0];
> -	  operands[5] = part[1][2];
> -	  operands[6] = part[1][1];
> -	  operands[7] = part[1][0];
> -	}
> -      else
> +      for (i = 0, j = nparts - 1; i < nparts; i++, j--)
>  	{
> -	  operands[2] = part[0][1];
> -	  operands[3] = part[0][0];
> -	  operands[5] = part[1][1];
> -	  operands[6] = part[1][0];
> +	  operands[2 + i] = part[0][j];
> +	  operands[6 + i] = part[1][j];
>  	}
>      }
>    else
>      {
> -      if (nparts == 3)
> -	{
> -	  operands[2] = part[0][0];
> -	  operands[3] = part[0][1];
> -	  operands[4] = part[0][2];
> -	  operands[5] = part[1][0];
> -	  operands[6] = part[1][1];
> -	  operands[7] = part[1][2];
> -	}
> -      else
> +      for (i = 0; i < nparts; i++)
>  	{
> -	  operands[2] = part[0][0];
> -	  operands[3] = part[0][1];
> -	  operands[5] = part[1][0];
> -	  operands[6] = part[1][1];
> +	  operands[2 + i] = part[0][i];
> +	  operands[6 + i] = part[1][i];
>  	}
>      }
>  
>    /* If optimizing for size, attempt to locally unCSE nonzero constants.  */
>    if (optimize_size)
>      {
> -      if (CONST_INT_P (operands[5])
> -	  && operands[5] != const0_rtx
> -	  && REG_P (operands[2]))
> -	{
> -	  if (CONST_INT_P (operands[6])
> -	      && INTVAL (operands[6]) == INTVAL (operands[5]))
> -	    operands[6] = operands[2];
> -
> -	  if (nparts == 3
> -	      && CONST_INT_P (operands[7])
> -	      && INTVAL (operands[7]) == INTVAL (operands[5]))
> -	    operands[7] = operands[2];
> -	}
> -
> -      if (nparts == 3
> -	  && CONST_INT_P (operands[6])
> -	  && operands[6] != const0_rtx
> -	  && REG_P (operands[3])
> -	  && CONST_INT_P (operands[7])
> -	  && INTVAL (operands[7]) == INTVAL (operands[6]))
> -	operands[7] = operands[3];
> -    }
> -
> -  emit_move_insn (operands[2], operands[5]);
> -  emit_move_insn (operands[3], operands[6]);
> -  if (nparts == 3)
> -    emit_move_insn (operands[4], operands[7]);
> +      for (j = 0; j < nparts - 1; j++)
> +	if (CONST_INT_P (operands[6 + j])
> +	    && operands[6 + j] != const0_rtx
> +	    && REG_P (operands[2 + j]))
> +	  for (i = j; i < nparts - 1; i++)
> +	    if (CONST_INT_P (operands[7 + i])
> +		&& INTVAL (operands[7 + i]) == INTVAL (operands[6 + j]))
> +	      operands[7 + i] = operands[2 + j];
> +    }
> +
> +  for (i = 0; i < nparts; i++)
> +    emit_move_insn (operands[2 + i], operands[6 + i]);
>  
>    return;
>  }
> @@ -18707,6 +18694,9 @@ static const struct builtin_description 
>  
>    { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmsqrtv2df2, "__builtin_ia32_sqrtsd", IX86_BUILTIN_SQRTSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_VEC_MERGE },
>  
> +  { OPTION_MASK_ISA_SSE2, CODE_FOR_abstf2, 0, IX86_BUILTIN_FABSQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128 },
> +  { OPTION_MASK_ISA_SSE2, CODE_FOR_copysigntf3, 0, IX86_BUILTIN_COPYSIGNQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128_FLOAT128 },
> +
>    /* SSE2 MMX */
>    { OPTION_MASK_ISA_SSE2, CODE_FOR_mmx_addv1di3, "__builtin_ia32_paddq", IX86_BUILTIN_PADDQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI },
>    { OPTION_MASK_ISA_SSE2, CODE_FOR_mmx_subv1di3, "__builtin_ia32_psubq", IX86_BUILTIN_PSUBQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI },
> @@ -18832,10 +18822,6 @@ static const struct builtin_description 
>  
>    /* PCLMUL */
>    { OPTION_MASK_ISA_SSE2, CODE_FOR_pclmulqdq, 0, IX86_BUILTIN_PCLMULQDQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT },
> -
> -   /* 64bit */
> -  { OPTION_MASK_ISA_64BIT, CODE_FOR_abstf2, 0, IX86_BUILTIN_FABSQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128 },
> -  { OPTION_MASK_ISA_64BIT, CODE_FOR_copysigntf3, 0, IX86_BUILTIN_COPYSIGNQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128_FLOAT128 },
>  };
>  
>  /* SSE5 */
> @@ -19633,47 +19619,6 @@ ix86_init_mmx_sse_builtins (void)
>  
>    tree ftype;
>  
> -  /* The __float80 type.  */
> -  if (TYPE_MODE (long_double_type_node) == XFmode)
> -    (*lang_hooks.types.register_builtin_type) (long_double_type_node,
> -					       "__float80");
> -  else
> -    {
> -      /* The __float80 type.  */
> -      tree float80_type_node = make_node (REAL_TYPE);
> -
> -      TYPE_PRECISION (float80_type_node) = 80;
> -      layout_type (float80_type_node);
> -      (*lang_hooks.types.register_builtin_type) (float80_type_node,
> -						 "__float80");
> -    }
> -
> -  if (TARGET_64BIT)
> -    {
> -      tree float128_type_node = make_node (REAL_TYPE);
> -
> -      TYPE_PRECISION (float128_type_node) = 128;
> -      layout_type (float128_type_node);
> -      (*lang_hooks.types.register_builtin_type) (float128_type_node,
> -						 "__float128");
> -
> -      /* TFmode support builtins.  */
> -      ftype = build_function_type (float128_type_node,
> -				   void_list_node);
> -      def_builtin (OPTION_MASK_ISA_64BIT, "__builtin_infq", ftype, IX86_BUILTIN_INFQ);
> -
> -      ftype = build_function_type_list (float128_type_node,
> -					float128_type_node,
> -					NULL_TREE);
> -      def_builtin_const (OPTION_MASK_ISA_64BIT, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
> -
> -      ftype = build_function_type_list (float128_type_node,
> -					float128_type_node,
> -					float128_type_node,
> -					NULL_TREE);
> -      def_builtin_const (OPTION_MASK_ISA_64BIT, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
> -    }
> -
>    /* Add all special builtins with variable number of operands.  */
>    for (i = 0, d = bdesc_special_args;
>         i < ARRAY_SIZE (bdesc_special_args);
> @@ -20279,6 +20224,52 @@ ix86_init_mmx_sse_builtins (void)
>  static void
>  ix86_init_builtins (void)
>  {
> +  tree float128_type_node = make_node (REAL_TYPE);
> +  tree ftype, decl;
> +
> +  /* The __float80 type.  */
> +  if (TYPE_MODE (long_double_type_node) == XFmode)
> +    (*lang_hooks.types.register_builtin_type) (long_double_type_node,
> +					       "__float80");
> +  else
> +    {
> +      /* The __float80 type.  */
> +      tree float80_type_node = make_node (REAL_TYPE);
> +
> +      TYPE_PRECISION (float80_type_node) = 80;
> +      layout_type (float80_type_node);
> +      (*lang_hooks.types.register_builtin_type) (float80_type_node,
> +						 "__float80");
> +    }
> +
> +  /* The __float128 type.  */
> +  TYPE_PRECISION (float128_type_node) = 128;
> +  layout_type (float128_type_node);
> +  (*lang_hooks.types.register_builtin_type) (float128_type_node,
> +					     "__float128");
> +
> +  /* TFmode support builtins.  */
> +  ftype = build_function_type (float128_type_node, void_list_node);
> +  decl = add_builtin_function ("__builtin_infq", ftype,
> +			       IX86_BUILTIN_INFQ, BUILT_IN_MD,
> +			       NULL, NULL_TREE);
> +  ix86_builtins[(int) IX86_BUILTIN_INFQ] = decl;
> +
> +  if (HOST_BITS_PER_WIDE_INT >= 64)
> +    {
> +      /* Those builtins need TImode to compile.  */
> +      ftype = build_function_type_list (float128_type_node,
> +					float128_type_node,
> +					NULL_TREE);
> +      def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
> +
> +      ftype = build_function_type_list (float128_type_node,
> +					float128_type_node,
> +					float128_type_node,
> +					NULL_TREE);
> +      def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
> +    }
> +
>    if (TARGET_MMX)
>      ix86_init_mmx_sse_builtins ();
>  }
> @@ -24735,7 +24726,7 @@ ix86_scalar_mode_supported_p (enum machi
>    if (DECIMAL_FLOAT_MODE_P (mode))
>      return true;
>    else if (mode == TFmode)
> -    return TARGET_64BIT;
> +    return true;
>    else
>      return default_scalar_mode_supported_p (mode);
>  }
> @@ -24759,9 +24750,9 @@ ix86_vector_mode_supported_p (enum machi
>  static enum machine_mode
>  ix86_c_mode_for_suffix (char suffix)
>  {
> -  if (TARGET_64BIT && suffix == 'q')
> +  if (suffix == 'q')
>      return TFmode;
> -  if (TARGET_MMX && suffix == 'w')
> +  if (suffix == 'w')
>      return XFmode;
>  
>    return VOIDmode;
> --- gcc/config/i386/i386.md.float128	2008-06-30 07:13:07.000000000 -0700
> +++ gcc/config/i386/i386.md	2008-06-30 07:13:08.000000000 -0700
> @@ -3261,7 +3261,7 @@
>  (define_expand "movtf"
>    [(set (match_operand:TF 0 "nonimmediate_operand" "")
>  	(match_operand:TF 1 "nonimmediate_operand" ""))]
> -  "TARGET_64BIT"
> +  "TARGET_SSE2"
>  {
>    ix86_expand_move (TFmode, operands);
>    DONE;
> @@ -3270,7 +3270,7 @@
>  (define_insn "*movtf_internal"
>    [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
>  	(match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
> -  "TARGET_64BIT
> +  "TARGET_SSE2
>     && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
>  {
>    switch (which_alternative)
> @@ -10348,7 +10348,7 @@
>  (define_expand "<code>tf2"
>    [(set (match_operand:TF 0 "register_operand" "")
>  	(absneg:TF (match_operand:TF 1 "register_operand" "")))]
> -  "TARGET_64BIT"
> +  "TARGET_SSE2"
>    "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
>  
>  (define_insn "*absnegtf2_sse"
> @@ -10357,7 +10357,7 @@
>  	  [(match_operand:TF 1 "register_operand" "0,x")]))
>     (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
>     (clobber (reg:CC FLAGS_REG))]
> -  "TARGET_64BIT"
> +  "TARGET_SSE2"
>    "#")
>  
>  ;; Splitters for fp abs and neg.
> @@ -10536,7 +10536,7 @@
>     (match_operand:CSGNMODE 1 "nonmemory_operand" "")
>     (match_operand:CSGNMODE 2 "register_operand" "")]
>    "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
> -   || (TARGET_64BIT && (<MODE>mode == TFmode))"
> +   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
>  {
>    ix86_expand_copysign (operands);
>    DONE;
> @@ -10550,7 +10550,7 @@
>  	   (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
>  	  UNSPEC_COPYSIGN))]
>    "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
> -   || (TARGET_64BIT && (<MODE>mode == TFmode))"
> +   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
>    "#"
>    "&& reload_completed"
>    [(const_int 0)]
> @@ -10569,7 +10569,7 @@
>  	  UNSPEC_COPYSIGN))
>     (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
>    "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
> -   || (TARGET_64BIT && (<MODE>mode == TFmode))"
> +   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
>    "#")
>  
>  (define_split
> @@ -10582,7 +10582,7 @@
>  	  UNSPEC_COPYSIGN))
>     (clobber (match_scratch:<CSGNVMODE> 1 ""))]
>    "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
> -    || (TARGET_64BIT && (<MODE>mode == TFmode)))
> +    || (TARGET_SSE2 && (<MODE>mode == TFmode)))
>     && reload_completed"
>    [(const_int 0)]
>  {
> --- gcc/config/i386/sse.md.float128	2008-05-21 17:24:11.000000000 -0700
> +++ gcc/config/i386/sse.md	2008-06-30 07:13:08.000000000 -0700
> @@ -3895,7 +3895,7 @@
>  	(and:TF
>  	  (not:TF (match_operand:TF 1 "register_operand" "0"))
>  	  (match_operand:TF 2 "nonimmediate_operand" "xm")))]
> -  "TARGET_64BIT"
> +  "TARGET_SSE2"
>    "pandn\t{%2, %0|%0, %2}"
>    [(set_attr "type" "sselog")
>     (set_attr "prefix_data16" "1")
> @@ -3936,7 +3936,7 @@
>  	(plogic:TF
>  	  (match_operand:TF 1 "nonimmediate_operand" "")
>  	  (match_operand:TF 2 "nonimmediate_operand" "")))]
> -  "TARGET_64BIT"
> +  "TARGET_SSE2"
>    "ix86_fixup_binary_operands_no_copy (<CODE>, TFmode, operands);")
>  
>  (define_insn "*<code>tf3"
> @@ -3944,7 +3944,7 @@
>  	(plogic:TF
>  	  (match_operand:TF 1 "nonimmediate_operand" "%0")
>  	  (match_operand:TF 2 "nonimmediate_operand" "xm")))]
> -  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, TFmode, operands)"
> +  "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, TFmode, operands)"
>    "p<plogicprefix>\t{%2, %0|%0, %2}"
>    [(set_attr "type" "sselog")
>     (set_attr "prefix_data16" "1")
>
>   

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-30 15:22               ` H.J. Lu
  2008-06-30 16:22                 ` Uros Bizjak
@ 2008-06-30 19:33                 ` Uros Bizjak
  2008-07-01 21:53                   ` H.J. Lu
  1 sibling, 1 reply; 32+ messages in thread
From: Uros Bizjak @ 2008-06-30 19:33 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Joseph S. Myers, GCC Patches

H.J. Lu wrote:

> Here is the updated patch. I had to comment out __FP_FRAC_SUB_4
> since I got
>
> /export/gnu/src/gcc/gcc/libgcc/../gcc/config/soft-fp/divtf3.c:44:
> error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
> /export/gnu/src/gcc/gcc/libgcc/../gcc/config/soft-fp/divtf3.c:44: error: ‘asm’ operand has impossible constraints
>   

Just change the last "g" into "im" in __FP_FRAC_SUB_4 and it will work. 
I hope that IRA solves this annoyance.

> +#if 0
> +/* FIXME: Reload doesn't work with it.  */
> +#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
> +  __asm__ ("sub{l} {%11,%3|%3,%11}\n\t"					\
> +	   "sbb{l} {%9,%2|%2,%9}\n\t"					\
> +	   "sbb{l} {%7,%1|%1,%7}\n\t"					\
> +	   "sbb{l} {%5,%0|%0,%5}"					\
> +	   : "=r" ((USItype) (r3)),					\
> +	     "=&r" ((USItype) (r2)),					\
> +	     "=&r" ((USItype) (r1)),					\
> +	     "=&r" ((USItype) (r0))					\
> +	   : "0" ((USItype) (x3)),					\
> +	     "g" ((USItype) (y3)),					\
> +	     "1" ((USItype) (x2)),					\
> +	     "g" ((USItype) (y2)),					\
> +	     "2" ((USItype) (x1)),					\
> +	     "g" ((USItype) (y1)),					\
> +	     "3" ((USItype) (x0)),					\
> +	     "g" ((USItype) (y0)))
> +#endif
>   

BTW: I have a preprocessed testcase, but the source looks like 
obfuscated-c contest winner. If anybody is interested, I can send it 
privatelly.

Uros.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-30 19:33                 ` Uros Bizjak
@ 2008-07-01 21:53                   ` H.J. Lu
  2008-07-01 22:02                     ` Joseph S. Myers
  0 siblings, 1 reply; 32+ messages in thread
From: H.J. Lu @ 2008-07-01 21:53 UTC (permalink / raw)
  To: Uros Bizjak, Ian Lance Taylor; +Cc: Joseph S. Myers, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 3120 bytes --]

Hi,

I decided to fix

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36669

while keeping the old version. It turns out that mkmap-symver.awk only
supports one version per symbol. My patch extends to multiple versions.
Since symbol version is only needed for shared library. I need to a way to
tell if we are compiling for shared library. I added -DSHARED to
shared-object.mk and provided backward compatibility for x86-64.

Also I have to enable _builtin_fabsq and __builtin_copysignq with fallbacks
since libgcc calls them when I define LIBGCC2_HAS_TF_MODE to 1 for
Linux/x86.

I am testing it on Linux/ia32, Linux/x86-64 and Linux/ia64. OK for trunk if
all pass?

Thanks.


H.J.
---
gcc/

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* config/i386/libgcc-glibc.ver: New.

	* config/i386/libgcc-x86_64-glibc.ver: Removed.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.  Add
	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
	i[34567]86-*-linux*, x86_64-*-linux*.

	* libgcc-std.ver: Add empty GCC_4.4.0.

	* mkmap-symver.awk: Support multiple versions per symbol.

	* config/i386/i386.c (ix86_init_builtins): Always define
	__builtin_fabsq and __builtin_copysignq with fallbacks.
	(ix86_expand_builtin): Emit normal call for __builtin_fabsq
	and __builtin_copysignq if SSE2 isn't available.

	* config/i386/linux.h (LIBGCC2_HAS_TF_MODE): Defined.
	(LIBGCC2_TF_CEXT): Likwise.
	(TF_SIZE): Likwise.

	* config/i386/linux64.h (LIBGCC2_HAS_TF_MODE): Defined as 1.

	* config/i386/sfp-machine.h: Moved to libgcc.

	* config/i386/sfp-machine.h: New.
	* config/i386/t-linux: Likwise.

	* config/i386/t-darwin: Remove softfp_wrap_start and
	softfp_wrap_end.
	* config/i386/t-darwin64: Likewise.

	* config/i386/t-fprules-softfp64: Renamed to ...
	* config/i386/t-fprules-softfp: This.

	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
	and softfp_wrap_end.

libgcc/

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* shared-object.mk ($(base)_s$(objext)): Add -DSHARED.

	* config/i386/64/_powitf2-compat.c: New.
	* config/i386/64/eqtf2.c: Likewise.
	* config/i386/64/getf2.c: Likewise.
	* config/i386/64/letf2.c: Likewise.
	* config/i386/64/t-fprules-softfp: Likewise.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	* config.host: Add i386/${host_address}/t-fprules-softfp to
	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.

	* configure.ac: Set host_address to 64 or 32 for x86.
	* configure: Regenerated.

	* Makefile.in (config.status): Also depend on
	$(srcdir)/config.host.

	* config/i386/32/t-fprules-softfp: New.
	* config/i386/32/tf-signs.c: Likewise.

	* config/i386/64/sfp-machine.h: New. Moved from gcc.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
	    Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/32/sfp-machine.h: New.

[-- Attachment #2: gcc-quad-11.patch --]
[-- Type: application/octet-stream, Size: 40493 bytes --]

gcc/

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* config/i386/libgcc-glibc.ver: New.

	* config/i386/libgcc-x86_64-glibc.ver: Removed.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.  Add
	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
	i[34567]86-*-linux*, x86_64-*-linux*.

	* libgcc-std.ver: Add empty GCC_4.4.0.

	* mkmap-symver.awk: Support multiple versions per symbol.

	* config/i386/i386.c (ix86_init_builtins): Always define
	__builtin_fabsq and __builtin_copysignq with fallbacks.
	(ix86_expand_builtin): Emit normal call for __builtin_fabsq
	and __builtin_copysignq if SSE2 isn't available.

	* config/i386/linux.h (LIBGCC2_HAS_TF_MODE): Defined.
	(LIBGCC2_TF_CEXT): Likwise.
	(TF_SIZE): Likwise.

	* config/i386/linux64.h (LIBGCC2_HAS_TF_MODE): Defined as 1.

	* config/i386/sfp-machine.h: Moved to libgcc.

	* config/i386/sfp-machine.h: New.
	* config/i386/t-linux: Likwise.

	* config/i386/t-darwin: Remove softfp_wrap_start and
	softfp_wrap_end.
	* config/i386/t-darwin64: Likewise.

	* config/i386/t-fprules-softfp64: Renamed to ...
	* config/i386/t-fprules-softfp: This.

	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
	and softfp_wrap_end.

libgcc/

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* shared-object.mk ($(base)_s$(objext)): Add -DSHARED.

	* config/i386/64/_powitf2-compat.c: New.
	* config/i386/64/eqtf2.c: Likewise.
	* config/i386/64/getf2.c: Likewise.
	* config/i386/64/letf2.c: Likewise.
	* config/i386/64/t-fprules-softfp: Likewise.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	* config.host: Add i386/${host_address}/t-fprules-softfp to
	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*. 

	* configure.ac: Set host_address to 64 or 32 for x86.
	* configure: Regenerated.

	* Makefile.in (config.status): Also depend on
	$(srcdir)/config.host.

	* config/i386/32/t-fprules-softfp: New.
	* config/i386/32/tf-signs.c: Likewise.

	* config/i386/64/sfp-machine.h: New. Moved from gcc.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
	    Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/32/sfp-machine.h: New.

--- gcc/gcc/config.gcc.quad	2008-06-27 08:52:44.000000000 -0700
+++ gcc/gcc/config.gcc	2008-07-01 09:30:35.000000000 -0700
@@ -1006,11 +1006,11 @@ i[34567]86-*-darwin*)
 	# then this file using that to set --with-cpu=i386 which has no -m64
 	# support.
 	with_cpu=${with_cpu:-generic}
-	tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 x86_64-*-darwin*)
 	with_cpu=${with_cpu:-generic}
-	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
 	tm_file="${tm_file} ${cpu_type}/darwin64.h"
 	;;
 i[34567]86-*-elf*)
@@ -1069,7 +1069,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
-			tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
+			tmake_file="${tmake_file} i386/t-linux64"
 			need_64bit_hwint=yes
 			case X"${with_cpu}" in
 			Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
@@ -1101,7 +1101,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
+	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-*-gnu*)
 	;;
@@ -2973,6 +2973,13 @@ case ${target} in
 		fi
 		;;
 
+	i[34567]86-*-darwin* | x86_64-*-darwin*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+		;;
+	i[34567]86-*-linux* | x86_64-*-linux*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
+		;;
+
 	mips*-*-*)
 		if test x$gnu_ld = xyes
 		then
--- gcc/gcc/config/i386/i386.c.quad	2008-07-01 12:49:55.000000000 -0700
+++ gcc/gcc/config/i386/i386.c	2008-07-01 13:57:56.000000000 -0700
@@ -20247,16 +20247,26 @@ ix86_init_builtins (void)
 			       NULL, NULL_TREE);
   ix86_builtins[(int) IX86_BUILTIN_INFQ] = decl;
 
+  /* We will expand them to normal call if SSE2 isn't available since
+     they are used by libgcc. */
   ftype = build_function_type_list (float128_type_node,
 				    float128_type_node,
 				    NULL_TREE);
-  def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
+  decl = add_builtin_function ("__builtin_fabsq", ftype,
+			       IX86_BUILTIN_FABSQ, BUILT_IN_MD,
+			       "__fabsq", NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_FABSQ] = decl;
+  TREE_READONLY (decl) = 1;
 
   ftype = build_function_type_list (float128_type_node,
 				    float128_type_node,
 				    float128_type_node,
 				    NULL_TREE);
-  def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
+  decl = add_builtin_function ("__builtin_copysignq", ftype,
+			       IX86_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
+			       "__copysignq", NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = decl;
+  TREE_READONLY (decl) = 1;
 
   if (TARGET_MMX)
     ix86_init_mmx_sse_builtins ();
@@ -21610,7 +21620,16 @@ ix86_expand_builtin (tree exp, rtx targe
        i < ARRAY_SIZE (bdesc_args);
        i++, d++)
     if (d->code == fcode)
-      return ix86_expand_args_builtin (d, exp, target);
+      switch (fcode)
+	{
+	case IX86_BUILTIN_FABSQ:
+	case IX86_BUILTIN_COPYSIGNQ:
+	  if (!TARGET_SSE2)
+	    /* Emit a normal call if SSE2 isn't available.  */
+	    return expand_call (exp, target, ignore);
+	default:
+	  return ix86_expand_args_builtin (d, exp, target);
+	}
 
   for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
     if (d->code == fcode)
--- gcc/gcc/config/i386/libgcc-glibc.ver.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-glibc.ver	2008-07-01 14:04:06.000000000 -0700
@@ -0,0 +1,170 @@
+# In order to work around the very problems that force us to now generally
+# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
+# By now choosing the same version tags for these specific routines, we
+# maintain enough binary compatibility to allow future versions of glibc
+# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
+
+%ifndef __x86_64__
+%inherit GCC_3.0 GLIBC_2.0
+GLIBC_2.0 {
+  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+
+  # Exception handling support functions used by most everyone.
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+%endif
+
+% 128 bit long double support was introduced with GCC 4.3.0 to 64bit
+% and with GCC 4.4.0 to 32bit.  These lines make the symbols to get
+% a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
+
+%ifdef __x86_64__
+%exclude {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+GCC_3.0 {
+  __gttf2
+  __lttf2
+  __netf2
+}
+
+GCC_4.0.0 {
+  __powitf2
+}
+
+GCC_4.3.0 {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%else
+%exclude {
+  __addtf3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2;
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+GCC_4.4.0 {
+  __addtf3
+  __copysignq
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fabsq
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%endif
--- gcc/gcc/config/i386/libgcc-x86_64-glibc.ver.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-x86_64-glibc.ver	2008-07-01 14:28:18.000000000 -0700
@@ -1,86 +0,0 @@
-# In order to work around the very problems that force us to now generally
-# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
-# By now choosing the same version tags for these specific routines, we
-# maintain enough binary compatibility to allow future versions of glibc
-# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
-
-%ifndef __x86_64__
-%inherit GCC_3.0 GLIBC_2.0
-GLIBC_2.0 {
-  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
-  __divdi3
-  __moddi3
-  __udivdi3
-  __umoddi3
-
-  # Exception handling support functions used by most everyone.
-  __register_frame
-  __register_frame_table
-  __deregister_frame
-  __register_frame_info
-  __deregister_frame_info
-  __frame_state_for
-  __register_frame_info_table
-}
-%endif
-
-% 128 bit long double support was introduced with GCC 4.3.0.
-% These lines make the symbols to get a @@GCC_4.3.0 attached.
-
-%ifdef __x86_64__
-%exclude {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-
-GCC_4.3.0 {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-%endif
--- gcc/gcc/config/i386/linux.h.quad	2008-04-26 09:19:19.000000000 -0700
+++ gcc/gcc/config/i386/linux.h	2008-07-01 09:30:35.000000000 -0700
@@ -189,6 +189,12 @@ along with GCC; see the file COPYING3.  
 	   : "=d"(BASE))
 #endif
 
+/* Put all *tf routines in libgcc.  */
+#undef LIBGCC2_HAS_TF_MODE
+#define LIBGCC2_HAS_TF_MODE 1
+#define LIBGCC2_TF_CEXT q
+#define TF_SIZE 113
+
 #undef NEED_INDICATE_EXEC_STACK
 #define NEED_INDICATE_EXEC_STACK 1
 
--- gcc/gcc/config/i386/linux64.h.quad	2007-08-04 16:50:17.000000000 -0700
+++ gcc/gcc/config/i386/linux64.h	2008-07-01 09:30:35.000000000 -0700
@@ -91,7 +91,7 @@ along with GCC; see the file COPYING3.  
 
 /* Put all *tf routines in libgcc.  */
 #undef LIBGCC2_HAS_TF_MODE
-#define LIBGCC2_HAS_TF_MODE TARGET_64BIT
+#define LIBGCC2_HAS_TF_MODE 1
 #define LIBGCC2_TF_CEXT q
 #define TF_SIZE 113
 
--- gcc/gcc/config/i386/sfp-machine.h.quad	2008-02-25 09:57:37.000000000 -0800
+++ gcc/gcc/config/i386/sfp-machine.h	2008-07-01 09:30:35.000000000 -0700
@@ -1,143 +1,5 @@
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-typedef int TItype __attribute__ ((mode (TI)));
-typedef unsigned int UTItype __attribute__ ((mode (TI)));
-
-#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
-
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
-#define _FP_MUL_MEAT_Q(R,X,Y)                           \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D
-#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_E		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID		0x01
-#define FP_EX_DENORM		0x02
-#define FP_EX_DIVZERO		0x04
-#define FP_EX_OVERFLOW		0x08
-#define FP_EX_UNDERFLOW		0x10
-#define FP_EX_INEXACT		0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS						\
-  do {									\
-    if (_fex & FP_EX_INVALID)						\
-      {									\
-	float f = 0.0;							\
-	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
-      }									\
-    if (_fex & FP_EX_DIVZERO)						\
-      {									\
-	float f = 1.0, g = 0.0;						\
-	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
-      }									\
-    if (_fex & FP_EX_OVERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_OVERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_UNDERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_UNDERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_INEXACT)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_INEXACT;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-  } while (0)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		0xc00
-#define FP_RND_PINF		0x800
-#define FP_RND_MINF		0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE			\
-  do {						\
-    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
-  } while (0)
-
-#define FP_ROUNDMODE		(_fcw & 0xc00)
-
-#define	__LITTLE_ENDIAN	1234
-#define	__BIG_ENDIAN	4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#ifdef __x86_64__
+#include "config/i386/64/sfp-machine.h"
 #else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#include "config/i386/32/sfp-machine.h"
 #endif
--- gcc/gcc/config/i386/t-darwin.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin	2008-07-01 09:30:35.000000000 -0700
@@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
 MULTILIB_DIRNAMES = x86_64
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-darwin64.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin64	2008-07-01 09:30:35.000000000 -0700
@@ -1,5 +1,2 @@
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-fprules-softfp.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp	2008-07-01 09:30:35.000000000 -0700
@@ -0,0 +1,6 @@
+softfp_float_modes := tf
+softfp_int_modes := si di ti
+softfp_extensions := sftf dftf xftf
+softfp_truncations := tfsf tfdf tfxf
+softfp_machine_header := i386/sfp-machine.h
+softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-fprules-softfp64.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp64	2008-07-01 14:28:18.000000000 -0700
@@ -1,6 +0,0 @@
-softfp_float_modes := tf
-softfp_int_modes := si di ti
-softfp_extensions := sftf dftf xftf
-softfp_truncations := tfsf tfdf tfxf
-softfp_machine_header := i386/sfp-machine.h
-softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-linux.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/gcc/config/i386/t-linux	2008-07-01 09:30:35.000000000 -0700
@@ -0,0 +1,5 @@
+# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
+# Need to support TImode for x86.  Override the settings from
+# t-slibgcc-elf-ver and t-linux
+SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
+		 $(srcdir)/config/i386/libgcc-glibc.ver
--- gcc/gcc/config/i386/t-linux64.quad	2007-10-01 19:21:34.000000000 -0700
+++ gcc/gcc/config/i386/t-linux64	2008-07-01 09:30:35.000000000 -0700
@@ -1,9 +1,3 @@
-# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
-# override the settings
-# from t-slibgcc-elf-ver and t-linux
-SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
-		 $(srcdir)/config/i386/libgcc-x86_64-glibc.ver
-
 # On Debian, Ubuntu and other derivative distributions, the 32bit libraries
 # are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to
 # /lib and /usr/lib, while other distributions install libraries into /lib64
@@ -21,6 +15,3 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
 		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
 		     crtfastmath.o
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/libgcc-std.ver.quad	2007-10-01 19:21:34.000000000 -0700
+++ gcc/gcc/libgcc-std.ver	2008-07-01 09:30:35.000000000 -0700
@@ -1800,3 +1800,7 @@ GCC_4.3.0 {
   __satfractunstiuda
   __satfractunstiuta
 }
+
+%inherit GCC_4.4.0 GCC_4.3.0
+GCC_4.4.0 {
+}
--- gcc/gcc/mkmap-symver.awk.quad	2008-06-06 15:10:06.000000000 -0700
+++ gcc/gcc/mkmap-symver.awk	2008-07-01 11:48:14.000000000 -0700
@@ -46,7 +46,8 @@ state == "nm" && ($1 == "U" || $2 == "U"
 }
 
 state == "nm" && NF == 3 {
-  def[$3] = 1;
+  split ($3, s, "@")
+  def[s[1]] = 1;
   sawsymbol = 1;
   next;
 }
@@ -82,10 +83,13 @@ $1 == "}" {
 
 {
   sym = prefix $1;
+  symbols[sym] = 1
   if (thislib != "%exclude")
-    ver[sym] = thislib;
-  else
-    delete ver[sym];
+    ver[sym, thislib] = 1;
+  else {
+    for (l in libs)
+      ver[sym, l] = 0;
+  }
   next;
 }
 
@@ -107,8 +111,8 @@ function output(lib) {
     output(inherit[lib]);
 
   empty=1
-  for (sym in ver)
-    if ((ver[sym] == lib) && (sym in def))
+  for (sym in symbols)
+    if ((ver[sym, lib] != 0) && (sym in def))
       {
 	if (empty)
 	  {
--- gcc/libgcc/Makefile.in.quad	2008-06-11 07:31:05.000000000 -0700
+++ gcc/libgcc/Makefile.in	2008-07-01 11:36:55.000000000 -0700
@@ -138,7 +138,7 @@ config.h: stamp-h ; @true
 stamp-h: $(srcdir)/config.in config.status Makefile
 	CONFIG_FILES= CONFIG_HEADERS=config.h:$(srcdir)/config.in $(SHELL) ./config.status
 
-config.status: $(srcdir)/configure
+config.status: $(srcdir)/configure $(srcdir)/config.host
 	$(SHELL) ./config.status --recheck
 
 include $(gcc_objdir)/libgcc.mvars
--- gcc/libgcc/config.host.quad	2008-06-10 09:48:12.000000000 -0700
+++ gcc/libgcc/config.host	2008-07-01 09:30:35.000000000 -0700
@@ -578,3 +578,10 @@ i[34567]86-*-linux* | x86_64-*-linux*)
 	tmake_file="${tmake_file} t-tls"
 	;;
 esac
+
+case ${host} in
+i[34567]86-*-darwin* | x86_64-*-darwin* | \
+  i[34567]86-*-linux* | x86_64-*-linux*)
+	tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	;;
+esac
--- gcc/libgcc/config/i386/32/sfp-machine.h.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/libgcc/config/i386/32/sfp-machine.h	2008-07-01 09:30:35.000000000 -0700
@@ -0,0 +1,215 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("add{l} {%11,%3|%3,%11}\n\t"					\
+	   "adc{l} {%9,%2|%2,%9}\n\t"					\
+	   "adc{l} {%7,%1|%1,%7}\n\t"					\
+	   "adc{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "%1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%3" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("add{l} {%8,%2|%2,%8}\n\t"					\
+	   "adc{l} {%6,%1|%1,%6}\n\t"					\
+	   "adc{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("sub{l} {%11,%3|%3,%11}\n\t"					\
+	   "sbb{l} {%9,%2|%2,%9}\n\t"					\
+	   "sbb{l} {%7,%1|%1,%7}\n\t"					\
+	   "sbb{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "3" ((USItype) (x0)),					\
+	     "im" ((USItype) (y0)))
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("sub{l} {%8,%2|%2,%8}\n\t"					\
+	   "sbb{l} {%6,%1|%1,%6}\n\t"					\
+	   "sbb{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
+   emulation is done in 16byte.  */
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0, 0, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f;							\
+	__asm__ __volatile__ ("fdiv %0" : "+t" (f));			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("fdivp" : "=t" (f)			\
+			      	      : "0" (f), "u" (g)		\
+				      : "st(1)");			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/32/t-fprules-softfp.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/libgcc/config/i386/32/t-fprules-softfp	2008-07-01 14:12:51.000000000 -0700
@@ -0,0 +1,8 @@
+# Filter out TImode functions
+tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
+
+# Provide fallbacks for  __builtin_copysignq nor __builtin_fabsq.
+LIB2ADD += $(srcdir)/config/i386/32/tf-signs.c
--- gcc/libgcc/config/i386/32/tf-signs.c.quad	2008-07-01 12:43:28.000000000 -0700
+++ gcc/libgcc/config/i386/32/tf-signs.c	2008-07-01 13:58:52.000000000 -0700
@@ -0,0 +1,64 @@
+/* Copyright (C) 2008 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 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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 COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+union _FP_UNION_Q
+{
+   __float128 flt;
+   struct 
+   {
+      unsigned long frac0 : 32;
+      unsigned long frac1 : 32;
+      unsigned long frac2 : 32;
+      unsigned long frac3 : 16;
+      unsigned exp : 15;
+      unsigned sign : 1;
+   } bits __attribute__((packed));
+};
+
+__float128
+__copysignq (__float128 a, __float128 b)
+{
+  union _FP_UNION_Q A, B;
+
+  A.flt = a;
+  B.flt = b;
+  A.bits.sign = B.bits.sign;
+
+  return A.flt;
+}
+
+__float128
+__fabsq (__float128 a)
+{
+  union _FP_UNION_Q A;
+
+  A.flt = a;
+  A.bits.sign = 0;
+
+  return A.flt;
+}
--- gcc/libgcc/config/i386/64/_powitf2-compat.c.quad	2008-07-01 12:43:41.000000000 -0700
+++ gcc/libgcc/config/i386/64/_powitf2-compat.c	2008-07-01 11:22:20.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __powitf2 __powitf2_shared
+#endif
+
+#define L_powitf2
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __powitf2
+extern __typeof__ (__powitf2_shared) __powitf2_compat __attribute__((alias ("__powitf2_shared")));
+
+asm (".symver __powitf2_compat,__powitf2@GCC_4.0.0");
+asm (".symver __powitf2_shared,__powitf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/eqtf2.c.quad	2008-07-01 12:43:41.000000000 -0700
+++ gcc/libgcc/config/i386/64/eqtf2.c	2008-07-01 11:06:46.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __netf2 __netf2_shared
+#endif
+
+#include "config/soft-fp/eqtf2.c"
+
+#ifdef SHARED
+#undef __netf2
+strong_alias (__netf2_shared, __netf2_compat);
+
+asm (".symver __netf2_compat,__netf2@GCC_3.0");
+asm (".symver __netf2_shared,__netf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/getf2.c.quad	2008-07-01 12:43:41.000000000 -0700
+++ gcc/libgcc/config/i386/64/getf2.c	2008-07-01 11:05:08.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __gttf2 __gttf2_shared
+#endif
+
+#include "config/soft-fp/getf2.c"
+
+#ifdef SHARED
+#undef __gttf2
+strong_alias (__gttf2_shared, __gttf2_compat);
+
+asm (".symver __gttf2_compat,__gttf2@GCC_3.0");
+asm (".symver __gttf2_shared,__gttf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/letf2.c.quad	2008-07-01 12:43:41.000000000 -0700
+++ gcc/libgcc/config/i386/64/letf2.c	2008-07-01 11:05:56.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __lttf2 __lttf2_shared
+#endif
+
+#include "config/soft-fp/letf2.c"
+
+#ifdef SHARED
+#undef __lttf2
+strong_alias (__lttf2_shared, __lttf2_compat);
+
+asm (".symver __lttf2_compat,__lttf2@GCC_3.0");
+asm (".symver __lttf2_shared,__lttf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/sfp-machine.h.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/libgcc/config/i386/64/sfp-machine.h	2008-07-01 09:30:35.000000000 -0700
@@ -0,0 +1,143 @@
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y)                           \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f = 0.0;							\
+	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/64/t-fprules-softfp.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/libgcc/config/i386/64/t-fprules-softfp	2008-07-01 11:29:30.000000000 -0700
@@ -0,0 +1,12 @@
+# Filter out the following TImode functions and provide backward binary
+# compatibility.
+ti-compats = getf2.c letf2.c eqtf2.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(ti-compats))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
+
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(ti-compats))
+
+# Replace _powitf2 with _powitf2-compat.
+LIB2FUNCS_EXCLUDE += _powitf2
+LIB2ADD += $(srcdir)/config/i386/64/_powitf2-compat.c
--- gcc/libgcc/configure.ac.quad	2008-06-22 08:04:12.000000000 -0700
+++ gcc/libgcc/configure.ac	2008-07-01 09:30:35.000000000 -0700
@@ -153,6 +153,21 @@ AC_CACHE_CHECK([whether fixed-point is s
 fixed_point=$libgcc_cv_fixed_point
 AC_SUBST(fixed_point)
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/configure.quad	2008-06-22 08:04:12.000000000 -0700
+++ gcc/libgcc/configure	2008-07-01 14:28:10.000000000 -0700
@@ -3402,6 +3402,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >
 fixed_point=$libgcc_cv_fixed_point
 
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/shared-object.mk.quad	2007-01-09 16:42:39.000000000 -0800
+++ gcc/libgcc/shared-object.mk	2008-07-01 09:30:35.000000000 -0700
@@ -12,7 +12,7 @@ $(base)$(objext): $o
 	$(gcc_compile) $(c_flags) -c $< $(vis_hide)
 
 $(base)_s$(objext): $o
-	$(gcc_s_compile) $(c_flags) -c $<
+	$(gcc_s_compile) -DSHARED $(c_flags) -c $<
 
 else
 
@@ -29,6 +29,6 @@ $(base).vis: $(base)_s$(objext)
 	$(gen-hide-list)
 
 $(base)_s$(objext): $o
-	$(gcc_s_compile) -c -xassembler-with-cpp $<
+	$(gcc_s_compile) -DSHARED -c -xassembler-with-cpp $<
 
 endif

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-07-01 21:53                   ` H.J. Lu
@ 2008-07-01 22:02                     ` Joseph S. Myers
  2008-07-02  3:55                       ` H.J. Lu
  0 siblings, 1 reply; 32+ messages in thread
From: Joseph S. Myers @ 2008-07-01 22:02 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Uros Bizjak, Ian Lance Taylor, GCC Patches

On Tue, 1 Jul 2008, H.J. Lu wrote:

> while keeping the old version. It turns out that mkmap-symver.awk only
> supports one version per symbol. My patch extends to multiple versions.
> Since symbol version is only needed for shared library. I need to a way to
> tell if we are compiling for shared library. I added -DSHARED to
> shared-object.mk and provided backward compatibility for x86-64.

This requires specific testing:

* A binary (64-bit) built with current 4.3 branch with references to the 
symbols in question at GCC_3.0 in shared libgcc should continue to run 
with libgcc built with the patched compiler.

* Such a binary built with the patched compiler should request the symbols 
in question at version GCC_4.3.0 and not GCC_3.0 (and so not work if run 
against the old libgcc).

If that works and the patch is approved for trunk then the 4.3.0 version 
should also be added on 4.3 branch.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-07-01 22:02                     ` Joseph S. Myers
@ 2008-07-02  3:55                       ` H.J. Lu
  2008-07-02  7:29                         ` Uros Bizjak
  2008-07-02 14:57                         ` Ian Lance Taylor
  0 siblings, 2 replies; 32+ messages in thread
From: H.J. Lu @ 2008-07-02  3:55 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Uros Bizjak, Ian Lance Taylor, GCC Patches

On Tue, Jul 01, 2008 at 09:57:01PM +0000, Joseph S. Myers wrote:
> On Tue, 1 Jul 2008, H.J. Lu wrote:
> 
> > while keeping the old version. It turns out that mkmap-symver.awk only
> > supports one version per symbol. My patch extends to multiple versions.
> > Since symbol version is only needed for shared library. I need to a way to
> > tell if we are compiling for shared library. I added -DSHARED to
> > shared-object.mk and provided backward compatibility for x86-64.
> 
> This requires specific testing:
> 
> * A binary (64-bit) built with current 4.3 branch with references to the 
> symbols in question at GCC_3.0 in shared libgcc should continue to run 
> with libgcc built with the patched compiler.
> 
> * Such a binary built with the patched compiler should request the symbols 
> in question at version GCC_4.3.0 and not GCC_3.0 (and so not work if run 
> against the old libgcc).
> 
> If that works and the patch is approved for trunk then the 4.3.0 version 
> should also be added on 4.3 branch.
> 

I noticed a few issues:

1. __divtc3 and __multc3 should have GCC_4.3.0.
2. config/libgcc-glibc.ver should use %exclude before redefining
version.

This patch fixes those issues. There are no regressions on Linux/ia32,
Linux/ia64 and Linux/x86-64. I will post 4.4 vs. 4.3 results at

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36669

OK for trunk.

H.J.
---
gcc/

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* config/i386/libgcc-glibc.ver: New.

	* config/i386/libgcc-x86_64-glibc.ver: Removed.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.  Add
	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
	i[34567]86-*-linux*, x86_64-*-linux*.

	* libgcc-std.ver: Add empty GCC_4.4.0.

	* mkmap-symver.awk: Support multiple versions per symbol.

	* config/libgcc-glibc.ver: Add %exclude.

	* config/i386/i386.c (ix86_init_builtins): Always define
	__builtin_fabsq and __builtin_copysignq with fallbacks.
	(ix86_expand_builtin): Emit normal call for __builtin_fabsq
	and __builtin_copysignq if SSE2 isn't available.

	* config/i386/linux.h (LIBGCC2_HAS_TF_MODE): Defined.
	(LIBGCC2_TF_CEXT): Likwise.
	(TF_SIZE): Likwise.

	* config/i386/linux64.h (LIBGCC2_HAS_TF_MODE): Defined as 1.

	* config/i386/sfp-machine.h: Moved to libgcc.

	* config/i386/sfp-machine.h: New.
	* config/i386/t-linux: Likwise.

	* config/i386/t-darwin: Remove softfp_wrap_start and
	softfp_wrap_end.
	* config/i386/t-darwin64: Likewise.

	* config/i386/t-fprules-softfp64: Renamed to ...
	* config/i386/t-fprules-softfp: This.

	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
	and softfp_wrap_end.

libgcc/

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* shared-object.mk ($(base)_s$(objext)): Add -DSHARED.

	* config/i386/64/_divtc3-compat.c: New.
	* config/i386/64/_multc3-compat.c: Likewise.
	* config/i386/64/_powitf2-compat.c: Likewise.
	* config/i386/64/eqtf2.c: Likewise.
	* config/i386/64/getf2.c: Likewise.
	* config/i386/64/letf2.c: Likewise.
	* config/i386/64/t-fprules-softfp: Likewise.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	* config.host: Add i386/${host_address}/t-fprules-softfp to
	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*. 

	* configure.ac: Set host_address to 64 or 32 for x86.
	* configure: Regenerated.

	* Makefile.in (config.status): Also depend on
	$(srcdir)/config.host.

	* config/i386/32/t-fprules-softfp: New.
	* config/i386/32/tf-signs.c: Likewise.

	* config/i386/64/sfp-machine.h: New. Moved from gcc.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
	    Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/32/sfp-machine.h: New.

--- gcc/gcc/config.gcc.quad	2008-06-27 08:52:44.000000000 -0700
+++ gcc/gcc/config.gcc	2008-07-01 09:30:35.000000000 -0700
@@ -1006,11 +1006,11 @@ i[34567]86-*-darwin*)
 	# then this file using that to set --with-cpu=i386 which has no -m64
 	# support.
 	with_cpu=${with_cpu:-generic}
-	tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 x86_64-*-darwin*)
 	with_cpu=${with_cpu:-generic}
-	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
 	tm_file="${tm_file} ${cpu_type}/darwin64.h"
 	;;
 i[34567]86-*-elf*)
@@ -1069,7 +1069,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
-			tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
+			tmake_file="${tmake_file} i386/t-linux64"
 			need_64bit_hwint=yes
 			case X"${with_cpu}" in
 			Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
@@ -1101,7 +1101,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
+	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-*-gnu*)
 	;;
@@ -2973,6 +2973,13 @@ case ${target} in
 		fi
 		;;
 
+	i[34567]86-*-darwin* | x86_64-*-darwin*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+		;;
+	i[34567]86-*-linux* | x86_64-*-linux*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
+		;;
+
 	mips*-*-*)
 		if test x$gnu_ld = xyes
 		then
--- gcc/gcc/config/i386/i386.c.quad	2008-07-01 12:49:55.000000000 -0700
+++ gcc/gcc/config/i386/i386.c	2008-07-01 13:57:56.000000000 -0700
@@ -20247,16 +20247,26 @@ ix86_init_builtins (void)
 			       NULL, NULL_TREE);
   ix86_builtins[(int) IX86_BUILTIN_INFQ] = decl;
 
+  /* We will expand them to normal call if SSE2 isn't available since
+     they are used by libgcc. */
   ftype = build_function_type_list (float128_type_node,
 				    float128_type_node,
 				    NULL_TREE);
-  def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
+  decl = add_builtin_function ("__builtin_fabsq", ftype,
+			       IX86_BUILTIN_FABSQ, BUILT_IN_MD,
+			       "__fabstf2", NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_FABSQ] = decl;
+  TREE_READONLY (decl) = 1;
 
   ftype = build_function_type_list (float128_type_node,
 				    float128_type_node,
 				    float128_type_node,
 				    NULL_TREE);
-  def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
+  decl = add_builtin_function ("__builtin_copysignq", ftype,
+			       IX86_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
+			       "__copysigntf3", NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = decl;
+  TREE_READONLY (decl) = 1;
 
   if (TARGET_MMX)
     ix86_init_mmx_sse_builtins ();
@@ -21610,7 +21620,16 @@ ix86_expand_builtin (tree exp, rtx targe
        i < ARRAY_SIZE (bdesc_args);
        i++, d++)
     if (d->code == fcode)
-      return ix86_expand_args_builtin (d, exp, target);
+      switch (fcode)
+	{
+	case IX86_BUILTIN_FABSQ:
+	case IX86_BUILTIN_COPYSIGNQ:
+	  if (!TARGET_SSE2)
+	    /* Emit a normal call if SSE2 isn't available.  */
+	    return expand_call (exp, target, ignore);
+	default:
+	  return ix86_expand_args_builtin (d, exp, target);
+	}
 
   for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
     if (d->code == fcode)
--- gcc/gcc/config/i386/libgcc-glibc.ver.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-glibc.ver	2008-07-01 17:23:58.000000000 -0700
@@ -0,0 +1,162 @@
+# In order to work around the very problems that force us to now generally
+# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
+# By now choosing the same version tags for these specific routines, we
+# maintain enough binary compatibility to allow future versions of glibc
+# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
+
+%ifndef __x86_64__
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
+%inherit GCC_3.0 GLIBC_2.0
+GLIBC_2.0 {
+  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+
+  # Exception handling support functions used by most everyone.
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+%endif
+
+% 128 bit long double support was introduced with GCC 4.3.0 to 64bit
+% and with GCC 4.4.0 to 32bit.  These lines make the symbols to get
+% a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
+
+%exclude {
+  __addtf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+%ifdef __x86_64__
+GCC_3.0 {
+  __gttf2
+  __lttf2
+  __netf2
+}
+
+GCC_4.0.0 {
+  __divtc3
+  __multc3
+  __powitf2
+}
+
+GCC_4.3.0 {
+  __addtf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%else
+GCC_4.4.0 {
+  __addtf3
+  __copysigntf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fabstf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%endif
--- gcc/gcc/config/i386/libgcc-x86_64-glibc.ver.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-x86_64-glibc.ver	2008-07-01 17:24:01.000000000 -0700
@@ -1,86 +0,0 @@
-# In order to work around the very problems that force us to now generally
-# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
-# By now choosing the same version tags for these specific routines, we
-# maintain enough binary compatibility to allow future versions of glibc
-# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
-
-%ifndef __x86_64__
-%inherit GCC_3.0 GLIBC_2.0
-GLIBC_2.0 {
-  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
-  __divdi3
-  __moddi3
-  __udivdi3
-  __umoddi3
-
-  # Exception handling support functions used by most everyone.
-  __register_frame
-  __register_frame_table
-  __deregister_frame
-  __register_frame_info
-  __deregister_frame_info
-  __frame_state_for
-  __register_frame_info_table
-}
-%endif
-
-% 128 bit long double support was introduced with GCC 4.3.0.
-% These lines make the symbols to get a @@GCC_4.3.0 attached.
-
-%ifdef __x86_64__
-%exclude {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-
-GCC_4.3.0 {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-%endif
--- gcc/gcc/config/i386/linux.h.quad	2008-04-26 09:19:19.000000000 -0700
+++ gcc/gcc/config/i386/linux.h	2008-07-01 09:30:35.000000000 -0700
@@ -189,6 +189,12 @@ along with GCC; see the file COPYING3.  
 	   : "=d"(BASE))
 #endif
 
+/* Put all *tf routines in libgcc.  */
+#undef LIBGCC2_HAS_TF_MODE
+#define LIBGCC2_HAS_TF_MODE 1
+#define LIBGCC2_TF_CEXT q
+#define TF_SIZE 113
+
 #undef NEED_INDICATE_EXEC_STACK
 #define NEED_INDICATE_EXEC_STACK 1
 
--- gcc/gcc/config/i386/linux64.h.quad	2007-08-04 16:50:17.000000000 -0700
+++ gcc/gcc/config/i386/linux64.h	2008-07-01 09:30:35.000000000 -0700
@@ -91,7 +91,7 @@ along with GCC; see the file COPYING3.  
 
 /* Put all *tf routines in libgcc.  */
 #undef LIBGCC2_HAS_TF_MODE
-#define LIBGCC2_HAS_TF_MODE TARGET_64BIT
+#define LIBGCC2_HAS_TF_MODE 1
 #define LIBGCC2_TF_CEXT q
 #define TF_SIZE 113
 
--- gcc/gcc/config/i386/sfp-machine.h.quad	2008-02-25 09:57:37.000000000 -0800
+++ gcc/gcc/config/i386/sfp-machine.h	2008-07-01 09:30:35.000000000 -0700
@@ -1,143 +1,5 @@
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-typedef int TItype __attribute__ ((mode (TI)));
-typedef unsigned int UTItype __attribute__ ((mode (TI)));
-
-#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
-
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
-#define _FP_MUL_MEAT_Q(R,X,Y)                           \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D
-#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_E		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID		0x01
-#define FP_EX_DENORM		0x02
-#define FP_EX_DIVZERO		0x04
-#define FP_EX_OVERFLOW		0x08
-#define FP_EX_UNDERFLOW		0x10
-#define FP_EX_INEXACT		0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS						\
-  do {									\
-    if (_fex & FP_EX_INVALID)						\
-      {									\
-	float f = 0.0;							\
-	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
-      }									\
-    if (_fex & FP_EX_DIVZERO)						\
-      {									\
-	float f = 1.0, g = 0.0;						\
-	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
-      }									\
-    if (_fex & FP_EX_OVERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_OVERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_UNDERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_UNDERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_INEXACT)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_INEXACT;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-  } while (0)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		0xc00
-#define FP_RND_PINF		0x800
-#define FP_RND_MINF		0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE			\
-  do {						\
-    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
-  } while (0)
-
-#define FP_ROUNDMODE		(_fcw & 0xc00)
-
-#define	__LITTLE_ENDIAN	1234
-#define	__BIG_ENDIAN	4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#ifdef __x86_64__
+#include "config/i386/64/sfp-machine.h"
 #else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#include "config/i386/32/sfp-machine.h"
 #endif
--- gcc/gcc/config/i386/t-darwin.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin	2008-07-01 09:30:35.000000000 -0700
@@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
 MULTILIB_DIRNAMES = x86_64
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-darwin64.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin64	2008-07-01 09:30:35.000000000 -0700
@@ -1,5 +1,2 @@
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-fprules-softfp.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp	2008-07-01 09:30:35.000000000 -0700
@@ -0,0 +1,6 @@
+softfp_float_modes := tf
+softfp_int_modes := si di ti
+softfp_extensions := sftf dftf xftf
+softfp_truncations := tfsf tfdf tfxf
+softfp_machine_header := i386/sfp-machine.h
+softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-fprules-softfp64.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp64	2008-07-01 17:24:01.000000000 -0700
@@ -1,6 +0,0 @@
-softfp_float_modes := tf
-softfp_int_modes := si di ti
-softfp_extensions := sftf dftf xftf
-softfp_truncations := tfsf tfdf tfxf
-softfp_machine_header := i386/sfp-machine.h
-softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-linux.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/gcc/config/i386/t-linux	2008-07-01 09:30:35.000000000 -0700
@@ -0,0 +1,5 @@
+# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
+# Need to support TImode for x86.  Override the settings from
+# t-slibgcc-elf-ver and t-linux
+SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
+		 $(srcdir)/config/i386/libgcc-glibc.ver
--- gcc/gcc/config/i386/t-linux64.quad	2007-10-01 19:21:34.000000000 -0700
+++ gcc/gcc/config/i386/t-linux64	2008-07-01 09:30:35.000000000 -0700
@@ -1,9 +1,3 @@
-# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
-# override the settings
-# from t-slibgcc-elf-ver and t-linux
-SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
-		 $(srcdir)/config/i386/libgcc-x86_64-glibc.ver
-
 # On Debian, Ubuntu and other derivative distributions, the 32bit libraries
 # are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to
 # /lib and /usr/lib, while other distributions install libraries into /lib64
@@ -21,6 +15,3 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
 		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
 		     crtfastmath.o
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/libgcc-glibc.ver.quad	2005-11-01 13:54:26.000000000 -0800
+++ gcc/gcc/config/libgcc-glibc.ver	2008-07-01 15:13:05.000000000 -0700
@@ -4,6 +4,20 @@
 # maintain enough binary compatibility to allow future versions of glibc
 # to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
 
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.0
 GLIBC_2.0 {
   # Sampling of DImode arithmetic used by (at least) i386 and m68k.
--- gcc/gcc/libgcc-std.ver.quad	2007-10-01 19:21:34.000000000 -0700
+++ gcc/gcc/libgcc-std.ver	2008-07-01 09:30:35.000000000 -0700
@@ -1800,3 +1800,7 @@ GCC_4.3.0 {
   __satfractunstiuda
   __satfractunstiuta
 }
+
+%inherit GCC_4.4.0 GCC_4.3.0
+GCC_4.4.0 {
+}
--- gcc/gcc/mkmap-symver.awk.quad	2008-06-06 15:10:06.000000000 -0700
+++ gcc/gcc/mkmap-symver.awk	2008-07-01 11:48:14.000000000 -0700
@@ -46,7 +46,8 @@ state == "nm" && ($1 == "U" || $2 == "U"
 }
 
 state == "nm" && NF == 3 {
-  def[$3] = 1;
+  split ($3, s, "@")
+  def[s[1]] = 1;
   sawsymbol = 1;
   next;
 }
@@ -82,10 +83,13 @@ $1 == "}" {
 
 {
   sym = prefix $1;
+  symbols[sym] = 1
   if (thislib != "%exclude")
-    ver[sym] = thislib;
-  else
-    delete ver[sym];
+    ver[sym, thislib] = 1;
+  else {
+    for (l in libs)
+      ver[sym, l] = 0;
+  }
   next;
 }
 
@@ -107,8 +111,8 @@ function output(lib) {
     output(inherit[lib]);
 
   empty=1
-  for (sym in ver)
-    if ((ver[sym] == lib) && (sym in def))
+  for (sym in symbols)
+    if ((ver[sym, lib] != 0) && (sym in def))
       {
 	if (empty)
 	  {
--- gcc/libgcc/Makefile.in.quad	2008-06-11 07:31:05.000000000 -0700
+++ gcc/libgcc/Makefile.in	2008-07-01 11:36:55.000000000 -0700
@@ -138,7 +138,7 @@ config.h: stamp-h ; @true
 stamp-h: $(srcdir)/config.in config.status Makefile
 	CONFIG_FILES= CONFIG_HEADERS=config.h:$(srcdir)/config.in $(SHELL) ./config.status
 
-config.status: $(srcdir)/configure
+config.status: $(srcdir)/configure $(srcdir)/config.host
 	$(SHELL) ./config.status --recheck
 
 include $(gcc_objdir)/libgcc.mvars
--- gcc/libgcc/config.host.quad	2008-06-10 09:48:12.000000000 -0700
+++ gcc/libgcc/config.host	2008-07-01 09:30:35.000000000 -0700
@@ -578,3 +578,10 @@ i[34567]86-*-linux* | x86_64-*-linux*)
 	tmake_file="${tmake_file} t-tls"
 	;;
 esac
+
+case ${host} in
+i[34567]86-*-darwin* | x86_64-*-darwin* | \
+  i[34567]86-*-linux* | x86_64-*-linux*)
+	tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	;;
+esac
--- gcc/libgcc/config/i386/32/sfp-machine.h.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/libgcc/config/i386/32/sfp-machine.h	2008-07-01 09:30:35.000000000 -0700
@@ -0,0 +1,215 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("add{l} {%11,%3|%3,%11}\n\t"					\
+	   "adc{l} {%9,%2|%2,%9}\n\t"					\
+	   "adc{l} {%7,%1|%1,%7}\n\t"					\
+	   "adc{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "%1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%3" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("add{l} {%8,%2|%2,%8}\n\t"					\
+	   "adc{l} {%6,%1|%1,%6}\n\t"					\
+	   "adc{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("sub{l} {%11,%3|%3,%11}\n\t"					\
+	   "sbb{l} {%9,%2|%2,%9}\n\t"					\
+	   "sbb{l} {%7,%1|%1,%7}\n\t"					\
+	   "sbb{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "3" ((USItype) (x0)),					\
+	     "im" ((USItype) (y0)))
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("sub{l} {%8,%2|%2,%8}\n\t"					\
+	   "sbb{l} {%6,%1|%1,%6}\n\t"					\
+	   "sbb{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
+   emulation is done in 16byte.  */
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0, 0, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f;							\
+	__asm__ __volatile__ ("fdiv %0" : "+t" (f));			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("fdivp" : "=t" (f)			\
+			      	      : "0" (f), "u" (g)		\
+				      : "st(1)");			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/32/t-fprules-softfp.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/libgcc/config/i386/32/t-fprules-softfp	2008-07-01 14:12:51.000000000 -0700
@@ -0,0 +1,8 @@
+# Filter out TImode functions
+tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
+
+# Provide fallbacks for  __builtin_copysignq nor __builtin_fabsq.
+LIB2ADD += $(srcdir)/config/i386/32/tf-signs.c
--- gcc/libgcc/config/i386/32/tf-signs.c.quad	2008-07-01 12:43:28.000000000 -0700
+++ gcc/libgcc/config/i386/32/tf-signs.c	2008-07-01 13:58:52.000000000 -0700
@@ -0,0 +1,64 @@
+/* Copyright (C) 2008 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 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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 COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+union _FP_UNION_Q
+{
+   __float128 flt;
+   struct 
+   {
+      unsigned long frac0 : 32;
+      unsigned long frac1 : 32;
+      unsigned long frac2 : 32;
+      unsigned long frac3 : 16;
+      unsigned exp : 15;
+      unsigned sign : 1;
+   } bits __attribute__((packed));
+};
+
+__float128
+__copysigntf3 (__float128 a, __float128 b)
+{
+  union _FP_UNION_Q A, B;
+
+  A.flt = a;
+  B.flt = b;
+  A.bits.sign = B.bits.sign;
+
+  return A.flt;
+}
+
+__float128
+__fabstf2 (__float128 a)
+{
+  union _FP_UNION_Q A;
+
+  A.flt = a;
+  A.bits.sign = 0;
+
+  return A.flt;
+}
--- gcc/libgcc/config/i386/64/_divtc3-compat.c.quad	2008-07-01 16:08:22.000000000 -0700
+++ gcc/libgcc/config/i386/64/_divtc3-compat.c	2008-07-01 16:06:41.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __divtc3 __divtc3_shared
+#endif
+
+#define L_divtc3
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __divtc3
+extern __typeof__ (__divtc3_shared) __divtc3_compat __attribute__((alias ("__divtc3_shared")));
+
+asm (".symver __divtc3_compat,__divtc3@GCC_4.0.0");
+asm (".symver __divtc3_shared,__divtc3@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/_multc3-compat.c.quad	2008-07-01 16:08:12.000000000 -0700
+++ gcc/libgcc/config/i386/64/_multc3-compat.c	2008-07-01 16:07:01.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __multc3 __multc3_shared
+#endif
+
+#define L_multc3
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __multc3
+extern __typeof__ (__multc3_shared) __multc3_compat __attribute__((alias ("__multc3_shared")));
+
+asm (".symver __multc3_compat,__multc3@GCC_4.0.0");
+asm (".symver __multc3_shared,__multc3@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/_powitf2-compat.c.quad	2008-07-01 12:43:41.000000000 -0700
+++ gcc/libgcc/config/i386/64/_powitf2-compat.c	2008-07-01 11:22:20.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __powitf2 __powitf2_shared
+#endif
+
+#define L_powitf2
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __powitf2
+extern __typeof__ (__powitf2_shared) __powitf2_compat __attribute__((alias ("__powitf2_shared")));
+
+asm (".symver __powitf2_compat,__powitf2@GCC_4.0.0");
+asm (".symver __powitf2_shared,__powitf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/eqtf2.c.quad	2008-07-01 12:43:41.000000000 -0700
+++ gcc/libgcc/config/i386/64/eqtf2.c	2008-07-01 11:06:46.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __netf2 __netf2_shared
+#endif
+
+#include "config/soft-fp/eqtf2.c"
+
+#ifdef SHARED
+#undef __netf2
+strong_alias (__netf2_shared, __netf2_compat);
+
+asm (".symver __netf2_compat,__netf2@GCC_3.0");
+asm (".symver __netf2_shared,__netf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/getf2.c.quad	2008-07-01 12:43:41.000000000 -0700
+++ gcc/libgcc/config/i386/64/getf2.c	2008-07-01 11:05:08.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __gttf2 __gttf2_shared
+#endif
+
+#include "config/soft-fp/getf2.c"
+
+#ifdef SHARED
+#undef __gttf2
+strong_alias (__gttf2_shared, __gttf2_compat);
+
+asm (".symver __gttf2_compat,__gttf2@GCC_3.0");
+asm (".symver __gttf2_shared,__gttf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/letf2.c.quad	2008-07-01 12:43:41.000000000 -0700
+++ gcc/libgcc/config/i386/64/letf2.c	2008-07-01 11:05:56.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __lttf2 __lttf2_shared
+#endif
+
+#include "config/soft-fp/letf2.c"
+
+#ifdef SHARED
+#undef __lttf2
+strong_alias (__lttf2_shared, __lttf2_compat);
+
+asm (".symver __lttf2_compat,__lttf2@GCC_3.0");
+asm (".symver __lttf2_shared,__lttf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/sfp-machine.h.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/libgcc/config/i386/64/sfp-machine.h	2008-07-01 09:30:35.000000000 -0700
@@ -0,0 +1,143 @@
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y)                           \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f = 0.0;							\
+	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/64/t-fprules-softfp.quad	2008-07-01 09:30:35.000000000 -0700
+++ gcc/libgcc/config/i386/64/t-fprules-softfp	2008-07-01 16:12:21.000000000 -0700
@@ -0,0 +1,12 @@
+# Filter out the following TImode functions and provide backward binary
+# compatibility.
+tf-compats = getf2.c letf2.c eqtf2.c
+tf-functions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tf-compats))
+LIB2ADD := $(filter-out $(tf-functions), $(LIB2ADD))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(tf-compats))
+
+# Replace _divtc3, _multc3 and _powitf2.
+libgcc2-tf-functions = _divtc3 _multc3 _powitf2
+LIB2FUNCS_EXCLUDE += $(libgcc2-tf-functions)
+libgcc2-tf-compats = $(addsuffix -compat.c, $(libgcc2-tf-functions))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(libgcc2-tf-compats))
--- gcc/libgcc/configure.ac.quad	2008-06-22 08:04:12.000000000 -0700
+++ gcc/libgcc/configure.ac	2008-07-01 09:30:35.000000000 -0700
@@ -153,6 +153,21 @@ AC_CACHE_CHECK([whether fixed-point is s
 fixed_point=$libgcc_cv_fixed_point
 AC_SUBST(fixed_point)
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/configure.quad	2008-06-22 08:04:12.000000000 -0700
+++ gcc/libgcc/configure	2008-07-01 14:28:10.000000000 -0700
@@ -3402,6 +3402,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >
 fixed_point=$libgcc_cv_fixed_point
 
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/shared-object.mk.quad	2007-01-09 16:42:39.000000000 -0800
+++ gcc/libgcc/shared-object.mk	2008-07-01 09:30:35.000000000 -0700
@@ -12,7 +12,7 @@ $(base)$(objext): $o
 	$(gcc_compile) $(c_flags) -c $< $(vis_hide)
 
 $(base)_s$(objext): $o
-	$(gcc_s_compile) $(c_flags) -c $<
+	$(gcc_s_compile) -DSHARED $(c_flags) -c $<
 
 else
 
@@ -29,6 +29,6 @@ $(base).vis: $(base)_s$(objext)
 	$(gen-hide-list)
 
 $(base)_s$(objext): $o
-	$(gcc_s_compile) -c -xassembler-with-cpp $<
+	$(gcc_s_compile) -DSHARED -c -xassembler-with-cpp $<
 
 endif

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-07-02  3:55                       ` H.J. Lu
@ 2008-07-02  7:29                         ` Uros Bizjak
  2008-07-02 14:41                           ` H.J. Lu
  2008-07-02 14:57                         ` Ian Lance Taylor
  1 sibling, 1 reply; 32+ messages in thread
From: Uros Bizjak @ 2008-07-02  7:29 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Joseph S. Myers, Ian Lance Taylor, GCC Patches

On Wed, Jul 2, 2008 at 5:14 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Jul 01, 2008 at 09:57:01PM +0000, Joseph S. Myers wrote:
>> On Tue, 1 Jul 2008, H.J. Lu wrote:
>>
>> > while keeping the old version. It turns out that mkmap-symver.awk only
>> > supports one version per symbol. My patch extends to multiple versions.
>> > Since symbol version is only needed for shared library. I need to a way to
>> > tell if we are compiling for shared library. I added -DSHARED to
>> > shared-object.mk and provided backward compatibility for x86-64.
>>
>> This requires specific testing:
>>
>> * A binary (64-bit) built with current 4.3 branch with references to the
>> symbols in question at GCC_3.0 in shared libgcc should continue to run
>> with libgcc built with the patched compiler.
>>
>> * Such a binary built with the patched compiler should request the symbols
>> in question at version GCC_4.3.0 and not GCC_3.0 (and so not work if run
>> against the old libgcc).
>>
>> If that works and the patch is approved for trunk then the 4.3.0 version
>> should also be added on 4.3 branch.
>>
>
> I noticed a few issues:
>
> 1. __divtc3 and __multc3 should have GCC_4.3.0.
> 2. config/libgcc-glibc.ver should use %exclude before redefining
> version.
>
> This patch fixes those issues. There are no regressions on Linux/ia32,
> Linux/ia64 and Linux/x86-64. I will post 4.4 vs. 4.3 results at
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36669
>
> OK for trunk.

386 backend (modulo library) parts are OK with a few nits below,
however libgcc parts should be approved by Ian, since I have no deep
knowledge in this area.

> +#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
> +  __asm__ ("sub{l} {%11,%3|%3,%11}\n\t"                                        \
> +          "sbb{l} {%9,%2|%2,%9}\n\t"                                   \
> +          "sbb{l} {%7,%1|%1,%7}\n\t"                                   \
> +          "sbb{l} {%5,%0|%0,%5}"                                       \
> +          : "=r" ((USItype) (r3)),                                     \
> +            "=&r" ((USItype) (r2)),                                    \
> +            "=&r" ((USItype) (r1)),                                    \
> +            "=&r" ((USItype) (r0))                                     \
> +          : "0" ((USItype) (x3)),                                      \
> +            "g" ((USItype) (y3)),                                      \
> +            "1" ((USItype) (x2)),                                      \
> +            "g" ((USItype) (y2)),                                      \
> +            "2" ((USItype) (x1)),                                      \
> +            "g" ((USItype) (y1)),                                      \
> +            "3" ((USItype) (x0)),                                      \
> +            "im" ((USItype) (y0)))

Please add a %%% comment that "im" constraint is due to reload
problems in the asm above. The correct constraint is "g".

> --- gcc/libgcc/config/i386/32/t-fprules-softfp.quad     2008-07-01 09:30:35.000000000 -0700
> +++ gcc/libgcc/config/i386/32/t-fprules-softfp  2008-07-01 14:12:51.000000000 -0700
> @@ -0,0 +1,8 @@
> +# Filter out TImode functions
> +tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
> +tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
> +
> +LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
> +
> +# Provide fallbacks for  __builtin_copysignq nor __builtin_fabsq.

__builtin_copysignq _and_ __builtin_fabsq.

Thanks,
Uros.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-07-02  7:29                         ` Uros Bizjak
@ 2008-07-02 14:41                           ` H.J. Lu
  0 siblings, 0 replies; 32+ messages in thread
From: H.J. Lu @ 2008-07-02 14:41 UTC (permalink / raw)
  To: Uros Bizjak
  Cc: Joseph S. Myers, Ian Lance Taylor, davem, jakub, aldyh, dje,
	aoliva, kkojima, nickc, uweigand, Andreas.Krebbel, GCC Patches

On Wed, Jul 02, 2008 at 09:15:16AM +0200, Uros Bizjak wrote:
> On Wed, Jul 2, 2008 at 5:14 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> > On Tue, Jul 01, 2008 at 09:57:01PM +0000, Joseph S. Myers wrote:
> >> On Tue, 1 Jul 2008, H.J. Lu wrote:
> >>
> >> > while keeping the old version. It turns out that mkmap-symver.awk only
> >> > supports one version per symbol. My patch extends to multiple versions.
> >> > Since symbol version is only needed for shared library. I need to a way to
> >> > tell if we are compiling for shared library. I added -DSHARED to
> >> > shared-object.mk and provided backward compatibility for x86-64.
> >>
> >> This requires specific testing:
> >>
> >> * A binary (64-bit) built with current 4.3 branch with references to the
> >> symbols in question at GCC_3.0 in shared libgcc should continue to run
> >> with libgcc built with the patched compiler.
> >>
> >> * Such a binary built with the patched compiler should request the symbols
> >> in question at version GCC_4.3.0 and not GCC_3.0 (and so not work if run
> >> against the old libgcc).
> >>
> >> If that works and the patch is approved for trunk then the 4.3.0 version
> >> should also be added on 4.3 branch.
> >>
> >
> > I noticed a few issues:
> >
> > 1. __divtc3 and __multc3 should have GCC_4.3.0.
> > 2. config/libgcc-glibc.ver should use %exclude before redefining
> > version.
> >
> > This patch fixes those issues. There are no regressions on Linux/ia32,
> > Linux/ia64 and Linux/x86-64. I will post 4.4 vs. 4.3 results at
> >
> > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36669
> >
> > OK for trunk.
> 
> 386 backend (modulo library) parts are OK with a few nits below,
> however libgcc parts should be approved by Ian, since I have no deep
> knowledge in this area.

Ian, is this OK for trunk?

> > +            "im" ((USItype) (y0)))
> 
> Please add a %%% comment that "im" constraint is due to reload
> problems in the asm above. The correct constraint is "g".
> 
> > +
> > +# Provide fallbacks for  __builtin_copysignq nor __builtin_fabsq.
> 
> __builtin_copysignq _and_ __builtin_fabsq.
> 

Here is the updated patch. Since now libgcc can now more than one
version per symbol, define a new version for a symbol won't
automatically remove the old one.  We need to exclude the old version
first if it is invalid. I visiually inspected all libgcc-glibc version
files and added %exclude to

config/m32r/libgcc-glibc.ver
config/s390/libgcc-glibc.ver
config/sh/libgcc-glibc.ver
config/sparc/libgcc-sparc-glibc.ver

Could sparc, rs6000, sh, m32r and s390 also review this patch?

Thanks.


H.J.
---
gcc/

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* config/i386/libgcc-glibc.ver: New.

	* config/i386/libgcc-x86_64-glibc.ver: Removed.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.  Add
	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
	i[34567]86-*-linux*, x86_64-*-linux*.

	* libgcc-std.ver: Add empty GCC_4.4.0.

	* mkmap-symver.awk: Support multiple versions per symbol.

	* config/libgcc-glibc.ver: Add %exclude.

	* config/i386/i386.c (ix86_init_builtins): Always define
	__builtin_fabsq and __builtin_copysignq with fallbacks.
	(ix86_expand_builtin): Emit normal call for __builtin_fabsq
	and __builtin_copysignq if SSE2 isn't available.

	* config/i386/linux.h (LIBGCC2_HAS_TF_MODE): Defined.
	(LIBGCC2_TF_CEXT): Likwise.
	(TF_SIZE): Likwise.

	* config/i386/linux64.h (LIBGCC2_HAS_TF_MODE): Defined as 1.

	* config/i386/sfp-machine.h: Moved to libgcc.

	* config/i386/sfp-machine.h: New.
	* config/i386/t-linux: Likwise.

	* config/i386/t-darwin: Remove softfp_wrap_start and
	softfp_wrap_end.
	* config/i386/t-darwin64: Likewise.

	* config/i386/t-fprules-softfp64: Renamed to ...
	* config/i386/t-fprules-softfp: This.

	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
	and softfp_wrap_end.

	* config/m32r/libgcc-glibc.ver: Add %exclude.
	* config/s390/libgcc-glibc.ver: Likwise.
	* config/sh/libgcc-glibc.ver: Likwise.
	* config/sparc/libgcc-sparc-glibc.ver: Likwise.

libgcc/

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* shared-object.mk ($(base)_s$(objext)): Add -DSHARED.

	* config/i386/64/_divtc3-compat.c: New.
	* config/i386/64/_multc3-compat.c: Likewise.
	* config/i386/64/_powitf2-compat.c: Likewise.
	* config/i386/64/eqtf2.c: Likewise.
	* config/i386/64/getf2.c: Likewise.
	* config/i386/64/letf2.c: Likewise.
	* config/i386/64/t-fprules-softfp: Likewise.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	* config.host: Add i386/${host_address}/t-fprules-softfp to
	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*. 

	* configure.ac: Set host_address to 64 or 32 for x86.
	* configure: Regenerated.

	* Makefile.in (config.status): Also depend on
	$(srcdir)/config.host.

	* config/i386/32/t-fprules-softfp: New.
	* config/i386/32/tf-signs.c: Likewise.

	* config/i386/64/sfp-machine.h: New. Moved from gcc.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
	    Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/32/sfp-machine.h: New.

--- gcc/gcc/config.gcc.quad	2008-06-27 18:43:07.000000000 -0700
+++ gcc/gcc/config.gcc	2008-07-02 06:36:59.000000000 -0700
@@ -1006,11 +1006,11 @@ i[34567]86-*-darwin*)
 	# then this file using that to set --with-cpu=i386 which has no -m64
 	# support.
 	with_cpu=${with_cpu:-generic}
-	tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 x86_64-*-darwin*)
 	with_cpu=${with_cpu:-generic}
-	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
 	tm_file="${tm_file} ${cpu_type}/darwin64.h"
 	;;
 i[34567]86-*-elf*)
@@ -1069,7 +1069,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
-			tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
+			tmake_file="${tmake_file} i386/t-linux64"
 			need_64bit_hwint=yes
 			case X"${with_cpu}" in
 			Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
@@ -1101,7 +1101,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
+	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-*-gnu*)
 	;;
@@ -2973,6 +2973,13 @@ case ${target} in
 		fi
 		;;
 
+	i[34567]86-*-darwin* | x86_64-*-darwin*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+		;;
+	i[34567]86-*-linux* | x86_64-*-linux*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
+		;;
+
 	mips*-*-*)
 		if test x$gnu_ld = xyes
 		then
--- gcc/gcc/config/i386/i386.c.quad	2008-07-01 19:01:42.000000000 -0700
+++ gcc/gcc/config/i386/i386.c	2008-07-02 06:37:00.000000000 -0700
@@ -20247,16 +20247,26 @@ ix86_init_builtins (void)
 			       NULL, NULL_TREE);
   ix86_builtins[(int) IX86_BUILTIN_INFQ] = decl;
 
+  /* We will expand them to normal call if SSE2 isn't available since
+     they are used by libgcc. */
   ftype = build_function_type_list (float128_type_node,
 				    float128_type_node,
 				    NULL_TREE);
-  def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
+  decl = add_builtin_function ("__builtin_fabsq", ftype,
+			       IX86_BUILTIN_FABSQ, BUILT_IN_MD,
+			       "__fabstf2", NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_FABSQ] = decl;
+  TREE_READONLY (decl) = 1;
 
   ftype = build_function_type_list (float128_type_node,
 				    float128_type_node,
 				    float128_type_node,
 				    NULL_TREE);
-  def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
+  decl = add_builtin_function ("__builtin_copysignq", ftype,
+			       IX86_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
+			       "__copysigntf3", NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = decl;
+  TREE_READONLY (decl) = 1;
 
   if (TARGET_MMX)
     ix86_init_mmx_sse_builtins ();
@@ -21610,7 +21620,16 @@ ix86_expand_builtin (tree exp, rtx targe
        i < ARRAY_SIZE (bdesc_args);
        i++, d++)
     if (d->code == fcode)
-      return ix86_expand_args_builtin (d, exp, target);
+      switch (fcode)
+	{
+	case IX86_BUILTIN_FABSQ:
+	case IX86_BUILTIN_COPYSIGNQ:
+	  if (!TARGET_SSE2)
+	    /* Emit a normal call if SSE2 isn't available.  */
+	    return expand_call (exp, target, ignore);
+	default:
+	  return ix86_expand_args_builtin (d, exp, target);
+	}
 
   for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
     if (d->code == fcode)
--- gcc/gcc/config/i386/libgcc-glibc.ver.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-glibc.ver	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,162 @@
+# In order to work around the very problems that force us to now generally
+# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
+# By now choosing the same version tags for these specific routines, we
+# maintain enough binary compatibility to allow future versions of glibc
+# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
+
+%ifndef __x86_64__
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
+%inherit GCC_3.0 GLIBC_2.0
+GLIBC_2.0 {
+  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+
+  # Exception handling support functions used by most everyone.
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+%endif
+
+% 128 bit long double support was introduced with GCC 4.3.0 to 64bit
+% and with GCC 4.4.0 to 32bit.  These lines make the symbols to get
+% a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
+
+%exclude {
+  __addtf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+%ifdef __x86_64__
+GCC_3.0 {
+  __gttf2
+  __lttf2
+  __netf2
+}
+
+GCC_4.0.0 {
+  __divtc3
+  __multc3
+  __powitf2
+}
+
+GCC_4.3.0 {
+  __addtf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%else
+GCC_4.4.0 {
+  __addtf3
+  __copysigntf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fabstf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%endif
--- gcc/gcc/config/i386/libgcc-x86_64-glibc.ver.quad	2007-05-18 07:10:43.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-x86_64-glibc.ver	2008-07-02 06:59:34.000000000 -0700
@@ -1,86 +0,0 @@
-# In order to work around the very problems that force us to now generally
-# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
-# By now choosing the same version tags for these specific routines, we
-# maintain enough binary compatibility to allow future versions of glibc
-# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
-
-%ifndef __x86_64__
-%inherit GCC_3.0 GLIBC_2.0
-GLIBC_2.0 {
-  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
-  __divdi3
-  __moddi3
-  __udivdi3
-  __umoddi3
-
-  # Exception handling support functions used by most everyone.
-  __register_frame
-  __register_frame_table
-  __deregister_frame
-  __register_frame_info
-  __deregister_frame_info
-  __frame_state_for
-  __register_frame_info_table
-}
-%endif
-
-% 128 bit long double support was introduced with GCC 4.3.0.
-% These lines make the symbols to get a @@GCC_4.3.0 attached.
-
-%ifdef __x86_64__
-%exclude {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-
-GCC_4.3.0 {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-%endif
--- gcc/gcc/config/i386/linux.h.quad	2008-04-25 18:36:32.000000000 -0700
+++ gcc/gcc/config/i386/linux.h	2008-07-02 06:37:00.000000000 -0700
@@ -189,6 +189,12 @@ along with GCC; see the file COPYING3.  
 	   : "=d"(BASE))
 #endif
 
+/* Put all *tf routines in libgcc.  */
+#undef LIBGCC2_HAS_TF_MODE
+#define LIBGCC2_HAS_TF_MODE 1
+#define LIBGCC2_TF_CEXT q
+#define TF_SIZE 113
+
 #undef NEED_INDICATE_EXEC_STACK
 #define NEED_INDICATE_EXEC_STACK 1
 
--- gcc/gcc/config/i386/linux64.h.quad	2007-08-03 06:25:42.000000000 -0700
+++ gcc/gcc/config/i386/linux64.h	2008-07-02 06:37:00.000000000 -0700
@@ -91,7 +91,7 @@ along with GCC; see the file COPYING3.  
 
 /* Put all *tf routines in libgcc.  */
 #undef LIBGCC2_HAS_TF_MODE
-#define LIBGCC2_HAS_TF_MODE TARGET_64BIT
+#define LIBGCC2_HAS_TF_MODE 1
 #define LIBGCC2_TF_CEXT q
 #define TF_SIZE 113
 
--- gcc/gcc/config/i386/sfp-machine.h.quad	2008-02-19 20:52:26.000000000 -0800
+++ gcc/gcc/config/i386/sfp-machine.h	2008-07-02 06:37:00.000000000 -0700
@@ -1,143 +1,5 @@
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-typedef int TItype __attribute__ ((mode (TI)));
-typedef unsigned int UTItype __attribute__ ((mode (TI)));
-
-#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
-
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
-#define _FP_MUL_MEAT_Q(R,X,Y)                           \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D
-#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_E		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID		0x01
-#define FP_EX_DENORM		0x02
-#define FP_EX_DIVZERO		0x04
-#define FP_EX_OVERFLOW		0x08
-#define FP_EX_UNDERFLOW		0x10
-#define FP_EX_INEXACT		0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS						\
-  do {									\
-    if (_fex & FP_EX_INVALID)						\
-      {									\
-	float f = 0.0;							\
-	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
-      }									\
-    if (_fex & FP_EX_DIVZERO)						\
-      {									\
-	float f = 1.0, g = 0.0;						\
-	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
-      }									\
-    if (_fex & FP_EX_OVERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_OVERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_UNDERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_UNDERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_INEXACT)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_INEXACT;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-  } while (0)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		0xc00
-#define FP_RND_PINF		0x800
-#define FP_RND_MINF		0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE			\
-  do {						\
-    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
-  } while (0)
-
-#define FP_ROUNDMODE		(_fcw & 0xc00)
-
-#define	__LITTLE_ENDIAN	1234
-#define	__BIG_ENDIAN	4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#ifdef __x86_64__
+#include "config/i386/64/sfp-machine.h"
 #else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#include "config/i386/32/sfp-machine.h"
 #endif
--- gcc/gcc/config/i386/t-darwin.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin	2008-07-02 06:37:00.000000000 -0700
@@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
 MULTILIB_DIRNAMES = x86_64
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-darwin64.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin64	2008-07-02 06:37:00.000000000 -0700
@@ -1,5 +1,2 @@
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-fprules-softfp.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,6 @@
+softfp_float_modes := tf
+softfp_int_modes := si di ti
+softfp_extensions := sftf dftf xftf
+softfp_truncations := tfsf tfdf tfxf
+softfp_machine_header := i386/sfp-machine.h
+softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-fprules-softfp64.quad	2007-05-18 07:10:43.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp64	2008-07-02 06:59:34.000000000 -0700
@@ -1,6 +0,0 @@
-softfp_float_modes := tf
-softfp_int_modes := si di ti
-softfp_extensions := sftf dftf xftf
-softfp_truncations := tfsf tfdf tfxf
-softfp_machine_header := i386/sfp-machine.h
-softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-linux.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/gcc/config/i386/t-linux	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,5 @@
+# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
+# Need to support TImode for x86.  Override the settings from
+# t-slibgcc-elf-ver and t-linux
+SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
+		 $(srcdir)/config/i386/libgcc-glibc.ver
--- gcc/gcc/config/i386/t-linux64.quad	2008-06-29 12:02:20.000000000 -0700
+++ gcc/gcc/config/i386/t-linux64	2008-07-02 06:37:00.000000000 -0700
@@ -1,9 +1,3 @@
-# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
-# override the settings
-# from t-slibgcc-elf-ver and t-linux
-SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
-		 $(srcdir)/config/i386/libgcc-x86_64-glibc.ver
-
 # On Debian, Ubuntu and other derivative distributions, the 32bit libraries
 # are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to
 # /lib and /usr/lib, while other distributions install libraries into /lib64
@@ -21,6 +15,3 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
 		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
 		     crtfastmath.o
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/libgcc-glibc.ver.quad	2008-07-01 19:05:44.000000000 -0700
+++ gcc/gcc/config/libgcc-glibc.ver	2008-07-02 06:37:00.000000000 -0700
@@ -4,6 +4,20 @@
 # maintain enough binary compatibility to allow future versions of glibc
 # to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
 
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.0
 GLIBC_2.0 {
   # Sampling of DImode arithmetic used by (at least) i386 and m68k.
--- gcc/gcc/config/m32r/libgcc-glibc.ver.quad	2006-09-27 22:37:56.000000000 -0700
+++ gcc/gcc/config/m32r/libgcc-glibc.ver	2008-07-02 06:52:15.000000000 -0700
@@ -8,6 +8,16 @@
 # because GLIBC_2.0 does not exist on this architecture, as the first 
 # ever glibc release on the platform was GLIBC_2.3.
 
+%exclude {
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.3
 GLIBC_2.3 {
   __register_frame
--- gcc/gcc/config/s390/libgcc-glibc.ver.quad	2006-09-27 22:37:54.000000000 -0700
+++ gcc/gcc/config/s390/libgcc-glibc.ver	2008-07-02 06:58:44.000000000 -0700
@@ -9,6 +9,20 @@
 # ever glibc release on the platform was GLIBC_2.2.
 
 %ifndef __s390x__
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.0
 GLIBC_2.0 {
   __divdi3
@@ -27,6 +41,16 @@ GLIBC_2.0 {
 %endif
 
 %ifdef __s390x__
+%exclude {
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.2
 GLIBC_2.2 {
   __register_frame
--- gcc/gcc/config/sh/libgcc-glibc.ver.quad	2006-09-27 22:38:01.000000000 -0700
+++ gcc/gcc/config/sh/libgcc-glibc.ver	2008-07-02 06:51:14.000000000 -0700
@@ -8,6 +8,16 @@
 # because GLIBC_2.0 does not exist on this architecture, as the first 
 # ever glibc release on the platform was GLIBC_2.2.
 
+%exclude {
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.2
 GLIBC_2.2 {
   __register_frame
@@ -18,4 +28,3 @@ GLIBC_2.2 {
   __frame_state_for
   __register_frame_info_table
 }
-
--- gcc/gcc/config/sparc/libgcc-sparc-glibc.ver.quad	2006-09-27 22:37:56.000000000 -0700
+++ gcc/gcc/config/sparc/libgcc-sparc-glibc.ver	2008-07-02 06:57:38.000000000 -0700
@@ -4,6 +4,20 @@
 # maintain enough binary compatibility to allow future versions of glibc
 # to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
 
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %ifdef __arch64__
 %define GLIBC_VER GLIBC_2.2
 %else
--- gcc/gcc/libgcc-std.ver.quad	2007-09-29 07:58:29.000000000 -0700
+++ gcc/gcc/libgcc-std.ver	2008-07-02 06:37:00.000000000 -0700
@@ -1800,3 +1800,7 @@ GCC_4.3.0 {
   __satfractunstiuda
   __satfractunstiuta
 }
+
+%inherit GCC_4.4.0 GCC_4.3.0
+GCC_4.4.0 {
+}
--- gcc/gcc/mkmap-symver.awk.quad	2008-06-06 19:41:18.000000000 -0700
+++ gcc/gcc/mkmap-symver.awk	2008-07-02 06:37:00.000000000 -0700
@@ -46,7 +46,8 @@ state == "nm" && ($1 == "U" || $2 == "U"
 }
 
 state == "nm" && NF == 3 {
-  def[$3] = 1;
+  split ($3, s, "@")
+  def[s[1]] = 1;
   sawsymbol = 1;
   next;
 }
@@ -82,10 +83,13 @@ $1 == "}" {
 
 {
   sym = prefix $1;
+  symbols[sym] = 1
   if (thislib != "%exclude")
-    ver[sym] = thislib;
-  else
-    delete ver[sym];
+    ver[sym, thislib] = 1;
+  else {
+    for (l in libs)
+      ver[sym, l] = 0;
+  }
   next;
 }
 
@@ -107,8 +111,8 @@ function output(lib) {
     output(inherit[lib]);
 
   empty=1
-  for (sym in ver)
-    if ((ver[sym] == lib) && (sym in def))
+  for (sym in symbols)
+    if ((ver[sym, lib] != 0) && (sym in def))
       {
 	if (empty)
 	  {
--- gcc/libgcc/Makefile.in.quad	2008-06-11 06:40:45.000000000 -0700
+++ gcc/libgcc/Makefile.in	2008-07-02 06:37:00.000000000 -0700
@@ -138,7 +138,7 @@ config.h: stamp-h ; @true
 stamp-h: $(srcdir)/config.in config.status Makefile
 	CONFIG_FILES= CONFIG_HEADERS=config.h:$(srcdir)/config.in $(SHELL) ./config.status
 
-config.status: $(srcdir)/configure
+config.status: $(srcdir)/configure $(srcdir)/config.host
 	$(SHELL) ./config.status --recheck
 
 include $(gcc_objdir)/libgcc.mvars
--- gcc/libgcc/config.host.quad	2008-06-08 08:48:36.000000000 -0700
+++ gcc/libgcc/config.host	2008-07-02 06:37:00.000000000 -0700
@@ -578,3 +578,10 @@ i[34567]86-*-linux* | x86_64-*-linux*)
 	tmake_file="${tmake_file} t-tls"
 	;;
 esac
+
+case ${host} in
+i[34567]86-*-darwin* | x86_64-*-darwin* | \
+  i[34567]86-*-linux* | x86_64-*-linux*)
+	tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	;;
+esac
--- gcc/libgcc/config/i386/32/sfp-machine.h.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/32/sfp-machine.h	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,217 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("add{l} {%11,%3|%3,%11}\n\t"					\
+	   "adc{l} {%9,%2|%2,%9}\n\t"					\
+	   "adc{l} {%7,%1|%1,%7}\n\t"					\
+	   "adc{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "%1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%3" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("add{l} {%8,%2|%2,%8}\n\t"					\
+	   "adc{l} {%6,%1|%1,%6}\n\t"					\
+	   "adc{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+/* FIXME: The last constraint should be "g" instead of "im" if reload
+   works properly.  */
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("sub{l} {%11,%3|%3,%11}\n\t"					\
+	   "sbb{l} {%9,%2|%2,%9}\n\t"					\
+	   "sbb{l} {%7,%1|%1,%7}\n\t"					\
+	   "sbb{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "3" ((USItype) (x0)),					\
+	     "im" ((USItype) (y0)))
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("sub{l} {%8,%2|%2,%8}\n\t"					\
+	   "sbb{l} {%6,%1|%1,%6}\n\t"					\
+	   "sbb{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
+   emulation is done in 16byte.  */
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0, 0, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f;							\
+	__asm__ __volatile__ ("fdiv %0" : "+t" (f));			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("fdivp" : "=t" (f)			\
+			      	      : "0" (f), "u" (g)		\
+				      : "st(1)");			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/32/t-fprules-softfp.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/32/t-fprules-softfp	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,8 @@
+# Filter out TImode functions
+tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
+
+# Provide fallbacks for __builtin_copysignq and __builtin_fabsq.
+LIB2ADD += $(srcdir)/config/i386/32/tf-signs.c
--- gcc/libgcc/config/i386/32/tf-signs.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/32/tf-signs.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,64 @@
+/* Copyright (C) 2008 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 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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 COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+union _FP_UNION_Q
+{
+   __float128 flt;
+   struct 
+   {
+      unsigned long frac0 : 32;
+      unsigned long frac1 : 32;
+      unsigned long frac2 : 32;
+      unsigned long frac3 : 16;
+      unsigned exp : 15;
+      unsigned sign : 1;
+   } bits __attribute__((packed));
+};
+
+__float128
+__copysigntf3 (__float128 a, __float128 b)
+{
+  union _FP_UNION_Q A, B;
+
+  A.flt = a;
+  B.flt = b;
+  A.bits.sign = B.bits.sign;
+
+  return A.flt;
+}
+
+__float128
+__fabstf2 (__float128 a)
+{
+  union _FP_UNION_Q A;
+
+  A.flt = a;
+  A.bits.sign = 0;
+
+  return A.flt;
+}
--- gcc/libgcc/config/i386/64/_divtc3-compat.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/_divtc3-compat.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __divtc3 __divtc3_shared
+#endif
+
+#define L_divtc3
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __divtc3
+extern __typeof__ (__divtc3_shared) __divtc3_compat __attribute__((alias ("__divtc3_shared")));
+
+asm (".symver __divtc3_compat,__divtc3@GCC_4.0.0");
+asm (".symver __divtc3_shared,__divtc3@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/_multc3-compat.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/_multc3-compat.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __multc3 __multc3_shared
+#endif
+
+#define L_multc3
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __multc3
+extern __typeof__ (__multc3_shared) __multc3_compat __attribute__((alias ("__multc3_shared")));
+
+asm (".symver __multc3_compat,__multc3@GCC_4.0.0");
+asm (".symver __multc3_shared,__multc3@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/_powitf2-compat.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/_powitf2-compat.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __powitf2 __powitf2_shared
+#endif
+
+#define L_powitf2
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __powitf2
+extern __typeof__ (__powitf2_shared) __powitf2_compat __attribute__((alias ("__powitf2_shared")));
+
+asm (".symver __powitf2_compat,__powitf2@GCC_4.0.0");
+asm (".symver __powitf2_shared,__powitf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/eqtf2.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/eqtf2.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __netf2 __netf2_shared
+#endif
+
+#include "config/soft-fp/eqtf2.c"
+
+#ifdef SHARED
+#undef __netf2
+strong_alias (__netf2_shared, __netf2_compat);
+
+asm (".symver __netf2_compat,__netf2@GCC_3.0");
+asm (".symver __netf2_shared,__netf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/getf2.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/getf2.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __gttf2 __gttf2_shared
+#endif
+
+#include "config/soft-fp/getf2.c"
+
+#ifdef SHARED
+#undef __gttf2
+strong_alias (__gttf2_shared, __gttf2_compat);
+
+asm (".symver __gttf2_compat,__gttf2@GCC_3.0");
+asm (".symver __gttf2_shared,__gttf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/letf2.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/letf2.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __lttf2 __lttf2_shared
+#endif
+
+#include "config/soft-fp/letf2.c"
+
+#ifdef SHARED
+#undef __lttf2
+strong_alias (__lttf2_shared, __lttf2_compat);
+
+asm (".symver __lttf2_compat,__lttf2@GCC_3.0");
+asm (".symver __lttf2_shared,__lttf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/sfp-machine.h.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/sfp-machine.h	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,143 @@
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y)                           \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f = 0.0;							\
+	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/64/t-fprules-softfp.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/t-fprules-softfp	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,12 @@
+# Filter out the following TImode functions and provide backward binary
+# compatibility.
+tf-compats = getf2.c letf2.c eqtf2.c
+tf-functions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tf-compats))
+LIB2ADD := $(filter-out $(tf-functions), $(LIB2ADD))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(tf-compats))
+
+# Replace _divtc3, _multc3 and _powitf2.
+libgcc2-tf-functions = _divtc3 _multc3 _powitf2
+LIB2FUNCS_EXCLUDE += $(libgcc2-tf-functions)
+libgcc2-tf-compats = $(addsuffix -compat.c, $(libgcc2-tf-functions))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(libgcc2-tf-compats))
--- gcc/libgcc/configure.ac.quad	2008-06-21 07:10:37.000000000 -0700
+++ gcc/libgcc/configure.ac	2008-07-02 06:37:00.000000000 -0700
@@ -153,6 +153,21 @@ AC_CACHE_CHECK([whether fixed-point is s
 fixed_point=$libgcc_cv_fixed_point
 AC_SUBST(fixed_point)
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/configure.quad	2008-06-21 07:10:37.000000000 -0700
+++ gcc/libgcc/configure	2008-07-02 06:37:38.000000000 -0700
@@ -3402,6 +3402,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >
 fixed_point=$libgcc_cv_fixed_point
 
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/shared-object.mk.quad	2007-01-03 21:41:23.000000000 -0800
+++ gcc/libgcc/shared-object.mk	2008-07-02 06:37:00.000000000 -0700
@@ -12,7 +12,7 @@ $(base)$(objext): $o
 	$(gcc_compile) $(c_flags) -c $< $(vis_hide)
 
 $(base)_s$(objext): $o
-	$(gcc_s_compile) $(c_flags) -c $<
+	$(gcc_s_compile) -DSHARED $(c_flags) -c $<
 
 else
 
@@ -29,6 +29,6 @@ $(base).vis: $(base)_s$(objext)
 	$(gen-hide-list)
 
 $(base)_s$(objext): $o
-	$(gcc_s_compile) -c -xassembler-with-cpp $<
+	$(gcc_s_compile) -DSHARED -c -xassembler-with-cpp $<
 
 endif

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-07-02  3:55                       ` H.J. Lu
  2008-07-02  7:29                         ` Uros Bizjak
@ 2008-07-02 14:57                         ` Ian Lance Taylor
  2008-07-02 15:53                           ` H.J. Lu
  1 sibling, 1 reply; 32+ messages in thread
From: Ian Lance Taylor @ 2008-07-02 14:57 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Joseph S. Myers, Uros Bizjak, Ian Lance Taylor, GCC Patches

"H.J. Lu" <hjl.tools@gmail.com> writes:

> gcc/
>
> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>
> 	PR target/36669
> 	* config/i386/libgcc-glibc.ver: New.
>
> 	* config/i386/libgcc-x86_64-glibc.ver: Removed.
>
> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>
> 	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
> 	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
> 	i[34567]86-*-linux*, x86_64-*-linux*.  Add
> 	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
> 	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
> 	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
> 	i[34567]86-*-linux*, x86_64-*-linux*.
>
> 	* libgcc-std.ver: Add empty GCC_4.4.0.
>
> 	* mkmap-symver.awk: Support multiple versions per symbol.
>
> 	* config/libgcc-glibc.ver: Add %exclude.
>
> 	* config/i386/i386.c (ix86_init_builtins): Always define
> 	__builtin_fabsq and __builtin_copysignq with fallbacks.
> 	(ix86_expand_builtin): Emit normal call for __builtin_fabsq
> 	and __builtin_copysignq if SSE2 isn't available.
>
> 	* config/i386/linux.h (LIBGCC2_HAS_TF_MODE): Defined.
> 	(LIBGCC2_TF_CEXT): Likwise.
> 	(TF_SIZE): Likwise.
>
> 	* config/i386/linux64.h (LIBGCC2_HAS_TF_MODE): Defined as 1.
>
> 	* config/i386/sfp-machine.h: Moved to libgcc.
>
> 	* config/i386/sfp-machine.h: New.
> 	* config/i386/t-linux: Likwise.
>
> 	* config/i386/t-darwin: Remove softfp_wrap_start and
> 	softfp_wrap_end.
> 	* config/i386/t-darwin64: Likewise.
>
> 	* config/i386/t-fprules-softfp64: Renamed to ...
> 	* config/i386/t-fprules-softfp: This.
>
> 	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
> 	and softfp_wrap_end.
>
> libgcc/
>
> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>
> 	PR target/36669
> 	* shared-object.mk ($(base)_s$(objext)): Add -DSHARED.
>
> 	* config/i386/64/_divtc3-compat.c: New.
> 	* config/i386/64/_multc3-compat.c: Likewise.
> 	* config/i386/64/_powitf2-compat.c: Likewise.
> 	* config/i386/64/eqtf2.c: Likewise.
> 	* config/i386/64/getf2.c: Likewise.
> 	* config/i386/64/letf2.c: Likewise.
> 	* config/i386/64/t-fprules-softfp: Likewise.
>
> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>
> 	* config.host: Add i386/${host_address}/t-fprules-softfp to
> 	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
> 	i[34567]86-*-linux*, x86_64-*-linux*. 
>
> 	* configure.ac: Set host_address to 64 or 32 for x86.
> 	* configure: Regenerated.
>
> 	* Makefile.in (config.status): Also depend on
> 	$(srcdir)/config.host.
>
> 	* config/i386/32/t-fprules-softfp: New.
> 	* config/i386/32/tf-signs.c: Likewise.
>
> 	* config/i386/64/sfp-machine.h: New. Moved from gcc.
>
> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
> 	    Uros Bizjak  <ubizjak@gmail.com>
>
> 	* config/i386/32/sfp-machine.h: New.


> +%ifdef __x86_64__
> +GCC_3.0 {
> +  __gttf2
> +  __lttf2
> +  __netf2
> +}
> +
> +GCC_4.0.0 {
> +  __divtc3
> +  __multc3
> +  __powitf2
> +}

Please add some comments explaining why we are doing this.


This is OK with that change.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-07-02 14:57                         ` Ian Lance Taylor
@ 2008-07-02 15:53                           ` H.J. Lu
  2008-07-02 16:05                             ` H.J. Lu
  2008-07-02 17:54                             ` H.J. Lu
  0 siblings, 2 replies; 32+ messages in thread
From: H.J. Lu @ 2008-07-02 15:53 UTC (permalink / raw)
  To: Ian Lance Taylor
  Cc: Joseph S. Myers, Uros Bizjak, Ian Lance Taylor, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 3499 bytes --]

On Wed, Jul 2, 2008 at 7:45 AM, Ian Lance Taylor <iant@google.com> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> gcc/
>>
>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>
>>       PR target/36669
>>       * config/i386/libgcc-glibc.ver: New.
>>
>>       * config/i386/libgcc-x86_64-glibc.ver: Removed.
>>
>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>
>>       * config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
>>       from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
>>       i[34567]86-*-linux*, x86_64-*-linux*.  Add
>>       i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
>>       i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
>>       x86_64-*-linux*.  Add i386/t-linux to tmake_file for
>>       i[34567]86-*-linux*, x86_64-*-linux*.
>>
>>       * libgcc-std.ver: Add empty GCC_4.4.0.
>>
>>       * mkmap-symver.awk: Support multiple versions per symbol.
>>
>>       * config/libgcc-glibc.ver: Add %exclude.
>>
>>       * config/i386/i386.c (ix86_init_builtins): Always define
>>       __builtin_fabsq and __builtin_copysignq with fallbacks.
>>       (ix86_expand_builtin): Emit normal call for __builtin_fabsq
>>       and __builtin_copysignq if SSE2 isn't available.
>>
>>       * config/i386/linux.h (LIBGCC2_HAS_TF_MODE): Defined.
>>       (LIBGCC2_TF_CEXT): Likwise.
>>       (TF_SIZE): Likwise.
>>
>>       * config/i386/linux64.h (LIBGCC2_HAS_TF_MODE): Defined as 1.
>>
>>       * config/i386/sfp-machine.h: Moved to libgcc.
>>
>>       * config/i386/sfp-machine.h: New.
>>       * config/i386/t-linux: Likwise.
>>
>>       * config/i386/t-darwin: Remove softfp_wrap_start and
>>       softfp_wrap_end.
>>       * config/i386/t-darwin64: Likewise.
>>
>>       * config/i386/t-fprules-softfp64: Renamed to ...
>>       * config/i386/t-fprules-softfp: This.
>>
>>       * config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
>>       and softfp_wrap_end.
>>
>> libgcc/
>>
>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>
>>       PR target/36669
>>       * shared-object.mk ($(base)_s$(objext)): Add -DSHARED.
>>
>>       * config/i386/64/_divtc3-compat.c: New.
>>       * config/i386/64/_multc3-compat.c: Likewise.
>>       * config/i386/64/_powitf2-compat.c: Likewise.
>>       * config/i386/64/eqtf2.c: Likewise.
>>       * config/i386/64/getf2.c: Likewise.
>>       * config/i386/64/letf2.c: Likewise.
>>       * config/i386/64/t-fprules-softfp: Likewise.
>>
>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>
>>       * config.host: Add i386/${host_address}/t-fprules-softfp to
>>       tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
>>       i[34567]86-*-linux*, x86_64-*-linux*.
>>
>>       * configure.ac: Set host_address to 64 or 32 for x86.
>>       * configure: Regenerated.
>>
>>       * Makefile.in (config.status): Also depend on
>>       $(srcdir)/config.host.
>>
>>       * config/i386/32/t-fprules-softfp: New.
>>       * config/i386/32/tf-signs.c: Likewise.
>>
>>       * config/i386/64/sfp-machine.h: New. Moved from gcc.
>>
>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>           Uros Bizjak  <ubizjak@gmail.com>
>>
>>       * config/i386/32/sfp-machine.h: New.
>
>
>> +%ifdef __x86_64__
>> +GCC_3.0 {
>> +  __gttf2
>> +  __lttf2
>> +  __netf2
>> +}
>> +
>> +GCC_4.0.0 {
>> +  __divtc3
>> +  __multc3
>> +  __powitf2
>> +}
>
> Please add some comments explaining why we are doing this.
>
>
> This is OK with that change.
>

This is the patch I am checking in.

Thanks.

-- 
H.J.

[-- Attachment #2: gcc-quad-19.patch --]
[-- Type: application/octet-stream, Size: 45606 bytes --]

gcc/

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* config/libgcc-glibc.ver: Add %exclude.
	* config/m32r/libgcc-glibc.ver: Likwise.
	* config/s390/libgcc-glibc.ver: Likwise.
	* config/sh/libgcc-glibc.ver: Likwise.
	* config/sparc/libgcc-sparc-glibc.ver: Likwise.

	* config/i386/libgcc-glibc.ver: New.

	* config/i386/libgcc-x86_64-glibc.ver: Removed.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.  Add
	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
	i[34567]86-*-linux*, x86_64-*-linux*.

	* libgcc-std.ver: Add empty GCC_4.4.0.

	* mkmap-symver.awk: Support multiple versions per symbol.

	* config/i386/i386.c (ix86_init_builtins): Always define
	__builtin_fabsq and __builtin_copysignq with fallbacks.
	(ix86_expand_builtin): Emit normal call for __builtin_fabsq
	and __builtin_copysignq if SSE2 isn't available.

	* config/i386/linux.h (LIBGCC2_HAS_TF_MODE): Defined.
	(LIBGCC2_TF_CEXT): Likwise.
	(TF_SIZE): Likwise.

	* config/i386/linux64.h (LIBGCC2_HAS_TF_MODE): Defined as 1.

	* config/i386/sfp-machine.h: Moved to libgcc.

	* config/i386/sfp-machine.h: New.
	* config/i386/t-linux: Likwise.

	* config/i386/t-darwin: Remove softfp_wrap_start and
	softfp_wrap_end.
	* config/i386/t-darwin64: Likewise.

	* config/i386/t-fprules-softfp64: Renamed to ...
	* config/i386/t-fprules-softfp: This.

	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
	and softfp_wrap_end.

libgcc/

2008-07-02  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* shared-object.mk ($(base)_s$(objext)): Add -DSHARED.

	* config/i386/64/_divtc3-compat.c: New.
	* config/i386/64/_multc3-compat.c: Likewise.
	* config/i386/64/_powitf2-compat.c: Likewise.
	* config/i386/64/eqtf2.c: Likewise.
	* config/i386/64/getf2.c: Likewise.
	* config/i386/64/letf2.c: Likewise.
	* config/i386/64/t-fprules-softfp: Likewise.

2008-07-02  H.J. Lu  <hongjiu.lu@intel.com>

	* config.host: Add i386/${host_address}/t-fprules-softfp to
	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*. 

	* configure.ac: Set host_address to 64 or 32 for x86.
	* configure: Regenerated.

	* Makefile.in (config.status): Also depend on
	$(srcdir)/config.host.

	* config/i386/32/t-fprules-softfp: New.
	* config/i386/32/tf-signs.c: Likewise.

	* config/i386/64/sfp-machine.h: New. Moved from gcc.

2008-07-02  H.J. Lu  <hongjiu.lu@intel.com>
	    Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/32/sfp-machine.h: New.

--- gcc/gcc/config.gcc.quad	2008-06-27 08:52:44.000000000 -0700
+++ gcc/gcc/config.gcc	2008-07-02 08:35:33.000000000 -0700
@@ -1006,11 +1006,11 @@ i[34567]86-*-darwin*)
 	# then this file using that to set --with-cpu=i386 which has no -m64
 	# support.
 	with_cpu=${with_cpu:-generic}
-	tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 x86_64-*-darwin*)
 	with_cpu=${with_cpu:-generic}
-	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
 	tm_file="${tm_file} ${cpu_type}/darwin64.h"
 	;;
 i[34567]86-*-elf*)
@@ -1069,7 +1069,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
-			tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
+			tmake_file="${tmake_file} i386/t-linux64"
 			need_64bit_hwint=yes
 			case X"${with_cpu}" in
 			Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
@@ -1101,7 +1101,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
+	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-*-gnu*)
 	;;
@@ -2973,6 +2973,13 @@ case ${target} in
 		fi
 		;;
 
+	i[34567]86-*-darwin* | x86_64-*-darwin*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+		;;
+	i[34567]86-*-linux* | x86_64-*-linux*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
+		;;
+
 	mips*-*-*)
 		if test x$gnu_ld = xyes
 		then
--- gcc/gcc/config/i386/i386.c.quad	2008-07-01 12:49:55.000000000 -0700
+++ gcc/gcc/config/i386/i386.c	2008-07-02 08:35:34.000000000 -0700
@@ -20247,16 +20247,26 @@ ix86_init_builtins (void)
 			       NULL, NULL_TREE);
   ix86_builtins[(int) IX86_BUILTIN_INFQ] = decl;
 
+  /* We will expand them to normal call if SSE2 isn't available since
+     they are used by libgcc. */
   ftype = build_function_type_list (float128_type_node,
 				    float128_type_node,
 				    NULL_TREE);
-  def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
+  decl = add_builtin_function ("__builtin_fabsq", ftype,
+			       IX86_BUILTIN_FABSQ, BUILT_IN_MD,
+			       "__fabstf2", NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_FABSQ] = decl;
+  TREE_READONLY (decl) = 1;
 
   ftype = build_function_type_list (float128_type_node,
 				    float128_type_node,
 				    float128_type_node,
 				    NULL_TREE);
-  def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
+  decl = add_builtin_function ("__builtin_copysignq", ftype,
+			       IX86_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
+			       "__copysigntf3", NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = decl;
+  TREE_READONLY (decl) = 1;
 
   if (TARGET_MMX)
     ix86_init_mmx_sse_builtins ();
@@ -21610,7 +21620,16 @@ ix86_expand_builtin (tree exp, rtx targe
        i < ARRAY_SIZE (bdesc_args);
        i++, d++)
     if (d->code == fcode)
-      return ix86_expand_args_builtin (d, exp, target);
+      switch (fcode)
+	{
+	case IX86_BUILTIN_FABSQ:
+	case IX86_BUILTIN_COPYSIGNQ:
+	  if (!TARGET_SSE2)
+	    /* Emit a normal call if SSE2 isn't available.  */
+	    return expand_call (exp, target, ignore);
+	default:
+	  return ix86_expand_args_builtin (d, exp, target);
+	}
 
   for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
     if (d->code == fcode)
--- gcc/gcc/config/i386/libgcc-glibc.ver.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-glibc.ver	2008-07-02 08:45:30.000000000 -0700
@@ -0,0 +1,165 @@
+# In order to work around the very problems that force us to now generally
+# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
+# By now choosing the same version tags for these specific routines, we
+# maintain enough binary compatibility to allow future versions of glibc
+# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
+
+%ifndef __x86_64__
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
+%inherit GCC_3.0 GLIBC_2.0
+GLIBC_2.0 {
+  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+
+  # Exception handling support functions used by most everyone.
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+%endif
+
+# 128 bit long double support was introduced with GCC 4.3.0 to 64bit
+# and with GCC 4.4.0 to 32bit.  These lines make the symbols to get
+# a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
+
+%exclude {
+  __addtf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+%ifdef __x86_64__
+# Those symbols had improper versions when they were added to gcc 4.3.0.
+# We corrected the default version to GCC_4.3.0.  But we keep the old
+# version for backward binary compatibility. 
+GCC_3.0 {
+  __gttf2
+  __lttf2
+  __netf2
+}
+
+GCC_4.0.0 {
+  __divtc3
+  __multc3
+  __powitf2
+}
+
+GCC_4.3.0 {
+  __addtf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%else
+GCC_4.4.0 {
+  __addtf3
+  __copysigntf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fabstf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%endif
--- gcc/gcc/config/i386/libgcc-x86_64-glibc.ver.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-x86_64-glibc.ver	2008-07-02 08:46:12.000000000 -0700
@@ -1,86 +0,0 @@
-# In order to work around the very problems that force us to now generally
-# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
-# By now choosing the same version tags for these specific routines, we
-# maintain enough binary compatibility to allow future versions of glibc
-# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
-
-%ifndef __x86_64__
-%inherit GCC_3.0 GLIBC_2.0
-GLIBC_2.0 {
-  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
-  __divdi3
-  __moddi3
-  __udivdi3
-  __umoddi3
-
-  # Exception handling support functions used by most everyone.
-  __register_frame
-  __register_frame_table
-  __deregister_frame
-  __register_frame_info
-  __deregister_frame_info
-  __frame_state_for
-  __register_frame_info_table
-}
-%endif
-
-% 128 bit long double support was introduced with GCC 4.3.0.
-% These lines make the symbols to get a @@GCC_4.3.0 attached.
-
-%ifdef __x86_64__
-%exclude {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-
-GCC_4.3.0 {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-%endif
--- gcc/gcc/config/i386/linux.h.quad	2008-04-26 09:19:19.000000000 -0700
+++ gcc/gcc/config/i386/linux.h	2008-07-02 08:35:34.000000000 -0700
@@ -189,6 +189,12 @@ along with GCC; see the file COPYING3.  
 	   : "=d"(BASE))
 #endif
 
+/* Put all *tf routines in libgcc.  */
+#undef LIBGCC2_HAS_TF_MODE
+#define LIBGCC2_HAS_TF_MODE 1
+#define LIBGCC2_TF_CEXT q
+#define TF_SIZE 113
+
 #undef NEED_INDICATE_EXEC_STACK
 #define NEED_INDICATE_EXEC_STACK 1
 
--- gcc/gcc/config/i386/linux64.h.quad	2007-08-04 16:50:17.000000000 -0700
+++ gcc/gcc/config/i386/linux64.h	2008-07-02 08:35:34.000000000 -0700
@@ -91,7 +91,7 @@ along with GCC; see the file COPYING3.  
 
 /* Put all *tf routines in libgcc.  */
 #undef LIBGCC2_HAS_TF_MODE
-#define LIBGCC2_HAS_TF_MODE TARGET_64BIT
+#define LIBGCC2_HAS_TF_MODE 1
 #define LIBGCC2_TF_CEXT q
 #define TF_SIZE 113
 
--- gcc/gcc/config/i386/sfp-machine.h.quad	2008-02-25 09:57:37.000000000 -0800
+++ gcc/gcc/config/i386/sfp-machine.h	2008-07-02 08:35:34.000000000 -0700
@@ -1,143 +1,5 @@
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-typedef int TItype __attribute__ ((mode (TI)));
-typedef unsigned int UTItype __attribute__ ((mode (TI)));
-
-#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
-
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
-#define _FP_MUL_MEAT_Q(R,X,Y)                           \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D
-#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_E		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID		0x01
-#define FP_EX_DENORM		0x02
-#define FP_EX_DIVZERO		0x04
-#define FP_EX_OVERFLOW		0x08
-#define FP_EX_UNDERFLOW		0x10
-#define FP_EX_INEXACT		0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS						\
-  do {									\
-    if (_fex & FP_EX_INVALID)						\
-      {									\
-	float f = 0.0;							\
-	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
-      }									\
-    if (_fex & FP_EX_DIVZERO)						\
-      {									\
-	float f = 1.0, g = 0.0;						\
-	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
-      }									\
-    if (_fex & FP_EX_OVERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_OVERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_UNDERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_UNDERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_INEXACT)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_INEXACT;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-  } while (0)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		0xc00
-#define FP_RND_PINF		0x800
-#define FP_RND_MINF		0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE			\
-  do {						\
-    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
-  } while (0)
-
-#define FP_ROUNDMODE		(_fcw & 0xc00)
-
-#define	__LITTLE_ENDIAN	1234
-#define	__BIG_ENDIAN	4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#ifdef __x86_64__
+#include "config/i386/64/sfp-machine.h"
 #else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#include "config/i386/32/sfp-machine.h"
 #endif
--- gcc/gcc/config/i386/t-darwin.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin	2008-07-02 08:35:34.000000000 -0700
@@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
 MULTILIB_DIRNAMES = x86_64
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-darwin64.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin64	2008-07-02 08:35:34.000000000 -0700
@@ -1,5 +1,2 @@
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-fprules-softfp.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,6 @@
+softfp_float_modes := tf
+softfp_int_modes := si di ti
+softfp_extensions := sftf dftf xftf
+softfp_truncations := tfsf tfdf tfxf
+softfp_machine_header := i386/sfp-machine.h
+softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-fprules-softfp64.quad	2007-06-12 05:45:21.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp64	2008-07-02 08:46:12.000000000 -0700
@@ -1,6 +0,0 @@
-softfp_float_modes := tf
-softfp_int_modes := si di ti
-softfp_extensions := sftf dftf xftf
-softfp_truncations := tfsf tfdf tfxf
-softfp_machine_header := i386/sfp-machine.h
-softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-linux.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/gcc/config/i386/t-linux	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,5 @@
+# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
+# Need to support TImode for x86.  Override the settings from
+# t-slibgcc-elf-ver and t-linux
+SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
+		 $(srcdir)/config/i386/libgcc-glibc.ver
--- gcc/gcc/config/i386/t-linux64.quad	2007-10-01 19:21:34.000000000 -0700
+++ gcc/gcc/config/i386/t-linux64	2008-07-02 08:35:34.000000000 -0700
@@ -1,9 +1,3 @@
-# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
-# override the settings
-# from t-slibgcc-elf-ver and t-linux
-SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
-		 $(srcdir)/config/i386/libgcc-x86_64-glibc.ver
-
 # On Debian, Ubuntu and other derivative distributions, the 32bit libraries
 # are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to
 # /lib and /usr/lib, while other distributions install libraries into /lib64
@@ -21,6 +15,3 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
 		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
 		     crtfastmath.o
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/libgcc-glibc.ver.quad	2005-11-01 13:54:26.000000000 -0800
+++ gcc/gcc/config/libgcc-glibc.ver	2008-07-02 08:35:34.000000000 -0700
@@ -4,6 +4,20 @@
 # maintain enough binary compatibility to allow future versions of glibc
 # to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
 
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.0
 GLIBC_2.0 {
   # Sampling of DImode arithmetic used by (at least) i386 and m68k.
--- gcc/gcc/config/m32r/libgcc-glibc.ver.quad	2005-11-01 13:53:36.000000000 -0800
+++ gcc/gcc/config/m32r/libgcc-glibc.ver	2008-07-02 08:35:34.000000000 -0700
@@ -8,6 +8,16 @@
 # because GLIBC_2.0 does not exist on this architecture, as the first 
 # ever glibc release on the platform was GLIBC_2.3.
 
+%exclude {
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.3
 GLIBC_2.3 {
   __register_frame
--- gcc/gcc/config/s390/libgcc-glibc.ver.quad	2006-02-04 06:50:59.000000000 -0800
+++ gcc/gcc/config/s390/libgcc-glibc.ver	2008-07-02 08:35:34.000000000 -0700
@@ -9,6 +9,20 @@
 # ever glibc release on the platform was GLIBC_2.2.
 
 %ifndef __s390x__
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.0
 GLIBC_2.0 {
   __divdi3
@@ -27,6 +41,16 @@ GLIBC_2.0 {
 %endif
 
 %ifdef __s390x__
+%exclude {
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.2
 GLIBC_2.2 {
   __register_frame
--- gcc/gcc/config/sh/libgcc-glibc.ver.quad	2005-11-01 13:54:02.000000000 -0800
+++ gcc/gcc/config/sh/libgcc-glibc.ver	2008-07-02 08:35:34.000000000 -0700
@@ -8,6 +8,16 @@
 # because GLIBC_2.0 does not exist on this architecture, as the first 
 # ever glibc release on the platform was GLIBC_2.2.
 
+%exclude {
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.2
 GLIBC_2.2 {
   __register_frame
@@ -18,4 +28,3 @@ GLIBC_2.2 {
   __frame_state_for
   __register_frame_info_table
 }
-
--- gcc/gcc/config/sparc/libgcc-sparc-glibc.ver.quad	2006-02-09 10:34:36.000000000 -0800
+++ gcc/gcc/config/sparc/libgcc-sparc-glibc.ver	2008-07-02 08:35:34.000000000 -0700
@@ -4,6 +4,20 @@
 # maintain enough binary compatibility to allow future versions of glibc
 # to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
 
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %ifdef __arch64__
 %define GLIBC_VER GLIBC_2.2
 %else
--- gcc/gcc/libgcc-std.ver.quad	2007-10-01 19:21:34.000000000 -0700
+++ gcc/gcc/libgcc-std.ver	2008-07-02 08:35:34.000000000 -0700
@@ -1800,3 +1800,7 @@ GCC_4.3.0 {
   __satfractunstiuda
   __satfractunstiuta
 }
+
+%inherit GCC_4.4.0 GCC_4.3.0
+GCC_4.4.0 {
+}
--- gcc/gcc/mkmap-symver.awk.quad	2008-06-06 15:10:06.000000000 -0700
+++ gcc/gcc/mkmap-symver.awk	2008-07-02 08:35:34.000000000 -0700
@@ -46,7 +46,8 @@ state == "nm" && ($1 == "U" || $2 == "U"
 }
 
 state == "nm" && NF == 3 {
-  def[$3] = 1;
+  split ($3, s, "@")
+  def[s[1]] = 1;
   sawsymbol = 1;
   next;
 }
@@ -82,10 +83,13 @@ $1 == "}" {
 
 {
   sym = prefix $1;
+  symbols[sym] = 1
   if (thislib != "%exclude")
-    ver[sym] = thislib;
-  else
-    delete ver[sym];
+    ver[sym, thislib] = 1;
+  else {
+    for (l in libs)
+      ver[sym, l] = 0;
+  }
   next;
 }
 
@@ -107,8 +111,8 @@ function output(lib) {
     output(inherit[lib]);
 
   empty=1
-  for (sym in ver)
-    if ((ver[sym] == lib) && (sym in def))
+  for (sym in symbols)
+    if ((ver[sym, lib] != 0) && (sym in def))
       {
 	if (empty)
 	  {
--- gcc/libgcc/Makefile.in.quad	2008-06-11 07:31:05.000000000 -0700
+++ gcc/libgcc/Makefile.in	2008-07-02 08:35:34.000000000 -0700
@@ -138,7 +138,7 @@ config.h: stamp-h ; @true
 stamp-h: $(srcdir)/config.in config.status Makefile
 	CONFIG_FILES= CONFIG_HEADERS=config.h:$(srcdir)/config.in $(SHELL) ./config.status
 
-config.status: $(srcdir)/configure
+config.status: $(srcdir)/configure $(srcdir)/config.host
 	$(SHELL) ./config.status --recheck
 
 include $(gcc_objdir)/libgcc.mvars
--- gcc/libgcc/config.host.quad	2008-06-10 09:48:12.000000000 -0700
+++ gcc/libgcc/config.host	2008-07-02 08:35:34.000000000 -0700
@@ -578,3 +578,10 @@ i[34567]86-*-linux* | x86_64-*-linux*)
 	tmake_file="${tmake_file} t-tls"
 	;;
 esac
+
+case ${host} in
+i[34567]86-*-darwin* | x86_64-*-darwin* | \
+  i[34567]86-*-linux* | x86_64-*-linux*)
+	tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	;;
+esac
--- gcc/libgcc/config/i386/32/sfp-machine.h.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/libgcc/config/i386/32/sfp-machine.h	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,217 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("add{l} {%11,%3|%3,%11}\n\t"					\
+	   "adc{l} {%9,%2|%2,%9}\n\t"					\
+	   "adc{l} {%7,%1|%1,%7}\n\t"					\
+	   "adc{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "%1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%3" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("add{l} {%8,%2|%2,%8}\n\t"					\
+	   "adc{l} {%6,%1|%1,%6}\n\t"					\
+	   "adc{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+/* FIXME: The last constraint should be "g" instead of "im" if reload
+   works properly.  */
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("sub{l} {%11,%3|%3,%11}\n\t"					\
+	   "sbb{l} {%9,%2|%2,%9}\n\t"					\
+	   "sbb{l} {%7,%1|%1,%7}\n\t"					\
+	   "sbb{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "3" ((USItype) (x0)),					\
+	     "im" ((USItype) (y0)))
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("sub{l} {%8,%2|%2,%8}\n\t"					\
+	   "sbb{l} {%6,%1|%1,%6}\n\t"					\
+	   "sbb{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
+   emulation is done in 16byte.  */
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0, 0, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f;							\
+	__asm__ __volatile__ ("fdiv %0" : "+t" (f));			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("fdivp" : "=t" (f)			\
+			      	      : "0" (f), "u" (g)		\
+				      : "st(1)");			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/32/t-fprules-softfp.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/libgcc/config/i386/32/t-fprules-softfp	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,8 @@
+# Filter out TImode functions
+tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
+
+# Provide fallbacks for __builtin_copysignq and __builtin_fabsq.
+LIB2ADD += $(srcdir)/config/i386/32/tf-signs.c
--- gcc/libgcc/config/i386/32/tf-signs.c.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/libgcc/config/i386/32/tf-signs.c	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,64 @@
+/* Copyright (C) 2008 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 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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 COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+union _FP_UNION_Q
+{
+   __float128 flt;
+   struct 
+   {
+      unsigned long frac0 : 32;
+      unsigned long frac1 : 32;
+      unsigned long frac2 : 32;
+      unsigned long frac3 : 16;
+      unsigned exp : 15;
+      unsigned sign : 1;
+   } bits __attribute__((packed));
+};
+
+__float128
+__copysigntf3 (__float128 a, __float128 b)
+{
+  union _FP_UNION_Q A, B;
+
+  A.flt = a;
+  B.flt = b;
+  A.bits.sign = B.bits.sign;
+
+  return A.flt;
+}
+
+__float128
+__fabstf2 (__float128 a)
+{
+  union _FP_UNION_Q A;
+
+  A.flt = a;
+  A.bits.sign = 0;
+
+  return A.flt;
+}
--- gcc/libgcc/config/i386/64/_divtc3-compat.c.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/libgcc/config/i386/64/_divtc3-compat.c	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __divtc3 __divtc3_shared
+#endif
+
+#define L_divtc3
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __divtc3
+extern __typeof__ (__divtc3_shared) __divtc3_compat __attribute__((alias ("__divtc3_shared")));
+
+asm (".symver __divtc3_compat,__divtc3@GCC_4.0.0");
+asm (".symver __divtc3_shared,__divtc3@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/_multc3-compat.c.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/libgcc/config/i386/64/_multc3-compat.c	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __multc3 __multc3_shared
+#endif
+
+#define L_multc3
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __multc3
+extern __typeof__ (__multc3_shared) __multc3_compat __attribute__((alias ("__multc3_shared")));
+
+asm (".symver __multc3_compat,__multc3@GCC_4.0.0");
+asm (".symver __multc3_shared,__multc3@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/_powitf2-compat.c.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/libgcc/config/i386/64/_powitf2-compat.c	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __powitf2 __powitf2_shared
+#endif
+
+#define L_powitf2
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __powitf2
+extern __typeof__ (__powitf2_shared) __powitf2_compat __attribute__((alias ("__powitf2_shared")));
+
+asm (".symver __powitf2_compat,__powitf2@GCC_4.0.0");
+asm (".symver __powitf2_shared,__powitf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/eqtf2.c.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/libgcc/config/i386/64/eqtf2.c	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __netf2 __netf2_shared
+#endif
+
+#include "config/soft-fp/eqtf2.c"
+
+#ifdef SHARED
+#undef __netf2
+strong_alias (__netf2_shared, __netf2_compat);
+
+asm (".symver __netf2_compat,__netf2@GCC_3.0");
+asm (".symver __netf2_shared,__netf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/getf2.c.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/libgcc/config/i386/64/getf2.c	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __gttf2 __gttf2_shared
+#endif
+
+#include "config/soft-fp/getf2.c"
+
+#ifdef SHARED
+#undef __gttf2
+strong_alias (__gttf2_shared, __gttf2_compat);
+
+asm (".symver __gttf2_compat,__gttf2@GCC_3.0");
+asm (".symver __gttf2_shared,__gttf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/letf2.c.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/libgcc/config/i386/64/letf2.c	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __lttf2 __lttf2_shared
+#endif
+
+#include "config/soft-fp/letf2.c"
+
+#ifdef SHARED
+#undef __lttf2
+strong_alias (__lttf2_shared, __lttf2_compat);
+
+asm (".symver __lttf2_compat,__lttf2@GCC_3.0");
+asm (".symver __lttf2_shared,__lttf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/sfp-machine.h.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/libgcc/config/i386/64/sfp-machine.h	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,143 @@
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y)                           \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f = 0.0;							\
+	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/64/t-fprules-softfp.quad	2008-07-02 08:35:34.000000000 -0700
+++ gcc/libgcc/config/i386/64/t-fprules-softfp	2008-07-02 08:35:34.000000000 -0700
@@ -0,0 +1,12 @@
+# Filter out the following TImode functions and provide backward binary
+# compatibility.
+tf-compats = getf2.c letf2.c eqtf2.c
+tf-functions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tf-compats))
+LIB2ADD := $(filter-out $(tf-functions), $(LIB2ADD))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(tf-compats))
+
+# Replace _divtc3, _multc3 and _powitf2.
+libgcc2-tf-functions = _divtc3 _multc3 _powitf2
+LIB2FUNCS_EXCLUDE += $(libgcc2-tf-functions)
+libgcc2-tf-compats = $(addsuffix -compat.c, $(libgcc2-tf-functions))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(libgcc2-tf-compats))
--- gcc/libgcc/configure.ac.quad	2008-06-22 08:04:12.000000000 -0700
+++ gcc/libgcc/configure.ac	2008-07-02 08:35:34.000000000 -0700
@@ -153,6 +153,21 @@ AC_CACHE_CHECK([whether fixed-point is s
 fixed_point=$libgcc_cv_fixed_point
 AC_SUBST(fixed_point)
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/configure.quad	2008-06-22 08:04:12.000000000 -0700
+++ gcc/libgcc/configure	2008-07-02 08:35:34.000000000 -0700
@@ -3402,6 +3402,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >
 fixed_point=$libgcc_cv_fixed_point
 
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/shared-object.mk.quad	2007-01-09 16:42:39.000000000 -0800
+++ gcc/libgcc/shared-object.mk	2008-07-02 08:35:34.000000000 -0700
@@ -12,7 +12,7 @@ $(base)$(objext): $o
 	$(gcc_compile) $(c_flags) -c $< $(vis_hide)
 
 $(base)_s$(objext): $o
-	$(gcc_s_compile) $(c_flags) -c $<
+	$(gcc_s_compile) -DSHARED $(c_flags) -c $<
 
 else
 
@@ -29,6 +29,6 @@ $(base).vis: $(base)_s$(objext)
 	$(gen-hide-list)
 
 $(base)_s$(objext): $o
-	$(gcc_s_compile) -c -xassembler-with-cpp $<
+	$(gcc_s_compile) -DSHARED -c -xassembler-with-cpp $<
 
 endif

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-07-02 15:53                           ` H.J. Lu
@ 2008-07-02 16:05                             ` H.J. Lu
  2008-07-02 17:54                             ` H.J. Lu
  1 sibling, 0 replies; 32+ messages in thread
From: H.J. Lu @ 2008-07-02 16:05 UTC (permalink / raw)
  To: Uros Bizjak, GCC Patches; +Cc: Joseph S. Myers

On Wed, Jul 2, 2008 at 8:50 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Jul 2, 2008 at 7:45 AM, Ian Lance Taylor <iant@google.com> wrote:
>> "H.J. Lu" <hjl.tools@gmail.com> writes:
>>
>>> gcc/
>>>
>>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>>
>>>       PR target/36669
>>>       * config/i386/libgcc-glibc.ver: New.
>>>
>>>       * config/i386/libgcc-x86_64-glibc.ver: Removed.
>>>
>>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>>
>>>       * config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
>>>       from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
>>>       i[34567]86-*-linux*, x86_64-*-linux*.  Add
>>>       i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
>>>       i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
>>>       x86_64-*-linux*.  Add i386/t-linux to tmake_file for
>>>       i[34567]86-*-linux*, x86_64-*-linux*.
>>>
>>>       * libgcc-std.ver: Add empty GCC_4.4.0.
>>>
>>>       * mkmap-symver.awk: Support multiple versions per symbol.
>>>
>>>       * config/libgcc-glibc.ver: Add %exclude.
>>>
>>>       * config/i386/i386.c (ix86_init_builtins): Always define
>>>       __builtin_fabsq and __builtin_copysignq with fallbacks.
>>>       (ix86_expand_builtin): Emit normal call for __builtin_fabsq
>>>       and __builtin_copysignq if SSE2 isn't available.
>>>
>>>       * config/i386/linux.h (LIBGCC2_HAS_TF_MODE): Defined.
>>>       (LIBGCC2_TF_CEXT): Likwise.
>>>       (TF_SIZE): Likwise.
>>>
>>>       * config/i386/linux64.h (LIBGCC2_HAS_TF_MODE): Defined as 1.
>>>
>>>       * config/i386/sfp-machine.h: Moved to libgcc.
>>>
>>>       * config/i386/sfp-machine.h: New.
>>>       * config/i386/t-linux: Likwise.
>>>
>>>       * config/i386/t-darwin: Remove softfp_wrap_start and
>>>       softfp_wrap_end.
>>>       * config/i386/t-darwin64: Likewise.
>>>
>>>       * config/i386/t-fprules-softfp64: Renamed to ...
>>>       * config/i386/t-fprules-softfp: This.
>>>
>>>       * config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
>>>       and softfp_wrap_end.
>>>
>>> libgcc/
>>>
>>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>>
>>>       PR target/36669
>>>       * shared-object.mk ($(base)_s$(objext)): Add -DSHARED.
>>>
>>>       * config/i386/64/_divtc3-compat.c: New.
>>>       * config/i386/64/_multc3-compat.c: Likewise.
>>>       * config/i386/64/_powitf2-compat.c: Likewise.
>>>       * config/i386/64/eqtf2.c: Likewise.
>>>       * config/i386/64/getf2.c: Likewise.
>>>       * config/i386/64/letf2.c: Likewise.
>>>       * config/i386/64/t-fprules-softfp: Likewise.
>>>
>>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>>
>>>       * config.host: Add i386/${host_address}/t-fprules-softfp to
>>>       tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
>>>       i[34567]86-*-linux*, x86_64-*-linux*.
>>>
>>>       * configure.ac: Set host_address to 64 or 32 for x86.
>>>       * configure: Regenerated.
>>>
>>>       * Makefile.in (config.status): Also depend on
>>>       $(srcdir)/config.host.
>>>
>>>       * config/i386/32/t-fprules-softfp: New.
>>>       * config/i386/32/tf-signs.c: Likewise.
>>>
>>>       * config/i386/64/sfp-machine.h: New. Moved from gcc.
>>>
>>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>>           Uros Bizjak  <ubizjak@gmail.com>
>>>
>>>       * config/i386/32/sfp-machine.h: New.
>>
>>
>>> +%ifdef __x86_64__
>>> +GCC_3.0 {
>>> +  __gttf2
>>> +  __lttf2
>>> +  __netf2
>>> +}
>>> +
>>> +GCC_4.0.0 {
>>> +  __divtc3
>>> +  __multc3
>>> +  __powitf2
>>> +}
>>
>> Please add some comments explaining why we are doing this.
>>
>>
>> This is OK with that change.
>>
>
> This is the patch I am checking in.
>
> Thanks.
>

Hi Uros,

__float128 is now supported on Linux/x86. Is this __float128 testsuite patch:

http://gcc.gnu.org/ml/gcc-patches/2008-06/msg01924.html

OK for trunk? Tested on Linux/ia32, Linux/ia64 and Linux/x86-64.

Thanks.


-- 
H.J.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-07-02 15:53                           ` H.J. Lu
  2008-07-02 16:05                             ` H.J. Lu
@ 2008-07-02 17:54                             ` H.J. Lu
  2008-07-02 19:27                               ` Andreas Tobler
  1 sibling, 1 reply; 32+ messages in thread
From: H.J. Lu @ 2008-07-02 17:54 UTC (permalink / raw)
  To: Ian Lance Taylor
  Cc: Joseph S. Myers, Uros Bizjak, Ian Lance Taylor, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 4136 bytes --]

On Wed, Jul 2, 2008 at 8:50 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Jul 2, 2008 at 7:45 AM, Ian Lance Taylor <iant@google.com> wrote:
>> "H.J. Lu" <hjl.tools@gmail.com> writes:
>>
>>> gcc/
>>>
>>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>>
>>>       PR target/36669
>>>       * config/i386/libgcc-glibc.ver: New.
>>>
>>>       * config/i386/libgcc-x86_64-glibc.ver: Removed.
>>>
>>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>>
>>>       * config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
>>>       from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
>>>       i[34567]86-*-linux*, x86_64-*-linux*.  Add
>>>       i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
>>>       i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
>>>       x86_64-*-linux*.  Add i386/t-linux to tmake_file for
>>>       i[34567]86-*-linux*, x86_64-*-linux*.
>>>
>>>       * libgcc-std.ver: Add empty GCC_4.4.0.
>>>
>>>       * mkmap-symver.awk: Support multiple versions per symbol.
>>>
>>>       * config/libgcc-glibc.ver: Add %exclude.
>>>
>>>       * config/i386/i386.c (ix86_init_builtins): Always define
>>>       __builtin_fabsq and __builtin_copysignq with fallbacks.
>>>       (ix86_expand_builtin): Emit normal call for __builtin_fabsq
>>>       and __builtin_copysignq if SSE2 isn't available.
>>>
>>>       * config/i386/linux.h (LIBGCC2_HAS_TF_MODE): Defined.
>>>       (LIBGCC2_TF_CEXT): Likwise.
>>>       (TF_SIZE): Likwise.
>>>
>>>       * config/i386/linux64.h (LIBGCC2_HAS_TF_MODE): Defined as 1.
>>>
>>>       * config/i386/sfp-machine.h: Moved to libgcc.
>>>
>>>       * config/i386/sfp-machine.h: New.
>>>       * config/i386/t-linux: Likwise.
>>>
>>>       * config/i386/t-darwin: Remove softfp_wrap_start and
>>>       softfp_wrap_end.
>>>       * config/i386/t-darwin64: Likewise.
>>>
>>>       * config/i386/t-fprules-softfp64: Renamed to ...
>>>       * config/i386/t-fprules-softfp: This.
>>>
>>>       * config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
>>>       and softfp_wrap_end.
>>>
>>> libgcc/
>>>
>>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>>
>>>       PR target/36669
>>>       * shared-object.mk ($(base)_s$(objext)): Add -DSHARED.
>>>
>>>       * config/i386/64/_divtc3-compat.c: New.
>>>       * config/i386/64/_multc3-compat.c: Likewise.
>>>       * config/i386/64/_powitf2-compat.c: Likewise.
>>>       * config/i386/64/eqtf2.c: Likewise.
>>>       * config/i386/64/getf2.c: Likewise.
>>>       * config/i386/64/letf2.c: Likewise.
>>>       * config/i386/64/t-fprules-softfp: Likewise.
>>>
>>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>>
>>>       * config.host: Add i386/${host_address}/t-fprules-softfp to
>>>       tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
>>>       i[34567]86-*-linux*, x86_64-*-linux*.
>>>
>>>       * configure.ac: Set host_address to 64 or 32 for x86.
>>>       * configure: Regenerated.
>>>
>>>       * Makefile.in (config.status): Also depend on
>>>       $(srcdir)/config.host.
>>>
>>>       * config/i386/32/t-fprules-softfp: New.
>>>       * config/i386/32/tf-signs.c: Likewise.
>>>
>>>       * config/i386/64/sfp-machine.h: New. Moved from gcc.
>>>
>>> 2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
>>>           Uros Bizjak  <ubizjak@gmail.com>
>>>
>>>       * config/i386/32/sfp-machine.h: New.
>>
>>
>>> +%ifdef __x86_64__
>>> +GCC_3.0 {
>>> +  __gttf2
>>> +  __lttf2
>>> +  __netf2
>>> +}
>>> +
>>> +GCC_4.0.0 {
>>> +  __divtc3
>>> +  __multc3
>>> +  __powitf2
>>> +}
>>
>> Please add some comments explaining why we are doing this.
>>
>>
>> This is OK with that change.
>>
>
> This is the patch I am checking in.
>
> Thanks.
>

The 64bit backward binary compatibility is only needed for Linux/x86.
It isn't needed on Darwin/x86.  Can someone please test it on Darwin/x86?

Thanks.


-- 
H.J.
---
2008-07-02  H.J. Lu  <hongjiu.lu@intel.com>

	PR boostrap/36702
	* config.host: Only include 32bit t-fprules-softfp for Darwin/x86
	and Linux/x86.  Include 64bit t-softfp-compat for Linux/x86.

	* config/i386/64/t-fprules-softfp: Moved to ...
	* config/i386/64/t-softfp-compat: This.  New.

[-- Attachment #2: gcc-darwin-1.patch --]
[-- Type: application/octet-stream, Size: 2556 bytes --]

2008-07-02  H.J. Lu  <hongjiu.lu@intel.com>

	PR boostrap/36702
	* config.host: Only include 32bit t-fprules-softfp for Darwin/x86
	and Linux/x86.  Include 64bit t-softfp-compat for Linux/x86.

	* config/i386/64/t-fprules-softfp: Moved to ...
	* config/i386/64/t-softfp-compat: This.  New.

--- libgcc/config.host.darwin	2008-07-02 09:06:20.000000000 -0700
+++ libgcc/config.host	2008-07-02 10:36:45.000000000 -0700
@@ -582,6 +582,17 @@ esac
 case ${host} in
 i[34567]86-*-darwin* | x86_64-*-darwin* | \
   i[34567]86-*-linux* | x86_64-*-linux*)
-	tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	if test "${host_address}" = 32; then
+		tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	fi
+	;;
+esac
+
+case ${host} in
+i[34567]86-*-linux* | x86_64-*-linux*)
+	# Provide backward binary compatibility for 64bit Linux/x86.
+	if test "${host_address}" = 64; then
+		tmake_file="${tmake_file} i386/${host_address}/t-softfp-compat"
+	fi
 	;;
 esac
--- libgcc/config/i386/64/t-fprules-softfp.darwin	2008-07-02 09:06:20.000000000 -0700
+++ libgcc/config/i386/64/t-fprules-softfp	2008-07-02 10:38:57.000000000 -0700
@@ -1,12 +0,0 @@
-# Filter out the following TImode functions and provide backward binary
-# compatibility.
-tf-compats = getf2.c letf2.c eqtf2.c
-tf-functions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tf-compats))
-LIB2ADD := $(filter-out $(tf-functions), $(LIB2ADD))
-LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(tf-compats))
-
-# Replace _divtc3, _multc3 and _powitf2.
-libgcc2-tf-functions = _divtc3 _multc3 _powitf2
-LIB2FUNCS_EXCLUDE += $(libgcc2-tf-functions)
-libgcc2-tf-compats = $(addsuffix -compat.c, $(libgcc2-tf-functions))
-LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(libgcc2-tf-compats))
--- libgcc/config/i386/64/t-softfp-compat.darwin	2008-07-02 10:29:42.000000000 -0700
+++ libgcc/config/i386/64/t-softfp-compat	2008-07-02 10:29:25.000000000 -0700
@@ -0,0 +1,12 @@
+# Filter out the following TImode functions and provide backward binary
+# compatibility.
+tf-compats = getf2.c letf2.c eqtf2.c
+tf-functions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tf-compats))
+LIB2ADD := $(filter-out $(tf-functions), $(LIB2ADD))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(tf-compats))
+
+# Replace _divtc3, _multc3 and _powitf2.
+libgcc2-tf-functions = _divtc3 _multc3 _powitf2
+LIB2FUNCS_EXCLUDE += $(libgcc2-tf-functions)
+libgcc2-tf-compats = $(addsuffix -compat.c, $(libgcc2-tf-functions))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(libgcc2-tf-compats))

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-06-30  5:43 ` H.J. Lu
@ 2008-07-02 18:49   ` Uros Bizjak
  2008-07-02 19:05     ` H.J. Lu
  0 siblings, 1 reply; 32+ messages in thread
From: Uros Bizjak @ 2008-07-02 18:49 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Joseph S. Myers, GCC Patches

H.J. Lu wrote:
> On Sun, Jun 29, 2008 at 10:36:40AM -0700, H.J. Lu wrote:
>   
>> I am enclosing 3 patches to enable TFmode for x86:
>>
>> 1. gcc-float128-3.patch. Support TFmode in x86 backend.
>> 2. gcc-quad-1.patch. Add x86 support to soft-fp.
>> 3. gcc-quadtest-2.patch. Enable __float80/__float128 tests for
>> x86.
>>
>>     
>
> Here is the updated patch for testcases with simplified targets.
> OK for trunk?
>
> Thanks.
>
>
> H.J.
> ----
> 2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>
>
> 	* g++.dg/abi/mangle24.C: Remove -mmmx.
> 	* gcc.dg/const-float80-ped.c: Likewise.
> 	* gcc.dg/const-float80.c: Likewise.
> 	* gcc.dg/torture/fp-int-convert-float80.c: Likewise.
>
> 	* g++.dg/abi/mangle25.C: Enable x86.
> 	* gcc.dg/const-float128-ped.c: Likewise.
> 	* gcc.dg/const-float128.c: Likewise.
> 	* gcc.dg/torture/fp-int-convert-float128.c: Likewise.
> 	* gcc.target/i386/pr32268.c: Likewise.
>   
You can also remove lp64 requirement for gcc.target/i386/pr32191. This 
one works in TCmode.

The patch is OK for mainline, now that TFmode is fully supported on 
x86_32. Great work, H.J.!

> --- gcc/testsuite/gcc.target/i386/pr32268.c.quadtest	2008-02-17 07:27:09.000000000 -0800
> +++ gcc/testsuite/gcc.target/i386/pr32268.c	2008-06-29 17:16:10.000000000 -0700
> @@ -1,5 +1,4 @@
>  /* { dg-do run { target *-*-linux* } } */
>   
I think that this can also run on darwin.
> -/* { dg-require-effective-target lp64 } */
>  /* { dg-options "-O2" } */
>  
>  extern void abort(void);
>   

Thanks,
Uros.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-07-02 18:49   ` Uros Bizjak
@ 2008-07-02 19:05     ` H.J. Lu
  0 siblings, 0 replies; 32+ messages in thread
From: H.J. Lu @ 2008-07-02 19:05 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: Joseph S. Myers, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 2439 bytes --]

On Wed, Jul 2, 2008 at 11:23 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> H.J. Lu wrote:
>>
>> On Sun, Jun 29, 2008 at 10:36:40AM -0700, H.J. Lu wrote:
>>
>>>
>>> I am enclosing 3 patches to enable TFmode for x86:
>>>
>>> 1. gcc-float128-3.patch. Support TFmode in x86 backend.
>>> 2. gcc-quad-1.patch. Add x86 support to soft-fp.
>>> 3. gcc-quadtest-2.patch. Enable __float80/__float128 tests for
>>> x86.
>>>
>>>
>>
>> Here is the updated patch for testcases with simplified targets.
>> OK for trunk?
>>
>> Thanks.
>>
>>
>> H.J.
>> ----
>> 2008-06-29  H.J. Lu  <hongjiu.lu@intel.com>
>>
>>        * g++.dg/abi/mangle24.C: Remove -mmmx.
>>        * gcc.dg/const-float80-ped.c: Likewise.
>>        * gcc.dg/const-float80.c: Likewise.
>>        * gcc.dg/torture/fp-int-convert-float80.c: Likewise.
>>
>>        * g++.dg/abi/mangle25.C: Enable x86.
>>        * gcc.dg/const-float128-ped.c: Likewise.
>>        * gcc.dg/const-float128.c: Likewise.
>>        * gcc.dg/torture/fp-int-convert-float128.c: Likewise.
>>        * gcc.target/i386/pr32268.c: Likewise.
>>
>
> You can also remove lp64 requirement for gcc.target/i386/pr32191. This one
> works in TCmode.
>
> The patch is OK for mainline, now that TFmode is fully supported on x86_32.
> Great work, H.J.!
>
>> --- gcc/testsuite/gcc.target/i386/pr32268.c.quadtest    2008-02-17
>> 07:27:09.000000000 -0800
>> +++ gcc/testsuite/gcc.target/i386/pr32268.c     2008-06-29
>> 17:16:10.000000000 -0700
>> @@ -1,5 +1,4 @@
>>  /* { dg-do run { target *-*-linux* } } */
>>
>
> I think that this can also run on darwin.
>>
>> -/* { dg-require-effective-target lp64 } */
>>  /* { dg-options "-O2" } */
>>   extern void abort(void);
>>
>

This is the patch I am checking in. I will let Darwin people enable
it. My last 64bit __float128 libgcc change doesn't work on Darwin:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36702

A patch is posted at

http://gcc.gnu.org/ml/gcc-patches/2008-07/msg00127.html

Thanks.

-- 
H.J.
---
2008-07-02  H.J. Lu  <hongjiu.lu@intel.com>

	* g++.dg/abi/mangle24.C: Remove -mmmx.
	* gcc.dg/const-float80-ped.c: Likewise.
	* gcc.dg/const-float80.c: Likewise.
	* gcc.dg/torture/fp-int-convert-float80.c: Likewise.

	* g++.dg/abi/mangle25.C: Enable x86.
	* gcc.dg/const-float128-ped.c: Likewise.
	* gcc.dg/const-float128.c: Likewise.
	* gcc.dg/torture/fp-int-convert-float128.c: Likewise.
	* gcc.target/i386/pr32191.c: Likewise.
	* gcc.target/i386/pr32268.c: Likewise.

[-- Attachment #2: gcc-quadtest-4.patch --]
[-- Type: application/octet-stream, Size: 5459 bytes --]

2008-07-02  H.J. Lu  <hongjiu.lu@intel.com>

	* g++.dg/abi/mangle24.C: Remove -mmmx.
	* gcc.dg/const-float80-ped.c: Likewise.
	* gcc.dg/const-float80.c: Likewise.
	* gcc.dg/torture/fp-int-convert-float80.c: Likewise.

	* g++.dg/abi/mangle25.C: Enable x86.
	* gcc.dg/const-float128-ped.c: Likewise.
	* gcc.dg/const-float128.c: Likewise.
	* gcc.dg/torture/fp-int-convert-float128.c: Likewise.
	* gcc.target/i386/pr32191.c: Likewise.
	* gcc.target/i386/pr32268.c: Likewise.

--- gcc/testsuite/g++.dg/abi/mangle24.C.quadtest	2005-12-10 16:16:18.000000000 -0800
+++ gcc/testsuite/g++.dg/abi/mangle24.C	2008-07-02 09:11:20.000000000 -0700
@@ -5,7 +5,6 @@
 // Origin: Joseph Myers <joseph@codesourcery.com>
 // { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
 // { dg-options "" } */
-// { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 // { dg-final { scan-assembler "_Z1fe" { target i?86-*-* x86_64-*-* } } } */
 // { dg-final { scan-assembler "_Z1fe" { target { ia64-*-* && { ! "ia64-*-hpux*" } } } } } */
 // { dg-final { scan-assembler "_Z1fu9__float80" { target ia64-*-hpux* } } } */
--- gcc/testsuite/g++.dg/abi/mangle25.C.quadtest	2006-01-17 22:04:40.000000000 -0800
+++ gcc/testsuite/g++.dg/abi/mangle25.C	2008-07-02 09:11:20.000000000 -0700
@@ -4,7 +4,7 @@
 // ia64-hpux where "long double" is "e" and __float128 is synonymous with
 // "long double".
 // Origin: Joseph Myers <joseph@codesourcery.com>
-// { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-*} && lp64 } } } }
+// { dg-do compile { target ia64-*-* i?86-*-* x86_64-*-* } }
 // { dg-options "" } */
 // { dg-final { scan-assembler "_Z1fg" { target i?86-*-* x86_64-*-* } } } */
 // { dg-final { scan-assembler "_Z1fg" { target { ia64-*-* && { ! "ia64-*-hpux*" } } } } } */
--- gcc/testsuite/gcc.dg/const-float128-ped.c.quadtest	2007-08-31 12:21:35.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float128-ped.c	2008-07-02 09:11:20.000000000 -0700
@@ -1,5 +1,5 @@
 /* Test 'q' suffix with -pedantic on __float128 type constants.  */
-/* { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-* } && lp64 } } } } */
+/* { dg-do compile { target ia64-*-* i?86-*-* x86_64-*-* } } */
 /* { dg-options "-pedantic" } */
 
 __float128 a = 123.456789q; /* { dg-warning "non-standard suffix on floating constant" } */
--- gcc/testsuite/gcc.dg/const-float128.c.quadtest	2007-08-31 12:21:35.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float128.c	2008-07-02 09:11:20.000000000 -0700
@@ -1,5 +1,5 @@
 /* Test 'q' and 'Q' suffixes on __float128 type constants.  */
-/* { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-* } && lp64 } } } } */
+/* { dg-do compile { target ia64-*-* i?86-*-* x86_64-*-* } } */
 /* { dg-options "" } */
 
 __float128 a = 123.456789q;
--- gcc/testsuite/gcc.dg/const-float80-ped.c.quadtest	2007-07-26 09:21:20.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float80-ped.c	2008-07-02 09:11:20.000000000 -0700
@@ -1,6 +1,5 @@
 /* Test 'w' suffix with -pedantic on __float80 type constants.  */
 /* { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
 /* { dg-options "-pedantic" } */
-/* { dg-options "-mmmx -pedantic" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 __float80 a = 123.456789w;  /* { dg-warning "non-standard suffix on floating constant" } */
--- gcc/testsuite/gcc.dg/const-float80.c.quadtest	2007-07-26 09:21:21.000000000 -0700
+++ gcc/testsuite/gcc.dg/const-float80.c	2008-07-02 09:11:20.000000000 -0700
@@ -1,7 +1,6 @@
 /* Test 'w' and 'W' suffixes on __float80 type constants.  */
 /* { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
 /* { dg-options "" } */
-/* { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 __float80 a = 123.456789W;
 __float80 b = 123.456789w;
--- gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c.quadtest	2007-06-12 05:44:41.000000000 -0700
+++ gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c	2008-07-02 09:11:20.000000000 -0700
@@ -1,6 +1,6 @@
 /* Test floating-point conversions.  __float128 type.  */
 /* Origin: Joseph Myers <joseph@codesourcery.com> */
-/* { dg-do run { target { ia64-*-* || { { i?86-*-* x86_64-*-*} && lp64 } } } } */
+/* { dg-do run { target ia64-*-* i?86-*-* x86_64-*-* } } */
 /* { dg-options "" } */
 
 #include "fp-int-convert.h"
--- gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c.quadtest	2007-05-25 17:42:34.000000000 -0700
+++ gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c	2008-07-02 09:11:20.000000000 -0700
@@ -2,7 +2,6 @@
 /* Origin: Joseph Myers <joseph@codesourcery.com> */
 /* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
 /* { dg-options "" } */
-/* { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 #include "fp-int-convert.h"
 
--- gcc/testsuite/gcc.target/i386/pr32191.c.quadtest	2007-08-27 09:34:52.000000000 -0700
+++ gcc/testsuite/gcc.target/i386/pr32191.c	2008-07-02 11:45:35.000000000 -0700
@@ -1,5 +1,4 @@
 /* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
 /* { dg-options "-std=c99" } */
 
 typedef _Complex float __attribute__((mode(TC))) _Complex128;
--- gcc/testsuite/gcc.target/i386/pr32268.c.quadtest	2008-02-18 09:03:26.000000000 -0800
+++ gcc/testsuite/gcc.target/i386/pr32268.c	2008-07-02 09:11:20.000000000 -0700
@@ -1,5 +1,4 @@
 /* { dg-do run { target *-*-linux* } } */
-/* { dg-require-effective-target lp64 } */
 /* { dg-options "-O2" } */
 
 extern void abort(void);

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-07-02 17:54                             ` H.J. Lu
@ 2008-07-02 19:27                               ` Andreas Tobler
  2008-07-02 19:41                                 ` H.J. Lu
  0 siblings, 1 reply; 32+ messages in thread
From: Andreas Tobler @ 2008-07-02 19:27 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Ian Lance Taylor, Joseph S. Myers, Uros Bizjak, Ian Lance Taylor,
	GCC Patches

H.J. Lu wrote:

> 
> The 64bit backward binary compatibility is only needed for Linux/x86.
> It isn't needed on Darwin/x86.  Can someone please test it on Darwin/x86?

Building runtime libs now. i686-apple-darwin multilib (32/64bit) and 
x86_64-apple-darwin. Passed failing stage on both builds.

Andreas

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: PATCH: Enable TFmode for x86
  2008-07-02 19:27                               ` Andreas Tobler
@ 2008-07-02 19:41                                 ` H.J. Lu
  0 siblings, 0 replies; 32+ messages in thread
From: H.J. Lu @ 2008-07-02 19:41 UTC (permalink / raw)
  To: Andreas Tobler
  Cc: Ian Lance Taylor, Joseph S. Myers, Uros Bizjak, Ian Lance Taylor,
	GCC Patches

On Wed, Jul 2, 2008 at 12:20 PM, Andreas Tobler <andreast-list@fgznet.ch> wrote:
> H.J. Lu wrote:
>
>>
>> The 64bit backward binary compatibility is only needed for Linux/x86.
>> It isn't needed on Darwin/x86.  Can someone please test it on Darwin/x86?
>
> Building runtime libs now. i686-apple-darwin multilib (32/64bit) and
> x86_64-apple-darwin. Passed failing stage on both builds.
>
> Andreas
>

Thanks. I will check it in.

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2008-07-02 19:28 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-29 17:43 PATCH: Enable TFmode for x86 H.J. Lu
2008-06-29 18:37 ` Joseph S. Myers
2008-06-29 19:23   ` H.J. Lu
2008-06-29 20:04     ` H.J. Lu
2008-06-29 20:10       ` Joseph S. Myers
2008-06-29 20:57         ` H.J. Lu
2008-06-29 20:18     ` Joseph S. Myers
2008-06-29 21:07       ` H.J. Lu
2008-06-29 22:44         ` Joseph S. Myers
2008-06-30  1:14           ` H.J. Lu
2008-06-30  7:26             ` Uros Bizjak
2008-06-30 10:28             ` Joseph S. Myers
2008-06-30 12:52             ` Uros Bizjak
2008-06-30 15:22               ` H.J. Lu
2008-06-30 16:22                 ` Uros Bizjak
2008-06-30 17:53                   ` H.J. Lu
2008-06-30 18:10                     ` Uros Bizjak
2008-06-30 19:33                 ` Uros Bizjak
2008-07-01 21:53                   ` H.J. Lu
2008-07-01 22:02                     ` Joseph S. Myers
2008-07-02  3:55                       ` H.J. Lu
2008-07-02  7:29                         ` Uros Bizjak
2008-07-02 14:41                           ` H.J. Lu
2008-07-02 14:57                         ` Ian Lance Taylor
2008-07-02 15:53                           ` H.J. Lu
2008-07-02 16:05                             ` H.J. Lu
2008-07-02 17:54                             ` H.J. Lu
2008-07-02 19:27                               ` Andreas Tobler
2008-07-02 19:41                                 ` H.J. Lu
2008-06-30  5:43 ` H.J. Lu
2008-07-02 18:49   ` Uros Bizjak
2008-07-02 19:05     ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).