From: Zoltan Varga Date: Fri, 7 Sep 2012 21:02:25 +0000 (+0200) Subject: Move the imul/idiv/irem emulation code out of #ifndef MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;ds=sidebyside;h=22ac526dc68a9e91e8c8a1578e2fec20d38d4041;p=mono.git Move the imul/idiv/irem emulation code out of #ifndef MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS. --- diff --git a/mono/mini/jit-icalls.c b/mono/mini/jit-icalls.c index 2f75e4301b5..7f485f74f2a 100644 --- a/mono/mini/jit-icalls.c +++ b/mono/mini/jit-icalls.c @@ -234,51 +234,48 @@ mono_llmult_ovf (gint64 a, gint64 b) return 0; } -#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_DIV) - -gint32 -mono_idiv (gint32 a, gint32 b) +gint64 +mono_lldiv (gint64 a, gint64 b) { MONO_ARCH_SAVE_REGS; #ifdef MONO_ARCH_NEED_DIV_CHECK if (!b) mono_raise_exception (mono_get_exception_divide_by_zero ()); - else if (b == -1 && a == (0x80000000)) - mono_raise_exception (mono_get_exception_overflow ()); + else if (b == -1 && a == (-9223372036854775807LL - 1LL)) + mono_raise_exception (mono_get_exception_arithmetic ()); #endif return a / b; } -guint32 -mono_idiv_un (guint32 a, guint32 b) +gint64 +mono_llrem (gint64 a, gint64 b) { MONO_ARCH_SAVE_REGS; #ifdef MONO_ARCH_NEED_DIV_CHECK if (!b) mono_raise_exception (mono_get_exception_divide_by_zero ()); + else if (b == -1 && a == (-9223372036854775807LL - 1LL)) + mono_raise_exception (mono_get_exception_arithmetic ()); #endif - return a / b; + return a % b; } -gint32 -mono_irem (gint32 a, gint32 b) +guint64 +mono_lldiv_un (guint64 a, guint64 b) { MONO_ARCH_SAVE_REGS; #ifdef MONO_ARCH_NEED_DIV_CHECK if (!b) mono_raise_exception (mono_get_exception_divide_by_zero ()); - else if (b == -1 && a == (0x80000000)) - mono_raise_exception (mono_get_exception_overflow ()); #endif - - return a % b; + return a / b; } -guint32 -mono_irem_un (guint32 a, guint32 b) +guint64 +mono_llrem_un (guint64 a, guint64 b) { MONO_ARCH_SAVE_REGS; @@ -291,99 +288,94 @@ mono_irem_un (guint32 a, guint32 b) #endif -#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_MUL_OVF) - -gint32 -mono_imul (gint32 a, gint32 b) -{ - MONO_ARCH_SAVE_REGS; - - return a * b; -} +#ifndef MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS -gint32 -mono_imul_ovf (gint32 a, gint32 b) +guint64 +mono_lshl (guint64 a, gint32 shamt) { - gint64 res; - - MONO_ARCH_SAVE_REGS; + guint64 res; - res = (gint64)a * (gint64)b; + /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/ + res = a << shamt; - if ((res > 0x7fffffffL) || (res < -2147483648LL)) - mono_raise_exception (mono_get_exception_overflow ()); + /*printf ("TESTL %lld << %d = %lld\n", a, shamt, res);*/ return res; } -gint32 -mono_imul_ovf_un (guint32 a, guint32 b) +guint64 +mono_lshr_un (guint64 a, gint32 shamt) { guint64 res; - MONO_ARCH_SAVE_REGS; - - res = (guint64)a * (guint64)b; + /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/ + res = a >> shamt; - if ((res >> 32)) - mono_raise_exception (mono_get_exception_overflow ()); + /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/ return res; } -#endif -#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_SOFT_FLOAT) -double -mono_fdiv (double a, double b) +gint64 +mono_lshr (gint64 a, gint32 shamt) { - MONO_ARCH_SAVE_REGS; + gint64 res; - return a / b; + /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/ + res = a >> shamt; + + /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/ + + return res; } + #endif -gint64 -mono_lldiv (gint64 a, gint64 b) +#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_DIV) + +gint32 +mono_idiv (gint32 a, gint32 b) { MONO_ARCH_SAVE_REGS; #ifdef MONO_ARCH_NEED_DIV_CHECK if (!b) mono_raise_exception (mono_get_exception_divide_by_zero ()); - else if (b == -1 && a == (-9223372036854775807LL - 1LL)) - mono_raise_exception (mono_get_exception_arithmetic ()); + else if (b == -1 && a == (0x80000000)) + mono_raise_exception (mono_get_exception_overflow ()); #endif return a / b; } -gint64 -mono_llrem (gint64 a, gint64 b) +guint32 +mono_idiv_un (guint32 a, guint32 b) { MONO_ARCH_SAVE_REGS; #ifdef MONO_ARCH_NEED_DIV_CHECK if (!b) mono_raise_exception (mono_get_exception_divide_by_zero ()); - else if (b == -1 && a == (-9223372036854775807LL - 1LL)) - mono_raise_exception (mono_get_exception_arithmetic ()); #endif - return a % b; + return a / b; } -guint64 -mono_lldiv_un (guint64 a, guint64 b) +gint32 +mono_irem (gint32 a, gint32 b) { MONO_ARCH_SAVE_REGS; #ifdef MONO_ARCH_NEED_DIV_CHECK if (!b) mono_raise_exception (mono_get_exception_divide_by_zero ()); + else if (b == -1 && a == (0x80000000)) + mono_raise_exception (mono_get_exception_overflow ()); #endif - return a / b; + + return a % b; } -guint64 -mono_llrem_un (guint64 a, guint64 b) +guint32 +mono_irem_un (guint32 a, guint32 b) { MONO_ARCH_SAVE_REGS; @@ -396,47 +388,55 @@ mono_llrem_un (guint64 a, guint64 b) #endif -#ifndef MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS +#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_MUL_OVF) -guint64 -mono_lshl (guint64 a, gint32 shamt) +gint32 +mono_imul (gint32 a, gint32 b) { - guint64 res; - - /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/ - res = a << shamt; - - /*printf ("TESTL %lld << %d = %lld\n", a, shamt, res);*/ + MONO_ARCH_SAVE_REGS; - return res; + return a * b; } -guint64 -mono_lshr_un (guint64 a, gint32 shamt) +gint32 +mono_imul_ovf (gint32 a, gint32 b) { - guint64 res; + gint64 res; - /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/ - res = a >> shamt; + MONO_ARCH_SAVE_REGS; - /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/ + res = (gint64)a * (gint64)b; + + if ((res > 0x7fffffffL) || (res < -2147483648LL)) + mono_raise_exception (mono_get_exception_overflow ()); return res; } -gint64 -mono_lshr (gint64 a, gint32 shamt) +gint32 +mono_imul_ovf_un (guint32 a, guint32 b) { - gint64 res; + guint64 res; - /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/ - res = a >> shamt; + MONO_ARCH_SAVE_REGS; - /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/ + res = (guint64)a * (guint64)b; + + if ((res >> 32)) + mono_raise_exception (mono_get_exception_overflow ()); return res; } +#endif + +#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_SOFT_FLOAT) +double +mono_fdiv (double a, double b) +{ + MONO_ARCH_SAVE_REGS; + return a / b; +} #endif #ifdef MONO_ARCH_SOFT_FLOAT