[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