Skip to content

Commit

Permalink
[mono] Enable floats in Vector128::ExtractMostSignificantBits on arm6…
Browse files Browse the repository at this point in the history
…4 and amd64 (#90304)

* ExtractMSB arm64 support

* Move arm64 specific code into ifdef
  • Loading branch information
matouskozak authored Aug 11, 2023
1 parent 5d30e6d commit 376e235
Showing 1 changed file with 24 additions and 4 deletions.
28 changes: 24 additions & 4 deletions src/mono/mono/mini/simd-intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,7 @@ is_element_type_primitive (MonoType *vector_type)
}
}

#ifdef TARGET_ARM64
static MonoInst*
emit_msb_vector_mask (MonoCompile *cfg, MonoClass *arg_class, MonoTypeEnum arg_type)
{
Expand Down Expand Up @@ -1358,6 +1359,7 @@ emit_msb_shift_vector_constant (MonoCompile *cfg, MonoClass *arg_class, MonoType
msb_shift_vec->klass = arg_class;
return msb_shift_vec;
}
#endif

/*
* Emit intrinsics in System.Numerics.Vector and System.Runtime.Intrinsics.Vector64/128/256/512.
Expand Down Expand Up @@ -1800,13 +1802,30 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
g_assert_not_reached ();
}
case SN_ExtractMostSignificantBits: {
if (!is_element_type_primitive (fsig->params [0]) || type_enum_is_float (arg0_type))
if (!is_element_type_primitive (fsig->params [0]))
return NULL;
#ifdef TARGET_WASM
if (type_enum_is_float (arg0_type))
return NULL;

return emit_simd_ins_for_sig (cfg, klass, OP_WASM_SIMD_BITMASK, -1, -1, fsig, args);
#elif defined(TARGET_ARM64)
MonoInst* result_ins = NULL;
MonoClass* arg_class = mono_class_from_mono_type_internal (fsig->params [0]);
MonoClass* arg_class;
if (type_enum_is_float (arg0_type)) {
MonoClass* cast_class;
if (arg0_type == MONO_TYPE_R4) {
arg0_type = MONO_TYPE_I4;
cast_class = mono_defaults.int32_class;
} else {
arg0_type = MONO_TYPE_I8;
cast_class = mono_defaults.int64_class;
}
arg_class = create_class_instance ("System.Runtime.Intrinsics", m_class_get_name (klass), m_class_get_byval_arg (cast_class));
} else {
arg_class = mono_class_from_mono_type_internal (fsig->params [0]);
}

// FIXME: Add support for Vector64 on arm64
int size = mono_class_value_size (arg_class, NULL);
if (size != 16)
return NULL;
Expand All @@ -1816,11 +1835,12 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
and_res_vec->sreg2 = msb_mask_vec->dreg;

MonoInst* msb_shift_vec = emit_msb_shift_vector_constant (cfg, arg_class, arg0_type);

MonoInst* shift_res_vec = emit_simd_ins (cfg, arg_class, OP_XOP_OVR_X_X_X, and_res_vec->dreg, msb_shift_vec->dreg);
shift_res_vec->inst_c0 = INTRINS_AARCH64_ADV_SIMD_USHL;
shift_res_vec->inst_c1 = arg0_type;

MonoInst* result_ins = NULL;
if (arg0_type == MONO_TYPE_I1 || arg0_type == MONO_TYPE_U1) {
// Always perform unsigned operations as vector sum and extract operations could sign-extend the result into the GP register
// making the final result invalid. This is not needed for wider type as the maximum sum of extracted MSB cannot be larger than 8bits
Expand Down

0 comments on commit 376e235

Please sign in to comment.