Commit aa4759c1 by Andrew Haley Committed by Andrew Haley

lang.c (flag_use_divide_subroutine): New variable.

1999-07-15  Andrew Haley  <aph@cygnus.com>

        * lang.c (flag_use_divide_subroutine): New variable.
        * typeck.c: (convert_ieee_real_to_integer): Bounds check
        fp-to-integer conversion.
        (convert): Call convert_ieee_real_to_integer when flag_fast_math
        is not set.

        * expr.c (build_java_soft_divmod): New function.
        (build_java_binop): Call build_java_soft_divmod if
        flag_use_divide_subroutine is set.
        * decl.c: soft_idiv_node, soft_irem_node, soft_ldiv_node, tree
        soft_lrem_node: new builtin functions.
        (init_decl_processing) Initialize the new builtins.
        * java-tree.h soft_idiv_node, soft_irem_node, soft_ldiv_node, tree
        soft_lrem_node: new builtin functions.
        (build_java_soft_divmod): New function.
        * parse.y: Call build_java_soft_divmod if
        flag_use_divide_subroutine is set.

From-SVN: r28208
parent 9c1ce433
1999-07-15 Andrew Haley <aph@cygnus.com>
* lang.c (flag_use_divide_subroutine): New variable.
* typeck.c: (convert_ieee_real_to_integer): Bounds check
fp-to-integer conversion.
(convert): Call convert_ieee_real_to_integer when flag_fast_math
is not set.
* expr.c (build_java_soft_divmod): New function.
(build_java_binop): Call build_java_soft_divmod if
flag_use_divide_subroutine is set.
* decl.c: soft_idiv_node, soft_irem_node, soft_ldiv_node, tree
soft_lrem_node: new builtin functions.
(init_decl_processing) Initialize the new builtins.
* java-tree.h soft_idiv_node, soft_irem_node, soft_ldiv_node, tree
soft_lrem_node: new builtin functions.
(build_java_soft_divmod): New function.
* parse.y: Call build_java_soft_divmod if
flag_use_divide_subroutine is set.
Tue Jul 20 13:20:05 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
* parse.y (resolve_and_layout): Check methods only once.
......
......@@ -365,6 +365,11 @@ tree soft_monitorexit_node;
tree soft_lookupinterfacemethod_node;
tree soft_fmod_node;
tree soft_exceptioninfo_call_node;
tree soft_idiv_node;
tree soft_irem_node;
tree soft_ldiv_node;
tree soft_lrem_node;
/* Build (and pushdecl) a "promoted type" for all standard
types shorter than int. */
......@@ -812,6 +817,26 @@ init_decl_processing ()
BUILT_IN_FMOD, "fmodf");
#endif
soft_idiv_node
= builtin_function ("_Jv_divI",
build_function_type (int_type_node, t),
NOT_BUILT_IN, NULL_PTR);
soft_irem_node
= builtin_function ("_Jv_remI",
build_function_type (int_type_node, t),
NOT_BUILT_IN, NULL_PTR);
soft_ldiv_node
= builtin_function ("_Jv_divJ",
build_function_type (long_type_node, t),
NOT_BUILT_IN, NULL_PTR);
soft_lrem_node
= builtin_function ("_Jv_remJ",
build_function_type (long_type_node, t),
NOT_BUILT_IN, NULL_PTR);
init_class_processing ();
}
......
......@@ -1052,6 +1052,53 @@ expand_iinc (local_var_index, ival, pc)
expand_assignment (local_var, res, 0, 0);
}
tree
build_java_soft_divmod (op, type, op1, op2)
enum tree_code op;
tree type, op1, op2;
{
tree call = NULL;
tree arg1 = convert (type, op1);
tree arg2 = convert (type, op2);
if (type == int_type_node)
{
switch (op)
{
case TRUNC_DIV_EXPR:
call = soft_idiv_node;
break;
case TRUNC_MOD_EXPR:
call = soft_irem_node;
break;
}
}
else if (type == long_type_node)
{
switch (op)
{
case TRUNC_DIV_EXPR:
call = soft_ldiv_node;
break;
case TRUNC_MOD_EXPR:
call = soft_lrem_node;
break;
}
}
if (! call)
fatal ("Internal compiler error in build_java_soft_divmod");
call = build (CALL_EXPR, type,
build_address_of (call),
tree_cons (NULL_TREE, arg1,
build_tree_list (NULL_TREE, arg2)),
NULL_TREE);
return call;
}
tree
build_java_binop (op, type, arg1, arg2)
enum tree_code op;
......@@ -1100,10 +1147,11 @@ build_java_binop (op, type, arg1, arg2)
integer_zero_node));
return fold (build (COND_EXPR, int_type_node,
ifexp1, integer_negative_one_node, second_compare));
}
}
case TRUNC_DIV_EXPR:
case TRUNC_MOD_EXPR:
if (TREE_CODE (type) == REAL_TYPE)
if (TREE_CODE (type) == REAL_TYPE
&& op == TRUNC_MOD_EXPR)
{
tree call;
if (type != double_type_node)
......@@ -1120,6 +1168,12 @@ build_java_binop (op, type, arg1, arg2)
call = convert (type, call);
return call;
}
if (TREE_CODE (type) == INTEGER_TYPE
&& flag_use_divide_subroutine
&& ! flag_syntax_only)
return build_java_soft_divmod (op, type, arg1, arg2);
break;
default: ;
}
......
......@@ -141,6 +141,9 @@ extern int flag_redundant;
extern int flag_not_overriding;
extern int flag_static_local_jdk1_1;
/* When non zero, call a library routine to do integer divisions. */
extern int flag_use_divide_subroutine;
/* The Java .class file that provides main_class; the main input file. */
extern struct JCF *current_jcf;
......@@ -283,6 +286,10 @@ extern tree soft_monitorexit_node;
extern tree soft_lookupinterfacemethod_node;
extern tree soft_fmod_node;
extern tree soft_exceptioninfo_call_node;
extern tree soft_idiv_node;
extern tree soft_irem_node;
extern tree soft_ldiv_node;
extern tree soft_lrem_node;
extern tree access_flags_type_node;
......@@ -544,6 +551,7 @@ extern tree invoke_build_dtable PROTO ((int, tree));
extern tree build_field_ref PROTO ((tree, tree, tree));
extern void pushdecl_force_head PROTO ((tree));
extern tree build_java_binop PROTO ((enum tree_code, tree, tree, tree));
extern tree build_java_soft_divmod PROTO ((enum tree_code, tree, tree, tree));
extern tree binary_numeric_promotion PROTO ((tree, tree, tree *, tree *));
extern tree build_java_arrayaccess PROTO ((tree, tree, tree));
extern tree build_newarray PROTO ((int, tree));
......
......@@ -105,6 +105,9 @@ int flag_not_overriding = 0;
/* When non zero, warns that final local are treated as non final. */
int flag_static_local_jdk1_1 = 0;
/* When non zero, call a library routine to do integer divisions. */
int flag_use_divide_subroutine = 1;
/* From gcc/flags.h, and indicates if exceptions are turned on or not. */
extern int flag_new_exceptions;
......@@ -123,6 +126,7 @@ lang_f_options[] =
{"assume-compiled", &flag_assume_compiled, 1},
{"emit-class-file", &flag_emit_class_files, 1},
{"emit-class-files", &flag_emit_class_files, 1},
{"use-divide-subroutine", &flag_use_divide_subroutine, 1},
};
JCF *current_jcf;
......
......@@ -9411,6 +9411,12 @@ patch_binop (node, wfl_op1, wfl_op2)
if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
TREE_SET_CODE (node, TRUNC_DIV_EXPR);
if (TREE_CODE (prom_type) == INTEGER_TYPE
&& flag_use_divide_subroutine
&& ! flag_emit_class_files
&& (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
/* This one is more complicated. FLOATs are processed by a
function call to soft_fmod. Duplicate the value of the
COMPOUND_ASSIGN_P flag. */
......
......@@ -55,23 +55,43 @@ set_local_type (slot, type)
/* Convert an IEEE real to an integer type. The result of such a
conversion when the source operand is a NaN isn't defined by
IEEE754, but by the Java language standard: it must be zero. This
conversion produces something like:
({ double tmp = expr; (tmp != tmp) ? 0 : (int)tmp; })
*/
IEEE754, but by the Java language standard: it must be zero. Also,
overflows must be clipped to within range. This conversion
produces something like:
((expr >= (float)MAX_INT)
? MAX_INT
: ((expr <= (float)MIN_INT)
? MIN_INT
: ((expr != expr)
? 0
: (int)expr))) */
static tree
convert_ieee_real_to_integer (type, expr)
tree type, expr;
{
tree result;
expr = save_expr (expr);
return build (COND_EXPR, type,
build (NE_EXPR, boolean_type_node, expr, expr),
convert (type, integer_zero_node),
convert_to_integer (type, expr));
result = build (COND_EXPR, type,
build (NE_EXPR, boolean_type_node, expr, expr),
convert (type, integer_zero_node),
convert_to_integer (type, expr));
result = build (COND_EXPR, type,
build (LE_EXPR, boolean_type_node, expr,
convert (TREE_TYPE (expr), TYPE_MIN_VALUE (type))),
TYPE_MIN_VALUE (type),
result);
result = build (COND_EXPR, type,
build (GE_EXPR, boolean_type_node, expr,
convert (TREE_TYPE (expr), TYPE_MAX_VALUE (type))),
TYPE_MAX_VALUE (type),
result);
return result;
}
/* Create an expression whose value is that of EXPR,
......@@ -100,12 +120,9 @@ convert (type, expr)
return fold (convert_to_boolean (type, expr));
if (code == INTEGER_TYPE)
{
if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
#ifdef TARGET_SOFT_FLOAT
&& !TARGET_SOFT_FLOAT
#endif
&& !flag_emit_class_files
&& !flag_fast_math
if (! flag_fast_math
&& ! flag_emit_class_files
&& TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
&& TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
return fold (convert_ieee_real_to_integer (type, expr));
else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment