[gcjx] Patch: FYI: fix float->int conversions in tree code

Tom Tromey tromey@redhat.com
Tue Oct 11 18:09:00 GMT 2005


I'm checking this in on the gcjx branch.

This cleans up the float->int conversion code in the gcc front end.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* lower.cc (handle_convert): Use convert_to_integer.
	* tree.cc (visit_cast): Handle float->integral conversions
	properly.

Index: lower.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/lower.cc,v
retrieving revision 1.1.2.20
diff -u -r1.1.2.20 lower.cc
--- lower.cc 18 May 2005 00:10:49 -0000 1.1.2.20
+++ lower.cc 11 Oct 2005 18:08:56 -0000
@@ -1631,50 +1631,25 @@
 tree
 tree_generator::handle_convert (model_type *dest_type, tree expr)
 {
+  assert (dest_type == primitive_int_type || dest_type == primitive_long_type);
+
   tree min_tree, max_tree;
   tree dest_tree = gcc_builtins->map_type (dest_type);
 
-  {
-    // Crazy gyrations to avoid dependency on sizeof (HOST_WIDE_INT).
-    // Some bit-twiddling genius should rewrite this.
-    HOST_WIDE_INT minlo, minhi, maxlo, maxhi;
-    HOST_WIDE_INT *pmin = &minlo, *pmax = &maxlo;
-    int n = dest_type == primitive_int_type ? 4 : 8;
-    int i, bits;
-    for (i = 0, bits = 0; i < 2 * sizeof (HOST_WIDE_INT); ++i, bits += 8)
-      {
-	if (i == sizeof (HOST_WIDE_INT))
-	  {
-	    pmin = &minhi;
-	    pmax = &maxhi;
-	  }
-
-	HOST_WIDE_INT minbits, maxbits;
-	if (i > n)
-	  {
-	    minbits = 0xff;
-	    maxbits = 0x00;
-	  }
-	else if (i == n)
-	  {
-	    minbits = 0x80;
-	    maxbits = 0x7f;
-	  }
-	else
-	  {
-	    minbits = 0x00;
-	    maxbits = 0xff;
-	  }
-
-	*pmin |= minbits << bits;
-	*pmax |= maxbits << bits;
-      }
+  if (dest_type == primitive_int_type)
+    {
+      min_tree = build_int (MIN_INT);
+      max_tree = build_int (MAX_INT);
+    }
+  else
+    {
+      min_tree = build_long (MIN_LONG);
+      max_tree = build_long (MAX_LONG);
+    }
+  assert (TREE_TYPE (min_tree) == dest_tree);
 
-    min_tree = convert (TREE_TYPE (expr),
-			build_int_cst_wide (dest_tree, minlo, minhi));
-    max_tree = convert (TREE_TYPE (expr),
-			build_int_cst_wide (dest_tree, maxlo, maxhi));
-  }
+  min_tree = convert (TREE_TYPE (expr), min_tree);
+  max_tree = convert (TREE_TYPE (expr), max_tree);
 
   expr = save_expr (expr);
 
@@ -1687,7 +1662,7 @@
   tree ne = build2 (NE_EXPR, type_jboolean, expr, expr);
   tree cond = build3 (COND_EXPR, dest_tree, ne,
 		      build_int_cst (dest_tree, 0),
-		      convert (dest_tree, expr));
+		      convert_to_integer (dest_tree, expr));
 
   // Now build:
   //   if (val <= (FROM) min) return min; else [ the above ]
Index: tree.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/tree.cc,v
retrieving revision 1.1.2.61
diff -u -r1.1.2.61 tree.cc
--- tree.cc 11 Oct 2005 01:49:08 -0000 1.1.2.61
+++ tree.cc 11 Oct 2005 18:08:57 -0000
@@ -1764,7 +1764,8 @@
   tree expr_tree = current;
 
   model_type *dest_type = dest->type ();
-  if (dest_type->primitive_p () != expr->type ()->primitive_p ())
+  model_type *expr_type = expr->type ();
+  if (dest_type->primitive_p () != expr_type->primitive_p ())
     {
       if (dest_type->primitive_p ())
 	{
@@ -1776,13 +1777,13 @@
 	  // FIXME: for the C++ ABI we could reference fields directly
 	  // in some situations.
 	  model_type *tmp_dest_type = dest_type;
-	  if (expr->type () == global->get_compiler ()->java_lang_Character ())
+	  if (expr_type == global->get_compiler ()->java_lang_Character ())
 	    tmp_dest_type = primitive_char_type;
 	  std::string method_name = (tmp_dest_type->get_pretty_name ()
 				     + "Value");
 	  model_method *call
 	    = find_method (method_name.c_str (),
-			   assert_cast<model_class *> (expr->type ()),
+			   assert_cast<model_class *> (expr_type),
 			   NULL, tmp_dest_type, elt);
 	  current = gcc_builtins->map_method_call (class_wrapper, expr_tree,
 						   NULL_TREE, call, false);
@@ -1799,7 +1800,7 @@
 	  // conversion.
 	  model_class *dest_class = assert_cast<model_class *> (dest_type);
 	  model_method *call = find_method ("valueOf", dest_class,
-					    expr->type (), dest_class,
+					    expr_type, dest_class,
 					    elt);
 	  tree args = build_tree_list (NULL_TREE, expr_tree);
 	  current = gcc_builtins->map_method_call (class_wrapper, NULL_TREE,
@@ -1809,16 +1810,32 @@
     }
   else if (dest_type->primitive_p ())
     {
-      // We can't use fold_convert() here since, apparently, it can't
-      // convert a float to an int.
-      current = convert (gcc_builtins->map_type (dest_type), expr_tree);
-      TREE_SIDE_EFFECTS (current) = TREE_SIDE_EFFECTS (expr_tree);
+      if (dest_type->integral_p () && (expr_type == primitive_float_type
+				       || expr_type == primitive_double_type))
+	{
+	  // We have to use 'int' as an intermediate type in cases
+	  // like float->byte.
+	  model_type *inter = dest_type;
+	  if (dest_type != primitive_int_type
+	      && dest_type != primitive_long_type)
+	    inter = primitive_int_type;
+	  current = handle_convert (inter, expr_tree);
+	  if (inter != dest_type)
+	    current = convert (gcc_builtins->map_type (dest_type), current);
+	  TREE_SIDE_EFFECTS (current) = TREE_SIDE_EFFECTS (expr_tree);
+	}
+      else
+	{
+	  current = fold_convert (gcc_builtins->map_type (dest_type),
+				  expr_tree);
+	  TREE_SIDE_EFFECTS (current) = TREE_SIDE_EFFECTS (expr_tree);
+	}
     }
   else
     {
       // Reference types.  We only need to emit a cast check if the
       // types are known to be incompatible.
-      if (! dest_type->assignable_from_p (expr->type ()))
+      if (! dest_type->assignable_from_p (expr_type))
 	{
 	  current = build3 (CALL_EXPR, gcc_builtins->map_type (dest_type),
 			    builtin_Jv_CheckCast,
@@ -1830,7 +1847,7 @@
 	}
       else
 	{
-	  emit_type_assertion (dest_type, expr->type ());
+	  emit_type_assertion (dest_type, expr_type);
 	  current = build1 (NOP_EXPR, gcc_builtins->map_type (dest_type),
 			    expr_tree);
 	  TREE_SIDE_EFFECTS (current) = TREE_SIDE_EFFECTS (expr_tree);



More information about the Java-patches mailing list