diff --git a/src/mono/mono/mini/calls.c b/src/mono/mono/mini/calls.c index a7d66f5ecf34ef..3689d8063897fd 100644 --- a/src/mono/mono/mini/calls.c +++ b/src/mono/mono/mini/calls.c @@ -111,7 +111,10 @@ ret_type_to_call_opcode (MonoCompile *cfg, MonoType *type, int calli, int virt) case MONO_TYPE_U8: return calli? OP_LCALL_REG: virt? OP_LCALL_MEMBASE: OP_LCALL; case MONO_TYPE_R4: - return calli? OP_RCALL_REG: virt? OP_RCALL_MEMBASE: OP_RCALL; + if (cfg->r4fp) + return calli? OP_RCALL_REG: virt? OP_RCALL_MEMBASE: OP_RCALL; + else + return calli? OP_FCALL_REG: virt? OP_FCALL_MEMBASE: OP_FCALL; case MONO_TYPE_R8: return calli? OP_FCALL_REG: virt? OP_FCALL_MEMBASE: OP_FCALL; case MONO_TYPE_VALUETYPE: diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index f19efd3c80ea76..e003caf4d24f3a 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -103,7 +103,7 @@ llvm_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign MonoInst *ins = NULL; int opcode = 0; // Convert Math and MathF methods into LLVM intrinsics, e.g. MathF.Sin -> @llvm.sin.f32 - if (in_corlib && !strcmp (m_class_get_name (cmethod->klass), "MathF")) { + if (in_corlib && !strcmp (m_class_get_name (cmethod->klass), "MathF") && cfg->r4fp) { // (float) if (fsig->param_count == 1 && fsig->params [0]->type == MONO_TYPE_R4) { if (!strcmp (cmethod->name, "Ceiling")) { @@ -1524,7 +1524,7 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign #endif break; case MONO_TYPE_R4: - ins->type = GINT_TO_UINT8 (STACK_R4); + ins->type = GINT_TO_UINT8 (cfg->r4_stack_type); break; case MONO_TYPE_R8: ins->type = STACK_R8; @@ -1662,7 +1662,7 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign #endif break; case MONO_TYPE_R4: - ins->type = GINT_TO_UINT8 (STACK_R4); + ins->type = GINT_TO_UINT8 (cfg->r4_stack_type); break; case MONO_TYPE_R8: ins->type = STACK_R8; diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index f39e35642268b0..6578497e745008 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -337,7 +337,7 @@ mono_type_to_regmove (MonoCompile *cfg, MonoType *type) return OP_LMOVE; #endif case MONO_TYPE_R4: - return OP_RMOVE; + return cfg->r4fp ? OP_RMOVE : OP_FMOVE; case MONO_TYPE_R8: return OP_FMOVE; case MONO_TYPE_VALUETYPE: @@ -483,8 +483,9 @@ add_widen_op (MonoCompile *cfg, MonoInst *ins, MonoInst **arg1_ref, MonoInst **a MonoInst *arg1 = *arg1_ref; MonoInst *arg2 = *arg2_ref; - if ((arg1->type == STACK_R4 && arg2->type == STACK_R8) || - (arg1->type == STACK_R8 && arg2->type == STACK_R4)) { + if (cfg->r4fp && + ((arg1->type == STACK_R4 && arg2->type == STACK_R8) || + (arg1->type == STACK_R8 && arg2->type == STACK_R4))) { MonoInst *conv; /* Mixing r4/r8 is allowed by the spec */ @@ -826,7 +827,7 @@ mini_type_to_eval_stack_type (MonoCompile *cfg, MonoType *type, MonoInst *inst) inst->type = STACK_I8; return; case MONO_TYPE_R4: - inst->type = GINT_TO_UINT8 (STACK_R4); + inst->type = GINT_TO_UINT8 (cfg->r4_stack_type); break; case MONO_TYPE_R8: inst->type = STACK_R8; @@ -1160,7 +1161,7 @@ type_from_op (MonoCompile *cfg, MonoInst *ins, MonoInst *src1, MonoInst *src2) ins->opcode += ovf2ops_op_map [src1->type]; break; case MONO_CEE_CONV_R4: - ins->type = GINT_TO_UINT8 (STACK_R4); + ins->type = GINT_TO_UINT8 (cfg->r4_stack_type); ins->opcode += unops_op_map [src1->type]; break; case MONO_CEE_CONV_R8: @@ -1218,7 +1219,7 @@ type_from_op (MonoCompile *cfg, MonoInst *ins, MonoInst *src1, MonoInst *src2) ins->type = STACK_I8; break; case OP_LOADR4_MEMBASE: - ins->type = GINT_TO_UINT8 (STACK_R4); + ins->type = GINT_TO_UINT8 (cfg->r4_stack_type); break; case OP_LOADR8_MEMBASE: ins->type = STACK_R8; @@ -1433,7 +1434,7 @@ mini_type_to_stack_type (MonoCompile *cfg, MonoType *t) case MONO_TYPE_U8: return STACK_I8; case MONO_TYPE_R4: - return (MonoStackType)STACK_R4; + return (MonoStackType)cfg->r4_stack_type; case MONO_TYPE_R8: return STACK_R8; case MONO_TYPE_VALUETYPE: @@ -1916,7 +1917,7 @@ target_type_is_incompatible (MonoCompile *cfg, MonoType *target, MonoInst *arg) return 1; return 0; case MONO_TYPE_R4: - if (arg->type != STACK_R4) + if (arg->type != cfg->r4_stack_type) return 1; return 0; case MONO_TYPE_R8: @@ -1979,6 +1980,8 @@ target_type_is_incompatible (MonoCompile *cfg, MonoType *target, MonoInst *arg) static MonoInst* convert_value (MonoCompile *cfg, MonoType *type, MonoInst *ins) { + if (!cfg->r4fp) + return ins; type = mini_get_underlying_type (type); switch (type->type) { case MONO_TYPE_R4: @@ -2071,7 +2074,7 @@ check_call_signature (MonoCompile *cfg, MonoMethodSignature *sig, MonoInst **arg return TRUE; continue; case MONO_TYPE_R4: - if (args [i]->type != STACK_R4) + if (args [i]->type != cfg->r4_stack_type) return TRUE; continue; case MONO_TYPE_R8: @@ -4636,7 +4639,7 @@ mini_emit_init_rvar (MonoCompile *cfg, int dreg, MonoType *rtype) MONO_EMIT_NEW_ICONST (cfg, dreg, 0); } else if (t == MONO_TYPE_I8 || t == MONO_TYPE_U8) { MONO_EMIT_NEW_I8CONST (cfg, dreg, 0); - } else if (t == MONO_TYPE_R4) { + } else if (cfg->r4fp && t == MONO_TYPE_R4) { MONO_INST_NEW (cfg, ins, OP_R4CONST); ins->type = STACK_R4; ins->inst_p0 = (void*)&r4_0; @@ -4672,7 +4675,7 @@ emit_dummy_init_rvar (MonoCompile *cfg, int dreg, MonoType *rtype) MONO_EMIT_NEW_DUMMY_INIT (cfg, dreg, OP_DUMMY_ICONST); } else if (t == MONO_TYPE_I8 || t == MONO_TYPE_U8) { MONO_EMIT_NEW_DUMMY_INIT (cfg, dreg, OP_DUMMY_I8CONST); - } else if (t == MONO_TYPE_R4) { + } else if (cfg->r4fp && t == MONO_TYPE_R4) { MONO_EMIT_NEW_DUMMY_INIT (cfg, dreg, OP_DUMMY_R4CONST); } else if (t == MONO_TYPE_R4 || t == MONO_TYPE_R8) { MONO_EMIT_NEW_DUMMY_INIT (cfg, dreg, OP_DUMMY_R8CONST); @@ -7278,10 +7281,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b dreg = alloc_freg (cfg); EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOADR4_MEMBASE, dreg, cons->dreg, 0); - ins->type = GINT_TO_UINT8 (STACK_R4); + ins->type = GINT_TO_UINT8 (cfg->r4_stack_type); } else { MONO_INST_NEW (cfg, ins, OP_R4CONST); - ins->type = GINT_TO_UINT8 (STACK_R4); + ins->type = GINT_TO_UINT8 (cfg->r4_stack_type); ins->dreg = alloc_dreg (cfg, STACK_R8); ins->inst_p0 = f; MONO_ADD_INS (cfg->cbb, ins); diff --git a/src/mono/mono/mini/mini-amd64.h b/src/mono/mono/mini/mini-amd64.h index 46e2828f868ed0..80c570e58f5bea 100644 --- a/src/mono/mono/mini/mini-amd64.h +++ b/src/mono/mono/mini/mini-amd64.h @@ -453,6 +453,7 @@ typedef struct { #define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1 #define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT 1 #define MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE 1 +#define MONO_ARCH_FLOAT32_SUPPORTED 1 #define MONO_ARCH_LLVM_TARGET_LAYOUT "e-i64:64-i128:128-n8:16:32:64-S128" #define MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP diff --git a/src/mono/mono/mini/mini-arm.h b/src/mono/mono/mini/mini-arm.h index 13b94cd8c8293c..73bcc8bb8bb4b8 100644 --- a/src/mono/mono/mini/mini-arm.h +++ b/src/mono/mono/mini/mini-arm.h @@ -363,6 +363,7 @@ typedef struct MonoCompileArch { #define MONO_ARCH_HAVE_OBJC_GET_SELECTOR 1 #define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1 #define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT 1 +#define MONO_ARCH_FLOAT32_SUPPORTED 1 #define MONO_ARCH_LLVM_TARGET_LAYOUT "e-p:32:32-n32-S64" #define MONO_ARCH_HAVE_INTERP_ENTRY_TRAMPOLINE 1 diff --git a/src/mono/mono/mini/mini-arm64.h b/src/mono/mono/mini/mini-arm64.h index 3b9218b32c0b1a..17195886b76725 100644 --- a/src/mono/mono/mini/mini-arm64.h +++ b/src/mono/mono/mini/mini-arm64.h @@ -177,6 +177,7 @@ typedef struct { #define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT 1 #define MONO_ARCH_HAVE_OPCODE_NEEDS_EMULATION 1 #define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1 +#define MONO_ARCH_FLOAT32_SUPPORTED 1 #define MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP 1 #define MONO_ARCH_HAVE_INIT_MRGCTX 1 #define MONO_ARCH_LLVM_TARGET_LAYOUT "e-i64:64-i128:128-n32:64-S128" diff --git a/src/mono/mono/mini/mini-s390x.h b/src/mono/mono/mini/mini-s390x.h index 8dafec4aefb560..b9deb1a2683d63 100644 --- a/src/mono/mono/mini/mini-s390x.h +++ b/src/mono/mono/mini/mini-s390x.h @@ -83,6 +83,7 @@ struct SeqPointInfo { #define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1 #define MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX 1 #define MONO_ARCH_HAVE_UNWIND_BACKTRACE 1 +#define MONO_ARCH_FLOAT32_SUPPORTED 1 #define S390_STACK_ALIGNMENT 8 #define S390_FIRST_ARG_REG s390_r2 diff --git a/src/mono/mono/mini/mini-wasm.h b/src/mono/mono/mini/mini-wasm.h index f8234087ea8c05..61e81e8a81fbdb 100644 --- a/src/mono/mono/mini/mini-wasm.h +++ b/src/mono/mono/mini/mini-wasm.h @@ -29,6 +29,7 @@ #define MONO_ARCH_EMULATE_FCONV_TO_U4 1 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS 1 #define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS 1 +#define MONO_ARCH_FLOAT32_SUPPORTED 1 //mini-codegen stubs - this doesn't do anything #define MONO_ARCH_CALLEE_REGS (1 << 0) diff --git a/src/mono/mono/mini/mini-x86.h b/src/mono/mono/mini/mini-x86.h index 7235aa7781f47e..ed839af690732e 100644 --- a/src/mono/mono/mini/mini-x86.h +++ b/src/mono/mono/mini/mini-x86.h @@ -229,6 +229,7 @@ typedef struct { #define MONO_ARCH_HAVE_OP_TAILCALL_REG 1 #define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1 #define MONO_ARCH_LLVM_TARGET_LAYOUT "e-p:32:32-n32-S128" +#define MONO_ARCH_FLOAT32_SUPPORTED 1 #define MONO_ARCH_NEED_SIMD_BANK 1 #define MONO_ARCH_USE_SHARED_FP_SIMD_BANK 1 diff --git a/src/mono/mono/mini/mini.c b/src/mono/mono/mini/mini.c index 9ceb79caa97dc6..0c68db6c01c9ef 100644 --- a/src/mono/mono/mini/mini.c +++ b/src/mono/mono/mini/mini.c @@ -3133,6 +3133,14 @@ mini_method_compile (MonoMethod *method, guint32 opts, JitFlags flags, int parts try_llvm = mono_use_llvm || llvm; #endif +#ifdef MONO_ARCH_FLOAT32_SUPPORTED + /* Force float32 mode on platforms where its supported */ + opts |= MONO_OPT_FLOAT32; +#else + opts &= ~MONO_OPT_FLOAT32; + g_assert (!llvm); +#endif + restart_compile: if (method_is_gshared) { method_to_compile = method; @@ -3209,6 +3217,8 @@ mini_method_compile (MonoMethod *method, guint32 opts, JitFlags flags, int parts if (!is_simd_supported (cfg)) cfg->opt &= ~MONO_OPT_SIMD; + cfg->r4fp = (cfg->opt & MONO_OPT_FLOAT32) ? 1 : 0; + cfg->r4_stack_type = cfg->r4fp ? STACK_R4 : STACK_R8; if (cfg->gen_seq_points) cfg->seq_points = g_ptr_array_new (); diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 32d057bd18fb83..a21e3c331af3e0 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -1501,6 +1501,7 @@ typedef struct { guint gshared : 1; guint gsharedvt : 1; guint gsharedvt_min : 1; + guint r4fp : 1; guint llvm_only : 1; guint interp : 1; guint use_current_cpu : 1; @@ -1512,6 +1513,7 @@ typedef struct { guint deopt : 1; guint prefer_instances : 1; guint8 uses_simd_intrinsics; + int r4_stack_type; gpointer debug_info; guint32 lmf_offset; guint16 *intvars;