* 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
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.
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)
{
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;
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);
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