? arm1.txt Index: gcc/config/arm/arm.h =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3cc/gcc/gcc/config/arm/arm.h,v retrieving revision 1.5 diff -u -w -r1.5 arm.h --- gcc/config/arm/arm.h 14 Apr 2008 12:48:34 -0000 1.5 +++ gcc/config/arm/arm.h 19 Jun 2010 09:02:42 -0000 @@ -2799,4 +2799,6 @@ #define NEED_INDICATE_EXEC_STACK 0 #endif +#define M3_MOD64_CALL 1 + #endif /* ! GCC_ARM_H */ Index: gcc/m3cg/parse.c =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3cc/gcc/gcc/m3cg/parse.c,v retrieving revision 1.185 diff -u -w -r1.185 parse.c --- gcc/m3cg/parse.c 6 Jun 2010 15:08:38 -0000 1.185 +++ gcc/m3cg/parse.c 19 Jun 2010 09:02:43 -0000 @@ -74,6 +74,9 @@ #ifndef TARGET_ARCH32 #define TARGET_ARCH32 0 #endif +#ifndef M3_MOD64_CALL +#define M3_MOD64_CALL 0 +#endif /* in particular, Solaris/sparc32 has a stack walker */ #define M3_ALL_VOLATILE (TARGET_SPARC && TARGET_SOLARIS && TARGET_ARCH32) @@ -188,6 +191,7 @@ static GTY (()) tree memmove_proc; static GTY (()) tree memset_proc; static GTY (()) tree memcmp_proc; +static GTY (()) tree mod64_proc; static GTY (()) tree set_union_proc; static GTY (()) tree set_diff_proc; static GTY (()) tree set_inter_proc; @@ -1137,6 +1141,12 @@ memcmp_proc = built_in_decls[BUILT_IN_MEMCMP]; #endif + if (M3_MOD64_CALL) + { + t = build_function_type_list (t_int_64, t_int_64, t_int_64, NULL_TREE); + mod64_proc = builtin_function ("m3_mod64", t, 0, NOT_BUILT_IN, NULL, NULL_TREE); + } + t = build_function_type_list (t_void, NULL_TREE); set_union_proc = builtin_function ("set_union", t, 0, NOT_BUILT_IN, NULL, NULL_TREE); @@ -4186,6 +4196,55 @@ } } +#if 0 /* possibly more optimal */ + +static void +m3cg_div (void) +{ + MTYPE2 (t, T); + SIGN (a); + SIGN (b); + enum tree_code code = FLOOR_DIV_EXPR; + + if ((a == b) || IS_WORD_TYPE(T)) + code = TRUNC_DIV_EXPR; + + EXPR_REF (-2) = m3_build2 (code, t, + m3_cast (t, EXPR_REF (-2)), + m3_cast (t, EXPR_REF (-1))); + EXPR_POP (); +} + +static void +m3cg_mod (void) +{ + MTYPE2 (t, T); + SIGN (a); + SIGN (b); + enum tree_code code = FLOOR_MOD_EXPR; + + if ((a == b) || IS_WORD_TYPE(T)) + code = TRUNC_MOD_EXPR; + + if ((!M3_MOD64_CALL) || (code == TRUNC_MOD_EXPR) + || (TYPE_SIZE (t) != TYPE_SIZE (long_long_integer_type_node))) + { + EXPR_REF (-2) = m3_build2 (code, t, + m3_cast (t, EXPR_REF (-2)), + m3_cast (t, EXPR_REF (-1))); + EXPR_POP (); + } + else + { + m3_start_call (); + m3_pop_param (t); + m3_pop_param (t); + m3_call_direct (mod64_proc, TREE_TYPE (TREE_TYPE (mod64_proc))); + } +} + +#else /* safer */ + static void m3cg_div (void) { @@ -4206,11 +4265,24 @@ UNUSED_SIGN (a); UNUSED_SIGN (b); + if ((!M3_MOD64_CALL) || + || (TYPE_SIZE (t) != TYPE_SIZE (long_long_integer_type_node))) + { EXPR_REF (-2) = m3_build2 (FLOOR_MOD_EXPR, t, m3_cast (t, EXPR_REF (-2)), m3_cast (t, EXPR_REF (-1))); EXPR_POP (); } + else + { + m3_start_call (); + m3_pop_param (t); + m3_pop_param (t); + m3_call_direct (mod64_proc, TREE_TYPE (TREE_TYPE (mod64_proc))); + } +} + +#endif static void m3cg_set_union (void)