From 85d287c4f86c5df21602540af125340aac54589d Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Wed, 18 May 2022 23:38:57 +0200 Subject: [PATCH] Implement a bunch of missing AVX instructions (#595) --- lib/Arch/X86/Semantics/AVX.cpp | 19 ++++++++++++++++-- lib/Arch/X86/Semantics/MMX.cpp | 36 ++++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/lib/Arch/X86/Semantics/AVX.cpp b/lib/Arch/X86/Semantics/AVX.cpp index 600068d4..380d168a 100644 --- a/lib/Arch/X86/Semantics/AVX.cpp +++ b/lib/Arch/X86/Semantics/AVX.cpp @@ -28,7 +28,7 @@ DEF_SEM(DoVZEROUPPER) { return memory; } -template +template DEF_SEM(VPBROADCASTB, D dst, S1 src1) { auto src_vec = UReadV8(src1); auto dst_vec = UClearV8(UReadV8(dst)); @@ -42,6 +42,20 @@ DEF_SEM(VPBROADCASTB, D dst, S1 src1) { return memory; } +template +DEF_SEM(VPBROADCASTQ, D dst, S1 src1) { + auto src_vec = UReadV64(src1); + auto dst_vec = UClearV64(UReadV64(dst)); + auto num_groups = NumVectorElems(dst_vec); + auto src_val = UExtractV64(src_vec, 0); + + for (std::size_t i = 0; i < num_groups; ++i) { + dst_vec = UInsertV64(dst_vec, i, src_val); + } + UWriteV64(dst, dst_vec); + return memory; +} + template DEF_SEM(VINSERTF128, VV256W dst, V256 src1, S2 src2, I8 src3) { auto dst_vec = UReadV128(src1); @@ -70,6 +84,7 @@ DEF_ISEL(VINSERTF128_YMMqq_YMMqq_MEMdq_IMMb) = VINSERTF128; DEF_ISEL(VINSERTF128_YMMqq_YMMqq_XMMdq_IMMb) = VINSERTF128; DEF_ISEL(VZEROUPPER) = DoVZEROUPPER; -DEF_ISEL(VPBROADCASTB_YMMqq_XMMb) = VPBROADCASTB; +DEF_ISEL(VPBROADCASTB_YMMqq_XMMb) = VPBROADCASTB; +DEF_ISEL(VPBROADCASTQ_YMMqq_XMMq) = VPBROADCASTQ; #endif // HAS_FEATURE_AVX diff --git a/lib/Arch/X86/Semantics/MMX.cpp b/lib/Arch/X86/Semantics/MMX.cpp index e9a99ae9..0f7f01e0 100644 --- a/lib/Arch/X86/Semantics/MMX.cpp +++ b/lib/Arch/X86/Semantics/MMX.cpp @@ -183,16 +183,14 @@ DEF_ISEL(PUNPCKLDQ_XMMdq_XMMq) = PUNPCKLDQ; DEF_ISEL(PUNPCKLQDQ_XMMdq_MEMdq) = PUNPCKLQDQ; DEF_ISEL(PUNPCKLQDQ_XMMdq_XMMq) = PUNPCKLQDQ; +IF_AVX(DEF_ISEL(VPUNPCKLQDQ_XMMdq_XMMdq_XMMdq) = PUNPCKLQDQ;) // Adding new MMX Instructions namespace { template DEF_SEM(PADDB, D dst, S1 src1, S2 src2) { - auto lhs_vec = UReadV8(src1); - auto rhs_vec = UReadV8(src2); - auto dst_vec = UAddV8(lhs_vec, rhs_vec); - UWriteV8(dst, dst_vec); + UWriteV8(dst, UAddV8(UReadV8(src1), UReadV8(src2))); return memory; } @@ -230,6 +228,8 @@ DEF_ISEL(PADDB_MMXq_MEMq) = PADDB; DEF_ISEL(PADDB_XMMdq_XMMdq) = PADDB; DEF_ISEL(PADDB_XMMdq_MEMdq) = PADDB; +IF_AVX(DEF_ISEL(VPADDB_YMMqq_YMMqq_YMMqq) = PADDB;) + DEF_ISEL(PADDW_MMXq_MMXq) = PADDW; DEF_ISEL(PADDW_MMXq_MEMq) = PADDW; DEF_ISEL(PADDW_XMMdq_XMMdq) = PADDW; @@ -240,6 +240,8 @@ DEF_ISEL(PADDD_MMXq_MEMq) = PADDD; DEF_ISEL(PADDD_XMMdq_XMMdq) = PADDD; DEF_ISEL(PADDD_XMMdq_MEMdq) = PADDD; +IF_AVX(DEF_ISEL(VPADDD_YMMqq_YMMqq_YMMqq) = PADDD;) + DEF_ISEL(PADDQ_MMXq_MMXq) = PADDQ; DEF_ISEL(PADDQ_MMXq_MEMq) = PADDQ; DEF_ISEL(PADDQ_XMMdq_XMMdq) = PADDQ; @@ -438,6 +440,8 @@ DEF_ISEL(PHADDD_MMXq_MEMq) = PHADDD; DEF_ISEL(PHADDD_XMMdq_XMMdq) = PHADDD; DEF_ISEL(PHADDD_XMMdq_MEMdq) = PHADDD; +IF_AVX(DEF_ISEL(VPHADDD_YMMqq_YMMqq_YMMqq) = PHADDD;) + template DEF_SEM(PHADDSW, D dst, S1 src1, S2 src2) { auto src1_vec = SReadV16(src1); @@ -530,6 +534,7 @@ DEF_ISEL(PSUBB_MMXq_MMXq) = PSUBB; DEF_ISEL(PSUBB_MMXq_MEMq) = PSUBB; DEF_ISEL(PSUBB_XMMdq_XMMdq) = PSUBB; DEF_ISEL(PSUBB_XMMdq_MEMdq) = PSUBB; +IF_AVX(DEF_ISEL(VPSUBB_YMMqq_YMMqq_YMMqq) = PSUBB;) DEF_ISEL(PSUBW_MMXq_MMXq) = PSUBW; DEF_ISEL(PSUBW_MMXq_MEMq) = PSUBW; @@ -542,6 +547,7 @@ DEF_ISEL(PSUBD_XMMdq_XMMdq) = PSUBD; DEF_ISEL(PSUBD_XMMdq_MEMdq) = PSUBD; IF_AVX(DEF_ISEL(VPSUBD_XMMdq_XMMdq_MEMdq) = PSUBD;) IF_AVX(DEF_ISEL(VPSUBD_XMMdq_XMMdq_XMMdq) = PSUBD;) +IF_AVX(DEF_ISEL(VPSUBD_YMMqq_YMMqq_YMMqq) = PSUBD;) DEF_ISEL(PSUBQ_MMXq_MMXq) = PSUBQ; DEF_ISEL(PSUBQ_MMXq_MEMq) = PSUBQ; @@ -549,6 +555,7 @@ DEF_ISEL(PSUBQ_XMMdq_XMMdq) = PSUBQ; DEF_ISEL(PSUBQ_XMMdq_MEMdq) = PSUBQ; IF_AVX(DEF_ISEL(VPSUBQ_XMMdq_XMMdq_MEMdq) = PSUBQ;) IF_AVX(DEF_ISEL(VPSUBQ_XMMdq_XMMdq_XMMdq) = PSUBQ;) +IF_AVX(DEF_ISEL(VPSUBQ_YMMqq_YMMqq_YMMqq) = PSUBQ;) /* 3305 VPSUBD VPSUBD_YMMqq_YMMqq_MEMqq AVX2 AVX2 AVX2 ATTRIBUTES: @@ -1760,6 +1767,23 @@ DEF_SEM(PMULUDQ, D dst, S1 src1, S2 src2) { return memory; } +template +DEF_SEM(PMULLD, D dst, S1 src1, S2 src2) { + auto src1_vec = SReadV32(src1); + auto src2_vec = SReadV32(src2); + auto dst_vec = SClearV32(SReadV32(dst)); + + auto vec_count = NumVectorElems(src1_vec); + _Pragma("unroll") for (size_t i = 0; i < vec_count; i++) { + auto v1 = SExtractV32(src1_vec, i); + auto v2 = SExtractV32(src2_vec, i); + auto mul = SMul(SExt(v1), SExt(v2)); + dst_vec = SInsertV32(dst_vec, i, Trunc(mul)); + } + SWriteV32(dst, dst_vec); + return memory; +} + template DEF_SEM(PMULLW, D dst, S1 src1, S2 src2) { auto src1_vec = SReadV16(src1); @@ -1817,11 +1841,15 @@ DEF_ISEL(PMULUDQ_MMXq_MMXq) = PMULUDQ; DEF_ISEL(PMULUDQ_MMXq_MEMq) = PMULUDQ; DEF_ISEL(PMULUDQ_XMMdq_XMMdq) = PMULUDQ; DEF_ISEL(PMULUDQ_XMMdq_MEMdq) = PMULUDQ; +IF_AVX(DEF_ISEL(VPMULUDQ_YMMqq_YMMqq_YMMqq) = PMULUDQ;) + +IF_AVX(DEF_ISEL(VPMULLD_YMMqq_YMMqq_YMMqq) = PMULLD;) DEF_ISEL(PMULLW_MMXq_MMXq) = PMULLW; DEF_ISEL(PMULLW_MMXq_MEMq) = PMULLW; DEF_ISEL(PMULLW_XMMdq_XMMdq) = PMULLW; DEF_ISEL(PMULLW_XMMdq_MEMdq) = PMULLW; +IF_AVX(DEF_ISEL(VPMULLW_YMMqq_YMMqq_YMMqq) = PMULLW;) DEF_ISEL(PMULHW_MMXq_MMXq) = PMULHW; DEF_ISEL(PMULHW_MMXq_MEMq) = PMULHW;