Some platforms don't support r4fp, so put back the general JIT support code.
Force r4fp on platforms that support it.
Fixes https://github.com/dotnet/runtime/issues/84401.
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:
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")) {
#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;
#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;
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:
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 */
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;
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:
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;
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:
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:
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:
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:
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;
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);
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);
#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
#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
#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"
#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
#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)
#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
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;
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 ();
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;
guint deopt : 1;
guint prefer_instances : 1;
guint8 uses_simd_intrinsics;
+ int r4_stack_type;
gpointer debug_info;
guint32 lmf_offset;
guint16 *intvars;