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
2 changes: 2 additions & 0 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -8229,6 +8229,8 @@ parse_cpu_features (const gchar *attr)
feature = MONO_CPU_ARM64_BASE;
else if (!strcmp (attr + prefix, "crc"))
feature = MONO_CPU_ARM64_CRC;
else if (!strcmp (attr + prefix, "simd"))
feature = MONO_CPU_ARM64_ADVSIMD;
#elif defined(TARGET_WASM)
if (!strcmp (attr + prefix, "simd"))
feature = MONO_CPU_WASM_SIMD;
Expand Down
6 changes: 6 additions & 0 deletions src/mono/mono/mini/llvm-intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,12 @@ INTRINS(AARCH64_SHA256SU0, aarch64_crypto_sha256su0)
INTRINS(AARCH64_SHA256SU1, aarch64_crypto_sha256su1)
INTRINS(AARCH64_SHA256H, aarch64_crypto_sha256h)
INTRINS(AARCH64_SHA256H2, aarch64_crypto_sha256h2)
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_FLOAT, fabs)
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_DOUBLE, fabs)
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT8, aarch64_neon_abs)
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT16, aarch64_neon_abs)
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT32, aarch64_neon_abs)
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT64, aarch64_neon_abs)
#endif

#undef INTRINS
Expand Down
35 changes: 35 additions & 0 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -9093,6 +9093,22 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
values [ins->dreg] = call_intrins (ctx, id, args, "");
break;
}
case OP_XOP_X_X: {
IntrinsicId id = (IntrinsicId)0;
switch (ins->inst_c0) {
case SIMD_OP_LLVM_FABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_FLOAT; break;
case SIMD_OP_LLVM_DABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_DOUBLE; break;
case SIMD_OP_LLVM_I8ABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_INT8; break;
case SIMD_OP_LLVM_I16ABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_INT16; break;
case SIMD_OP_LLVM_I32ABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_INT32; break;
case SIMD_OP_LLVM_I64ABS: id = INTRINS_AARCH64_ADV_SIMD_ABS_INT64; break;
default: g_assert_not_reached (); break;
}

LLVMValueRef arg0 = lhs;
values [ins->dreg] = call_intrins (ctx, id, &arg0, "");
break;
}
case OP_LSCNT32:
case OP_LSCNT64: {
// %shr = ashr i32 %x, 31
Expand Down Expand Up @@ -10564,6 +10580,24 @@ add_intrinsic (LLVMModuleRef module, int id)
case INTRINS_BITREVERSE_I64:
intrins = add_intrins1 (module, id, LLVMInt64Type ());
break;
case INTRINS_AARCH64_ADV_SIMD_ABS_FLOAT:
intrins = add_intrins1 (module, id, sse_r4_t);
break;
case INTRINS_AARCH64_ADV_SIMD_ABS_DOUBLE:
intrins = add_intrins1 (module, id, sse_r8_t);
break;
case INTRINS_AARCH64_ADV_SIMD_ABS_INT8:
intrins = add_intrins1 (module, id, sse_i1_t);
break;
case INTRINS_AARCH64_ADV_SIMD_ABS_INT16:
intrins = add_intrins1 (module, id, sse_i2_t);
break;
case INTRINS_AARCH64_ADV_SIMD_ABS_INT32:
intrins = add_intrins1 (module, id, sse_i4_t);
break;
case INTRINS_AARCH64_ADV_SIMD_ABS_INT64:
intrins = add_intrins1 (module, id, sse_i8_t);
break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole function looks like the work to define signatures for intrinsics could be done via macros in llvm-intrinsics.h instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have macros to do this type of thing, or were you suggesting I create some? I would have think think a little about how to do it; this function predates my changes and would need some reworking.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I mean in general, if you want to eventually implement the full set of intrinsics it makes sense to minimize verbosity of the changes.

#endif
default:
g_assert_not_reached ();
Expand Down Expand Up @@ -11951,6 +11985,7 @@ MonoCPUFeatures mono_llvm_get_cpu_features (void)
#if defined(TARGET_ARM64)
{ "crc", MONO_CPU_ARM64_CRC },
{ "crypto", MONO_CPU_ARM64_CRYPTO },
{ "neon", MONO_CPU_ARM64_ADVSIMD }
#endif
};
if (!cpu_features)
Expand Down
7 changes: 7 additions & 0 deletions src/mono/mono/mini/mini.h
Original file line number Diff line number Diff line change
Expand Up @@ -2872,6 +2872,7 @@ typedef enum {
MONO_CPU_ARM64_BASE = 1 << 1,
MONO_CPU_ARM64_CRC = 1 << 2,
MONO_CPU_ARM64_CRYPTO = 1 << 3,
MONO_CPU_ARM64_ADVSIMD = 1 << 4,
#endif
} MonoCPUFeatures;

Expand Down Expand Up @@ -2899,6 +2900,12 @@ enum {

/* SIMD operations */
typedef enum {
SIMD_OP_LLVM_FABS,
SIMD_OP_LLVM_DABS,
SIMD_OP_LLVM_I8ABS,
SIMD_OP_LLVM_I16ABS,
SIMD_OP_LLVM_I32ABS,
SIMD_OP_LLVM_I64ABS,
SIMD_OP_SSE_CVTSS2SI,
SIMD_OP_SSE_CVTTSS2SI,
SIMD_OP_SSE_CVTSS2SI64,
Expand Down
43 changes: 43 additions & 0 deletions src/mono/mono/mini/simd-intrinsics-netcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,10 @@ static SimdIntrinsic sha256_methods [] = {
{SN_get_IsSupported}
};

static SimdIntrinsic advsimd_methods [] = {
{SN_Abs}
};

static MonoInst*
emit_arm64_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
{
Expand Down Expand Up @@ -941,6 +945,45 @@ emit_arm64_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignatur
if (info->op != 0)
return emit_simd_ins_for_sig (cfg, klass, info->op, info->instc0, arg0_type, fsig, args);
}

if (is_hw_intrinsics_class (klass, "AdvSimd", &is_64bit)) {
info = lookup_intrins_info (advsimd_methods, sizeof (advsimd_methods), cmethod);

if (!info)
return NULL;

supported = (mini_get_cpu_features (cfg) & MONO_CPU_ARM64_ADVSIMD) != 0;

switch (info -> id) {
case SN_Abs: {
SimdOp op = (SimdOp)0;
switch (get_underlying_type (fsig->params [0])) {
case MONO_TYPE_R8:
op = SIMD_OP_LLVM_DABS;
break;
case MONO_TYPE_R4:
op = SIMD_OP_LLVM_FABS;
break;
case MONO_TYPE_I1:
op = SIMD_OP_LLVM_I8ABS;
break;
case MONO_TYPE_I2:
op = SIMD_OP_LLVM_I16ABS;
break;
case MONO_TYPE_I4:
op = SIMD_OP_LLVM_I32ABS;
break;
case MONO_TYPE_I8:
op = SIMD_OP_LLVM_I64ABS;
break;
}

return emit_simd_ins_for_sig (cfg, klass, OP_XOP_X_X, op, arg0_type, fsig, args);
}
}

}

return NULL;
}
#endif // TARGET_ARM64
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/simd-methods-netcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ METHOD(MoveAndDuplicate)
METHOD(MoveHighAndDuplicate)
METHOD(MoveLowAndDuplicate)
// Ssse3
METHOD(Abs)
METHOD(Abs) // Also used by ARM64
METHOD(AlignRight)
METHOD(HorizontalAddSaturate)
METHOD(HorizontalSubtractSaturate)
Expand Down