diff --git a/src/asmjit/x86/x86instapi.cpp b/src/asmjit/x86/x86instapi.cpp index 27671b3..fc17b5c 100644 --- a/src/asmjit/x86/x86instapi.cpp +++ b/src/asmjit/x86/x86instapi.cpp @@ -895,8 +895,10 @@ Error queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* operands, siz case Inst::kIdVpternlogq: { if (opCount == 4 && operands[3].isImm()) { uint32_t predicate = operands[3].as().valueAs(); + if ((predicate >> 4) == (predicate & 0xF)) { out->_operands[0].clearOpFlags(OpRWFlags::kRead); + out->_operands[0].setReadByteMask(0); } } break; diff --git a/src/asmjit/x86/x86rapass.cpp b/src/asmjit/x86/x86rapass.cpp index c7b46f5..c106c6c 100644 --- a/src/asmjit/x86/x86rapass.cpp +++ b/src/asmjit/x86/x86rapass.cpp @@ -477,6 +477,20 @@ Error RACFGBuilder::onInst(InstNode* inst, InstControlFlow& cf, RAInstBuilder& i } } } + else if (opCount == 4 && inst->op(3).isImm()) { + const Imm& imm = inst->op(3).as(); + + switch (inst->id()) { + case Inst::kIdVpternlogd: + case Inst::kIdVpternlogq: { + uint32_t predicate = uint32_t(imm.value() & 0xFFu); + if (predicate == 0x00u || predicate == 0xFFu) { + ib[0]->makeWriteOnly(); + } + break; + } + } + } switch (sameRegHint) { case InstSameRegHint::kNone: diff --git a/test/asmjit_test_compiler_x86.cpp b/test/asmjit_test_compiler_x86.cpp index 1a37ec2..9ff6d89 100644 --- a/test/asmjit_test_compiler_x86.cpp +++ b/test/asmjit_test_compiler_x86.cpp @@ -2463,6 +2463,60 @@ public: } }; +// x86::Compiler - X86Test_AVX512_TernLog +// ====================================== + +class X86Test_AVX512_TernLog : public X86TestCase { +public: + X86Test_AVX512_TernLog() : X86TestCase("AVX512_TernLog") {} + + static void add(TestApp& app) { + const CpuInfo& cpuInfo = CpuInfo::host(); + + if (cpuInfo.features().x86().hasAVX512_F()) { + app.add(new X86Test_AVX512_TernLog()); + } + } + + virtual void compile(x86::Compiler& cc) { + FuncNode* funcNode = cc.addFunc(FuncSignature::build()); + + x86::Gp out = cc.newIntPtr("outPtr"); + x86::Vec vec = cc.newZmm("vec"); + + funcNode->setArg(0, out); + + cc.vpternlogd(vec, vec, vec, 0xFFu); + cc.vmovdqu8(x86::ptr(out), vec); + cc.endFunc(); + } + + virtual bool run(void* _func, String& result, String& expect) { + typedef void (*Func)(void*); + Func func = ptr_as_func(_func); + + uint32_t out[16]; + func(out); + + result.assign("{"); + expect.assign("{"); + + for (uint32_t i = 0; i < 16; i++) { + if (i) { + result.append(", "); + expect.append(", "); + } + result.appendFormat("0x%08X", out[i]); + expect.appendFormat("0x%08X", 0xFFFFFFFFu); + } + + result.append("}"); + expect.append("}"); + + return result == expect; + } +}; + // x86::Compiler - X86Test_FuncArgInt8 // =================================== @@ -4590,6 +4644,7 @@ void compiler_add_x86_tests(TestApp& app) { app.addT(); app.addT(); app.addT(); + app.addT(); // Function arguments handling tests. app.addT(); diff --git a/test/asmjit_test_instinfo.cpp b/test/asmjit_test_instinfo.cpp index 466d8a5..c8cf058 100644 --- a/test/asmjit_test_instinfo.cpp +++ b/test/asmjit_test_instinfo.cpp @@ -151,6 +151,7 @@ static void testX86Arch() { Arch arch = Arch::kX64; printInfoSimple(arch, Inst::kIdAdd, InstOptions::kNone, eax, ebx); + printInfoSimple(arch, Inst::kIdXor, InstOptions::kNone, eax, eax); printInfoSimple(arch, Inst::kIdLods, InstOptions::kNone, eax, dword_ptr(rsi)); printInfoSimple(arch, Inst::kIdPshufd, InstOptions::kNone, xmm0, xmm1, imm(0)); @@ -167,6 +168,9 @@ static void testX86Arch() { printInfoSimple(arch, Inst::kIdVaddpd, InstOptions::kNone, ymm0, ymm30, ymm31); printInfoSimple(arch, Inst::kIdVaddpd, InstOptions::kNone, zmm0, zmm1, zmm2); + printInfoSimple(arch, Inst::kIdVpternlogd, InstOptions::kNone, zmm0, zmm0, zmm0, imm(0xFF)); + printInfoSimple(arch, Inst::kIdVpternlogq, InstOptions::kNone, zmm0, zmm1, zmm2, imm(0x33)); + printInfoExtra(arch, Inst::kIdVaddpd, InstOptions::kNone, k1, zmm0, zmm1, zmm2); printInfoExtra(arch, Inst::kIdVaddpd, InstOptions::kX86_ZMask, k1, zmm0, zmm1, zmm2); #endif // !ASMJIT_NO_X86