2009-01-30 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Fri, 30 Jan 2009 13:32:51 +0000 (13:32 -0000)
committerZoltan Varga <vargaz@gmail.com>
Fri, 30 Jan 2009 13:32:51 +0000 (13:32 -0000)
* mini.c (mini_init): Register mono_isfinite.

* jit-icalls.c (mono_isfinite): New jit icall.

* method-to-ir.c (mono_decompose_soft_float): Add support for OP_CKFINITE.

svn path=/trunk/mono/; revision=125086

mono/mini/ChangeLog
mono/mini/jit-icalls.c
mono/mini/jit-icalls.h
mono/mini/method-to-ir.c
mono/mini/mini.c

index 9721dd719ed0d9726016a16917906f6a60493ba6..0c72e26f5b142ab69437071a3cbaefde3ab688b5 100644 (file)
@@ -1,5 +1,11 @@
 2009-01-30  Zoltan Varga  <vargaz@gmail.com>
 
+       * mini.c (mini_init): Register mono_isfinite.
+
+       * jit-icalls.c (mono_isfinite): New jit icall.
+
+       * method-to-ir.c (mono_decompose_soft_float): Add support for OP_CKFINITE.
+       
        * exceptions-arm.c (mono_arch_find_jit_info): When unwinding using the LMF,
        set esp to ARMREG_FP instead of R12, since R12 stores the value of sp for
        the parent frame.
index 4a5de5dc7a74a1193a5c9c90ee7134e1dea1c82e..fc5602f3c627e7cd087f7e01ee0a0ac5c6e73f49 100644 (file)
@@ -600,6 +600,17 @@ mono_fclt_un (double a, double b)
        return isunordered (a, b) || a < b;
 }
 
+gboolean
+mono_isfinite (double a)
+{
+#ifdef HAVE_ISFINITE
+       return isfinite (a);
+#else
+       g_assert_not_reached ();
+       return TRUE;
+#endif
+}
+
 double
 mono_fload_r4 (float *ptr)
 {
index 8461d2362b30d194cf48ca60e666c2d3c208aadb..05585345b52a53341ebaf7ceb761a3b265542cbc 100644 (file)
@@ -141,6 +141,8 @@ gboolean mono_fclt (double a, double b) MONO_INTERNAL;
 
 gboolean mono_fclt_un (double a, double b) MONO_INTERNAL;
 
+gboolean mono_isfinite (double a) MONO_INTERNAL;
+
 double   mono_fload_r4 (float *ptr) MONO_INTERNAL;
 
 void     mono_fstore_r4 (double val, float *ptr) MONO_INTERNAL;
index 3e332fe2d8166c2fe774d42cf2e5e0cc6ba24d8a..021c5d9cf36e7efb9ff822f40b6c696cc2178f7d 100644 (file)
@@ -4943,6 +4943,31 @@ mono_decompose_soft_float (MonoCompile *cfg)
                                        restart = TRUE;
                                        break;
                                }
+                               case OP_CKFINITE: {
+                                       MonoInst *iargs [2];
+                                       MonoInst *call, *cmp;
+
+                                       /* Convert to icall+icompare+cond_exc+move */
+
+                                       /* Create dummy MonoInst's for the arguments */
+                                       MONO_INST_NEW (cfg, iargs [0], OP_ARG);
+                                       iargs [0]->dreg = ins->sreg1;
+
+                                       call = mono_emit_jit_icall (cfg, mono_isfinite, iargs);
+
+                                       MONO_INST_NEW (cfg, cmp, OP_ICOMPARE_IMM);
+                                       cmp->sreg1 = call->dreg;
+                                       cmp->inst_imm = 1;
+                                       MONO_ADD_INS (cfg->cbb, cmp);
+
+                                       MONO_EMIT_NEW_COND_EXC (cfg, INE_UN, "ArithmeticException");
+
+                                       /* Do the assignment if the value is finite */
+                                       MONO_EMIT_NEW_UNALU (cfg, OP_FMOVE, ins->dreg, ins->sreg1);
+
+                                       restart = TRUE;
+                                       break;
+                               }
                                default:
                                        if (spec [MONO_INST_SRC1] == 'f' || spec [MONO_INST_SRC2] == 'f' || spec [MONO_INST_DEST] == 'f') {
                                                mono_print_ins (ins);
index 55316cf0a164d0956160d5d3457fe36f19ee5be4..f591f97d6549550f17d215108d625890c0923ad7 100644 (file)
@@ -4758,6 +4758,7 @@ mini_init (const char *filename, const char *runtime_version)
        register_icall (mono_fload_r4, "mono_fload_r4", "double ptr", FALSE);
        register_icall (mono_fstore_r4, "mono_fstore_r4", "void double ptr", FALSE);
        register_icall (mono_fload_r4_arg, "mono_fload_r4_arg", "uint32 double", FALSE);
+       register_icall (mono_isfinite, "mono_isfinite", "uint32 double", FALSE);
 #endif
 
 #if SIZEOF_REGISTER == 4