diff options
author | Andrew Haley <aph@cygnus.com> | 1999-07-21 14:28:33 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 1999-07-21 14:28:33 +0000 |
commit | aa4759c11cc78443455b69fca236c24ff89c91a1 (patch) | |
tree | 7a86e6410656ef434107be5353da306f7adf35c0 /gcc/java | |
parent | 9c1ce4332e0bfc9289296fde205af0eb3a21e50b (diff) | |
download | gcc-aa4759c11cc78443455b69fca236c24ff89c91a1.zip gcc-aa4759c11cc78443455b69fca236c24ff89c91a1.tar.gz gcc-aa4759c11cc78443455b69fca236c24ff89c91a1.tar.bz2 |
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
Diffstat (limited to 'gcc/java')
-rw-r--r-- | gcc/java/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/java/decl.c | 25 | ||||
-rw-r--r-- | gcc/java/expr.c | 60 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 8 | ||||
-rw-r--r-- | gcc/java/lang.c | 4 | ||||
-rw-r--r-- | gcc/java/parse.y | 6 | ||||
-rw-r--r-- | gcc/java/typeck.c | 49 |
7 files changed, 153 insertions, 19 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 2e7bb3a..372d29441 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,23 @@ +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. diff --git a/gcc/java/decl.c b/gcc/java/decl.c index de03e5fd..6779747 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -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 (); } diff --git a/gcc/java/expr.c b/gcc/java/expr.c index d47ed1a..dbf6db5 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -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: ; } diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index be1f143..307218c 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -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)); diff --git a/gcc/java/lang.c b/gcc/java/lang.c index cd6fb3b..976ed64 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -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; diff --git a/gcc/java/parse.y b/gcc/java/parse.y index be1c788..23b2c7a 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -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. */ diff --git a/gcc/java/typeck.c b/gcc/java/typeck.c index 1416245..99536ff 100644 --- a/gcc/java/typeck.c +++ b/gcc/java/typeck.c @@ -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 |