Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ internal static int LeadingZeroCount(Int128 value)
/// Similar in behavior to the x86 instruction LZCNT.
/// </summary>
/// <param name="value">The value.</param>
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static int LeadingZeroCount(uint value)
Expand Down Expand Up @@ -223,6 +224,7 @@ public static int LeadingZeroCount(uint value)
/// Similar in behavior to the x86 instruction LZCNT.
/// </summary>
/// <param name="value">The value.</param>
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static int LeadingZeroCount(ulong value)
Expand Down Expand Up @@ -557,6 +559,7 @@ public static int TrailingZeroCount(int value)
/// Similar in behavior to the x86 instruction TZCNT.
/// </summary>
/// <param name="value">The value.</param>
[Intrinsic]
[CLSCompliant(false)]
Comment thread
vargaz marked this conversation as resolved.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int TrailingZeroCount(uint value)
Expand Down Expand Up @@ -610,6 +613,7 @@ public static int TrailingZeroCount(long value)
/// Similar in behavior to the x86 instruction TZCNT.
/// </summary>
/// <param name="value">The value.</param>
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static int TrailingZeroCount(ulong value)
Expand Down
50 changes: 43 additions & 7 deletions src/mono/mono/mini/simd-intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -4265,6 +4265,11 @@ emit_sum_vector (MonoCompile *cfg, MonoType *vector_type, MonoTypeEnum element_t
return extract_first_element (cfg, vector_class, element_type, vsum->dreg);
}

static guint16 bitoperations_methods [] = {
SN_LeadingZeroCount,
SN_TrailingZeroCount,
};

static SimdIntrinsic wasmbase_methods [] = {
{SN_LeadingZeroCount},
{SN_TrailingZeroCount},
Expand Down Expand Up @@ -4297,6 +4302,39 @@ static const IntrinGroup supported_wasm_common_intrinsics [] = {
{ "WasmBase", MONO_CPU_WASM_BASE, wasmbase_methods, sizeof (wasmbase_methods) },
};

static MonoInst*
emit_wasm_zero_count (MonoCompile *cfg, MonoMethodSignature *fsig, MonoInst **args,
MonoClass *klass, int id, MonoTypeEnum arg0_type)
{
gboolean arg0_i32 = (arg0_type == MONO_TYPE_I4) || (arg0_type == MONO_TYPE_U4);
#if TARGET_SIZEOF_VOID_P == 4
arg0_i32 = arg0_i32 || (arg0_type == MONO_TYPE_I) || (arg0_type == MONO_TYPE_U);
#endif
int opcode = id == SN_LeadingZeroCount ? (arg0_i32 ? OP_LZCNT32 : OP_LZCNT64) : (arg0_i32 ? OP_CTTZ32 : OP_CTTZ64);

return emit_simd_ins_for_sig (cfg, klass, opcode, 0, arg0_type, fsig, args);
}

static MonoInst*
emit_wasm_bitoperations_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
{
int id = lookup_intrins (bitoperations_methods, sizeof (bitoperations_methods), cmethod);
if (id == -1) {
return NULL;
}

MonoTypeEnum arg0_type = fsig->param_count > 0 ? get_underlying_type (fsig->params [0]) : MONO_TYPE_VOID;

switch (id) {
case SN_LeadingZeroCount:
case SN_TrailingZeroCount: {
return emit_wasm_zero_count(cfg, fsig, args, cmethod->klass, id, arg0_type);
}
}

return NULL;
}

static MonoInst*
emit_wasm_supported_intrinsics (
MonoCompile *cfg, MonoMethodSignature *fsig, MonoInst **args,
Expand All @@ -4310,13 +4348,7 @@ emit_wasm_supported_intrinsics (
switch (id) {
case SN_LeadingZeroCount:
case SN_TrailingZeroCount: {
gboolean arg0_i32 = (arg0_type == MONO_TYPE_I4) || (arg0_type == MONO_TYPE_U4);
#if TARGET_SIZEOF_VOID_P == 4
arg0_i32 = arg0_i32 || (arg0_type == MONO_TYPE_I) || (arg0_type == MONO_TYPE_U);
#endif
int opcode = id == SN_LeadingZeroCount ? (arg0_i32 ? OP_LZCNT32 : OP_LZCNT64) : (arg0_i32 ? OP_CTTZ32 : OP_CTTZ64);

return emit_simd_ins_for_sig (cfg, klass, opcode, 0, arg0_type, fsig, args);
return emit_wasm_zero_count(cfg, fsig, args, klass, id, arg0_type);
}
}
}
Expand Down Expand Up @@ -4478,6 +4510,10 @@ arch_emit_common_intrinsics (const char *class_ns, const char *class_name, MonoC
emit_wasm_supported_intrinsics);
}

if (!strcmp (class_ns, "System.Numerics") && !strcmp (class_name, "BitOperations")) {
return emit_wasm_bitoperations_intrinsics (cfg, cmethod, fsig, args);
}

return NULL;
}
#else
Expand Down