|
25 | 25 | #include <mono/arch/arm64/arm64-codegen.h>
|
26 | 26 | #include <mono/utils/mono-mmap.h>
|
27 | 27 | #include <mono/utils/mono-memory-model.h>
|
| 28 | +#include <mono/utils/mono-hwcap.h> |
28 | 29 | #include <mono/metadata/abi-details.h>
|
29 | 30 | #include <mono/metadata/tokentype.h>
|
30 | 31 | #include "llvm-intrinsics-types.h"
|
@@ -3835,6 +3836,28 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
3835 | 3836 | }
|
3836 | 3837 | break;
|
3837 | 3838 | }
|
| 3839 | + case OP_XOP_OVR_X_X_X_X: { |
| 3840 | + IntrinsicId iid = (IntrinsicId) ins->inst_c0; |
| 3841 | + g_assert (dreg == sreg1); |
| 3842 | + g_assert (mono_class_value_size (ins->klass, NULL) == 16); |
| 3843 | + switch (iid) { |
| 3844 | + case INTRINS_AARCH64_ADV_SIMD_SDOT: |
| 3845 | + arm_neon_sdot_4s (code, dreg, sreg2, sreg3); |
| 3846 | + break; |
| 3847 | + case INTRINS_AARCH64_ADV_SIMD_UDOT: |
| 3848 | + arm_neon_udot_4s (code, dreg, sreg2, sreg3); |
| 3849 | + break; |
| 3850 | + default: |
| 3851 | + g_assert_not_reached (); |
| 3852 | + break; |
| 3853 | + } |
| 3854 | + break; |
| 3855 | + } |
| 3856 | + case OP_ARM64_BROADCAST_ELEM: |
| 3857 | + arm_neon_smov (code, TYPE_I32, ARMREG_IP0, sreg1, ins->inst_c0); |
| 3858 | + arm_neon_dup_g_4s (code, dreg, ARMREG_IP0); |
| 3859 | + break; |
| 3860 | + |
3838 | 3861 | case OP_XZERO:
|
3839 | 3862 | arm_neon_eor_16b (code, dreg, dreg, dreg);
|
3840 | 3863 | break;
|
@@ -5383,7 +5406,46 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
5383 | 5406 | g_assert (ins->inst_c0 == INTRINS_BITREVERSE_I32);
|
5384 | 5407 | arm_rbitw (code, dreg, sreg1);
|
5385 | 5408 | break;
|
5386 |
| - |
| 5409 | + case OP_XOP_I4_I4_I4: { |
| 5410 | + switch (ins->inst_c0) { |
| 5411 | + case INTRINS_AARCH64_CRC32B: |
| 5412 | + arm_crc32b (code, dreg, sreg1, sreg2); |
| 5413 | + break; |
| 5414 | + case INTRINS_AARCH64_CRC32H: |
| 5415 | + arm_crc32h (code, dreg, sreg1, sreg2); |
| 5416 | + break; |
| 5417 | + case INTRINS_AARCH64_CRC32W: |
| 5418 | + arm_crc32w (code, dreg, sreg1, sreg2); |
| 5419 | + break; |
| 5420 | + case INTRINS_AARCH64_CRC32CB: |
| 5421 | + arm_crc32cb (code, dreg, sreg1, sreg2); |
| 5422 | + break; |
| 5423 | + case INTRINS_AARCH64_CRC32CH: |
| 5424 | + arm_crc32ch (code, dreg, sreg1, sreg2); |
| 5425 | + break; |
| 5426 | + case INTRINS_AARCH64_CRC32CW: |
| 5427 | + arm_crc32cw (code, dreg, sreg1, sreg2); |
| 5428 | + break; |
| 5429 | + default: |
| 5430 | + g_assert_not_reached (); |
| 5431 | + break; |
| 5432 | + } |
| 5433 | + break; |
| 5434 | + } |
| 5435 | + case OP_XOP_I4_I4_I8: { |
| 5436 | + switch (ins->inst_c0) { |
| 5437 | + case INTRINS_AARCH64_CRC32X: |
| 5438 | + arm_crc32x (code, dreg, sreg1, sreg2); |
| 5439 | + break; |
| 5440 | + case INTRINS_AARCH64_CRC32CX: |
| 5441 | + arm_crc32cx (code, dreg, sreg1, sreg2); |
| 5442 | + break; |
| 5443 | + default: |
| 5444 | + g_assert_not_reached (); |
| 5445 | + break; |
| 5446 | + } |
| 5447 | + break; |
| 5448 | + } |
5387 | 5449 | case OP_ARM64_HINT:
|
5388 | 5450 | g_assert (ins->inst_c0 <= ARMHINT_SEVL);
|
5389 | 5451 | arm_hint (code, ins->inst_c0);
|
@@ -6382,3 +6444,20 @@ mono_arm_emit_brx (guint8 *code, int reg)
|
6382 | 6444 | {
|
6383 | 6445 | return emit_brx (code, reg);
|
6384 | 6446 | }
|
| 6447 | + |
| 6448 | +MonoCPUFeatures |
| 6449 | +mono_arch_get_cpu_features (void) |
| 6450 | +{ |
| 6451 | + guint64 features = MONO_CPU_INITED; |
| 6452 | + |
| 6453 | + if (mono_hwcap_arm64_has_crc32) |
| 6454 | + features |= MONO_CPU_ARM64_CRC; |
| 6455 | + if (mono_hwcap_arm64_has_dot) |
| 6456 | + features |= MONO_CPU_ARM64_DP; |
| 6457 | + if (mono_hwcap_arm64_has_rdm) |
| 6458 | + features |= MONO_CPU_ARM64_RDM; |
| 6459 | + if (mono_hwcap_arm64_has_sha1 && mono_hwcap_arm64_has_sha256 && mono_hwcap_arm64_has_aes) |
| 6460 | + features |= MONO_CPU_ARM64_CRYPTO; |
| 6461 | + |
| 6462 | + return features; |
| 6463 | +} |
0 commit comments