diff --git a/External/FEXCore/Source/Interface/Context/Context.h b/External/FEXCore/Source/Interface/Context/Context.h index 2714cfd6b..10e74c44c 100644 --- a/External/FEXCore/Source/Interface/Context/Context.h +++ b/External/FEXCore/Source/Interface/Context/Context.h @@ -22,7 +22,9 @@ #include #include #include +#include #include +#include namespace FEXCore { class ThunkHandler; @@ -266,6 +268,14 @@ namespace FEXCore::Context { std::mutex ExitMutex; std::unique_ptr DebugServer; + std::shared_mutex AOTIRCacheLock; + std::shared_mutex AOTIRCaptureCacheWriteoutLock; + std::atomic AOTIRCaptureCacheWriteoutFlusing; + + std::queue> AOTIRCaptureCacheWriteoutQueue; + void AOTIRCaptureCacheWriteoutQueue_Flush(); + void AOTIRCaptureCacheWriteoutQueue_Append(const std::function &fn); + bool StartPaused = false; FEX_CONFIG_OPT(AppFilename, APP_FILENAME); }; diff --git a/External/FEXCore/Source/Interface/Core/CPUID.cpp b/External/FEXCore/Source/Interface/Core/CPUID.cpp index 3f522d928..a4e0d87f1 100644 --- a/External/FEXCore/Source/Interface/Core/CPUID.cpp +++ b/External/FEXCore/Source/Interface/Core/CPUID.cpp @@ -90,7 +90,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_01h() { (0 << 16) | // Reserved (0 << 17) | // Process-context identifiers (1 << 18) | // Prefetching from memory mapped device - (0 << 19) | // SSE4.1 + (1 << 19) | // SSE4.1 (0 << 20) | // SSE4.2 (0 << 21) | // X2APIC (1 << 22) | // MOVBE diff --git a/External/FEXCore/Source/Interface/Core/Core.cpp b/External/FEXCore/Source/Interface/Core/Core.cpp index be1d27ad5..cf1d65dc3 100644 --- a/External/FEXCore/Source/Interface/Core/Core.cpp +++ b/External/FEXCore/Source/Interface/Core/Core.cpp @@ -43,7 +43,6 @@ $end_info$ #include #include "Interface/Core/GdbServer.h" -#include namespace FEXCore::CPU { bool CreateCPUCore(FEXCore::Context::Context *CTX) { @@ -53,61 +52,6 @@ namespace FEXCore::CPU { } } -static std::shared_mutex AOTIRCacheLock; -static std::shared_mutex AOTIRCaptureCacheWriteoutLock; -static std::queue> AOTIRCaptureCacheWriteoutQueue; -static std::atomic AOTIRCaptureCacheWriteoutFlusing; - -void AOTIRCaptureCacheWriteoutQueue_Flush() { - - { - std::shared_lock lk{AOTIRCaptureCacheWriteoutLock}; - if (AOTIRCaptureCacheWriteoutQueue.size() == 0) { - AOTIRCaptureCacheWriteoutFlusing.store(false); - return; - } - } - - for (;;) { - AOTIRCaptureCacheWriteoutLock.lock(); - std::function fn = std::move(AOTIRCaptureCacheWriteoutQueue.front()); - bool MaybeEmpty = false; - AOTIRCaptureCacheWriteoutQueue.pop(); - MaybeEmpty = AOTIRCaptureCacheWriteoutQueue.size() == 0; - AOTIRCaptureCacheWriteoutLock.unlock(); - - fn(); - if (MaybeEmpty) { - std::shared_lock lk{AOTIRCaptureCacheWriteoutLock}; - if (AOTIRCaptureCacheWriteoutQueue.size() == 0) { - AOTIRCaptureCacheWriteoutFlusing.store(false); - return; - } - } - } - - LOGMAN_MSG_A("Must never get here"); -} - -void AOTIRCaptureCacheWriteoutQueue_Append(const std::function &fn) { - bool Flush = false; - - { - std::unique_lock lk{AOTIRCaptureCacheWriteoutLock}; - AOTIRCaptureCacheWriteoutQueue.push(fn); - if (AOTIRCaptureCacheWriteoutQueue.size() > 10000) { - Flush = true; - } - } - - bool test_val = false; - if (Flush && AOTIRCaptureCacheWriteoutFlusing.compare_exchange_strong(test_val, true)) { - AOTIRCaptureCacheWriteoutQueue_Flush(); - } -} - - - namespace FEXCore::Core { struct ThreadLocalData { FEXCore::Core::InternalThreadState* Thread; @@ -201,6 +145,53 @@ namespace DefaultFallbackCore { } namespace FEXCore::Context { + void Context::AOTIRCaptureCacheWriteoutQueue_Flush() { + { + std::shared_lock lk{AOTIRCaptureCacheWriteoutLock}; + if (AOTIRCaptureCacheWriteoutQueue.size() == 0) { + AOTIRCaptureCacheWriteoutFlusing.store(false); + return; + } + } + + for (;;) { + AOTIRCaptureCacheWriteoutLock.lock(); + std::function fn = std::move(AOTIRCaptureCacheWriteoutQueue.front()); + bool MaybeEmpty = false; + AOTIRCaptureCacheWriteoutQueue.pop(); + MaybeEmpty = AOTIRCaptureCacheWriteoutQueue.size() == 0; + AOTIRCaptureCacheWriteoutLock.unlock(); + + fn(); + if (MaybeEmpty) { + std::shared_lock lk{AOTIRCaptureCacheWriteoutLock}; + if (AOTIRCaptureCacheWriteoutQueue.size() == 0) { + AOTIRCaptureCacheWriteoutFlusing.store(false); + return; + } + } + } + + LOGMAN_MSG_A("Must never get here"); + } + + void Context::AOTIRCaptureCacheWriteoutQueue_Append(const std::function &fn) { + bool Flush = false; + + { + std::unique_lock lk{AOTIRCaptureCacheWriteoutLock}; + AOTIRCaptureCacheWriteoutQueue.push(fn); + if (AOTIRCaptureCacheWriteoutQueue.size() > 10000) { + Flush = true; + } + } + + bool test_val = false; + if (Flush && AOTIRCaptureCacheWriteoutFlusing.compare_exchange_strong(test_val, true)) { + AOTIRCaptureCacheWriteoutQueue_Flush(); + } + } + Context::Context() { #ifdef BLOCKSTATS BlockData = std::make_unique(); @@ -878,14 +869,14 @@ namespace FEXCore::Context { //GuestLength Stream->write((char*)&Length, sizeof(Length)); - + // RAData (inline) // In file, IsShared is always set auto Shared = RAData->IsShared; RAData->IsShared = true; Stream->write((char*)RAData, RAData->Size(RAData->MapCount)); RAData->IsShared = Shared; - + // IRData (inline) IRList->Serialize(*Stream); } @@ -1006,14 +997,14 @@ namespace FEXCore::Context { bool Context::LoadAOTIRCache(int streamfd) { uint64_t tag; - + if (!readAll(streamfd, (char*)&tag, sizeof(tag)) || tag != 0xDEADBEEFC0D30004) return false; - + std::string Module; uint64_t ModSize; uint64_t IndexSize; - + lseek(streamfd, -sizeof(ModSize), SEEK_END); if (!readAll(streamfd, (char*)&ModSize, sizeof(ModSize))) @@ -1072,7 +1063,7 @@ namespace FEXCore::Context { auto ModSize = AOTModule.first.size(); auto &stream = AOTModule.second.Stream; - + // pad to 32 bytes char Zero = 0; while(stream->tellp() & 31) @@ -1094,7 +1085,7 @@ namespace FEXCore::Context { // DataOffset stream->write((char*)&entry.second, sizeof(entry.second)); } - + // End of file header auto IndexSize = FnCount * sizeof(AOTIRInlineIndexEntry) + sizeof(DataBase) + sizeof(FnCount); stream->write((char*)&IndexSize, sizeof(IndexSize)); @@ -1220,7 +1211,7 @@ namespace FEXCore::Context { --Thread->CompileBlockReentrantRefCount; Thread->CPUBackend->ClearCache(); - + return (uintptr_t)CodePtr; } } diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.cpp index 56fbf48a3..e10cee48c 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.cpp @@ -21,6 +21,7 @@ #include "Interface/HLE/Thunks/Thunks.h" +#include #include #include #include @@ -1217,7 +1218,41 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin } break; } + case IR::OP_VDUPELEMENT: { + auto Op = IROp->C(); + uint8_t Elements = OpSize / Op->Header.ElementSize; + LOGMAN_THROW_A(OpSize <= 16, "OpSize is too large for VDupElement: %d", OpSize); + if (OpSize == 16) { + __uint128_t SourceMask = (1ULL << (Op->Header.ElementSize * 8)) - 1; + uint64_t Shift = Op->Header.ElementSize * Op->Index * 8; + if (Op->Header.ElementSize == 8) + SourceMask = ~0ULL; + + __uint128_t Src = *GetSrc<__uint128_t*>(SSAData, Op->Header.Args[0]); + Src >>= Shift; + Src &= SourceMask; + for (size_t i = 0; i < Elements; ++i) { + memcpy(reinterpret_cast(reinterpret_cast(GDP) + (Op->Header.ElementSize * i)), + &Src, Op->Header.ElementSize); + } + } + else { + uint64_t SourceMask = (1ULL << (Op->Header.ElementSize * 8)) - 1; + uint64_t Shift = Op->Header.ElementSize * Op->Index * 8; + if (Op->Header.ElementSize == 8) + SourceMask = ~0ULL; + + uint64_t Src = *GetSrc(SSAData, Op->Header.Args[0]); + Src >>= Shift; + Src &= SourceMask; + for (size_t i = 0; i < Elements; ++i) { + memcpy(reinterpret_cast(reinterpret_cast(GDP) + (Op->Header.ElementSize * i)), + &Src, Op->Header.ElementSize); + } + } + break; + } case IR::OP_ENTRYPOINTOFFSET: { auto Op = IROp->C(); GD = Entry + Op->Offset; @@ -1575,10 +1610,10 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin uint8_t Mask = OpSize * 8 - 1; switch (OpSize) { case 4: - GD = static_cast(Src1) << (Src2 & Mask); + GD = static_cast(Src1) << (Src2 & Mask); break; case 8: - GD = static_cast(Src1) << (Src2 & Mask); + GD = static_cast(Src1) << (Src2 & Mask); break; default: LOGMAN_MSG_A("Unknown LSHL Size: %d\n", OpSize); break; }; @@ -2519,6 +2554,16 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin memcpy(GDP, &Dst, 16); break; } + case IR::OP_VBIC: { + auto Op = IROp->C(); + __uint128_t Src1 = *GetSrc<__uint128_t*>(SSAData, Op->Header.Args[0]); + __uint128_t Src2 = *GetSrc<__uint128_t*>(SSAData, Op->Header.Args[1]); + + __uint128_t Dst = Src1 & ~Src2; + memcpy(GDP, &Dst, 16); + break; + } + case IR::OP_VXOR: { auto Op = IROp->C(); __uint128_t Src1 = *GetSrc<__uint128_t*>(SSAData, Op->Header.Args[0]); @@ -2964,6 +3009,24 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin memcpy(GDP, Tmp, Op->Header.ElementSize); break; } + case IR::OP_VUMINV: { + auto Op = IROp->C(); + void *Src = GetSrc(SSAData, Op->Header.Args[0]); + uint8_t Tmp[16]; + + uint8_t Elements = OpSize / Op->Header.ElementSize; + + auto Func = [](auto current, auto a) { return std::min(current, a); }; + switch (Op->Header.ElementSize) { + DO_VECTOR_REDUCE_1SRC_OP(1, uint8_t, Func, ~0) + DO_VECTOR_REDUCE_1SRC_OP(2, uint16_t, Func, ~0) + DO_VECTOR_REDUCE_1SRC_OP(4, uint32_t, Func, ~0U) + DO_VECTOR_REDUCE_1SRC_OP(8, uint64_t, Func, ~0ULL) + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + memcpy(GDP, Tmp, Op->Header.ElementSize); + break; + } case IR::OP_VURAVG: { auto Op = IROp->C(); void *Src1 = GetSrc(SSAData, Op->Header.Args[0]); @@ -2999,6 +3062,24 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin memcpy(GDP, Tmp, OpSize); break; } + case IR::OP_VPOPCOUNT: { + auto Op = IROp->C(); + void *Src = GetSrc(SSAData, Op->Header.Args[0]); + uint8_t Tmp[16]; + + uint8_t Elements = OpSize / Op->Header.ElementSize; + + auto Func = [](auto a) { return std::popcount(a); }; + switch (Op->Header.ElementSize) { + DO_VECTOR_1SRC_OP(1, uint8_t, Func) + DO_VECTOR_1SRC_OP(2, uint16_t, Func) + DO_VECTOR_1SRC_OP(4, uint32_t, Func) + DO_VECTOR_1SRC_OP(8, uint64_t, Func) + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + memcpy(GDP, Tmp, OpSize); + break; + } case IR::OP_VFMUL: { auto Op = IROp->C(); void *Src1 = GetSrc(SSAData, Op->Header.Args[0]); @@ -3478,6 +3559,28 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin memcpy(GDP, Tmp, Op->Header.Size); break; } + case IR::OP_VUABDL: { + auto Op = IROp->C(); + void *Src1 = GetSrc(SSAData, Op->Header.Args[0]); + void *Src2 = GetSrc(SSAData, Op->Header.Args[1]); + + uint8_t Tmp[16]; + + uint8_t Elements = OpSize / Op->Header.ElementSize; + + auto Func8 = [](auto a, auto b) { return std::abs((int16_t)a - (int16_t)b); }; + auto Func16 = [](auto a, auto b) { return std::abs((int32_t)a - (int32_t)b); }; + auto Func32 = [](auto a, auto b) { return std::abs((int64_t)a - (int64_t)b); }; + + switch (Op->Header.ElementSize) { + DO_VECTOR_2SRC_2TYPE_OP(2, uint16_t, uint8_t, Func8) + DO_VECTOR_2SRC_2TYPE_OP(4, uint32_t, uint16_t, Func16) + DO_VECTOR_2SRC_2TYPE_OP(8, uint64_t, uint32_t, Func32) + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + memcpy(GDP, Tmp, OpSize); + break; + } case IR::OP_VSXTL: { auto Op = IROp->C(); void *Src = GetSrc(SSAData, Op->Header.Args[0]); @@ -3798,6 +3901,64 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin memcpy(GDP, Tmp, OpSize); break; } + case IR::OP_VUNZIP2: + case IR::OP_VUNZIP: { + auto Op = IROp->C(); + void *Src1 = GetSrc(SSAData, Op->Header.Args[0]); + void *Src2 = GetSrc(SSAData, Op->Header.Args[1]); + uint8_t Tmp[16]; + uint8_t Elements = OpSize / Op->Header.ElementSize; + unsigned Start = IROp->Op == IR::OP_VUNZIP ? 0 : 1; + Elements >>= 1; + + switch (Op->Header.ElementSize) { + case 1: { + auto *Dst_d = reinterpret_cast(Tmp); + auto *Src1_d = reinterpret_cast(Src1); + auto *Src2_d = reinterpret_cast(Src2); + for (unsigned i = 0; i < Elements; ++i) { + Dst_d[i] = Src1_d[Start + (i * 2)]; + Dst_d[Elements+i] = Src2_d[Start + (i * 2)]; + } + break; + } + case 2: { + auto *Dst_d = reinterpret_cast(Tmp); + auto *Src1_d = reinterpret_cast(Src1); + auto *Src2_d = reinterpret_cast(Src2); + for (unsigned i = 0; i < Elements; ++i) { + Dst_d[i] = Src1_d[Start + (i * 2)]; + Dst_d[Elements+i] = Src2_d[Start + (i * 2)]; + } + break; + } + case 4: { + auto *Dst_d = reinterpret_cast(Tmp); + auto *Src1_d = reinterpret_cast(Src1); + auto *Src2_d = reinterpret_cast(Src2); + for (unsigned i = 0; i < Elements; ++i) { + Dst_d[i] = Src1_d[Start + (i * 2)]; + Dst_d[Elements+i] = Src2_d[Start + (i * 2)]; + } + break; + } + case 8: { + auto *Dst_d = reinterpret_cast(Tmp); + auto *Src1_d = reinterpret_cast(Src1); + auto *Src2_d = reinterpret_cast(Src2); + for (unsigned i = 0; i < Elements; ++i) { + Dst_d[i] = Src1_d[Start + (i * 2)]; + Dst_d[Elements+i] = Src2_d[Start + (i * 2)]; + } + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + + memcpy(GDP, Tmp, OpSize); + break; + } + case IR::OP_VINSELEMENT: { auto Op = IROp->C(); void *Src1 = GetSrc(SSAData, Op->Header.Args[0]); @@ -4180,6 +4341,10 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin uint64_t Offset = Op->Index * Op->Header.ElementSize * 8; __uint128_t Mask = (1ULL << (Op->Header.ElementSize * 8)) - 1; + if (Op->Header.ElementSize == 8) { + Mask = ~0ULL; + } + Src2 = Src2 & Mask; Mask <<= Offset; Mask = ~Mask; __uint128_t Dst = Src1 & Mask; @@ -4339,6 +4504,53 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin memcpy(GDP, Tmp, OpSize); break; } + case IR::OP_VECTOR_FTOI: { + auto Op = IROp->C(); + void *Src = GetSrc(SSAData, Op->Header.Args[0]); + uint8_t Tmp[16]{}; + + uint8_t Elements = OpSize / Op->Header.ElementSize; + auto Func_Nearest = [](auto a) { return std::rint(a); }; + auto Func_Neg = [](auto a) { return std::floor(a); }; + auto Func_Pos = [](auto a) { return std::ceil(a); }; + auto Func_Trunc = [](auto a) { return std::trunc(a); }; + auto Func_Host = [](auto a) { return std::rint(a); }; + + switch (Op->Round) { + case FEXCore::IR::Round_Nearest.Val: + switch (Op->Header.ElementSize) { + DO_VECTOR_1SRC_OP(4, float, Func_Nearest) + DO_VECTOR_1SRC_OP(8, double, Func_Nearest) + } + break; + case FEXCore::IR::Round_Negative_Infinity.Val: + switch (Op->Header.ElementSize) { + DO_VECTOR_1SRC_OP(4, float, Func_Neg) + DO_VECTOR_1SRC_OP(8, double, Func_Neg) + } + break; + case FEXCore::IR::Round_Positive_Infinity.Val: + switch (Op->Header.ElementSize) { + DO_VECTOR_1SRC_OP(4, float, Func_Pos) + DO_VECTOR_1SRC_OP(8, double, Func_Pos) + } + break; + case FEXCore::IR::Round_Towards_Zero.Val: + switch (Op->Header.ElementSize) { + DO_VECTOR_1SRC_OP(4, float, Func_Trunc) + DO_VECTOR_1SRC_OP(8, double, Func_Trunc) + } + break; + case FEXCore::IR::Round_Host.Val: + switch (Op->Header.ElementSize) { + DO_VECTOR_1SRC_OP(4, float, Func_Host) + DO_VECTOR_1SRC_OP(8, double, Func_Host) + } + break; + } + memcpy(GDP, Tmp, OpSize); + break; + } case IR::OP_FCMP: { auto Op = IROp->C(); uint32_t ResultFlags{}; diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp index 2916e7057..fa32124b3 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp @@ -198,6 +198,62 @@ DEF_OP(Vector_FToF) { } } +DEF_OP(Vector_FToI) { + auto Op = IROp->C(); + switch (Op->Round) { + case FEXCore::IR::Round_Nearest.Val: + switch (Op->Header.ElementSize) { + case 4: + frintn(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4S()); + break; + case 8: + frintn(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2D()); + break; + } + break; + case FEXCore::IR::Round_Negative_Infinity.Val: + switch (Op->Header.ElementSize) { + case 4: + frintm(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4S()); + break; + case 8: + frintm(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2D()); + break; + } + break; + case FEXCore::IR::Round_Positive_Infinity.Val: + switch (Op->Header.ElementSize) { + case 4: + frintp(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4S()); + break; + case 8: + frintp(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2D()); + break; + } + break; + case FEXCore::IR::Round_Towards_Zero.Val: + switch (Op->Header.ElementSize) { + case 4: + frintz(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4S()); + break; + case 8: + frintz(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2D()); + break; + } + break; + case FEXCore::IR::Round_Host.Val: + switch (Op->Header.ElementSize) { + case 4: + frinti(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4S()); + break; + case 8: + frinti(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2D()); + break; + } + break; + } +} + #undef DEF_OP void Arm64JITCore::RegisterConversionHandlers() { #define REGISTER_OP(op, x) OpHandlers[FEXCore::IR::IROps::OP_##op] = &Arm64JITCore::Op_##x @@ -213,6 +269,7 @@ void Arm64JITCore::RegisterConversionHandlers() { REGISTER_OP(VECTOR_FTOU, Vector_FToU); REGISTER_OP(VECTOR_FTOS, Vector_FToS); REGISTER_OP(VECTOR_FTOF, Vector_FToF); + REGISTER_OP(VECTOR_FTOI, Vector_FToI); #undef REGISTER_OP } } diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h index a42367648..1b7425447 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h @@ -287,6 +287,7 @@ private: DEF_OP(Vector_FToU); DEF_OP(Vector_FToS); DEF_OP(Vector_FToF); + DEF_OP(Vector_FToI); ///< Flag ops DEF_OP(GetHostFlag); @@ -336,6 +337,7 @@ private: DEF_OP(SplatVector4); DEF_OP(VMov); DEF_OP(VAnd); + DEF_OP(VBic); DEF_OP(VOr); DEF_OP(VXor); DEF_OP(VAdd); @@ -346,8 +348,10 @@ private: DEF_OP(VSQSub); DEF_OP(VAddP); DEF_OP(VAddV); + DEF_OP(VUMinV); DEF_OP(VURAvg); DEF_OP(VAbs); + DEF_OP(VPopcount); DEF_OP(VFAdd); DEF_OP(VFAddP); DEF_OP(VFSub); @@ -367,6 +371,8 @@ private: DEF_OP(VSMax); DEF_OP(VZip); DEF_OP(VZip2); + DEF_OP(VUnZip); + DEF_OP(VUnZip2); DEF_OP(VBSL); DEF_OP(VCMPEQ); DEF_OP(VCMPEQZ); @@ -389,6 +395,7 @@ private: DEF_OP(VInsElement); DEF_OP(VInsScalarElement); DEF_OP(VExtractElement); + DEF_OP(VDupElement); DEF_OP(VExtr); DEF_OP(VSLI); DEF_OP(VSRI); @@ -411,6 +418,7 @@ private: DEF_OP(VSMull); DEF_OP(VUMull2); DEF_OP(VSMull2); + DEF_OP(VUABDL); DEF_OP(VTBL1); ///< Encryption ops diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp index c6f97609d..914a3eaf5 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp @@ -127,6 +127,11 @@ DEF_OP(VAnd) { and_(GetDst(Node).V16B(), GetSrc(Op->Header.Args[0].ID()).V16B(), GetSrc(Op->Header.Args[1].ID()).V16B()); } +DEF_OP(VBic) { + auto Op = IROp->C(); + bic(GetDst(Node).V16B(), GetSrc(Op->Header.Args[0].ID()).V16B(), GetSrc(Op->Header.Args[1].ID()).V16B()); +} + DEF_OP(VOr) { auto Op = IROp->C(); orr(GetDst(Node).V16B(), GetSrc(Op->Header.Args[0].ID()).V16B(), GetSrc(Op->Header.Args[1].ID()).V16B()); @@ -337,6 +342,21 @@ DEF_OP(VAddV) { } } +DEF_OP(VUMinV) { + auto Op = IROp->C(); + uint8_t OpSize = IROp->Size; + uint8_t Elements = OpSize / Op->Header.ElementSize; + // Vector + switch (Op->Header.ElementSize) { + case 1: + case 2: + case 4: + uminv(GetDst(Node).VCast(Op->Header.ElementSize * 8, 1), GetSrc(Op->Header.Args[0].ID()).VCast(OpSize * 8, Elements)); + break; + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } +} + DEF_OP(VURAvg) { auto Op = IROp->C(); switch (Op->Header.ElementSize) { @@ -380,6 +400,30 @@ DEF_OP(VAbs) { } } +DEF_OP(VPopcount) { + auto Op = IROp->C(); + uint8_t OpSize = IROp->Size; + if (OpSize == 8) { + // Scalar + switch (Op->Header.ElementSize) { + case 1: { + cnt(GetDst(Node).V8B(), GetSrc(Op->Header.Args[0].ID()).V8B()); + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + } + else { + // Vector + switch (Op->Header.ElementSize) { + case 1: + cnt(GetDst(Node).V16B(), GetSrc(Op->Header.Args[0].ID()).V16B()); + break; + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + } +} + DEF_OP(VFAdd) { auto Op = IROp->C(); uint8_t OpSize = IROp->Size; @@ -949,6 +993,92 @@ DEF_OP(VZip2) { } } +DEF_OP(VUnZip) { + auto Op = IROp->C(); + uint8_t OpSize = IROp->Size; + if (OpSize == 8) { + switch (Op->Header.ElementSize) { + case 1: { + uzp1(GetDst(Node).V8B(), GetSrc(Op->Header.Args[0].ID()).V8B(), GetSrc(Op->Header.Args[1].ID()).V8B()); + break; + } + case 2: { + uzp1(GetDst(Node).V4H(), GetSrc(Op->Header.Args[0].ID()).V4H(), GetSrc(Op->Header.Args[1].ID()).V4H()); + break; + } + case 4: { + uzp1(GetDst(Node).V2S(), GetSrc(Op->Header.Args[0].ID()).V2S(), GetSrc(Op->Header.Args[1].ID()).V2S()); + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + } + else { + switch (Op->Header.ElementSize) { + case 1: { + uzp1(GetDst(Node).V16B(), GetSrc(Op->Header.Args[0].ID()).V16B(), GetSrc(Op->Header.Args[1].ID()).V16B()); + break; + } + case 2: { + uzp1(GetDst(Node).V8H(), GetSrc(Op->Header.Args[0].ID()).V8H(), GetSrc(Op->Header.Args[1].ID()).V8H()); + break; + } + case 4: { + uzp1(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4S(), GetSrc(Op->Header.Args[1].ID()).V4S()); + break; + } + case 8: { + uzp1(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2D(), GetSrc(Op->Header.Args[1].ID()).V2D()); + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + } +} + +DEF_OP(VUnZip2) { + auto Op = IROp->C(); + uint8_t OpSize = IROp->Size; + if (OpSize == 8) { + switch (Op->Header.ElementSize) { + case 1: { + uzp2(GetDst(Node).V8B(), GetSrc(Op->Header.Args[0].ID()).V8B(), GetSrc(Op->Header.Args[1].ID()).V8B()); + break; + } + case 2: { + uzp2(GetDst(Node).V4H(), GetSrc(Op->Header.Args[0].ID()).V4H(), GetSrc(Op->Header.Args[1].ID()).V4H()); + break; + } + case 4: { + uzp2(GetDst(Node).V2S(), GetSrc(Op->Header.Args[0].ID()).V2S(), GetSrc(Op->Header.Args[1].ID()).V2S()); + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + } + else { + switch (Op->Header.ElementSize) { + case 1: { + uzp2(GetDst(Node).V16B(), GetSrc(Op->Header.Args[0].ID()).V16B(), GetSrc(Op->Header.Args[1].ID()).V16B()); + break; + } + case 2: { + uzp2(GetDst(Node).V8H(), GetSrc(Op->Header.Args[0].ID()).V8H(), GetSrc(Op->Header.Args[1].ID()).V8H()); + break; + } + case 4: { + uzp2(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4S(), GetSrc(Op->Header.Args[1].ID()).V4S()); + break; + } + case 8: { + uzp2(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2D(), GetSrc(Op->Header.Args[1].ID()).V2D()); + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + } +} + DEF_OP(VBSL) { auto Op = IROp->C(); if (IROp->Size == 16) { @@ -1648,6 +1778,25 @@ DEF_OP(VExtractElement) { } } +DEF_OP(VDupElement) { + auto Op = IROp->C(); + switch (Op->Header.ElementSize) { + case 1: + dup(GetDst(Node).V16B(), GetSrc(Op->Header.Args[0].ID()).V16B(), Op->Index); + break; + case 2: + dup(GetDst(Node).V8H(), GetSrc(Op->Header.Args[0].ID()).V8H(), Op->Index); + break; + case 4: + dup(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4S(), Op->Index); + break; + case 8: + dup(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2D(), Op->Index); + break; + default: LOGMAN_MSG_A("Unhandled DupElementSize: %d", Op->Header.ElementSize); + } +} + DEF_OP(VExtr) { auto Op = IROp->C(); uint8_t OpSize = IROp->Size; @@ -2135,6 +2284,25 @@ DEF_OP(VSMull2) { } } +DEF_OP(VUABDL) { + auto Op = IROp->C(); + switch (Op->Header.ElementSize) { + case 2: { + uabdl(GetDst(Node).V8H(), GetSrc(Op->Header.Args[0].ID()).V8B(), GetSrc(Op->Header.Args[1].ID()).V8B()); + break; + } + case 4: { + uabdl(GetDst(Node).V4S(), GetSrc(Op->Header.Args[0].ID()).V4H(), GetSrc(Op->Header.Args[1].ID()).V4H()); + break; + } + case 8: { + uabdl(GetDst(Node).V2D(), GetSrc(Op->Header.Args[0].ID()).V2S(), GetSrc(Op->Header.Args[1].ID()).V2S()); + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize >> 1); break; + } +} + DEF_OP(VTBL1) { auto Op = IROp->C(); uint8_t OpSize = IROp->Size; @@ -2163,6 +2331,7 @@ void Arm64JITCore::RegisterVectorHandlers() { REGISTER_OP(SPLATVECTOR4, SplatVector4); REGISTER_OP(VMOV, VMov); REGISTER_OP(VAND, VAnd); + REGISTER_OP(VBIC, VBic); REGISTER_OP(VOR, VOr); REGISTER_OP(VXOR, VXor); REGISTER_OP(VADD, VAdd); @@ -2173,8 +2342,10 @@ void Arm64JITCore::RegisterVectorHandlers() { REGISTER_OP(VSQSUB, VSQSub); REGISTER_OP(VADDP, VAddP); REGISTER_OP(VADDV, VAddV); + REGISTER_OP(VUMINV, VUMinV); REGISTER_OP(VURAVG, VURAvg); REGISTER_OP(VABS, VAbs); + REGISTER_OP(VPOPCOUNT, VPopcount); REGISTER_OP(VFADD, VFAdd); REGISTER_OP(VFADDP, VFAddP); REGISTER_OP(VFSUB, VFSub); @@ -2194,6 +2365,8 @@ void Arm64JITCore::RegisterVectorHandlers() { REGISTER_OP(VSMAX, VSMax); REGISTER_OP(VZIP, VZip); REGISTER_OP(VZIP2, VZip2); + REGISTER_OP(VUNZIP, VUnZip); + REGISTER_OP(VUNZIP2, VUnZip2); REGISTER_OP(VBSL, VBSL); REGISTER_OP(VCMPEQ, VCMPEQ); REGISTER_OP(VCMPEQZ, VCMPEQZ); @@ -2216,6 +2389,7 @@ void Arm64JITCore::RegisterVectorHandlers() { REGISTER_OP(VINSELEMENT, VInsElement); REGISTER_OP(VINSSCALARELEMENT, VInsScalarElement); REGISTER_OP(VEXTRACTELEMENT, VExtractElement); + REGISTER_OP(VDUPELEMENT, VDupElement); REGISTER_OP(VEXTR, VExtr); REGISTER_OP(VSLI, VSLI); REGISTER_OP(VSRI, VSRI); @@ -2239,6 +2413,7 @@ void Arm64JITCore::RegisterVectorHandlers() { REGISTER_OP(VSMULL, VSMull); REGISTER_OP(VUMULL2, VUMull2); REGISTER_OP(VSMULL2, VSMull2); + REGISTER_OP(VUABDL, VUABDL); REGISTER_OP(VTBL1, VTBL1); #undef REGISTER_OP } diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/ConversionOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/ConversionOps.cpp index 63a97625a..0581ebcff 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/ConversionOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/ConversionOps.cpp @@ -176,6 +176,38 @@ DEF_OP(Vector_FToF) { } } +DEF_OP(Vector_FToI) { + auto Op = IROp->C(); + uint8_t RoundMode{}; + + switch (Op->Round) { + case FEXCore::IR::Round_Nearest.Val: + RoundMode = 0b0000'0'0'00; + break; + case FEXCore::IR::Round_Negative_Infinity.Val: + RoundMode = 0b0000'0'0'01; + break; + case FEXCore::IR::Round_Positive_Infinity.Val: + RoundMode = 0b0000'0'0'10; + break; + case FEXCore::IR::Round_Towards_Zero.Val: + RoundMode = 0b0000'0'0'11; + break; + case FEXCore::IR::Round_Host.Val: + RoundMode = 0b0000'0'1'00; + break; + } + + switch (Op->Header.ElementSize) { + case 4: + roundps(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), RoundMode); + break; + case 8: + roundpd(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), RoundMode); + break; + } +} + #undef DEF_OP void X86JITCore::RegisterConversionHandlers() { #define REGISTER_OP(op, x) OpHandlers[FEXCore::IR::IROps::OP_##op] = &X86JITCore::Op_##x @@ -191,6 +223,7 @@ void X86JITCore::RegisterConversionHandlers() { REGISTER_OP(VECTOR_FTOU, Vector_FToU); REGISTER_OP(VECTOR_FTOS, Vector_FToS); REGISTER_OP(VECTOR_FTOF, Vector_FToF); + REGISTER_OP(VECTOR_FTOI, Vector_FToI); #undef REGISTER_OP } } diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h index b1be7e03b..49e5024b1 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h @@ -291,6 +291,7 @@ private: DEF_OP(Vector_FToU); DEF_OP(Vector_FToS); DEF_OP(Vector_FToF); + DEF_OP(Vector_FToI); ///< Flag ops DEF_OP(GetHostFlag); @@ -333,6 +334,7 @@ private: DEF_OP(SplatVector); DEF_OP(VMov); DEF_OP(VAnd); + DEF_OP(VBic); DEF_OP(VOr); DEF_OP(VXor); DEF_OP(VAdd); @@ -343,8 +345,10 @@ private: DEF_OP(VSQSub); DEF_OP(VAddP); DEF_OP(VAddV); + DEF_OP(VUMinV); DEF_OP(VURAvg); DEF_OP(VAbs); + DEF_OP(VPopcount); DEF_OP(VFAdd); DEF_OP(VFAddP); DEF_OP(VFSub); @@ -364,6 +368,8 @@ private: DEF_OP(VSMax); DEF_OP(VZip); DEF_OP(VZip2); + DEF_OP(VUnZip); + DEF_OP(VUnZip2); DEF_OP(VBSL); DEF_OP(VCMPEQ); DEF_OP(VCMPEQZ); @@ -386,6 +392,7 @@ private: DEF_OP(VInsElement); DEF_OP(VInsScalarElement); DEF_OP(VExtractElement); + DEF_OP(VDupElement); DEF_OP(VExtr); DEF_OP(VSLI); DEF_OP(VSRI); @@ -408,6 +415,7 @@ private: DEF_OP(VSMull); DEF_OP(VUMull2); DEF_OP(VSMull2); + DEF_OP(VUABDL); DEF_OP(VTBL1); ///< Encryption ops diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/MiscOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/MiscOps.cpp index ad715871a..7c27dbe75 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/MiscOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/MiscOps.cpp @@ -12,6 +12,10 @@ static void PrintValue(uint64_t Value) { LogMan::Msg::D("Value: 0x%lx", Value); } +static void PrintVectorValue(uint64_t Value, uint64_t ValueUpper) { + LogMan::Msg::D("Value: 0x%016lx'%016lx", ValueUpper, Value); +} + #define DEF_OP(x) void X86JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) DEF_OP(Fence) { @@ -119,24 +123,22 @@ DEF_OP(SetRoundingMode) { DEF_OP(Print) { auto Op = IROp->C(); - for (auto &Reg : RA64) - push(Reg); + PushRegs(); + if (IsGPR(Op->Header.Args[0].ID())) { + mov (rdi, GetSrc(Op->Header.Args[0].ID())); - auto NumPush = RA64.size(); - if (NumPush & 1) - sub(rsp, 8); // Align + mov(rax, reinterpret_cast(PrintValue)); + } + else { + pextrq(rdi, GetSrc(Op->Header.Args[0].ID()), 0); + pextrq(rsi, GetSrc(Op->Header.Args[0].ID()), 1); - mov (rdi, GetSrc(Op->Header.Args[0].ID())); - - mov(rax, reinterpret_cast(PrintValue)); + mov(rax, reinterpret_cast(PrintVectorValue)); + } call(rax); - if (NumPush & 1) - add(rsp, 8); // Align - - for (uint32_t i = RA64.size(); i > 0; --i) - pop(RA64[i - 1]); + PopRegs(); } #undef DEF_OP diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp index ff4566576..c4314fcc7 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp @@ -139,6 +139,14 @@ DEF_OP(VAnd) { vpand(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID())); } +DEF_OP(VBic) { + auto Op = IROp->C(); + // This doesn't map directly to ARM + vpcmpeqd(xmm15, xmm15, xmm15); + vpxor(xmm15, GetSrc(Op->Header.Args[1].ID()), xmm15); + vpand(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), xmm15); +} + DEF_OP(VOr) { auto Op = IROp->C(); vpor(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID())); @@ -355,6 +363,23 @@ DEF_OP(VAddV) { movaps(Dest, xmm15); } +DEF_OP(VUMinV) { + auto Op = IROp->C(); + + auto Src = GetSrc(Op->Header.Args[0].ID()); + auto Dest = GetDst(Node); + switch (Op->Header.ElementSize) { + case 2: { + phminposuw(Dest, Src); + // Extract the upper bits which are zero, overwriting position + pextrw(eax, Dest, 2); + pinsrw(Dest, eax, 1); + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } +} + DEF_OP(VURAvg) { auto Op = IROp->C(); switch (Op->Header.ElementSize) { @@ -393,6 +418,32 @@ DEF_OP(VAbs) { } } +DEF_OP(VPopcount) { + auto Op = IROp->C(); + uint8_t OpSize = IROp->Size; + // This only supports 8bit popcount on 8byte to 16byte registers + + auto Src = GetSrc(Op->Header.Args[0].ID()); + auto Dest = GetDst(Node); + vpxor(xmm15, xmm15, xmm15); + uint8_t Elements = OpSize / Op->Header.ElementSize; + + // This is disgustingly bad on x86-64 but we only need it for compatibility + switch (Op->Header.ElementSize) { + case 1: { + for (size_t i = 0; i < Elements; ++i) { + pextrb(eax, Src, i); + popcnt(eax, eax); + pinsrb(xmm15, eax, i); + } + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + + movaps(Dest, xmm15); +} + DEF_OP(VFAdd) { auto Op = IROp->C(); uint8_t OpSize = IROp->Size; @@ -933,6 +984,112 @@ DEF_OP(VZip2) { } } +DEF_OP(VUnZip) { + auto Op = IROp->C(); + uint8_t OpSize = IROp->Size; + + if (OpSize == 8) { + LOGMAN_MSG_A("Unsupported registersize on VunZip"); + } + else { + switch (Op->Header.ElementSize) { + case 1: { + // Shuffle low bits + mov(rax, 0x0E'0C'0A'08'06'04'02'00); // Lower + mov(rcx, 0x80'80'80'80'80'80'80'80); // Upper + vmovq(xmm15, rax); + pinsrq(xmm15, rcx, 1); + vpshufb(xmm14, GetSrc(Op->Header.Args[0].ID()), xmm15); + vpshufb(xmm13, GetSrc(Op->Header.Args[1].ID()), xmm15); + // movlhps back to combine + vmovlhps(GetDst(Node), xmm14, xmm13); + break; + } + case 2: { + // Shuffle low bits + mov(rax, 0x0D'0C'09'08'05'04'01'00); // Lower + mov(rcx, 0x80'80'80'80'80'80'80'80); // Upper + vmovq(xmm15, rax); + pinsrq(xmm15, rcx, 1); + vpshufb(xmm14, GetSrc(Op->Header.Args[0].ID()), xmm15); + vpshufb(xmm13, GetSrc(Op->Header.Args[1].ID()), xmm15); + // movlhps back to combine + vmovlhps(GetDst(Node), xmm14, xmm13); + break; + } + case 4: { + vshufps(GetDst(Node), + GetSrc(Op->Header.Args[0].ID()), + GetSrc(Op->Header.Args[1].ID()), + 0b10'00'10'00); + break; + } + case 8: { + vshufpd(GetDst(Node), + GetSrc(Op->Header.Args[0].ID()), + GetSrc(Op->Header.Args[1].ID()), + 0b0'0); + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + } +} + +DEF_OP(VUnZip2) { + auto Op = IROp->C(); + uint8_t OpSize = IROp->Size; + + + if (OpSize == 8) { + LOGMAN_MSG_A("Unsupported registersize on VunZip"); + } + else { + switch (Op->Header.ElementSize) { + case 1: { + // Shuffle low bits + mov(rax, 0x0F'0D'0B'09'07'05'03'01); // Lower + mov(rcx, 0x80'80'80'80'80'80'80'80); // Upper + vmovq(xmm15, rax); + pinsrq(xmm15, rcx, 1); + vpshufb(xmm14, GetSrc(Op->Header.Args[0].ID()), xmm15); + vpshufb(xmm13, GetSrc(Op->Header.Args[1].ID()), xmm15); + // movlhps back to combine + vmovlhps(GetDst(Node), xmm14, xmm13); + break; + } + case 2: { + // Shuffle low bits + mov(rax, 0x0F'0E'0B'0A'07'06'03'02); // Lower + mov(rcx, 0x80'80'80'80'80'80'80'80); // Upper + vmovq(xmm15, rax); + pinsrq(xmm15, rcx, 1); + vpshufb(xmm14, GetSrc(Op->Header.Args[0].ID()), xmm15); + vpshufb(xmm13, GetSrc(Op->Header.Args[1].ID()), xmm15); + // movlhps back to combine + vmovlhps(GetDst(Node), xmm14, xmm13); + break; + } + case 4: { + vshufps(GetDst(Node), + GetSrc(Op->Header.Args[0].ID()), + GetSrc(Op->Header.Args[1].ID()), + 0b11'01'11'01); + break; + } + case 8: { + vshufpd(GetDst(Node), + GetSrc(Op->Header.Args[0].ID()), + GetSrc(Op->Header.Args[1].ID()), + 0b1'1); + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } + } +} + + DEF_OP(VBSL) { auto Op = IROp->C(); vpand(xmm0, GetSrc(Op->Header.Args[0].ID()), GetSrc(Op->Header.Args[1].ID())); @@ -1407,6 +1564,61 @@ DEF_OP(VExtractElement) { } } +DEF_OP(VDupElement) { + auto Op = IROp->C(); + + switch (Op->Header.ElementSize) { + case 1: { + // First extract the index + pextrb(eax, GetSrc(Op->Header.Args[0].ID()), Op->Index); + // Insert it in to the first element of the destination + pinsrb(GetDst(Node), eax, 0); + pinsrb(GetDst(Node), eax, 1); + // Shuffle low elements + vpshuflw(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), 0); + // Insert element in to the first upper 64bit element + pinsrb(GetDst(Node), eax, 8); + pinsrb(GetDst(Node), eax, 9); + // Shuffle high elements + vpshufhw(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), 0); + break; + } + case 2: { + // First extract the index + pextrw(eax, GetSrc(Op->Header.Args[0].ID()), Op->Index); + // Insert it in to the first element of the destination + pinsrw(GetDst(Node), eax, 0); + // Shuffle low elements + vpshuflw(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), 0); + // Insert element in to the first upper 64bit element + pinsrw(GetDst(Node), eax, 4); + // Shuffle high elements + vpshufhw(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), 0); + break; + } + case 4: { + vpshufd(GetDst(Node), + GetSrc(Op->Header.Args[0].ID()), + (Op->Index << 0) | + (Op->Index << 2) | + (Op->Index << 4) | + (Op->Index << 6)); + break; + } + case 8: { + vshufpd(GetDst(Node), + GetSrc(Op->Header.Args[0].ID()), + GetSrc(Op->Header.Args[0].ID()), + (Op->Index << 0) | + (Op->Index << 1)); + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } +} + + + DEF_OP(VExtr) { auto Op = IROp->C(); uint8_t OpSize = IROp->Size; @@ -1460,14 +1672,36 @@ DEF_OP(VUShrI) { DEF_OP(VSShrI) { auto Op = IROp->C(); - movapd(GetDst(Node), GetSrc(Op->Header.Args[0].ID())); + auto Dest = GetDst(Node); + movapd(Dest, GetSrc(Op->Header.Args[0].ID())); switch (Op->Header.ElementSize) { + case 1: { + // This isn't a native instruction on x86 + uint8_t OpSize = IROp->Size; + uint8_t Elements = OpSize / Op->Header.ElementSize; + for (int i = 0; i < Elements; ++i) { + pextrb(eax, Dest, i); + movsx(eax, al); + sar(al, Op->BitShift); + pinsrb(Dest, eax, i); + } + break; + } case 2: { - psraw(GetDst(Node), Op->BitShift); + psraw(Dest, Op->BitShift); break; } case 4: { - psrad(GetDst(Node), Op->BitShift); + psrad(Dest, Op->BitShift); + break; + } + case 8: { + // This isn't a native instruction on x86 + for (int i = 0; i < 2; ++i) { + pextrq(rax, Dest, i); + sar(rax, Op->BitShift); + pinsrq(Dest, rax, i); + } break; } default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; @@ -1872,6 +2106,27 @@ DEF_OP(VSMull2) { } } +DEF_OP(VUABDL) { + auto Op = IROp->C(); + switch (Op->Header.ElementSize) { + case 2: { + pmovzxbw(xmm14, GetSrc(Op->Header.Args[0].ID())); + pmovzxbw(xmm15, GetSrc(Op->Header.Args[1].ID())); + vpsubw(GetDst(Node), xmm14, xmm15); + vpabsw(GetDst(Node), GetDst(Node)); + break; + } + case 4: { + pmovzxwd(xmm14, GetSrc(Op->Header.Args[0].ID())); + pmovzxwd(xmm15, GetSrc(Op->Header.Args[1].ID())); + vpsubd(GetDst(Node), xmm14, xmm15); + vpabsd(GetDst(Node), GetDst(Node)); + break; + } + default: LOGMAN_MSG_A("Unknown Element Size: %d", Op->Header.ElementSize); break; + } +} + DEF_OP(VTBL1) { auto Op = IROp->C(); uint8_t OpSize = IROp->Size; @@ -1901,6 +2156,7 @@ void X86JITCore::RegisterVectorHandlers() { REGISTER_OP(SPLATVECTOR4, SplatVector); REGISTER_OP(VMOV, VMov); REGISTER_OP(VAND, VAnd); + REGISTER_OP(VBIC, VBic); REGISTER_OP(VOR, VOr); REGISTER_OP(VXOR, VXor); REGISTER_OP(VADD, VAdd); @@ -1911,8 +2167,10 @@ void X86JITCore::RegisterVectorHandlers() { REGISTER_OP(VSQSUB, VSQSub); REGISTER_OP(VADDP, VAddP); REGISTER_OP(VADDV, VAddV); + REGISTER_OP(VUMINV, VUMinV); REGISTER_OP(VURAVG, VURAvg); REGISTER_OP(VABS, VAbs); + REGISTER_OP(VPOPCOUNT, VPopcount); REGISTER_OP(VFADD, VFAdd); REGISTER_OP(VFADDP, VFAddP); REGISTER_OP(VFSUB, VFSub); @@ -1932,6 +2190,8 @@ void X86JITCore::RegisterVectorHandlers() { REGISTER_OP(VSMAX, VSMax); REGISTER_OP(VZIP, VZip); REGISTER_OP(VZIP2, VZip2); + REGISTER_OP(VUNZIP, VUnZip); + REGISTER_OP(VUNZIP2, VUnZip2); REGISTER_OP(VBSL, VBSL); REGISTER_OP(VCMPEQ, VCMPEQ); REGISTER_OP(VCMPEQZ, VCMPEQZ); @@ -1954,6 +2214,7 @@ void X86JITCore::RegisterVectorHandlers() { REGISTER_OP(VINSELEMENT, VInsElement); REGISTER_OP(VINSSCALARELEMENT, VInsScalarElement); REGISTER_OP(VEXTRACTELEMENT, VExtractElement); + REGISTER_OP(VDUPELEMENT, VDupElement); REGISTER_OP(VEXTR, VExtr); REGISTER_OP(VSLI, VSLI); REGISTER_OP(VSRI, VSRI); @@ -1977,6 +2238,7 @@ void X86JITCore::RegisterVectorHandlers() { REGISTER_OP(VSMULL, VSMull); REGISTER_OP(VUMULL2, VUMull2); REGISTER_OP(VSMULL2, VSMull2); + REGISTER_OP(VUABDL, VUABDL); REGISTER_OP(VTBL1, VTBL1); #undef REGISTER_OP } diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 1c59ad2ac..a7894b178 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -4013,44 +4013,6 @@ void OpDispatchBuilder::PSUBQOp(OpcodeArgs) { StoreResult(FPRClass, Op, ALUOp, -1); } -template -void OpDispatchBuilder::PMINUOp(OpcodeArgs) { - auto Size = GetSrcSize(Op); - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); - - auto ALUOp = _VUMin(Size, ElementSize, Dest, Src); - StoreResult(FPRClass, Op, ALUOp, -1); -} - -template -void OpDispatchBuilder::PMAXUOp(OpcodeArgs) { - auto Size = GetSrcSize(Op); - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); - - auto ALUOp = _VUMax(Size, ElementSize, Dest, Src); - StoreResult(FPRClass, Op, ALUOp, -1); -} - -void OpDispatchBuilder::PMINSWOp(OpcodeArgs) { - auto Size = GetSrcSize(Op); - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); - - auto ALUOp = _VSMin(Size, 2, Dest, Src); - StoreResult(FPRClass, Op, ALUOp, -1); -} - -void OpDispatchBuilder::PMAXSWOp(OpcodeArgs) { - auto Size = GetSrcSize(Op); - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); - - auto ALUOp = _VSMax(Size, 2, Dest, Src); - StoreResult(FPRClass, Op, ALUOp, -1); -} - template void OpDispatchBuilder::VectorALUOp(OpcodeArgs) { auto Size = GetSrcSize(Op); @@ -4292,7 +4254,14 @@ template void OpDispatchBuilder::PINSROp(OpcodeArgs) { auto Size = GetDstSize(Op); - OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1); + OrderedNode *Src{}; + if (Op->Src[0].IsGPR()) { + Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1); + } + else { + // If loading from memory then we only load the element size + Src = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], ElementSize, Op->Flags, -1); + } OrderedNode *Dest = LoadSource_WithOpSize(FPRClass, Op, Op->Dest, GetDstSize(Op), Op->Flags, -1); LOGMAN_THROW_A(Op->Src[1].IsLiteral(), "Src1 needs to be literal here"); uint64_t Index = Op->Src[1].Data.Literal.Value; @@ -4362,25 +4331,19 @@ void OpDispatchBuilder::PExtrOp(OpcodeArgs) { OrderedNode *Result = _VExtractToGPR(16, ElementSize, Src, Index); - if (ElementSize < 4) { - Result = _Bfe(4, ElementSize * 8, 0, Result); + if (Op->Dest.IsGPR()) { + uint8_t GPRSize = CTX->Config.Is64BitMode ? 8 : 4; + + // If we are storing to a GPR then we zero extend it + if (ElementSize < 4) { + Result = _Bfe(GPRSize, ElementSize * 8, 0, Result); + } + StoreResult_WithOpSize(GPRClass, Op, Op->Dest, Result, GPRSize, -1); + } + else { + // If we are storing to memory then we store the size of the element extracted + StoreResult(GPRClass, Op, Result, -1); } - StoreResult(GPRClass, Op, Result, -1); -} - -template -void OpDispatchBuilder::PMULOp(OpcodeArgs) { - auto Size = GetSrcSize(Op); - - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); - - OrderedNode *Res{}; - if (Signed) - Res = _VSMul(Size, ElementSize, Dest, Src); - else - Res = _VUMul(Size, ElementSize, Dest, Src); - StoreResult(FPRClass, Op, Res, -1); } template @@ -4411,37 +4374,6 @@ void OpDispatchBuilder::PSIGN(OpcodeArgs) { StoreResult(FPRClass, Op, Res, -1); } -template -void OpDispatchBuilder::PABS(OpcodeArgs) { - auto Size = GetSrcSize(Op); - - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - auto Res = _VAbs(Size, ElementSize, Src); - StoreResult(FPRClass, Op, Res, -1); -} - -template -void OpDispatchBuilder::PCMPEQOp(OpcodeArgs) { - auto Size = GetSrcSize(Op); - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); - - // This maps 1:1 to an AArch64 NEON Op - auto ALUOp = _VCMPEQ(Size, ElementSize, Dest, Src); - StoreResult(FPRClass, Op, ALUOp, -1); -} - -template -void OpDispatchBuilder::PCMPGTOp(OpcodeArgs) { - auto Size = GetSrcSize(Op); - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); - - // This maps 1:1 to an AArch64 NEON Op - auto ALUOp = _VCMPGT(Size, ElementSize, Dest, Src); - StoreResult(FPRClass, Op, ALUOp, -1); -} - void OpDispatchBuilder::CMPXCHGOp(OpcodeArgs) { // CMPXCHG ModRM, reg, {RAX} // MemData = *ModRM.dest @@ -8465,6 +8397,298 @@ void OpDispatchBuilder::AESKeyGenAssist(OpcodeArgs) { StoreResult(FPRClass, Op, Res, -1); } +template +void OpDispatchBuilder::ExtendVectorElements(OpcodeArgs) { + auto Size = GetDstSize(Op); + + OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); + + OrderedNode *Result {Src}; + + for (size_t CurrentElementSize = ElementSize; + CurrentElementSize != DstElementSize; + CurrentElementSize <<= 1) { + if (Signed) { + Result = _VSXTL(Result, Size, CurrentElementSize); + } + else { + Result = _VUXTL(Result, Size, CurrentElementSize); + } + } + StoreResult(FPRClass, Op, Result, -1); +} + +template +void OpDispatchBuilder::VectorRound(OpcodeArgs) { + LOGMAN_THROW_A(Op->Src[1].IsLiteral(), "Src1 needs to be literal here"); + uint64_t Mode = Op->Src[1].Data.Literal.Value; + uint64_t RoundControlSource = (Mode >> 2) & 1; + uint64_t RoundControl = Mode & 0b11; + + auto Size = GetSrcSize(Op); + OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); + + if (RoundControlSource) RoundControl = 0; // MXCSR + + std::array SourceModes = { + FEXCore::IR::Round_Nearest, + FEXCore::IR::Round_Negative_Infinity, + FEXCore::IR::Round_Positive_Infinity, + FEXCore::IR::Round_Towards_Zero, + FEXCore::IR::Round_Host, + }; + + Src = _Vector_FToI(Src, SourceModes[(RoundControlSource << 2) | RoundControl], Size, ElementSize); + + if (Scalar) { + // Insert the lower bits + OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); + auto Result = _VInsScalarElement(GetDstSize(Op), ElementSize, 0, Dest, Src); + StoreResult(FPRClass, Op, Result, -1); + } + else { + StoreResult(FPRClass, Op, Src, -1); + } +} + +template +void OpDispatchBuilder::VectorBlend(OpcodeArgs) { + LOGMAN_THROW_A(Op->Src[1].IsLiteral(), "Src1 needs to be literal here"); + uint8_t Select = Op->Src[1].Data.Literal.Value; + + OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); + OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); + for (size_t i = 0; i < (16 / ElementSize); ++i) { + if (Select & (1 << i)) { + // This could be optimized if it becomes costly + Dest = _VInsElement(16, ElementSize, i, i, Dest, Src); + } + } + StoreResult(FPRClass, Op, Dest, -1); +} + +template +void OpDispatchBuilder::VectorVariableBlend(OpcodeArgs) { + auto Size = GetSrcSize(Op); + + OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); + OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); + + // The mask is hardcoded to be xmm0 in this instruction + OrderedNode *Mask = _LoadContext(16, offsetof(FEXCore::Core::CPUState, xmm[0]), FPRClass); + // Each element is selected by the high bit of that element size + // Dest[ElementIdx] = Xmm0[ElementIndex][HighBit] ? Src : Dest; + // + // To emulate this on AArch64 + // Arithmetic shift right by the element size, then use BSL to select the registers + Mask = _VSShrI(Size, ElementSize, Mask, (ElementSize * 8) - 1); + auto Result = _VBSL(Mask, Src, Dest); + + StoreResult(FPRClass, Op, Result, -1); +} + +void OpDispatchBuilder::PTestOp(OpcodeArgs) { + auto Size = GetSrcSize(Op); + + OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); + OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); + + OrderedNode *Test1 = _VAnd(Dest, Src, Size, 1); + OrderedNode *Test2 = _VBic(Src, Dest, Size, 1); + + Test1 = _VPopcount(Size, 1, Test1); + Test2 = _VPopcount(Size, 1, Test2); + + // Element size doesn't matter here + // x86-64 doesn't support a horizontal byte add though + Test1 = _VAddV(Size, 2, Test1); + Test2 = _VAddV(Size, 2, Test2); + + Test1 = _VExtractToGPR(16, 2, Test1, 0); + Test2 = _VExtractToGPR(16, 2, Test2, 0); + + auto ZeroConst = _Constant(0); + auto OneConst = _Constant(1); + + Test1 = _Select(FEXCore::IR::COND_EQ, + Test1, ZeroConst, OneConst, ZeroConst); + + Test2 = _Select(FEXCore::IR::COND_EQ, + Test2, ZeroConst, OneConst, ZeroConst); + + SetRFLAG(Test1); + SetRFLAG(Test2); +} + +void OpDispatchBuilder::PHMINPOSUWOp(OpcodeArgs) { + auto Size = GetSrcSize(Op); + + OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); + auto Min = _VUMinV(Size, 2, Src); + + std::array Indexes { + _Constant(0), + _Constant(1), + _Constant(2), + _Constant(3), + _Constant(4), + _Constant(5), + _Constant(6), + _Constant(7), + }; + + auto Pos = Indexes[7]; + auto MinGPR = _VExtractToGPR(16, 2, Min, 0); + + // Calculate position + // This doesn't match with ARM behaviour at all + // Instruction returns the minimum matching index + for (size_t i = 8; i > 0; --i) { + auto Element = _VExtractToGPR(16, 2, Src, i - 1); + Pos = _Select(FEXCore::IR::COND_EQ, + Element, MinGPR, Indexes[i - 1], Pos); + } + + // Insert the minimum in to bits [15:0] + OrderedNode *Result = _VMov(Min, 2); + + // Insert position in to bits [18:16] + Result = _VInsGPR(16, 2, Result, Pos, 1); + + StoreResult(FPRClass, Op, Result, -1); +} + +template +void OpDispatchBuilder::DPPOp(OpcodeArgs) { + LOGMAN_THROW_A(Op->Src[1].IsLiteral(), "Src1 needs to be literal here"); + uint8_t Mask = Op->Src[1].Data.Literal.Value; + uint8_t SrcMask = Mask >> 4; + uint8_t DstMask = Mask & 0xF; + + OrderedNode *ZeroVec = _VectorZero(16); + + OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); + OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); + + // First step is to do an FMUL + OrderedNode *Temp = _VFMul(16, ElementSize, Dest, Src); + + // Now we zero out elements based on src mask + for (size_t i = 0; i < (16 / ElementSize); ++i) { + if ((SrcMask & (1 << i)) == 0) { + Temp = _VInsElement(16, ElementSize, i, 0, Temp, ZeroVec); + } + } + + // Now we need to do a horizontal add of the elements + // We only have pairwise float add so this needs to be done in steps + Temp = _VFAddP(16, ElementSize, Temp, ZeroVec); + + if (ElementSize == 4) { + // For 32-bit float we need one more step to add all four results together + Temp = _VFAddP(16, ElementSize, Temp, ZeroVec); + } + + // Now using the destination mask we choose where the result ends up + // It can duplicate and zero results + auto Result = ZeroVec; + + for (size_t i = 0; i < (16 / ElementSize); ++i) { + if (DstMask & (1 << i)) { + Result = _VInsElement(16, ElementSize, i, 0, Result, Temp); + } + } + + StoreResult(FPRClass, Op, Result, -1); +} + +void OpDispatchBuilder::MPSADBWOp(OpcodeArgs) { + LOGMAN_THROW_A(Op->Src[1].IsLiteral(), "Src1 needs to be literal here"); + uint8_t Select = Op->Src[1].Data.Literal.Value; + + // Src1 needs to be in byte offset + uint8_t Select_Dest = ((Select & 0b100) >> 2) * 32 / 8; + uint8_t Select_Src2 = Select & 0b11; + + OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); + OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); + + // Src2 will grab a 32bit element and duplicate it across the 128bits + OrderedNode *DupSrc = _VDupElement(16, 4, Src, Select_Src2); + + // Src1/Dest needs a bunch of magic + + // Shift right by selected bytes + // This will give us Dest[15:0], and Dest[79:64] + OrderedNode *Dest1 = _VExtr(16, 1, Dest, Dest, Select_Dest + 0); + // This will give us Dest[31:16], and Dest[95:80] + OrderedNode *Dest2 = _VExtr(16, 1, Dest, Dest, Select_Dest + 1); + // This will give us Dest[47:32], and Dest[111:96] + OrderedNode *Dest3 = _VExtr(16, 1, Dest, Dest, Select_Dest + 2); + // This will give us Dest[63:48], and Dest[127:112] + OrderedNode *Dest4 = _VExtr(16, 1, Dest, Dest, Select_Dest + 3); + + // For each shifted section, we now have two 32-bit values per vector that can be used + // Dest1.S[0] and Dest1.S[1] = Bytes - 0,1,2,3:4,5,6,7 + // Dest2.S[0] and Dest2.S[1] = Bytes - 1,2,3,4:5,6,7,8 + // Dest3.S[0] and Dest3.S[1] = Bytes - 2,3,4,5:6,7,8,9 + // Dest4.S[0] and Dest4.S[1] = Bytes - 3,4,5,6:7,8,9,10 + Dest1 = _VUABDL(16, 1, Dest1, DupSrc); + Dest2 = _VUABDL(16, 1, Dest2, DupSrc); + Dest3 = _VUABDL(16, 1, Dest3, DupSrc); + Dest4 = _VUABDL(16, 1, Dest4, DupSrc); + + // Dest[1,2,3,4] Now contains the data prior to combining + // Temp[0,1,2,3] for each step + + // Each destination now has 16bit x 8 elements in it that were the absolute difference for each byte + // Needs each to be 16bit to store the next step + // Next stage is to sum pairwise + // Dest1: + // ADDP Dest2, Dest1: TmpCombine1 + // ADDP Dest4, Dest3: TmpCombine2 + // TmpCombine1.8H[0] = Dest1.8H[0] + Dest1.8H[1]; + // TmpCombine1.8H[1] = Dest1.8H[2] + Dest1.8H[3]; + // TmpCombine1.8H[2] = Dest1.8H[4] + Dest1.8H[5]; + // TmpCombine1.8H[3] = Dest1.8H[6] + Dest1.8H[7]; + // TmpCombine1.8H[4] = Dest2.8H[0] + Dest2.8H[1]; + // TmpCombine1.8H[5] = Dest2.8H[2] + Dest2.8H[3]; + // TmpCombine1.8H[6] = Dest2.8H[4] + Dest2.8H[5]; + // TmpCombine1.8H[7] = Dest2.8H[6] + Dest2.8H[7]; + // + // ADDP TmpCombine2, TmpCombine1: FinalCombine + // FinalCombine.8H[0] = TmpCombine1.8H[0] + TmpCombine1.8H[1] + // FinalCombine.8H[1] = TmpCombine1.8H[2] + TmpCombine1.8H[3] + // FinalCombine.8H[2] = TmpCombine1.8H[4] + TmpCombine1.8H[5] + // FinalCombine.8H[3] = TmpCombine1.8H[6] + TmpCombine1.8H[7] + // FinalCombine.8H[4] = TmpCombine2.8H[0] + TmpCombine2.8H[1] + // FinalCombine.8H[5] = TmpCombine2.8H[2] + TmpCombine2.8H[3] + // FinalCombine.8H[6] = TmpCombine2.8H[4] + TmpCombine2.8H[5] + // FinalCombine.8H[7] = TmpCombine2.8H[6] + TmpCombine2.8H[7] + + auto TmpCombine1 = _VAddP(16, 2, Dest1, Dest2); + auto TmpCombine2 = _VAddP(16, 2, Dest3, Dest4); + + auto FinalCombine = _VAddP(16, 2, TmpCombine1, TmpCombine2); + + // This now contains our results but they are in the wrong order. + // We need to swizzle the results in to the correct ordering + // Result.8H[0] = FinalCombine.8H[0] + // Result.8H[1] = FinalCombine.8H[2] + // Result.8H[2] = FinalCombine.8H[4] + // Result.8H[3] = FinalCombine.8H[6] + // Result.8H[4] = FinalCombine.8H[1] + // Result.8H[5] = FinalCombine.8H[3] + // Result.8H[6] = FinalCombine.8H[5] + // Result.8H[7] = FinalCombine.8H[7] + + auto Even = _VUnZip(16, 2, FinalCombine, FinalCombine); + auto Odd = _VUnZip2(16, 2, FinalCombine, FinalCombine); + auto Result = _VInsElement(16, 8, 1, 0, Even, Odd); + + StoreResult(FPRClass, Op, Result, -1); +} + void OpDispatchBuilder::UnimplementedOp(OpcodeArgs) { uint8_t GPRSize = CTX->Config.Is64BitMode ? 8 : 4; @@ -8645,9 +8869,9 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0x61, 1, &OpDispatchBuilder::PUNPCKLOp<2>}, {0x62, 1, &OpDispatchBuilder::PUNPCKLOp<4>}, {0x63, 1, &OpDispatchBuilder::PACKSSOp<2>}, - {0x64, 1, &OpDispatchBuilder::PCMPGTOp<1>}, - {0x65, 1, &OpDispatchBuilder::PCMPGTOp<2>}, - {0x66, 1, &OpDispatchBuilder::PCMPGTOp<4>}, + {0x64, 1, &OpDispatchBuilder::VectorALUOp}, + {0x65, 1, &OpDispatchBuilder::VectorALUOp}, + {0x66, 1, &OpDispatchBuilder::VectorALUOp}, {0x67, 1, &OpDispatchBuilder::PACKUSOp<2>}, {0x68, 1, &OpDispatchBuilder::PUNPCKHOp<1>}, {0x69, 1, &OpDispatchBuilder::PUNPCKHOp<2>}, @@ -8655,9 +8879,9 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0x6B, 1, &OpDispatchBuilder::PACKSSOp<4>}, {0x70, 1, &OpDispatchBuilder::PSHUFDOp<2, false, true>}, - {0x74, 1, &OpDispatchBuilder::PCMPEQOp<1>}, - {0x75, 1, &OpDispatchBuilder::PCMPEQOp<2>}, - {0x76, 1, &OpDispatchBuilder::PCMPEQOp<4>}, + {0x74, 1, &OpDispatchBuilder::VectorALUOp}, + {0x75, 1, &OpDispatchBuilder::VectorALUOp}, + {0x76, 1, &OpDispatchBuilder::VectorALUOp}, {0x77, 1, &OpDispatchBuilder::NOPOp}, {0xC2, 1, &OpDispatchBuilder::VFCMPOp<4, false>}, @@ -8667,15 +8891,15 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0xD2, 1, &OpDispatchBuilder::PSRLDOp<4, true, 0>}, {0xD3, 1, &OpDispatchBuilder::PSRLDOp<8, true, 0>}, {0xD4, 1, &OpDispatchBuilder::PADDQOp<8>}, - {0xD5, 1, &OpDispatchBuilder::PMULOp<2, true>}, + {0xD5, 1, &OpDispatchBuilder::VectorALUOp}, {0xD7, 1, &OpDispatchBuilder::MOVMSKOpOne}, // PMOVMSKB {0xD8, 1, &OpDispatchBuilder::PSUBSOp<1, false>}, {0xD9, 1, &OpDispatchBuilder::PSUBSOp<2, false>}, - {0xDA, 1, &OpDispatchBuilder::PMINUOp<1>}, + {0xDA, 1, &OpDispatchBuilder::VectorALUOp}, {0xDB, 1, &OpDispatchBuilder::VectorALUOp}, {0xDC, 1, &OpDispatchBuilder::PADDSOp<1, false>}, {0xDD, 1, &OpDispatchBuilder::PADDSOp<2, false>}, - {0xDE, 1, &OpDispatchBuilder::PMAXUOp<1>}, + {0xDE, 1, &OpDispatchBuilder::VectorALUOp}, {0xDF, 1, &OpDispatchBuilder::ANDNOp}, {0xE0, 1, &OpDispatchBuilder::PAVGOp<1>}, {0xE1, 1, &OpDispatchBuilder::PSRAOp<2, true, 0>}, @@ -8686,11 +8910,11 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0xE7, 1, &OpDispatchBuilder::MOVUPSOp}, {0xE8, 1, &OpDispatchBuilder::PSUBSOp<1, true>}, {0xE9, 1, &OpDispatchBuilder::PSUBSOp<2, true>}, - {0xEA, 1, &OpDispatchBuilder::PMINSWOp}, + {0xEA, 1, &OpDispatchBuilder::VectorALUOp}, {0xEB, 1, &OpDispatchBuilder::VectorALUOp}, {0xEC, 1, &OpDispatchBuilder::PADDSOp<1, true>}, {0xED, 1, &OpDispatchBuilder::PADDSOp<2, true>}, - {0xEE, 1, &OpDispatchBuilder::PMAXSWOp}, + {0xEE, 1, &OpDispatchBuilder::VectorALUOp}, {0xEF, 1, &OpDispatchBuilder::VectorALUOp}, {0xF1, 1, &OpDispatchBuilder::PSLL<2, true, 0>}, @@ -8935,9 +9159,9 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0x61, 1, &OpDispatchBuilder::PUNPCKLOp<2>}, {0x62, 1, &OpDispatchBuilder::PUNPCKLOp<4>}, {0x63, 1, &OpDispatchBuilder::PACKSSOp<2>}, - {0x64, 1, &OpDispatchBuilder::PCMPGTOp<1>}, - {0x65, 1, &OpDispatchBuilder::PCMPGTOp<2>}, - {0x66, 1, &OpDispatchBuilder::PCMPGTOp<4>}, + {0x64, 1, &OpDispatchBuilder::VectorALUOp}, + {0x65, 1, &OpDispatchBuilder::VectorALUOp}, + {0x66, 1, &OpDispatchBuilder::VectorALUOp}, {0x67, 1, &OpDispatchBuilder::PACKUSOp<2>}, {0x68, 1, &OpDispatchBuilder::PUNPCKHOp<1>}, {0x69, 1, &OpDispatchBuilder::PUNPCKHOp<2>}, @@ -8949,9 +9173,9 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0x6F, 1, &OpDispatchBuilder::MOVUPSOp}, {0x70, 1, &OpDispatchBuilder::PSHUFDOp<4, false, true>}, - {0x74, 1, &OpDispatchBuilder::PCMPEQOp<1>}, - {0x75, 1, &OpDispatchBuilder::PCMPEQOp<2>}, - {0x76, 1, &OpDispatchBuilder::PCMPEQOp<4>}, + {0x74, 1, &OpDispatchBuilder::VectorALUOp}, + {0x75, 1, &OpDispatchBuilder::VectorALUOp}, + {0x76, 1, &OpDispatchBuilder::VectorALUOp}, {0x78, 1, nullptr}, // GROUP 17 {0x7C, 1, &OpDispatchBuilder::HADDP<8>}, {0x7D, 1, &OpDispatchBuilder::HSUBP<8>}, @@ -8967,16 +9191,16 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0xD2, 1, &OpDispatchBuilder::PSRLDOp<4, true, 0>}, {0xD3, 1, &OpDispatchBuilder::PSRLDOp<8, true, 0>}, {0xD4, 1, &OpDispatchBuilder::PADDQOp<8>}, - {0xD5, 1, &OpDispatchBuilder::PMULOp<2, true>}, + {0xD5, 1, &OpDispatchBuilder::VectorALUOp}, {0xD6, 1, &OpDispatchBuilder::MOVQOp}, {0xD7, 1, &OpDispatchBuilder::MOVMSKOpOne}, // PMOVMSKB {0xD8, 1, &OpDispatchBuilder::VectorALUOp}, {0xD9, 1, &OpDispatchBuilder::VectorALUOp}, - {0xDA, 1, &OpDispatchBuilder::PMINUOp<1>}, + {0xDA, 1, &OpDispatchBuilder::VectorALUOp}, {0xDB, 1, &OpDispatchBuilder::VectorALUOp}, {0xDC, 1, &OpDispatchBuilder::VectorALUOp}, {0xDD, 1, &OpDispatchBuilder::VectorALUOp}, - {0xDE, 1, &OpDispatchBuilder::PMAXUOp<1>}, + {0xDE, 1, &OpDispatchBuilder::VectorALUOp}, {0xDF, 1, &OpDispatchBuilder::ANDNOp}, {0xE0, 1, &OpDispatchBuilder::PAVGOp<1>}, {0xE1, 1, &OpDispatchBuilder::PSRAOp<2, true, 0>}, @@ -8988,7 +9212,7 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0xE7, 1, &OpDispatchBuilder::MOVVectorOp}, {0xE8, 1, &OpDispatchBuilder::VectorALUOp}, {0xE9, 1, &OpDispatchBuilder::VectorALUOp}, - {0xEA, 1, &OpDispatchBuilder::PMINSWOp}, + {0xEA, 1, &OpDispatchBuilder::VectorALUOp}, {0xEB, 1, &OpDispatchBuilder::VectorALUOp}, {0xEC, 1, &OpDispatchBuilder::VectorALUOp}, {0xED, 1, &OpDispatchBuilder::VectorALUOp}, @@ -9341,6 +9565,7 @@ constexpr uint16_t PF_F2 = 3; #define OPD(prefix, opcode) ((prefix << 8) | opcode) constexpr uint16_t PF_38_NONE = 0; constexpr uint16_t PF_38_66 = 1; + const std::vector> H0F38Table = { {OPD(PF_38_NONE, 0x00), 1, &OpDispatchBuilder::PSHUFBOp}, {OPD(PF_38_66, 0x00), 1, &OpDispatchBuilder::PSHUFBOp}, @@ -9366,14 +9591,42 @@ constexpr uint16_t PF_F2 = 3; {OPD(PF_38_66, 0x0A), 1, &OpDispatchBuilder::PSIGN<4>}, {OPD(PF_38_NONE, 0x0B), 1, &OpDispatchBuilder::PMULHRSW}, {OPD(PF_38_66, 0x0B), 1, &OpDispatchBuilder::PMULHRSW}, - {OPD(PF_38_NONE, 0x1C), 1, &OpDispatchBuilder::PABS<1>}, - {OPD(PF_38_66, 0x1C), 1, &OpDispatchBuilder::PABS<1>}, - {OPD(PF_38_NONE, 0x1D), 1, &OpDispatchBuilder::PABS<2>}, - {OPD(PF_38_66, 0x1D), 1, &OpDispatchBuilder::PABS<2>}, - {OPD(PF_38_NONE, 0x1E), 1, &OpDispatchBuilder::PABS<4>}, - {OPD(PF_38_66, 0x1E), 1, &OpDispatchBuilder::PABS<4>}, + {OPD(PF_38_66, 0x10), 1, &OpDispatchBuilder::VectorVariableBlend<1>}, + {OPD(PF_38_66, 0x14), 1, &OpDispatchBuilder::VectorVariableBlend<4>}, + {OPD(PF_38_66, 0x15), 1, &OpDispatchBuilder::VectorVariableBlend<8>}, + {OPD(PF_38_66, 0x17), 1, &OpDispatchBuilder::PTestOp}, + {OPD(PF_38_NONE, 0x1C), 1, &OpDispatchBuilder::VectorUnaryOp}, + {OPD(PF_38_66, 0x1C), 1, &OpDispatchBuilder::VectorUnaryOp}, + {OPD(PF_38_NONE, 0x1D), 1, &OpDispatchBuilder::VectorUnaryOp}, + {OPD(PF_38_66, 0x1D), 1, &OpDispatchBuilder::VectorUnaryOp}, + {OPD(PF_38_NONE, 0x1E), 1, &OpDispatchBuilder::VectorUnaryOp}, + {OPD(PF_38_66, 0x1E), 1, &OpDispatchBuilder::VectorUnaryOp}, + {OPD(PF_38_66, 0x20), 1, &OpDispatchBuilder::ExtendVectorElements<1, 2, true>}, + {OPD(PF_38_66, 0x21), 1, &OpDispatchBuilder::ExtendVectorElements<1, 4, true>}, + {OPD(PF_38_66, 0x22), 1, &OpDispatchBuilder::ExtendVectorElements<1, 8, true>}, + {OPD(PF_38_66, 0x23), 1, &OpDispatchBuilder::ExtendVectorElements<2, 4, true>}, + {OPD(PF_38_66, 0x24), 1, &OpDispatchBuilder::ExtendVectorElements<2, 8, true>}, + {OPD(PF_38_66, 0x25), 1, &OpDispatchBuilder::ExtendVectorElements<4, 8, true>}, + {OPD(PF_38_66, 0x28), 1, &OpDispatchBuilder::PMULLOp<4, true>}, + {OPD(PF_38_66, 0x29), 1, &OpDispatchBuilder::VectorALUOp}, {OPD(PF_38_66, 0x2A), 1, &OpDispatchBuilder::MOVAPSOp}, - {OPD(PF_38_66, 0x3B), 1, &OpDispatchBuilder::UnimplementedOp}, + {OPD(PF_38_66, 0x2B), 1, &OpDispatchBuilder::PACKUSOp<4>}, + {OPD(PF_38_66, 0x30), 1, &OpDispatchBuilder::ExtendVectorElements<1, 2, false>}, + {OPD(PF_38_66, 0x31), 1, &OpDispatchBuilder::ExtendVectorElements<1, 4, false>}, + {OPD(PF_38_66, 0x32), 1, &OpDispatchBuilder::ExtendVectorElements<1, 8, false>}, + {OPD(PF_38_66, 0x33), 1, &OpDispatchBuilder::ExtendVectorElements<2, 4, false>}, + {OPD(PF_38_66, 0x34), 1, &OpDispatchBuilder::ExtendVectorElements<2, 8, false>}, + {OPD(PF_38_66, 0x35), 1, &OpDispatchBuilder::ExtendVectorElements<4, 8, false>}, + {OPD(PF_38_66, 0x38), 1, &OpDispatchBuilder::VectorALUOp}, + {OPD(PF_38_66, 0x39), 1, &OpDispatchBuilder::VectorALUOp}, + {OPD(PF_38_66, 0x3A), 1, &OpDispatchBuilder::VectorALUOp}, + {OPD(PF_38_66, 0x3B), 1, &OpDispatchBuilder::VectorALUOp}, + {OPD(PF_38_66, 0x3C), 1, &OpDispatchBuilder::VectorALUOp}, + {OPD(PF_38_66, 0x3D), 1, &OpDispatchBuilder::VectorALUOp}, + {OPD(PF_38_66, 0x3E), 1, &OpDispatchBuilder::VectorALUOp}, + {OPD(PF_38_66, 0x3F), 1, &OpDispatchBuilder::VectorALUOp}, + {OPD(PF_38_66, 0x40), 1, &OpDispatchBuilder::VectorALUOp}, + {OPD(PF_38_66, 0x41), 1, &OpDispatchBuilder::PHMINPOSUWOp}, {OPD(PF_38_66, 0xDB), 1, &OpDispatchBuilder::AESImcOp}, {OPD(PF_38_66, 0xDC), 1, &OpDispatchBuilder::AESEncOp}, @@ -9391,6 +9644,14 @@ constexpr uint16_t PF_F2 = 3; #define PF_3A_NONE 0 #define PF_3A_66 1 const std::vector> H0F3ATable = { + {OPD(0, PF_3A_66, 0x08), 1, &OpDispatchBuilder::VectorRound<4, false>}, + {OPD(0, PF_3A_66, 0x09), 1, &OpDispatchBuilder::VectorRound<8, false>}, + {OPD(0, PF_3A_66, 0x0A), 1, &OpDispatchBuilder::VectorRound<4, true>}, + {OPD(0, PF_3A_66, 0x0B), 1, &OpDispatchBuilder::VectorRound<8, true>}, + {OPD(0, PF_3A_66, 0x0C), 1, &OpDispatchBuilder::VectorBlend<4>}, + {OPD(0, PF_3A_66, 0x0D), 1, &OpDispatchBuilder::VectorBlend<8>}, + {OPD(0, PF_3A_66, 0x0E), 1, &OpDispatchBuilder::VectorBlend<2>}, + {OPD(0, PF_3A_NONE, 0x0F), 1, &OpDispatchBuilder::PAlignrOp}, {OPD(0, PF_3A_66, 0x0F), 1, &OpDispatchBuilder::PAlignrOp}, {OPD(1, PF_3A_66, 0x0F), 1, &OpDispatchBuilder::PAlignrOp}, @@ -9399,11 +9660,15 @@ constexpr uint16_t PF_F2 = 3; {OPD(0, PF_3A_66, 0x15), 1, &OpDispatchBuilder::PExtrOp<2>}, {OPD(0, PF_3A_66, 0x16), 1, &OpDispatchBuilder::PExtrOp<4>}, {OPD(1, PF_3A_66, 0x16), 1, &OpDispatchBuilder::PExtrOp<8>}, + {OPD(0, PF_3A_66, 0x17), 1, &OpDispatchBuilder::PExtrOp<4>}, {OPD(0, PF_3A_66, 0x20), 1, &OpDispatchBuilder::PINSROp<1>}, {OPD(0, PF_3A_66, 0x21), 1, &OpDispatchBuilder::InsertPSOp}, {OPD(0, PF_3A_66, 0x22), 1, &OpDispatchBuilder::PINSROp<4>}, {OPD(1, PF_3A_66, 0x22), 1, &OpDispatchBuilder::PINSROp<8>}, + {OPD(0, PF_3A_66, 0x40), 1, &OpDispatchBuilder::DPPOp<4>}, + {OPD(0, PF_3A_66, 0x41), 1, &OpDispatchBuilder::DPPOp<8>}, + {OPD(0, PF_3A_66, 0x42), 1, &OpDispatchBuilder::MPSADBWOp}, {OPD(0, PF_3A_66, 0xDF), 1, &OpDispatchBuilder::AESKeyGenAssist}, }; diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 1f43c8c76..8b8298647 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -260,12 +260,6 @@ public: template void PSUBQOp(OpcodeArgs); template - void PMINUOp(OpcodeArgs); - template - void PMAXUOp(OpcodeArgs); - void PMINSWOp(OpcodeArgs); - void PMAXSWOp(OpcodeArgs); - template void MOVMSKOp(OpcodeArgs); void MOVMSKOpOne(OpcodeArgs); template @@ -275,10 +269,6 @@ public: void PSHUFBOp(OpcodeArgs); template void PSHUFDOp(OpcodeArgs); - template - void PCMPEQOp(OpcodeArgs); - template - void PCMPGTOp(OpcodeArgs); void MOVDOp(OpcodeArgs); template void PSRLDOp(OpcodeArgs); @@ -328,15 +318,10 @@ public: void InsertPSOp(OpcodeArgs); template void PExtrOp(OpcodeArgs); - template - void PMULOp(OpcodeArgs); template void PSIGN(OpcodeArgs); - template - void PABS(OpcodeArgs); - // X87 Ops template void FLD(OpcodeArgs); @@ -471,6 +456,23 @@ public: void AESDecLastOp(OpcodeArgs); void AESKeyGenAssist(OpcodeArgs); + template + void ExtendVectorElements(OpcodeArgs); + template + void VectorRound(OpcodeArgs); + + template + void VectorBlend(OpcodeArgs); + + template + void VectorVariableBlend(OpcodeArgs); + void PTestOp(OpcodeArgs); + void PHMINPOSUWOp(OpcodeArgs); + template + void DPPOp(OpcodeArgs); + + void MPSADBWOp(OpcodeArgs); + void UnimplementedOp(OpcodeArgs); #undef OpcodeArgs diff --git a/External/FEXCore/Source/Interface/Core/X86Tables/H0F38Tables.cpp b/External/FEXCore/Source/Interface/Core/X86Tables/H0F38Tables.cpp index 4529b4572..8a304bf75 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables/H0F38Tables.cpp +++ b/External/FEXCore/Source/Interface/Core/X86Tables/H0F38Tables.cpp @@ -41,10 +41,10 @@ void InitializeH0F38Tables() { {OPD(PF_38_NONE, 0x0B), 1, X86InstInfo{"PMULHRSW", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}}, {OPD(PF_38_66, 0x0B), 1, X86InstInfo{"PMULHRSW", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {OPD(PF_38_66, 0x10), 1, X86InstInfo{"PBLENDVB", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x14), 1, X86InstInfo{"BLENDVPS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x15), 1, X86InstInfo{"BLENDVPD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x17), 1, X86InstInfo{"PTEST", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(PF_38_66, 0x10), 1, X86InstInfo{"PBLENDVB", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x14), 1, X86InstInfo{"BLENDVPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x15), 1, X86InstInfo{"BLENDVPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x17), 1, X86InstInfo{"PTEST", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(PF_38_NONE, 0x1C), 1, X86InstInfo{"PABSB", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}}, {OPD(PF_38_66, 0x1C), 1, X86InstInfo{"PABSB", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(PF_38_NONE, 0x1D), 1, X86InstInfo{"PABSW", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}}, @@ -52,34 +52,34 @@ void InitializeH0F38Tables() { {OPD(PF_38_NONE, 0x1E), 1, X86InstInfo{"PABSD", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 0, nullptr}}, {OPD(PF_38_66, 0x1E), 1, X86InstInfo{"PABSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {OPD(PF_38_66, 0x20), 1, X86InstInfo{"PMOVSXBW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x21), 1, X86InstInfo{"PMOVSXBD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x22), 1, X86InstInfo{"PMOVSXBQ", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x23), 1, X86InstInfo{"PMOVSXWD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x24), 1, X86InstInfo{"PMOVSXWQ", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x25), 1, X86InstInfo{"PMOVSXDQ", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x28), 1, X86InstInfo{"PMULDQ", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x29), 1, X86InstInfo{"PCMPEQQ", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(PF_38_66, 0x20), 1, X86InstInfo{"PMOVSXBW", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x21), 1, X86InstInfo{"PMOVSXBD", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_32BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x22), 1, X86InstInfo{"PMOVSXBQ", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_16BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x23), 1, X86InstInfo{"PMOVSXWD", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x24), 1, X86InstInfo{"PMOVSXWQ", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_32BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x25), 1, X86InstInfo{"PMOVSXDQ", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x28), 1, X86InstInfo{"PMULDQ", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x29), 1, X86InstInfo{"PCMPEQQ", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(PF_38_66, 0x2A), 1, X86InstInfo{"MOVNTDQA", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_MEM_ONLY | FLAGS_XMM_FLAGS, 0, nullptr}}, - {OPD(PF_38_66, 0x2B), 1, X86InstInfo{"PACKUSDW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(PF_38_66, 0x2B), 1, X86InstInfo{"PACKUSDW", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {OPD(PF_38_66, 0x30), 1, X86InstInfo{"PMOVZXBW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x31), 1, X86InstInfo{"PMOVZXBD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x32), 1, X86InstInfo{"PMOVZXBQ", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x33), 1, X86InstInfo{"PMOVZXWD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x34), 1, X86InstInfo{"PMOVZXWQ", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x35), 1, X86InstInfo{"PMOVZXDQ", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x38), 1, X86InstInfo{"PMINSB", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x39), 1, X86InstInfo{"PMINSD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x3A), 1, X86InstInfo{"PMINUW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x3B), 1, X86InstInfo{"PMINUD", TYPE_INST, FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {OPD(PF_38_66, 0x3C), 1, X86InstInfo{"PMAXSB", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x3D), 1, X86InstInfo{"PMAXSD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x3E), 1, X86InstInfo{"PMAXUW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x3F), 1, X86InstInfo{"PMAXUD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(PF_38_66, 0x30), 1, X86InstInfo{"PMOVZXBW", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x31), 1, X86InstInfo{"PMOVZXBD", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_32BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x32), 1, X86InstInfo{"PMOVZXBQ", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_16BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x33), 1, X86InstInfo{"PMOVZXWD", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x34), 1, X86InstInfo{"PMOVZXWQ", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_32BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x35), 1, X86InstInfo{"PMOVZXDQ", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x38), 1, X86InstInfo{"PMINSB", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x39), 1, X86InstInfo{"PMINSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x3A), 1, X86InstInfo{"PMINUW", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x3B), 1, X86InstInfo{"PMINUD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x3C), 1, X86InstInfo{"PMAXSB", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x3D), 1, X86InstInfo{"PMAXSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x3E), 1, X86InstInfo{"PMAXUW", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x3F), 1, X86InstInfo{"PMAXUD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {OPD(PF_38_66, 0x40), 1, X86InstInfo{"PMULLD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(PF_38_66, 0x41), 1, X86InstInfo{"PHMINPOSUW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(PF_38_66, 0x40), 1, X86InstInfo{"PMULLD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {OPD(PF_38_66, 0x41), 1, X86InstInfo{"PHMINPOSUW", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(PF_38_66, 0xDB), 1, X86InstInfo{"AESIMC", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(PF_38_66, 0xDC), 1, X86InstInfo{"AESENC", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, diff --git a/External/FEXCore/Source/Interface/Core/X86Tables/H0F3ATables.cpp b/External/FEXCore/Source/Interface/Core/X86Tables/H0F3ATables.cpp index 4db6d59a7..46f728658 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables/H0F3ATables.cpp +++ b/External/FEXCore/Source/Interface/Core/X86Tables/H0F3ATables.cpp @@ -16,26 +16,26 @@ void InitializeH0F3ATables(Context::OperatingMode Mode) { const U16U8InfoStruct H0F3ATable[] = { {OPD(0, PF_3A_NONE, 0x0F), 1, X86InstInfo{"PALIGNR", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX, 1, nullptr}}, - {OPD(0, PF_3A_66, 0x08), 1, X86InstInfo{"ROUNDPS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(0, PF_3A_66, 0x09), 1, X86InstInfo{"ROUNDPD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(0, PF_3A_66, 0x0A), 1, X86InstInfo{"ROUNDSS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(0, PF_3A_66, 0x0B), 1, X86InstInfo{"ROUNDSD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(0, PF_3A_66, 0x0C), 1, X86InstInfo{"BLENDPS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(0, PF_3A_66, 0x0D), 1, X86InstInfo{"BLENDPD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(0, PF_3A_66, 0x0E), 1, X86InstInfo{"PBLENDW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(0, PF_3A_66, 0x08), 1, X86InstInfo{"ROUNDPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, + {OPD(0, PF_3A_66, 0x09), 1, X86InstInfo{"ROUNDPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, + {OPD(0, PF_3A_66, 0x0A), 1, X86InstInfo{"ROUNDSS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, + {OPD(0, PF_3A_66, 0x0B), 1, X86InstInfo{"ROUNDSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, + {OPD(0, PF_3A_66, 0x0C), 1, X86InstInfo{"BLENDPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, + {OPD(0, PF_3A_66, 0x0D), 1, X86InstInfo{"BLENDPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, + {OPD(0, PF_3A_66, 0x0E), 1, X86InstInfo{"PBLENDW", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, {OPD(0, PF_3A_66, 0x0F), 1, X86InstInfo{"PALIGNR", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, {OPD(0, PF_3A_66, 0x14), 1, X86InstInfo{"PEXTRB", TYPE_INST, GenFlagsSizes(SIZE_8BIT, SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_DST | FLAGS_SF_DST_GPR | FLAGS_XMM_FLAGS, 1, nullptr}}, {OPD(0, PF_3A_66, 0x15), 1, X86InstInfo{"PEXTRW", TYPE_INST, GenFlagsSizes(SIZE_16BIT, SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_DST | FLAGS_SF_DST_GPR | FLAGS_XMM_FLAGS, 1, nullptr}}, {OPD(0, PF_3A_66, 0x16), 1, X86InstInfo{"PEXTRD", TYPE_INST, GenFlagsSizes(SIZE_32BIT, SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_DST | FLAGS_SF_DST_GPR | FLAGS_XMM_FLAGS, 1, nullptr}}, - {OPD(0, PF_3A_66, 0x17), 1, X86InstInfo{"EXTRACTPS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(0, PF_3A_66, 0x17), 1, X86InstInfo{"EXTRACTPS", TYPE_INST, GenFlagsSizes(SIZE_32BIT, SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_DST | FLAGS_SF_DST_GPR | FLAGS_XMM_FLAGS, 1, nullptr}}, - {OPD(0, PF_3A_66, 0x20), 1, X86InstInfo{"PINSRB", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_8BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_SRC_GPR, 1, nullptr}}, + {OPD(0, PF_3A_66, 0x20), 1, X86InstInfo{"PINSRB", TYPE_INST, GenFlagsDstSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_SRC_GPR, 1, nullptr}}, {OPD(0, PF_3A_66, 0x21), 1, X86InstInfo{"INSERTPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, {OPD(0, PF_3A_66, 0x22), 1, X86InstInfo{"PINSRD", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_32BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_SRC_GPR, 1, nullptr}}, - {OPD(0, PF_3A_66, 0x40), 1, X86InstInfo{"DPPS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(0, PF_3A_66, 0x41), 1, X86InstInfo{"DPPD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(0, PF_3A_66, 0x42), 1, X86InstInfo{"MPSADBW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(0, PF_3A_66, 0x40), 1, X86InstInfo{"DPPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, + {OPD(0, PF_3A_66, 0x41), 1, X86InstInfo{"DPPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, + {OPD(0, PF_3A_66, 0x42), 1, X86InstInfo{"MPSADBW", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}}, {OPD(0, PF_3A_66, 0x44), 1, X86InstInfo{"PCLMULQDQ", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, {OPD(0, PF_3A_66, 0x60), 1, X86InstInfo{"PCMPESTRM", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, diff --git a/External/FEXCore/Source/Interface/IR/IR.json b/External/FEXCore/Source/Interface/IR/IR.json index 44a87f83c..27077e753 100644 --- a/External/FEXCore/Source/Interface/IR/IR.json +++ b/External/FEXCore/Source/Interface/IR/IR.json @@ -60,6 +60,12 @@ "constexpr static uint8_t ROUND_MODE_TOWARDS_ZERO = 3", "constexpr static uint8_t ROUND_MODE_FLUSH_TO_ZERO = 1 << 2", + "static constexpr FEXCore::IR::RoundType Round_Nearest {ROUND_MODE_NEAREST}", + "static constexpr FEXCore::IR::RoundType Round_Negative_Infinity {ROUND_MODE_NEGATIVE_INFINITY}", + "static constexpr FEXCore::IR::RoundType Round_Positive_Infinity {ROUND_MODE_POSITIVE_INFINITY}", + "static constexpr FEXCore::IR::RoundType Round_Towards_Zero {ROUND_MODE_TOWARDS_ZERO} /* Truncate */", + "static constexpr FEXCore::IR::RoundType Round_Host {ROUND_MODE_TOWARDS_ZERO + 1}", + "constexpr static FEXCore::IR::MemOffsetType MEM_OFFSET_SXTX {0};", "constexpr static FEXCore::IR::MemOffsetType MEM_OFFSET_UXTW {1};", "constexpr static FEXCore::IR::MemOffsetType MEM_OFFSET_SXTW {2};" @@ -1664,6 +1670,23 @@ ] }, + "VBic": { + "OpClass": "Vector", + "HasDest": true, + "DestClass": "FPR", + "DestSize": "RegisterSize", + "NumElements": "RegisterSize / ElementSize", + "SSAArgs": "2", + "SSANames": [ + "Vector1", + "Vector2" + ], + "HelperArgs": [ + "uint8_t", "RegisterSize", + "uint8_t", "ElementSize" + ] + }, + "VOr": { "OpClass": "Vector", "HasDest": true, @@ -1809,8 +1832,8 @@ "NumElements": "RegisterSize / ElementSize", "SSAArgs": "2", "SSANames": [ - "Vector1", - "Vector2" + "VectorLower", + "VectorUpper" ], "HelperArgs": [ "uint8_t", "RegisterSize", @@ -1837,6 +1860,25 @@ ] }, + "VUMinV": { + "OpClass": "Vector", + "Desc": ["Does a horizontal vector unsigned minimum of elements across the source vector", + "Result is a zero extended scalar" + ], + "HasDest": true, + "DestClass": "FPR", + "DestSize": "RegisterSize", + "NumElements": "RegisterSize / ElementSize", + "SSAArgs": "1", + "SSANames": [ + "Vector" + ], + "HelperArgs": [ + "uint8_t", "RegisterSize", + "uint8_t", "ElementSize" + ] + }, + "VURAvg": { "OpClass": "Vector", "Desc": ["Does an unsigned rounded average", "dst_elem = (src1_elem + src2_elem + 1) >> 1"], @@ -1873,6 +1915,24 @@ ] }, + "VPopcount": { + "OpClass": "Vector", + "Desc": ["Does a popcount for each element of the register" + ], + "HasDest": true, + "DestClass": "FPR", + "DestSize": "RegisterSize", + "NumElements": "RegisterSize / ElementSize", + "SSAArgs": "1", + "SSANames": [ + "Vector" + ], + "HelperArgs": [ + "uint8_t", "RegisterSize", + "uint8_t", "ElementSize" + ] + }, + "VFAdd": { "OpClass": "Vector", "HasDest": true, @@ -1899,8 +1959,8 @@ "NumElements": "RegisterSize / ElementSize", "SSAArgs": "2", "SSANames": [ - "Vector1", - "Vector2" + "VectorLow", + "VectorHigh" ], "HelperArgs": [ "uint8_t", "RegisterSize", @@ -2192,6 +2252,40 @@ ] }, + "VUnZip": { + "OpClass": "Vector", + "HasDest": true, + "DestClass": "FPR", + "DestSize": "RegisterSize", + "NumElements": "RegisterSize / ElementSize", + "SSAArgs": "2", + "SSANames": [ + "Lower", + "Upper" + ], + "HelperArgs": [ + "uint8_t", "RegisterSize", + "uint8_t", "ElementSize" + ] + }, + + "VUnZip2": { + "OpClass": "Vector", + "HasDest": true, + "DestClass": "FPR", + "DestSize": "RegisterSize", + "NumElements": "RegisterSize / ElementSize", + "SSAArgs": "2", + "SSANames": [ + "Lower", + "Upper" + ], + "HelperArgs": [ + "uint8_t", "RegisterSize", + "uint8_t", "ElementSize" + ] + }, + "VBSL": { "Desc": ["Does a vector bitwise select.", "If the bit in the field is 1 then the corresponding bit is pulled from VectorTrue", @@ -2583,6 +2677,26 @@ ] }, + "VDupElement": { + "Desc": ["Duplicates one element from the source register across the whole register"], + "OpClass": "Vector", + "HasDest": true, + "DestClass": "FPR", + "DestSize": "RegisterSize", + "NumElements": "RegisterSize / ElementSize", + "SSAArgs": "1", + "SSANames": [ + "Vector" + ], + "HelperArgs": [ + "uint8_t", "RegisterSize", + "uint8_t", "ElementSize" + ], + "Args": [ + "uint8_t", "Index" + ] + }, + "VExtr": { "Desc": ["Concats two vector registers together and extracts a full width register from the element index", "Index is an element index. So it is offset by ElementSize argument", @@ -3124,6 +3238,28 @@ ] }, + "Vector_FToI": { + "OpClass": "Conv", + "Desc": ["Vector op: Rounds float to integral", + "Rounding mode determined by argument" + ], + "HasDest": true, + "DestClass": "FPR", + "DestSize": "RegisterSize", + "NumElements": "RegisterSize / ElementSize", + "SSAArgs": "1", + "SSANames": [ + "Vector" + ], + "HelperArgs": [ + "uint8_t", "RegisterSize", + "uint8_t", "ElementSize" + ], + "Args":[ + "FEXCore::IR::RoundType", "Round" + ] + }, + "VUMul": { "OpClass": "Vector", "HasDest": true, @@ -3231,6 +3367,25 @@ ] }, + "VUABDL": { + "OpClass": "Vector", + "Desc": ["Unsigned Absolute Difference Long" + ], + "HasDest": true, + "DestClass": "FPR", + "DestSize": "RegisterSize", + "NumElements": "RegisterSize / (ElementSize << 1)", + "SSAArgs": "2", + "SSANames": [ + "Vector1", + "Vector2" + ], + "HelperArgs": [ + "uint8_t", "RegisterSize", + "uint8_t", "ElementSize" + ] + }, + "VTBL1": { "Desc": ["Does a vector table lookup from one register in to the destination", "Lookup is byte sized per byte element.", diff --git a/External/FEXCore/Source/Interface/IR/IRDumper.cpp b/External/FEXCore/Source/Interface/IR/IRDumper.cpp index 7bede836e..18a549135 100644 --- a/External/FEXCore/Source/Interface/IR/IRDumper.cpp +++ b/External/FEXCore/Source/Interface/IR/IRDumper.cpp @@ -154,6 +154,17 @@ static void PrintArg(std::stringstream *out, [[maybe_unused]] IRListView const* } } +static void PrintArg(std::stringstream *out, [[maybe_unused]] IRListView const* IR, FEXCore::IR::RoundType Arg) { + switch (Arg) { + case FEXCore::IR::Round_Nearest: *out << "Nearest"; break; + case FEXCore::IR::Round_Negative_Infinity: *out << "-Inf"; break; + case FEXCore::IR::Round_Positive_Infinity: *out << "+Inf"; break; + case FEXCore::IR::Round_Towards_Zero: *out << "Towards Zero"; break; + case FEXCore::IR::Round_Host: *out << "Host"; break; + default: *out << ""; break; + } +} + void Dump(std::stringstream *out, IRListView const* IR, IR::RegisterAllocationData *RAData) { auto HeaderOp = IR->GetHeader(); diff --git a/External/FEXCore/include/FEXCore/IR/IR.h b/External/FEXCore/include/FEXCore/IR/IR.h index 9f1e62860..84bdab88e 100644 --- a/External/FEXCore/include/FEXCore/IR/IR.h +++ b/External/FEXCore/include/FEXCore/IR/IR.h @@ -323,6 +323,14 @@ struct FenceType final { friend constexpr bool operator==(const FenceType&, const FenceType&) = default; }; +struct RoundType final { + uint8_t Val; + constexpr operator uint8_t() const { + return Val; + } + friend constexpr bool operator==(const RoundType&, const RoundType&) = default; +}; + struct SHA256Sum final { uint8_t data[32]; bool operator<(SHA256Sum const &rhs) const { return memcmp(data, rhs.data, sizeof(data)) < 0; } diff --git a/External/FEXCore/include/FEXCore/IR/IREmitter.h b/External/FEXCore/include/FEXCore/IR/IREmitter.h index adf9ed976..f5de5dc20 100644 --- a/External/FEXCore/include/FEXCore/IR/IREmitter.h +++ b/External/FEXCore/include/FEXCore/IR/IREmitter.h @@ -111,9 +111,15 @@ friend class FEXCore::IR::PassManager; IRPair _VExtractElement(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, uint8_t Index) { return _VExtractElement(ssa0, Index, RegisterSize, ElementSize); } + IRPair _VDupElement(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, uint8_t Index) { + return _VDupElement(ssa0, Index, RegisterSize, ElementSize); + } IRPair _VAnd(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { return _VAnd(ssa0, ssa1, RegisterSize, ElementSize); } + IRPair _VBic(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { + return _VBic(ssa0, ssa1, RegisterSize, ElementSize); + } IRPair _VOr(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { return _VOr(ssa0, ssa1, RegisterSize, ElementSize); } @@ -144,12 +150,21 @@ friend class FEXCore::IR::PassManager; IRPair _VAddV(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0) { return _VAddV(ssa0, RegisterSize, ElementSize); } + IRPair _VUMinV(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0) { + return _VUMinV(ssa0, RegisterSize, ElementSize); + } IRPair _VURAvg(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { return _VURAvg(ssa0, ssa1, RegisterSize, ElementSize); } IRPair _VAbs(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0) { return _VAbs(ssa0, RegisterSize, ElementSize); } + IRPair _VPopcount(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0) { + return _VPopcount(ssa0, RegisterSize, ElementSize); + } + IRPair _VFMul(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { + return _VFMul(ssa0, ssa1, RegisterSize, ElementSize); + } IRPair _VUMin(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { return _VUMin(ssa0, ssa1, RegisterSize, ElementSize); } @@ -168,6 +183,12 @@ friend class FEXCore::IR::PassManager; IRPair _VZip2(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { return _VZip2(ssa0, ssa1, RegisterSize, ElementSize); } + IRPair _VUnZip(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { + return _VUnZip(ssa0, ssa1, RegisterSize, ElementSize); + } + IRPair _VUnZip2(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { + return _VUnZip2(ssa0, ssa1, RegisterSize, ElementSize); + } IRPair _VCMPEQ(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { return _VCMPEQ(ssa0, ssa1, RegisterSize, ElementSize); } @@ -321,6 +342,9 @@ friend class FEXCore::IR::PassManager; IRPair _VSMull2(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { return _VSMull2(ssa0, ssa1, RegisterSize, ElementSize); } + IRPair _VUABDL(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { + return _VUABDL(ssa0, ssa1, RegisterSize, ElementSize); + } IRPair _VSXTL(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0) { return _VSXTL(ssa0, RegisterSize, ElementSize); } diff --git a/unittests/ASM/H0F38/66_10.asm b/unittests/ASM/H0F38/66_10.asm new file mode 100644 index 000000000..e39224c61 --- /dev/null +++ b/unittests/ASM/H0F38/66_10.asm @@ -0,0 +1,74 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x48510f254d2f5b7f", "0x2b5774313ad348ea"], + "XMM2": ["0x30a9567b1f6d776b", "0x673d5d0730c6762c"], + "XMM3": ["0x41159b533d5b4c09", "0xca64724c74043978"], + "XMM4": ["0x24426b4c72f2101c", "0x656780205f15c767"], + "XMM5": ["0x4f1694df78236612", "0x19826b033d3c78c0"], + "XMM6": ["0x00f9589268e0127f", "0x1e7d27031e881972"], + "XMM7": ["0x1c4c4322f8f65504", "0x07f565f98b1bb7bc"], + "XMM8": ["0x10c41f28710f2147", "0x09925e327f5e2938"] + } +} +%endif + +lea rdx, [rel .data] +lea rdi, [rel .mask] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +; pblend uses xmm0 implicitly +movaps xmm0, [rdx + 16 * 0] +pblendvb xmm1, [rdx + 16 * 8] +movaps xmm0, [rdx + 16 * 1] +pblendvb xmm2, [rdx + 16 * 9] +movaps xmm0, [rdx + 16 * 2] +pblendvb xmm3, [rdx + 16 * 10] +movaps xmm0, [rdx + 16 * 3] +pblendvb xmm4, [rdx + 16 * 11] +movaps xmm0, [rdx + 16 * 4] +pblendvb xmm5, [rdx + 16 * 12] +movaps xmm0, [rdx + 16 * 5] +pblendvb xmm6, [rdx + 16 * 13] +movaps xmm0, [rdx + 16 * 6] +pblendvb xmm7, [rdx + 16 * 14] +movaps xmm0, [rdx + 16 * 7] +pblendvb xmm8, [rdx + 16 * 15] + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 +.mask: +db 0xb5, 0xdb, 0xca, 0x08, 0x0a, 0xae, 0x17, 0xb6, 0x54, 0x0d, 0xd3, 0xa1, 0x1d, 0x28, 0x25, 0xd3 +db 0x02, 0xf5, 0xce, 0x94, 0x2e, 0x56, 0x01, 0xf4, 0xae, 0x81, 0xbe, 0x50, 0x70, 0x45, 0x83, 0x18 +db 0x33, 0x46, 0x60, 0x4e, 0x29, 0xe4, 0x49, 0xae, 0xc2, 0x0e, 0x70, 0xcd, 0x2a, 0x6f, 0xb8, 0x9d +db 0x47, 0x1e, 0x8e, 0x94, 0x81, 0xaa, 0x12, 0xe4, 0x8e, 0x77, 0x48, 0x34, 0x63, 0x8f, 0x4c, 0x57 +db 0x34, 0xf9, 0x5b, 0x37, 0x76, 0x9f, 0xff, 0x8c, 0x6b, 0xf2, 0x6e, 0xd0, 0x15, 0x61, 0x4e, 0x0f +db 0xe2, 0xa7, 0xd0, 0x73, 0x7f, 0xf0, 0xae, 0xe7, 0x48, 0x32, 0x2a, 0x56, 0xc3, 0x29, 0x12, 0x4f +db 0x7d, 0x5b, 0x37, 0xc2, 0x83, 0x74, 0xd2, 0xf9, 0xcc, 0x98, 0x0a, 0x3c, 0x3c, 0x38, 0xd9, 0x4d diff --git a/unittests/ASM/H0F38/66_14.asm b/unittests/ASM/H0F38/66_14.asm new file mode 100644 index 000000000..00967f28d --- /dev/null +++ b/unittests/ASM/H0F38/66_14.asm @@ -0,0 +1,74 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x48510f254d2fa47f", "0x2b5774313a974886"], + "XMM2": ["0x30b556de1f6de86b", "0x67d29af330ae762c"], + "XMM3": ["0x41029b7f3de8ad09", "0xca79a24c7404b890"], + "XMM4": ["0x24426b4c72f110ad", "0x65f580205ffdc710"], + "XMM5": ["0x4f1694df78236612", "0x19a26b823d3ca2a9"], + "XMM6": ["0x00f658ab689712b0", "0x1ea627241ed21972"], + "XMM7": ["0x1c864322f8f69004", "0x07f565f98b8db7bc"], + "XMM8": ["0x10c41fa1710f2147", "0x099224327fb5ac38"] + } +} +%endif + +lea rdx, [rel .data] +lea rdi, [rel .mask] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +; pblend uses xmm0 implicitly +movaps xmm0, [rdx + 16 * 0] +blendvps xmm1, [rdx + 16 * 8] +movaps xmm0, [rdx + 16 * 1] +blendvps xmm2, [rdx + 16 * 9] +movaps xmm0, [rdx + 16 * 2] +blendvps xmm3, [rdx + 16 * 10] +movaps xmm0, [rdx + 16 * 3] +blendvps xmm4, [rdx + 16 * 11] +movaps xmm0, [rdx + 16 * 4] +blendvps xmm5, [rdx + 16 * 12] +movaps xmm0, [rdx + 16 * 5] +blendvps xmm6, [rdx + 16 * 13] +movaps xmm0, [rdx + 16 * 6] +blendvps xmm7, [rdx + 16 * 14] +movaps xmm0, [rdx + 16 * 7] +blendvps xmm8, [rdx + 16 * 15] + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 +.mask: +db 0xb5, 0xdb, 0xca, 0x08, 0x0a, 0xae, 0x17, 0xb6, 0x54, 0x0d, 0xd3, 0xa1, 0x1d, 0x28, 0x25, 0xd3 +db 0x02, 0xf5, 0xce, 0x94, 0x2e, 0x56, 0x01, 0xf4, 0xae, 0x81, 0xbe, 0x50, 0x70, 0x45, 0x83, 0x18 +db 0x33, 0x46, 0x60, 0x4e, 0x29, 0xe4, 0x49, 0xae, 0xc2, 0x0e, 0x70, 0xcd, 0x2a, 0x6f, 0xb8, 0x9d +db 0x47, 0x1e, 0x8e, 0x94, 0x81, 0xaa, 0x12, 0xe4, 0x8e, 0x77, 0x48, 0x34, 0x63, 0x8f, 0x4c, 0x57 +db 0x34, 0xf9, 0x5b, 0x37, 0x76, 0x9f, 0xff, 0x8c, 0x6b, 0xf2, 0x6e, 0xd0, 0x15, 0x61, 0x4e, 0x0f +db 0xe2, 0xa7, 0xd0, 0x73, 0x7f, 0xf0, 0xae, 0xe7, 0x48, 0x32, 0x2a, 0x56, 0xc3, 0x29, 0x12, 0x4f +db 0x7d, 0x5b, 0x37, 0xc2, 0x83, 0x74, 0xd2, 0xf9, 0xcc, 0x98, 0x0a, 0x3c, 0x3c, 0x38, 0xd9, 0x4d diff --git a/unittests/ASM/H0F38/66_15.asm b/unittests/ASM/H0F38/66_15.asm new file mode 100644 index 000000000..6243110fe --- /dev/null +++ b/unittests/ASM/H0F38/66_15.asm @@ -0,0 +1,74 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x48510f254d2fa47f", "0x2b5774313a974886"], + "XMM2": ["0x30b556de1f6de86b", "0x67d29af330ae762c"], + "XMM3": ["0x41029b7f255b4cf4", "0xca79a24c3e9e3978"], + "XMM4": ["0x24426b4c72f110ad", "0x65f580205ffdc710"], + "XMM5": ["0x4f1694dfa8fb773c", "0x19a26b823d3ca2a9"], + "XMM6": ["0x00f658ab689712b0", "0x1ea62724c8883dfa"], + "XMM7": ["0x1c86432298df55c8", "0x07f565f98b8db7bc"], + "XMM8": ["0x10c41fa17837c17f", "0x099224327e5e296c"] + } +} +%endif + +lea rdx, [rel .data] +lea rdi, [rel .mask] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +; pblend uses xmm0 implicitly +movaps xmm0, [rdx + 16 * 0] +blendvpd xmm1, [rdx + 16 * 8] +movaps xmm0, [rdx + 16 * 1] +blendvpd xmm2, [rdx + 16 * 9] +movaps xmm0, [rdx + 16 * 2] +blendvpd xmm3, [rdx + 16 * 10] +movaps xmm0, [rdx + 16 * 3] +blendvpd xmm4, [rdx + 16 * 11] +movaps xmm0, [rdx + 16 * 4] +blendvpd xmm5, [rdx + 16 * 12] +movaps xmm0, [rdx + 16 * 5] +blendvpd xmm6, [rdx + 16 * 13] +movaps xmm0, [rdx + 16 * 6] +blendvpd xmm7, [rdx + 16 * 14] +movaps xmm0, [rdx + 16 * 7] +blendvpd xmm8, [rdx + 16 * 15] + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 +.mask: +db 0xb5, 0xdb, 0xca, 0x08, 0x0a, 0xae, 0x17, 0xb6, 0x54, 0x0d, 0xd3, 0xa1, 0x1d, 0x28, 0x25, 0xd3 +db 0x02, 0xf5, 0xce, 0x94, 0x2e, 0x56, 0x01, 0xf4, 0xae, 0x81, 0xbe, 0x50, 0x70, 0x45, 0x83, 0x18 +db 0x33, 0x46, 0x60, 0x4e, 0x29, 0xe4, 0x49, 0xae, 0xc2, 0x0e, 0x70, 0xcd, 0x2a, 0x6f, 0xb8, 0x9d +db 0x47, 0x1e, 0x8e, 0x94, 0x81, 0xaa, 0x12, 0xe4, 0x8e, 0x77, 0x48, 0x34, 0x63, 0x8f, 0x4c, 0x57 +db 0x34, 0xf9, 0x5b, 0x37, 0x76, 0x9f, 0xff, 0x8c, 0x6b, 0xf2, 0x6e, 0xd0, 0x15, 0x61, 0x4e, 0x0f +db 0xe2, 0xa7, 0xd0, 0x73, 0x7f, 0xf0, 0xae, 0xe7, 0x48, 0x32, 0x2a, 0x56, 0xc3, 0x29, 0x12, 0x4f +db 0x7d, 0x5b, 0x37, 0xc2, 0x83, 0x74, 0xd2, 0xf9, 0xcc, 0x98, 0x0a, 0x3c, 0x3c, 0x38, 0xd9, 0x4d diff --git a/unittests/ASM/H0F38/66_17.asm b/unittests/ASM/H0F38/66_17.asm new file mode 100644 index 000000000..d6a3f5a67 --- /dev/null +++ b/unittests/ASM/H0F38/66_17.asm @@ -0,0 +1,104 @@ +%ifdef CONFIG +{ + "RegData": { + "R15": "0x000000000003a759", + "XMM1": ["0", "0"], + "XMM2": ["0xFFFFFFFFFFFFFFFF", "0xFFFFFFFFFFFFFFFF"], + "XMM3": ["0x4142434445464748", "0x5152535455565758"], + "XMM4": ["0", "0"], + "XMM5": ["0xFFFFFFFFFFFFFFFF", "0xFFFFFFFFFFFFFFFF"], + "XMM6": ["0x4142434445464748", "0x5152535455565758"], + "XMM7": ["0", "0"], + "XMM8": ["0xFFFFFFFFFFFFFFFF", "0xFFFFFFFFFFFFFFFF"], + "XMM9": ["0x4142434445464748", "0x5152535455565758"] + + } +} +%endif + +; Uses AX and BX and stores result in r15 +; CF:ZF +%macro zfcfmerge 0 + lahf + + ; Shift CF to zero + shr ax, 8 + + ; Move to a temp + mov bx, ax + and rbx, 1 + + shl r15, 1 + or r15, rbx + + shl r15, 1 + + ; Move to a temp + mov bx, ax + + ; Extract ZF + shr bx, 6 + and rbx, 1 + + ; Insert ZF + or r15, rbx +%endmacro + +lea rdx, [rel .data] + +mov rax, 0 +mov rbx, 0 +mov r15, 0 + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 0] +movaps xmm5, [rdx + 16 * 1] +movaps xmm6, [rdx + 16 * 2] +movaps xmm7, [rdx + 16 * 0] +movaps xmm8, [rdx + 16 * 1] +movaps xmm9, [rdx + 16 * 2] + + +ptest xmm1, [rdx + 16 * 3] +zfcfmerge +ptest xmm2, [rdx + 16 * 4] +zfcfmerge +ptest xmm3, [rdx + 16 * 5] +zfcfmerge +ptest xmm4, [rdx + 16 * 6] +zfcfmerge +ptest xmm5, [rdx + 16 * 7] +zfcfmerge +ptest xmm6, [rdx + 16 * 8] +zfcfmerge +ptest xmm7, [rdx + 16 * 9] +zfcfmerge +ptest xmm8, [rdx + 16 * 10] +zfcfmerge +ptest xmm9, [rdx + 16 * 11] +zfcfmerge + +hlt + +align 16 +.data: +dq 0, 0 +dq 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF +dq 0x4142434445464748, 0x5152535455565758 + +; Match +dq 0, 0 +dq 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF +dq 0x4142434445464748, 0x5152535455565758 + +; Match on not +dq 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF +dq 0, 0 +dq 0xBEBDBCBBBAB9B8B7, 0xAEADACABAAA9A8A7 + +; No match on either case +dq 1, 1 +dq 2, 2 +dq 3, 3 diff --git a/unittests/ASM/H0F38/66_20.asm b/unittests/ASM/H0F38/66_20.asm new file mode 100644 index 000000000..26b02aeb9 --- /dev/null +++ b/unittests/ASM/H0F38/66_20.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0xff85ff86ff87ff88", "0x0041004200430044"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovsxbw xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_21.asm b/unittests/ASM/H0F38/66_21.asm new file mode 100644 index 000000000..8afff64da --- /dev/null +++ b/unittests/ASM/H0F38/66_21.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0xffffff87ffffff88", "0xffffff85ffffff86"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovsxbd xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_22.asm b/unittests/ASM/H0F38/66_22.asm new file mode 100644 index 000000000..a1124723f --- /dev/null +++ b/unittests/ASM/H0F38/66_22.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0xffffffffffffff88", "0xffffffffffffff87"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovsxbq xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_23.asm b/unittests/ASM/H0F38/66_23.asm new file mode 100644 index 000000000..7b34fc61e --- /dev/null +++ b/unittests/ASM/H0F38/66_23.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0xffff8586ffff8788", "0x0000414200004344"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovsxwd xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_24.asm b/unittests/ASM/H0F38/66_24.asm new file mode 100644 index 000000000..27a664b75 --- /dev/null +++ b/unittests/ASM/H0F38/66_24.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0xffffffffffff8788", "0xffffffffffff8586"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovsxwq xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_25.asm b/unittests/ASM/H0F38/66_25.asm new file mode 100644 index 000000000..72b7e1e7c --- /dev/null +++ b/unittests/ASM/H0F38/66_25.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0xffffffff85868788", "0x0000000041424344"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovsxdq xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_28.asm b/unittests/ASM/H0F38/66_28.asm new file mode 100644 index 000000000..e15da5c2d --- /dev/null +++ b/unittests/ASM/H0F38/66_28.asm @@ -0,0 +1,57 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0xee65166050ac19a0", "0xfe1eb34a32b1a0b2"], + "XMM2": ["0x28a18cdd2d20fb20", "0x1d6fa69c44caed04"], + "XMM3": ["0xf514cf89a88edcde", "0x01e3dc4237becfcf"], + "XMM4": ["0x0004b0350897f35a", "0x03cd750e809c18d0"], + "XMM5": ["0x066a5fa4ad5148c8", "0x00bca2da387e55a2"], + "XMM6": ["0x1e0f03011112ed90", "0x18c90f3ec0d58440"], + "XMM7": ["0xee94b334b2358df2", "0x1b82409d7ae7fa28"], + "XMM8": ["0xed12f34e8fb5e098", "0xd83d0ba0ff8632db"] + } +} +%endif + +lea rdx, [rel .data] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +pmuldq xmm1, [rdx + 16 * 8] +pmuldq xmm2, [rdx + 16 * 9] +pmuldq xmm3, [rdx + 16 * 10] +pmuldq xmm4, [rdx + 16 * 11] +pmuldq xmm5, [rdx + 16 * 12] +pmuldq xmm6, [rdx + 16 * 13] +pmuldq xmm7, [rdx + 16 * 14] +pmuldq xmm8, [rdx + 16 * 15] + +hlt + +align 16 +; 256bytes of random data +.data: +db 0xe0, 0xfc, 0x2b, 0xa1, 0x06, 0x4f, 0x6c, 0xa7, 0x0f, 0x06, 0x6a, 0x1e, 0x7f, 0x76, 0x80, 0x9b +db 0xe0, 0x56, 0xed, 0xaa, 0xf3, 0xc3, 0x68, 0x68, 0xde, 0xe6, 0xe6, 0x94, 0xe2, 0xe9, 0xfc, 0xf0 +db 0x6e, 0x35, 0xa8, 0x54, 0xd7, 0xab, 0x8b, 0x6c, 0x77, 0x5f, 0x92, 0xca, 0x25, 0xa6, 0x7e, 0x27 +db 0xc7, 0xcd, 0x73, 0xec, 0x95, 0xd6, 0x6f, 0x6a, 0xbb, 0xae, 0xf2, 0xbb, 0x27, 0xb9, 0xa1, 0xdd +db 0x73, 0x4d, 0xd1, 0xc7, 0xd5, 0x2c, 0x31, 0x88, 0xfe, 0xe7, 0xdb, 0xfd, 0x1e, 0x1e, 0x09, 0x7f +db 0x14, 0xfa, 0x4e, 0x95, 0xef, 0xe6, 0x9a, 0xf2, 0xa0, 0x42, 0x62, 0x9a, 0xa4, 0xa8, 0x73, 0x82 +db 0x0e, 0x0f, 0x16, 0x82, 0x38, 0x07, 0x12, 0x32, 0x07, 0x35, 0x92, 0xc1, 0x63, 0x07, 0x78, 0xb3 +db 0xcb, 0x46, 0x19, 0x57, 0x2b, 0x37, 0x2a, 0x46, 0x1f, 0x04, 0x0e, 0x79, 0x3d, 0xcd, 0x8d, 0xa3 +db 0x2b, 0xf3, 0x86, 0x2f, 0xab, 0xba, 0x57, 0x30, 0x2e, 0xd6, 0x2c, 0xf0, 0x46, 0x4f, 0x3f, 0xef +db 0xef, 0xd1, 0xbb, 0x85, 0x34, 0x4b, 0x3c, 0xde, 0x9e, 0x48, 0xa3, 0xb9, 0x8d, 0x71, 0xe3, 0x9d +db 0x09, 0x72, 0xfb, 0xde, 0x8a, 0x32, 0x50, 0x9d, 0x69, 0x98, 0xf1, 0xf6, 0x52, 0xeb, 0xf7, 0xee +db 0xd6, 0x99, 0xc2, 0xff, 0x30, 0x1c, 0x02, 0xce, 0x70, 0x05, 0xb2, 0xf1, 0x56, 0x9c, 0x0e, 0xa6 +db 0x18, 0x62, 0xc4, 0xe2, 0x86, 0x38, 0x76, 0x30, 0x2f, 0xa1, 0xe4, 0xa7, 0x0e, 0x5d, 0x53, 0xeb +db 0x14, 0x45, 0xe0, 0xb7, 0xe1, 0xe8, 0x02, 0x68, 0x1a, 0xfe, 0x8e, 0xc1, 0x8f, 0xf2, 0xeb, 0x46 +db 0x7f, 0x5d, 0x6a, 0x23, 0x46, 0x97, 0x2e, 0x03, 0x98, 0x12, 0x32, 0x8f, 0x54, 0x76, 0x59, 0xac +db 0xc8, 0x76, 0x5f, 0xc8, 0x71, 0x0c, 0xd3, 0xb6, 0xc5, 0x19, 0xea, 0xab, 0xa6, 0x2c, 0x1d, 0x88 + diff --git a/unittests/ASM/H0F38/66_29.asm b/unittests/ASM/H0F38/66_29.asm new file mode 100644 index 000000000..745236fdc --- /dev/null +++ b/unittests/ASM/H0F38/66_29.asm @@ -0,0 +1,64 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0xffffffffffffffff", "0xffffffffffffffff"], + "XMM2": ["0xffffffffffffffff", "0xffffffffffffffff"], + "XMM3": ["0xffffffffffffffff", "0xffffffffffffffff"], + "XMM4": ["0xffffffffffffffff", "0xffffffffffffffff"], + "XMM5": ["0x0", "0x0"], + "XMM6": ["0x0", "0x0"], + "XMM7": ["0x0", "0x0"], + "XMM8": ["0xffffffffffffffff", "0xffffffffffffffff"], + "XMM9": ["0x0", "0xffffffffffffffff"], + "XMM10": ["0xffffffffffffffff", "0x0"] + } +} +%endif + +lea rdx, [rel .data] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] +movaps xmm9, [rdx + 16 * 0] +movaps xmm10, [rdx + 16 * 0] + +pcmpeqq xmm1, [rdx + 16 * 8] +pcmpeqq xmm2, [rdx + 16 * 9] +pcmpeqq xmm3, [rdx + 16 * 10] +pcmpeqq xmm4, [rdx + 16 * 11] +pcmpeqq xmm5, [rdx + 16 * 12] +pcmpeqq xmm6, [rdx + 16 * 13] +pcmpeqq xmm7, [rdx + 16 * 14] +pcmpeqq xmm8, [rdx + 16 * 15] +pcmpeqq xmm9, [rdx + 16 * 16] +pcmpeqq xmm10, [rdx + 16 * 17] + +hlt + +align 16 +.data: +dq 0.0, 0.0 +dq 0.0, 1.0 +dq 1.0, 0.0 +dq 1.0, 1.0 +dq 0.0, 0.0 +dq 0.0, 1.0 +dq 1.0, 0.0 +dq 1.0, 1.0 + +dq 0.0, 0.0 +dq 0.0, 1.0 +dq 1.0, 0.0 +dq 1.0, 1.0 +dq 1.0, 1.0 +dq 1.0, 0.0 +dq 0.0, 1.0 +dq 1.0, 1.0 +dq 1.0, 0.0 +dq 0.0, 1.0 diff --git a/unittests/ASM/H0F38/66_2B.asm b/unittests/ASM/H0F38/66_2B.asm new file mode 100644 index 000000000..1efc5bac3 --- /dev/null +++ b/unittests/ASM/H0F38/66_2B.asm @@ -0,0 +1,44 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0xffffffffffffffff", "0x00000000ffff0000"], + "XMM1": ["0xffffffffffffffff", "0x12348000ffff0000"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov eax, 0 +mov [rdx + 8 * 2 + 0], eax +mov eax, 0x7FFFFFFF +mov [rdx + 8 * 2 + 4], eax +mov eax, 0x80000000 +mov [rdx + 8 * 3 + 0], eax +mov eax, 0xFFFFFFFF +mov [rdx + 8 * 3 + 4], eax + +; Values that actually fit in to 16bit unsigned +mov eax, 0 +mov [rdx + 8 * 4 + 0], eax +mov eax, 0xFFFF +mov [rdx + 8 * 4 + 4], eax +mov eax, 0x8000 +mov [rdx + 8 * 5 + 0], eax +mov eax, 0x1234 +mov [rdx + 8 * 5 + 4], eax + +; Setup source +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] + +; Pack it +packusdw xmm0, [rdx + 8 * 2] +packusdw xmm1, [rdx + 8 * 4] + +hlt diff --git a/unittests/ASM/H0F38/66_30.asm b/unittests/ASM/H0F38/66_30.asm new file mode 100644 index 000000000..cceaeabcb --- /dev/null +++ b/unittests/ASM/H0F38/66_30.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x0085008600870088", "0x0041004200430044"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovzxbw xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_31.asm b/unittests/ASM/H0F38/66_31.asm new file mode 100644 index 000000000..c2f98bd20 --- /dev/null +++ b/unittests/ASM/H0F38/66_31.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x0000008700000088", "0x0000008500000086"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovzxbd xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_32.asm b/unittests/ASM/H0F38/66_32.asm new file mode 100644 index 000000000..9f41b1eda --- /dev/null +++ b/unittests/ASM/H0F38/66_32.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x0000000000000088", "0x0000000000000087"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovzxbq xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_33.asm b/unittests/ASM/H0F38/66_33.asm new file mode 100644 index 000000000..8d632b414 --- /dev/null +++ b/unittests/ASM/H0F38/66_33.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x0000858600008788", "0x0000414200004344"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovzxwd xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_34.asm b/unittests/ASM/H0F38/66_34.asm new file mode 100644 index 000000000..ccf49642f --- /dev/null +++ b/unittests/ASM/H0F38/66_34.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x0000000000008788", "0x0000000000008586"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovzxwq xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_35.asm b/unittests/ASM/H0F38/66_35.asm new file mode 100644 index 000000000..c3e798944 --- /dev/null +++ b/unittests/ASM/H0F38/66_35.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x0000000085868788", "0x0000000041424344"] + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434485868788 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 3], rax + +; Fill register with trash +movapd xmm0, [rdx + 8 * 2] + +; Now do the move +pmovzxdq xmm0, [rdx + 8 * 0] + +hlt diff --git a/unittests/ASM/H0F38/66_38.asm b/unittests/ASM/H0F38/66_38.asm new file mode 100644 index 000000000..df7a6742e --- /dev/null +++ b/unittests/ASM/H0F38/66_38.asm @@ -0,0 +1,32 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x4142434445464748", "0x5152535455565758"], + "XMM1": ["0x4142434445464748", "0x5152535455565758"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 3], rax + +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] +movapd xmm2, [rdx + 8 * 2] + +pminsb xmm0, xmm2 +pminsb xmm1, [rdx + 8 * 2] + +hlt diff --git a/unittests/ASM/H0F38/66_39.asm b/unittests/ASM/H0F38/66_39.asm new file mode 100644 index 000000000..b5a3aca3f --- /dev/null +++ b/unittests/ASM/H0F38/66_39.asm @@ -0,0 +1,32 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x4142434445464748", "0x5152535455565758"], + "XMM1": ["0x4142434445464748", "0x5152535455565758"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 3], rax + +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] +movapd xmm2, [rdx + 8 * 2] + +pminsd xmm0, xmm2 +pminsd xmm1, [rdx + 8 * 2] + +hlt diff --git a/unittests/ASM/H0F38/66_3A.asm b/unittests/ASM/H0F38/66_3A.asm new file mode 100644 index 000000000..4f0dfd04a --- /dev/null +++ b/unittests/ASM/H0F38/66_3A.asm @@ -0,0 +1,32 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x4142434445464748", "0x5152535455565758"], + "XMM1": ["0x4142434445464748", "0x5152535455565758"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 3], rax + +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] +movapd xmm2, [rdx + 8 * 2] + +pminuw xmm0, xmm2 +pminuw xmm1, [rdx + 8 * 2] + +hlt diff --git a/unittests/ASM/H0F38/66_3B.asm b/unittests/ASM/H0F38/66_3B.asm new file mode 100644 index 000000000..853318ece --- /dev/null +++ b/unittests/ASM/H0F38/66_3B.asm @@ -0,0 +1,32 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x4142434445464748", "0x5152535455565758"], + "XMM1": ["0x4142434445464748", "0x5152535455565758"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 3], rax + +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] +movapd xmm2, [rdx + 8 * 2] + +pminud xmm0, xmm2 +pminud xmm1, [rdx + 8 * 2] + +hlt diff --git a/unittests/ASM/H0F38/66_3C.asm b/unittests/ASM/H0F38/66_3C.asm new file mode 100644 index 000000000..aa017236b --- /dev/null +++ b/unittests/ASM/H0F38/66_3C.asm @@ -0,0 +1,32 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x6162636465666768", "0x7172737475767778"], + "XMM1": ["0x6162636465666768", "0x7172737475767778"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 3], rax + +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] +movapd xmm2, [rdx + 8 * 2] + +pmaxsb xmm0, xmm2 +pmaxsb xmm1, [rdx + 8 * 2] + +hlt diff --git a/unittests/ASM/H0F38/66_3D.asm b/unittests/ASM/H0F38/66_3D.asm new file mode 100644 index 000000000..ebf4b9924 --- /dev/null +++ b/unittests/ASM/H0F38/66_3D.asm @@ -0,0 +1,32 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x6162636465666768", "0x7172737475767778"], + "XMM1": ["0x6162636465666768", "0x7172737475767778"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 3], rax + +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] +movapd xmm2, [rdx + 8 * 2] + +pmaxsd xmm0, xmm2 +pmaxsd xmm1, [rdx + 8 * 2] + +hlt diff --git a/unittests/ASM/H0F38/66_3E.asm b/unittests/ASM/H0F38/66_3E.asm new file mode 100644 index 000000000..d8499a0ec --- /dev/null +++ b/unittests/ASM/H0F38/66_3E.asm @@ -0,0 +1,32 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x6162636465666768", "0x7172737475767778"], + "XMM1": ["0x6162636465666768", "0x7172737475767778"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 3], rax + +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] +movapd xmm2, [rdx + 8 * 2] + +pmaxuw xmm0, xmm2 +pmaxuw xmm1, [rdx + 8 * 2] + +hlt diff --git a/unittests/ASM/H0F38/66_3F.asm b/unittests/ASM/H0F38/66_3F.asm new file mode 100644 index 000000000..8860d65d2 --- /dev/null +++ b/unittests/ASM/H0F38/66_3F.asm @@ -0,0 +1,32 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x6162636465666768", "0x7172737475767778"], + "XMM1": ["0x6162636465666768", "0x7172737475767778"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x7172737475767778 +mov [rdx + 8 * 1], rax + +mov rax, 0x6162636465666768 +mov [rdx + 8 * 2], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 3], rax + +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] +movapd xmm2, [rdx + 8 * 2] + +pmaxud xmm0, xmm2 +pmaxud xmm1, [rdx + 8 * 2] + +hlt diff --git a/unittests/ASM/H0F38/66_40.asm b/unittests/ASM/H0F38/66_40.asm new file mode 100644 index 000000000..9c7a777eb --- /dev/null +++ b/unittests/ASM/H0F38/66_40.asm @@ -0,0 +1,41 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x7a84d3fa541ef1be", "0x5f0d7667e4d8e24a"], + "XMM2": ["0x44683c4ce9ac9780", "0x9da95e9a6f25ef94"], + "XMM3": ["0x4bc94ea0ccb0a64c", "0x3cf36ee04f371510"], + "XMM4": ["0x1ac415407b8ba3db", "0x92cdc300dab0773c"], + "XMM5": ["0x6796b1563f8d578c", "0x4c64f16199291fe4"], + "XMM6": ["0x01a14ef664207dc6", "0x1d3220da400e1027"], + "XMM7": ["0x75ddba582c3dd348", "0xa5141c506d8c60d7"], + "XMM8": ["0x7873ff38fb240e0d", "0x6c154f1adb67cd17"] + } +} +%endif + +lea rdx, [rel .data] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +pmulld xmm1, [rdx + 16 * 8] +pmulld xmm2, [rdx + 16 * 9] +pmulld xmm3, [rdx + 16 * 10] +pmulld xmm4, [rdx + 16 * 11] +pmulld xmm5, [rdx + 16 * 12] +pmulld xmm6, [rdx + 16 * 13] +pmulld xmm7, [rdx + 16 * 14] +pmulld xmm8, [rdx + 16 * 15] + +hlt + +align 16 +; 256bytes of random data +.data: +dd 655.9708,532.2244,108.0451,512.4019,754.227,586.0859,127.7574,114.8167,764.4266,226.6145,337.864,320.3296,296.5247,480.0057,28.4267,565.9418,265.8255,536.4473,754.3489,460.681,818.7269,43.7204,464.592,847.9381,306.0592,702.7584,887.6473,551.5908,620.9001,520.9829,232.9532,510.3388,204.8474,225.626,564.973,790.5175,836.1953,844.5266,633.5626,501.7409,393.2616,674.4415,244.3265,971.1598,770.8029,746.1836,255.9902,567.7578,187.7175,924.181,466.4362,169.8267,651.7481,462.4206,396.6924,355.8538,6.148,523.1443,989.7004,713.6646,497.5427,657.6965,651.0534,778.5236 diff --git a/unittests/ASM/H0F38/66_41.asm b/unittests/ASM/H0F38/66_41.asm new file mode 100644 index 000000000..9fb62a164 --- /dev/null +++ b/unittests/ASM/H0F38/66_41.asm @@ -0,0 +1,47 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x0000000000000001", "0x0"], + "XMM1": ["0x0000000000030001", "0x0"], + "XMM2": ["0x0000000000070001", "0x0"], + "XMM3": ["0x0000000000010001", "0x0"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +; Pos 0 +mov rax, 0x0004000300020001 +mov [rdx + 8 * 0], rax +mov rax, 0x0008000700060005 +mov [rdx + 8 * 1], rax + +; Pos 3 +mov rax, 0x0001000300020004 +mov [rdx + 8 * 2], rax +mov rax, 0x0008000700060005 +mov [rdx + 8 * 3], rax + +; Pos 7 +mov rax, 0x0008000300020004 +mov [rdx + 8 * 4], rax +mov rax, 0x0001000700060005 +mov [rdx + 8 * 5], rax + +; Pos 7 & 3 & 2 +; Should return lowest position +mov rax, 0x0008000100010004 +mov [rdx + 8 * 6], rax +mov rax, 0x0001000700060005 +mov [rdx + 8 * 7], rax + +phminposuw xmm0, [rdx + 8 * 0] +phminposuw xmm1, [rdx + 8 * 2] +phminposuw xmm2, [rdx + 8 * 4] +phminposuw xmm3, [rdx + 8 * 6] + +hlt diff --git a/unittests/ASM/H0F3A/66_08.asm b/unittests/ASM/H0F3A/66_08.asm new file mode 100644 index 000000000..74cd895f0 --- /dev/null +++ b/unittests/ASM/H0F3A/66_08.asm @@ -0,0 +1,57 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x8000000000000000", "0xc000000040000000"], + "XMM1": ["0xbf80000000000000", "0xc00000003f800000"], + "XMM2": ["0x800000003f800000", "0xbf80000040000000"], + "XMM3": ["0x8000000000000000", "0xbf8000003f800000"], + "XMM4": ["0x8000000000000000", "0xc000000040000000"], + "XMM5": ["0xbf80000000000000", "0xc00000003f800000"], + "XMM6": ["0x800000003f800000", "0xbf80000040000000"], + "XMM7": ["0x8000000000000000", "0xbf8000003f800000"] + } +} +%endif + +lea rdx, [rel .data] + +roundps xmm0, [rdx + 8 * 0], 00000000b ; Nearest +roundps xmm1, [rdx + 8 * 0], 00000001b ; -inf +roundps xmm2, [rdx + 8 * 0], 00000010b ; +inf +roundps xmm3, [rdx + 8 * 0], 00000011b ; truncate + +; MXCSR +; Set to nearest +mov eax, 0x1F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundps xmm4, [rdx + 8 * 0], 00000100b + +; Set to -inf +mov eax, 0x3F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundps xmm5, [rdx + 8 * 0], 00000100b + +; Set to +inf +mov eax, 0x5F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundps xmm6, [rdx + 8 * 0], 00000100b + +; Set to truncate +mov eax, 0x7F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundps xmm7, [rdx + 8 * 0], 00000100b + +hlt + +align 16 +.data: +dd 0.5, -0.5, 1.5, -1.5 +dq 0, 0 diff --git a/unittests/ASM/H0F3A/66_09.asm b/unittests/ASM/H0F3A/66_09.asm new file mode 100644 index 000000000..c9d383cef --- /dev/null +++ b/unittests/ASM/H0F3A/66_09.asm @@ -0,0 +1,57 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x0000000000000000", "0x8000000000000000"], + "XMM1": ["0x0000000000000000", "0xbff0000000000000"], + "XMM2": ["0x3ff0000000000000", "0x8000000000000000"], + "XMM3": ["0x0000000000000000", "0x8000000000000000"], + "XMM4": ["0x0000000000000000", "0x8000000000000000"], + "XMM5": ["0x0000000000000000", "0xbff0000000000000"], + "XMM6": ["0x3ff0000000000000", "0x8000000000000000"], + "XMM7": ["0x0000000000000000", "0x8000000000000000"] + } +} +%endif + +lea rdx, [rel .data] + +roundpd xmm0, [rdx + 8 * 0], 00000000b ; Nearest +roundpd xmm1, [rdx + 8 * 0], 00000001b ; -inf +roundpd xmm2, [rdx + 8 * 0], 00000010b ; +inf +roundpd xmm3, [rdx + 8 * 0], 00000011b ; truncate + +; MXCSR +; Set to nearest +mov eax, 0x1F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundpd xmm4, [rdx + 8 * 0], 00000100b + +; Set to -inf +mov eax, 0x3F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundpd xmm5, [rdx + 8 * 0], 00000100b + +; Set to +inf +mov eax, 0x5F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundpd xmm6, [rdx + 8 * 0], 00000100b + +; Set to truncate +mov eax, 0x7F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundpd xmm7, [rdx + 8 * 0], 00000100b + +hlt + +align 16 +.data: +dq 0.5, -0.5 +dq 0, 0 diff --git a/unittests/ASM/H0F3A/66_0A.asm b/unittests/ASM/H0F3A/66_0A.asm new file mode 100644 index 000000000..e451d4539 --- /dev/null +++ b/unittests/ASM/H0F3A/66_0A.asm @@ -0,0 +1,66 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0xbf00000000000000", "0xbfc000003fc00000"], + "XMM1": ["0xbf00000000000000", "0xbfc000003fc00000"], + "XMM2": ["0xbf0000003f800000", "0xbfc000003fc00000"], + "XMM3": ["0xbf00000000000000", "0xbfc000003fc00000"], + "XMM4": ["0xbf00000000000000", "0xbfc000003fc00000"], + "XMM5": ["0xbf00000000000000", "0xbfc000003fc00000"], + "XMM6": ["0xbf0000003f800000", "0xbfc000003fc00000"], + "XMM7": ["0xbf00000000000000", "0xbfc000003fc00000"] + } +} +%endif + +lea rdx, [rel .data] + +movaps xmm0, [rdx + 8 * 0] +movaps xmm1, [rdx + 8 * 0] +movaps xmm2, [rdx + 8 * 0] +movaps xmm3, [rdx + 8 * 0] +movaps xmm4, [rdx + 8 * 0] +movaps xmm5, [rdx + 8 * 0] +movaps xmm6, [rdx + 8 * 0] +movaps xmm7, [rdx + 8 * 0] + +roundss xmm0, [rdx + 8 * 0], 00000000b ; Nearest +roundss xmm1, [rdx + 8 * 0], 00000001b ; -inf +roundss xmm2, [rdx + 8 * 0], 00000010b ; +inf +roundss xmm3, [rdx + 8 * 0], 00000011b ; truncate + +; MXCSR +; Set to nearest +mov eax, 0x1F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundss xmm4, [rdx + 8 * 0], 00000100b + +; Set to -inf +mov eax, 0x3F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundss xmm5, [rdx + 8 * 0], 00000100b + +; Set to +inf +mov eax, 0x5F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundss xmm6, [rdx + 8 * 0], 00000100b + +; Set to truncate +mov eax, 0x7F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundss xmm7, [rdx + 8 * 0], 00000100b + +hlt + +align 16 +.data: +dd 0.5, -0.5, 1.5, -1.5 +dq 0, 0 diff --git a/unittests/ASM/H0F3A/66_0B.asm b/unittests/ASM/H0F3A/66_0B.asm new file mode 100644 index 000000000..6578a09c6 --- /dev/null +++ b/unittests/ASM/H0F3A/66_0B.asm @@ -0,0 +1,66 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x0000000000000000", "0xbfe0000000000000"], + "XMM1": ["0x0000000000000000", "0xbfe0000000000000"], + "XMM2": ["0x3ff0000000000000", "0xbfe0000000000000"], + "XMM3": ["0x0000000000000000", "0xbfe0000000000000"], + "XMM4": ["0x0000000000000000", "0xbfe0000000000000"], + "XMM5": ["0x0000000000000000", "0xbfe0000000000000"], + "XMM6": ["0x3ff0000000000000", "0xbfe0000000000000"], + "XMM7": ["0x0000000000000000", "0xbfe0000000000000"] + } +} +%endif + +lea rdx, [rel .data] + +movaps xmm0, [rdx + 8 * 0] +movaps xmm1, [rdx + 8 * 0] +movaps xmm2, [rdx + 8 * 0] +movaps xmm3, [rdx + 8 * 0] +movaps xmm4, [rdx + 8 * 0] +movaps xmm5, [rdx + 8 * 0] +movaps xmm6, [rdx + 8 * 0] +movaps xmm7, [rdx + 8 * 0] + +roundsd xmm0, [rdx + 8 * 0], 00000000b ; Nearest +roundsd xmm1, [rdx + 8 * 0], 00000001b ; -inf +roundsd xmm2, [rdx + 8 * 0], 00000010b ; +inf +roundsd xmm3, [rdx + 8 * 0], 00000011b ; truncate + +; MXCSR +; Set to nearest +mov eax, 0x1F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundsd xmm4, [rdx + 8 * 0], 00000100b + +; Set to -inf +mov eax, 0x3F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundsd xmm5, [rdx + 8 * 0], 00000100b + +; Set to +inf +mov eax, 0x5F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundsd xmm6, [rdx + 8 * 0], 00000100b + +; Set to truncate +mov eax, 0x7F80 +mov [rdx + 8 * 2], eax +ldmxcsr [rdx + 8 * 2] + +roundsd xmm7, [rdx + 8 * 0], 00000100b + +hlt + +align 16 +.data: +dq 0.5, -0.5 +dq 0, 0 diff --git a/unittests/ASM/H0F3A/66_0C.asm b/unittests/ASM/H0F3A/66_0C.asm new file mode 100644 index 000000000..926b4be3f --- /dev/null +++ b/unittests/ASM/H0F3A/66_0C.asm @@ -0,0 +1,56 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x48510f254d2fa47f", "0x2b5774313a974886"], + "XMM2": ["0x30b556de38c17718", "0x67d29af330ae762c"], + "XMM3": ["0x41029b7f255b4cf4", "0xb76472a37404b890"], + "XMM4": ["0x57fa6daf9af2e91c", "0x8a6789f25ffdc710"], + "XMM5": ["0x4f1694dfa8fb773c", "0x10828c03760078c0"], + "XMM6": ["0x2ef9bb92689712b0", "0x1ea62724c8883dfa"], + "XMM7": ["0x1c86432298df55c8", "0x07f565f98b8db7bc"], + "XMM8": ["0x88b0bd28710f2147", "0x099224327fb5ac38"] + } +} +%endif + +lea rdx, [rel .data] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +blendps xmm1, [rdx + 16 * 8], 0000b +blendps xmm2, [rdx + 16 * 9], 0001b +blendps xmm3, [rdx + 16 * 10], 0011b +blendps xmm4, [rdx + 16 * 11], 0111b +blendps xmm5, [rdx + 16 * 12], 1111b +blendps xmm6, [rdx + 16 * 13], 1110b +blendps xmm7, [rdx + 16 * 14], 1100b +blendps xmm8, [rdx + 16 * 15], 1000b + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 diff --git a/unittests/ASM/H0F3A/66_0D.asm b/unittests/ASM/H0F3A/66_0D.asm new file mode 100644 index 000000000..0eeecb26b --- /dev/null +++ b/unittests/ASM/H0F3A/66_0D.asm @@ -0,0 +1,44 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x48510f254d2fa47f", "0x2b5774313a974886"], + "XMM2": ["0x58a9fc7b38c17718", "0x67d29af330ae762c"], + "XMM3": ["0xb615b9533de8ad09", "0xca79a24c3e9e3978"], + "XMM4": ["0x57fa6daf9af2e91c", "0x65f580205ffdc710"] + } +} +%endif + +lea rdx, [rel .data] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] + +blendpd xmm1, [rdx + 16 * 8], 00b +blendpd xmm2, [rdx + 16 * 9], 01b +blendpd xmm3, [rdx + 16 * 10], 10b +blendpd xmm4, [rdx + 16 * 11], 11b + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 diff --git a/unittests/ASM/H0F3A/66_0E.asm b/unittests/ASM/H0F3A/66_0E.asm new file mode 100644 index 000000000..8c4e691ab --- /dev/null +++ b/unittests/ASM/H0F3A/66_0E.asm @@ -0,0 +1,56 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x48510f254d2fa47f", "0x2b5774313a974886"], + "XMM2": ["0x30b556de1f6d7718", "0x67d29af330ae762c"], + "XMM3": ["0xb615b953255b4cf4", "0xb76472a37404b890"], + "XMM4": ["0x24426daf9af2e91c", "0x8a6789f2d415a567"], + "XMM5": ["0x4f1694dfa8fb773c", "0x19a26b823d3ca2a9"], + "XMM6": ["0x2ef9bb9202e0077f", "0xc97d9d031ed23dfa"], + "XMM7": ["0x944c0a76f8f69004", "0xb29bfeda8b8db7bc"], + "XMM8": ["0x10c41fa17837c17f", "0x099224327e5e296c"] + } +} +%endif + +lea rdx, [rel .data] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +pblendw xmm1, [rdx + 16 * 8], 00000000b +pblendw xmm2, [rdx + 16 * 9], 00000001b +pblendw xmm3, [rdx + 16 * 10], 00000011b +pblendw xmm4, [rdx + 16 * 11], 00000111b +pblendw xmm5, [rdx + 16 * 12], 00001111b +pblendw xmm6, [rdx + 16 * 13], 00011111b +pblendw xmm7, [rdx + 16 * 14], 00111111b +pblendw xmm8, [rdx + 16 * 15], 11111111b + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 diff --git a/unittests/ASM/H0F3A/66_14.asm b/unittests/ASM/H0F3A/66_14.asm new file mode 100644 index 000000000..54bbcf3b5 --- /dev/null +++ b/unittests/ASM/H0F3A/66_14.asm @@ -0,0 +1,56 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0x000000000000007f", + "RBX": "0x0000000000000067", + "RCX": "0x0000888658818ae8" + } +} +%endif + +lea rdx, [rel .data] +mov rsi, 0xe0000000 + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +mov rax, 0 +mov [rsi + 8 * 0], rax + +pextrb rax, xmm1, 0 +pextrb rbx, xmm2, 0xFF +pextrb [rsi + 8 * 0 + 0], xmm3, 2 +pextrb [rsi + 8 * 0 + 1], xmm4, 0xFF +pextrb [rsi + 8 * 0 + 2], xmm5, 4 +pextrb [rsi + 8 * 0 + 3], xmm6, 5 +pextrb [rsi + 8 * 0 + 4], xmm7, 6 +pextrb [rsi + 8 * 0 + 5], xmm8, 7 +mov rcx, [rsi + 8 * 0] + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 diff --git a/unittests/ASM/H0F3A/66_15.asm b/unittests/ASM/H0F3A/66_15.asm new file mode 100644 index 000000000..9f75cb919 --- /dev/null +++ b/unittests/ASM/H0F3A/66_15.asm @@ -0,0 +1,59 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0x000000000000a47f", + "RBX": "0x00000000000067d2", + "RCX": "0x1ed2a2a98a67b953" + } +} +%endif + +lea rdx, [rel .data] +mov rsi, 0xe0000000 + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +mov rax, 0 +mov [rsi + 8 * 0], rax + +; Nasm only encodes pextrw instructions that have register as their destination with sse2 +; hand code these following instructions +; pextrw eax, xmm1, 0 +; pextrw ebx, xmm2, 0xFF +db 0x66, 0x0f, 0x3a, 0x15, 0xc8, 0x00 +db 0x66, 0x0f, 0x3a, 0x15, 0xd3, 0xFF + +pextrw [rsi + 8 * 0 + 0], xmm3, 2 +pextrw [rsi + 8 * 0 + 2], xmm4, 0xFF +pextrw [rsi + 8 * 0 + 4], xmm5, 4 +pextrw [rsi + 8 * 0 + 6], xmm6, 5 +mov rcx, [rsi + 8 * 0] + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 diff --git a/unittests/ASM/H0F3A/66_16.asm b/unittests/ASM/H0F3A/66_16.asm new file mode 100644 index 000000000..c6e6696b5 --- /dev/null +++ b/unittests/ASM/H0F3A/66_16.asm @@ -0,0 +1,56 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0x000000004d2fa47f", + "RBX": "0x0000000067d29af3", + "RCX": "0x8a6789f27404b890", + "RDX": "0x00f658ab78236612" + } +} +%endif + +lea rdx, [rel .data] +mov rsi, 0xe0000000 + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +mov rax, 0 +mov [rsi + 8 * 0], rax + +pextrd eax, xmm1, 0 +pextrd ebx, xmm2, 0xFF +pextrd [rsi + 8 * 0 + 0], xmm3, 2 +pextrd [rsi + 8 * 0 + 4], xmm4, 0xFF +pextrd [rsi + 8 * 1 + 0], xmm5, 4 +pextrd [rsi + 8 * 1 + 4], xmm6, 5 +mov rcx, [rsi + 8 * 0] +mov rdx, [rsi + 8 * 1] + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 diff --git a/unittests/ASM/H0F3A/66_16_1.asm b/unittests/ASM/H0F3A/66_16_1.asm new file mode 100644 index 000000000..5ef201ed0 --- /dev/null +++ b/unittests/ASM/H0F3A/66_16_1.asm @@ -0,0 +1,60 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0x48510f254d2fa47f", + "RBX": "0x67d29af330ae762c", + "RCX": "0xb615b9533de8ad09", + "RDX": "0x8a6789f2d415a567", + "RDI": "0x8996f88178236612", + "RSP": "0xc97d9d031ed21972" + } +} +%endif + +lea rdx, [rel .data] +mov rsi, 0xe0000000 + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +mov rax, 0 +mov [rsi + 8 * 0], rax + +pextrq rax, xmm1, 0 +pextrq rbx, xmm2, 0xFF +pextrq [rsi + 8 * 0], xmm3, 2 +pextrq [rsi + 8 * 1], xmm4, 0xFF +pextrq [rsi + 8 * 2], xmm5, 4 +pextrq [rsi + 8 * 3], xmm6, 5 +mov rcx, [rsi + 8 * 0] +mov rdx, [rsi + 8 * 1] +mov rdi, [rsi + 8 * 2] +mov rsp, [rsi + 8 * 3] + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 diff --git a/unittests/ASM/H0F3A/66_17.asm b/unittests/ASM/H0F3A/66_17.asm new file mode 100644 index 000000000..87ce8b62d --- /dev/null +++ b/unittests/ASM/H0F3A/66_17.asm @@ -0,0 +1,56 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0x000000004d2fa47f", + "RBX": "0x0000000067d29af3", + "RCX": "0x8a6789f27404b890", + "RDX": "0x00f658ab78236612" + } +} +%endif + +lea rdx, [rel .data] +mov rsi, 0xe0000000 + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +mov rax, 0 +mov [rsi + 8 * 0], rax + +extractps eax, xmm1, 0 +extractps ebx, xmm2, 0xFF +extractps [rsi + 8 * 0 + 0], xmm3, 2 +extractps [rsi + 8 * 0 + 4], xmm4, 0xFF +extractps [rsi + 8 * 1 + 0], xmm5, 4 +extractps [rsi + 8 * 1 + 4], xmm6, 5 +mov rcx, [rsi + 8 * 0] +mov rdx, [rsi + 8 * 1] + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 diff --git a/unittests/ASM/H0F3A/66_20.asm b/unittests/ASM/H0F3A/66_20.asm new file mode 100644 index 000000000..f1a13c899 --- /dev/null +++ b/unittests/ASM/H0F3A/66_20.asm @@ -0,0 +1,73 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x48510f254d2fa47f", "0x2b5774313a974886"], + "XMM2": ["0x006b6b6b6b6b6b6b", "0x6b00000000000000"] + } +} +%endif + +lea rdx, [rel .data] +mov rsi, 0xe0000000 + +mov rax, 0 +mov [rsi + 8 * 0], rax +mov [rsi + 8 * 1], rax + +movaps xmm1, [rsi + 16 * 0] +movaps xmm2, [rsi + 16 * 0] +movaps xmm3, [rsi + 16 * 0] +movaps xmm4, [rsi + 16 * 0] +movaps xmm5, [rsi + 16 * 0] +movaps xmm6, [rsi + 16 * 0] +movaps xmm7, [rsi + 16 * 0] +movaps xmm8, [rsi + 16 * 0] + +pinsrb xmm1, [rdx + 8 * 0 + 0], 0x00 +pinsrb xmm1, [rdx + 8 * 0 + 1], 0x01 +pinsrb xmm1, [rdx + 8 * 0 + 2], 0x02 +pinsrb xmm1, [rdx + 8 * 0 + 3], 0x03 +pinsrb xmm1, [rdx + 8 * 0 + 4], 0x04 +pinsrb xmm1, [rdx + 8 * 0 + 5], 0x05 +pinsrb xmm1, [rdx + 8 * 0 + 6], 0x06 +pinsrb xmm1, [rdx + 8 * 0 + 7], 0x07 +pinsrb xmm1, [rdx + 8 * 1 + 0], 0x08 +pinsrb xmm1, [rdx + 8 * 1 + 1], 0x09 +pinsrb xmm1, [rdx + 8 * 1 + 2], 0x0A +pinsrb xmm1, [rdx + 8 * 1 + 3], 0x0B +pinsrb xmm1, [rdx + 8 * 1 + 4], 0x0C +pinsrb xmm1, [rdx + 8 * 1 + 5], 0x0D +pinsrb xmm1, [rdx + 8 * 1 + 6], 0x0E +pinsrb xmm1, [rdx + 8 * 1 + 7], 0x0F +pinsrb xmm2, [rdx + 8 * 2 + 0], 0xFF +mov rax, [rdx + 8 * 2 + 0] + +pinsrb xmm2, eax, 0x00 +pinsrb xmm2, eax, 0x01 +pinsrb xmm2, eax, 0x02 +pinsrb xmm2, eax, 0x03 +pinsrb xmm2, eax, 0x04 +pinsrb xmm2, eax, 0x05 +pinsrb xmm2, eax, 0x06 + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 diff --git a/unittests/ASM/H0F3A/66_20_1.asm b/unittests/ASM/H0F3A/66_20_1.asm new file mode 100644 index 000000000..c0f533b95 --- /dev/null +++ b/unittests/ASM/H0F3A/66_20_1.asm @@ -0,0 +1,23 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0xFFFFFFFFFFFF42FF", "0xFFFFFFFFFFFFFFFF"] + } +} +%endif + +mov rsi, 0xe0000000 + +mov rax, -1 +mov [rsi + 8 * 0], rax +mov [rsi + 8 * 1], rax + +movaps xmm0, [rsi + 16 * 0] + +mov rcx, 0 +mov edi, 0x42 +; This tests a frontend decoder bug in FEX +; FEX thought this was ch +pinsrb xmm0, edi, 0x01 + +hlt diff --git a/unittests/ASM/H0F3A/66_22.asm b/unittests/ASM/H0F3A/66_22.asm new file mode 100644 index 000000000..63cef371c --- /dev/null +++ b/unittests/ASM/H0F3A/66_22.asm @@ -0,0 +1,59 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x48510f254d2fa47f", "0x2b5774314d2fa47f"], + "XMM2": ["0x0000000000000000", "0x1f6de86b00000000"], + "XMM3": ["0x1f6de86b1f6de86b", "0x1f6de86b1f6de86b"] + } +} +%endif + +lea rdx, [rel .data] +mov rsi, 0xe0000000 + +mov rax, 0 +mov [rsi + 8 * 0], rax +mov [rsi + 8 * 1], rax + +movaps xmm1, [rsi + 16 * 0] +movaps xmm2, [rsi + 16 * 0] +movaps xmm3, [rsi + 16 * 0] +movaps xmm4, [rsi + 16 * 0] +movaps xmm5, [rsi + 16 * 0] +movaps xmm6, [rsi + 16 * 0] +movaps xmm7, [rsi + 16 * 0] +movaps xmm8, [rsi + 16 * 0] + +pinsrd xmm1, [rdx + 8 * 0 + 0], 0x00 +pinsrd xmm1, [rdx + 8 * 0 + 4], 0x01 +pinsrd xmm1, [rdx + 8 * 0 + 0], 0x02 +pinsrd xmm1, [rdx + 8 * 1 + 4], 0x03 +pinsrd xmm2, [rdx + 8 * 2 + 0], 0xFF +mov rax, [rdx + 8 * 2 + 0] + +pinsrd xmm3, eax, 0x00 +pinsrd xmm3, eax, 0x01 +pinsrd xmm3, eax, 0x02 +pinsrd xmm3, eax, 0x03 + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 diff --git a/unittests/ASM/H0F3A/66_22_1.asm b/unittests/ASM/H0F3A/66_22_1.asm new file mode 100644 index 000000000..036377ff5 --- /dev/null +++ b/unittests/ASM/H0F3A/66_22_1.asm @@ -0,0 +1,55 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x48510f254d2fa47f", "0x2b5774313a974886"], + "XMM2": ["0x0000000000000000", "0xb615b9533de8ad09"], + "XMM3": ["0x30b556de1f6de86b", "0x30b556de1f6de86b"] + } +} +%endif + +lea rdx, [rel .data] +mov rsi, 0xe0000000 + +mov rax, 0 +mov [rsi + 8 * 0], rax +mov [rsi + 8 * 1], rax + +movaps xmm1, [rsi + 16 * 0] +movaps xmm2, [rsi + 16 * 0] +movaps xmm3, [rsi + 16 * 0] +movaps xmm4, [rsi + 16 * 0] +movaps xmm5, [rsi + 16 * 0] +movaps xmm6, [rsi + 16 * 0] +movaps xmm7, [rsi + 16 * 0] +movaps xmm8, [rsi + 16 * 0] + +pinsrq xmm1, [rdx + 8 * 0], 0x00 +pinsrq xmm1, [rdx + 8 * 1], 0x01 +pinsrq xmm2, [rdx + 8 * 4], 0xFF +mov rax, [rdx + 8 * 2 + 0] + +pinsrq xmm3, rax, 0x00 +pinsrq xmm3, rax, 0x01 + +hlt + +align 16 +; 256bytes of random data +.data: +db 0x7f, 0xa4, 0x2f, 0x4d, 0x25, 0x0f, 0x51, 0x48, 0x86, 0x48, 0x97, 0x3a, 0x31, 0x74, 0x57, 0x2b +db 0x6b, 0xe8, 0x6d, 0x1f, 0xde, 0x56, 0xb5, 0x30, 0x2c, 0x76, 0xae, 0x30, 0xf3, 0x9a, 0xd2, 0x67 +db 0x09, 0xad, 0xe8, 0x3d, 0x53, 0xb9, 0x15, 0xb6, 0x90, 0xb8, 0x04, 0x74, 0xa3, 0x72, 0x64, 0xb7 +db 0xad, 0x10, 0xf1, 0x72, 0x4c, 0x6b, 0x42, 0x24, 0x67, 0xa5, 0x15, 0xd4, 0xf2, 0x89, 0x67, 0x8a +db 0x12, 0x66, 0x23, 0x78, 0x81, 0xf8, 0x96, 0x89, 0xa9, 0xa2, 0x3c, 0x3d, 0x82, 0x6b, 0xa2, 0x19 +db 0xb0, 0x12, 0x97, 0x68, 0xab, 0x58, 0xf6, 0x00, 0x72, 0x19, 0xd2, 0x1e, 0x03, 0x9d, 0x7d, 0xc9 +db 0xc8, 0x55, 0xdf, 0x98, 0x22, 0x43, 0x86, 0x1c, 0xcc, 0xe9, 0x1b, 0x89, 0xda, 0xfe, 0x9b, 0xb2 +db 0x47, 0x21, 0x0f, 0x71, 0x28, 0xbd, 0xb0, 0x88, 0x38, 0xac, 0xb5, 0x7f, 0x88, 0x5e, 0xe9, 0xc4 +db 0xe4, 0x5b, 0x3e, 0xd0, 0x2a, 0x8c, 0xdf, 0xa7, 0xea, 0x95, 0xd3, 0xc2, 0xee, 0xd1, 0x70, 0x6c +db 0x18, 0x77, 0xc1, 0x38, 0x7b, 0xfc, 0xa9, 0x58, 0x92, 0xe8, 0xc6, 0xcd, 0x07, 0x5d, 0x3d, 0x76 +db 0xf4, 0x4c, 0x5b, 0x25, 0x7f, 0x9b, 0x02, 0x41, 0x78, 0x39, 0x9e, 0x3e, 0x4c, 0xa2, 0x79, 0xca +db 0x1c, 0xe9, 0xf2, 0x9a, 0xaf, 0x6d, 0xfa, 0x57, 0x10, 0xc7, 0xfd, 0x5f, 0x20, 0x80, 0xf5, 0x65 +db 0x3c, 0x77, 0xfb, 0xa8, 0xdf, 0x94, 0x16, 0x4f, 0xc0, 0x78, 0x00, 0x76, 0x03, 0x8c, 0x82, 0x10 +db 0x7f, 0x07, 0xe0, 0x02, 0x92, 0xbb, 0xf9, 0x2e, 0xfa, 0x3d, 0x88, 0xc8, 0x24, 0x27, 0xa6, 0x1e +db 0x04, 0x90, 0xf6, 0xf8, 0x76, 0x0a, 0x4c, 0x94, 0xbc, 0xb7, 0x8d, 0x8b, 0xf9, 0x65, 0xf5, 0x07 +db 0x7f, 0xc1, 0x37, 0x78, 0xa1, 0x1f, 0xc4, 0x10, 0x6c, 0x29, 0x5e, 0x7e, 0x32, 0x24, 0x92, 0x09 diff --git a/unittests/ASM/H0F3A/66_40.asm b/unittests/ASM/H0F3A/66_40.asm new file mode 100644 index 000000000..f32d40014 --- /dev/null +++ b/unittests/ASM/H0F3A/66_40.asm @@ -0,0 +1,41 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x492feb2e492feb2e", "0x492feb2e492feb2e"], + "XMM2": ["0x499a5226499a5226", "0x499a5226499a5226"], + "XMM3": ["0x494ecfa4494ecfa4", "0x494ecfa4494ecfa4"], + "XMM4": ["0x495f7816495f7816", "0x495f7816495f7816"], + "XMM5": ["0x496e3962496e3962", "0x496e3962496e3962"], + "XMM6": ["0", "0"], + "XMM7": ["0", "0"], + "XMM8": ["0", "0"] + } +} +%endif + +lea rdx, [rel .data] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +dpps xmm1, [rdx + 16 * 8], 11111111b +dpps xmm2, [rdx + 16 * 9], 11111111b +dpps xmm3, [rdx + 16 * 10], 11111111b +dpps xmm4, [rdx + 16 * 11], 11111111b +dpps xmm5, [rdx + 16 * 12], 11111111b +dpps xmm6, [rdx + 16 * 13], 00000000b +dpps xmm7, [rdx + 16 * 14], 11110000b +dpps xmm8, [rdx + 16 * 15], 00001111b + +hlt + +align 16 +; 256bytes of random data +.data: +dd 655.9708,532.2244,108.0451,512.4019,754.227,586.0859,127.7574,114.8167,764.4266,226.6145,337.864,320.3296,296.5247,480.0057,28.4267,565.9418,265.8255,536.4473,754.3489,460.681,818.7269,43.7204,464.592,847.9381,306.0592,702.7584,887.6473,551.5908,620.9001,520.9829,232.9532,510.3388,204.8474,225.626,564.973,790.5175,836.1953,844.5266,633.5626,501.7409,393.2616,674.4415,244.3265,971.1598,770.8029,746.1836,255.9902,567.7578,187.7175,924.181,466.4362,169.8267,651.7481,462.4206,396.6924,355.8538,6.148,523.1443,989.7004,713.6646,497.5427,657.6965,651.0534,778.5236 diff --git a/unittests/ASM/H0F3A/66_41.asm b/unittests/ASM/H0F3A/66_41.asm new file mode 100644 index 000000000..8a79f6b65 --- /dev/null +++ b/unittests/ASM/H0F3A/66_41.asm @@ -0,0 +1,41 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x41278c496c911a6e", "0x41278c496c911a6e"], + "XMM2": ["0x41235ccc64afb361", "0x41235ccc64afb361"], + "XMM3": ["0x412bace273945dc5", "0x412bace273945dc5"], + "XMM4": ["0x412cf22ef582fd76", "0x412cf22ef582fd76"], + "XMM5": ["0x4121c80e40f3bc7b", "0x4121c80e40f3bc7b"], + "XMM6": ["0", "0"], + "XMM7": ["0", "0"], + "XMM8": ["0", "0"] + } +} +%endif + +lea rdx, [rel .data] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +dppd xmm1, [rdx + 16 * 8], 11111111b +dppd xmm2, [rdx + 16 * 9], 11111111b +dppd xmm3, [rdx + 16 * 10], 11111111b +dppd xmm4, [rdx + 16 * 11], 11111111b +dppd xmm5, [rdx + 16 * 12], 11111111b +dppd xmm6, [rdx + 16 * 13], 00000000b +dppd xmm7, [rdx + 16 * 14], 11110000b +dppd xmm8, [rdx + 16 * 15], 00001111b + +hlt + +align 16 +; 256bytes of random data +.data: +dq 470.4127,683.87,711.3545,511.5631,996.8793,548.682,588.9345,832.5925,210.6613,792.6059,298.4494,154.4895,818.4,881.6027,705.3087,687.478,737.0665,621.31,755.3097,189.9614,552.4284,649.1206,798.252,574.5732,593.7565,577.3129,383.3844,443.3476,414.3571,615.1567,94.898,438.3107 diff --git a/unittests/ASM/H0F3A/66_42.asm b/unittests/ASM/H0F3A/66_42.asm new file mode 100644 index 000000000..59cc89b60 --- /dev/null +++ b/unittests/ASM/H0F3A/66_42.asm @@ -0,0 +1,57 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM1": ["0x01d700f201dd018b", "0x021b012d00ec015b"], + "XMM2": ["0x021b01ea0147019c", "0x017900fb00d801d9"], + "XMM3": ["0x010500e801000153", "0x011a015f01530171"], + "XMM4": ["0x019c0124018f014d", "0x011f0100011e0116"], + "XMM5": ["0x0136007e009d01e0", "0x02a802c80245019d"], + "XMM6": ["0x009f0115017b0132", "0x013c01af01f90179"], + "XMM7": ["0x0077012b011900e8", "0x00bc016e019e0146"], + "XMM8": ["0x0100011c010300d5", "0x00f3014a016700cd"] + } +} +%endif + +lea rdx, [rel .data] + +movaps xmm1, [rdx + 16 * 0] +movaps xmm2, [rdx + 16 * 1] +movaps xmm3, [rdx + 16 * 2] +movaps xmm4, [rdx + 16 * 3] +movaps xmm5, [rdx + 16 * 4] +movaps xmm6, [rdx + 16 * 5] +movaps xmm7, [rdx + 16 * 6] +movaps xmm8, [rdx + 16 * 7] + +mpsadbw xmm1, [rdx + 16 * 8], 000b +mpsadbw xmm2, [rdx + 16 * 9], 001b +mpsadbw xmm3, [rdx + 16 * 10], 010b +mpsadbw xmm4, [rdx + 16 * 11], 011b +mpsadbw xmm5, [rdx + 16 * 12], 100b +mpsadbw xmm6, [rdx + 16 * 13], 101b +mpsadbw xmm7, [rdx + 16 * 14], 110b +mpsadbw xmm8, [rdx + 16 * 15], 111b + +hlt + +align 16 +; 256bytes of random data +.data: +db 0xe0, 0xfc, 0x2b, 0xa1, 0x06, 0x4f, 0x6c, 0xa7, 0x0f, 0x06, 0x6a, 0x1e, 0x7f, 0x76, 0x80, 0x9b +db 0xe0, 0x56, 0xed, 0xaa, 0xf3, 0xc3, 0x68, 0x68, 0xde, 0xe6, 0xe6, 0x94, 0xe2, 0xe9, 0xfc, 0xf0 +db 0x6e, 0x35, 0xa8, 0x54, 0xd7, 0xab, 0x8b, 0x6c, 0x77, 0x5f, 0x92, 0xca, 0x25, 0xa6, 0x7e, 0x27 +db 0xc7, 0xcd, 0x73, 0xec, 0x95, 0xd6, 0x6f, 0x6a, 0xbb, 0xae, 0xf2, 0xbb, 0x27, 0xb9, 0xa1, 0xdd +db 0x73, 0x4d, 0xd1, 0xc7, 0xd5, 0x2c, 0x31, 0x88, 0xfe, 0xe7, 0xdb, 0xfd, 0x1e, 0x1e, 0x09, 0x7f +db 0x14, 0xfa, 0x4e, 0x95, 0xef, 0xe6, 0x9a, 0xf2, 0xa0, 0x42, 0x62, 0x9a, 0xa4, 0xa8, 0x73, 0x82 +db 0x0e, 0x0f, 0x16, 0x82, 0x38, 0x07, 0x12, 0x32, 0x07, 0x35, 0x92, 0xc1, 0x63, 0x07, 0x78, 0xb3 +db 0xcb, 0x46, 0x19, 0x57, 0x2b, 0x37, 0x2a, 0x46, 0x1f, 0x04, 0x0e, 0x79, 0x3d, 0xcd, 0x8d, 0xa3 +db 0x2b, 0xf3, 0x86, 0x2f, 0xab, 0xba, 0x57, 0x30, 0x2e, 0xd6, 0x2c, 0xf0, 0x46, 0x4f, 0x3f, 0xef +db 0xef, 0xd1, 0xbb, 0x85, 0x34, 0x4b, 0x3c, 0xde, 0x9e, 0x48, 0xa3, 0xb9, 0x8d, 0x71, 0xe3, 0x9d +db 0x09, 0x72, 0xfb, 0xde, 0x8a, 0x32, 0x50, 0x9d, 0x69, 0x98, 0xf1, 0xf6, 0x52, 0xeb, 0xf7, 0xee +db 0xd6, 0x99, 0xc2, 0xff, 0x30, 0x1c, 0x02, 0xce, 0x70, 0x05, 0xb2, 0xf1, 0x56, 0x9c, 0x0e, 0xa6 +db 0x18, 0x62, 0xc4, 0xe2, 0x86, 0x38, 0x76, 0x30, 0x2f, 0xa1, 0xe4, 0xa7, 0x0e, 0x5d, 0x53, 0xeb +db 0x14, 0x45, 0xe0, 0xb7, 0xe1, 0xe8, 0x02, 0x68, 0x1a, 0xfe, 0x8e, 0xc1, 0x8f, 0xf2, 0xeb, 0x46 +db 0x7f, 0x5d, 0x6a, 0x23, 0x46, 0x97, 0x2e, 0x03, 0x98, 0x12, 0x32, 0x8f, 0x54, 0x76, 0x59, 0xac +db 0xc8, 0x76, 0x5f, 0xc8, 0x71, 0x0c, 0xd3, 0xb6, 0xc5, 0x19, 0xea, 0xab, 0xa6, 0x2c, 0x1d, 0x88 + diff --git a/unittests/gcc-target-tests-32/Disabled_Tests b/unittests/gcc-target-tests-32/Disabled_Tests index 69e6d98fb..9459e6580 100644 --- a/unittests/gcc-target-tests-32/Disabled_Tests +++ b/unittests/gcc-target-tests-32/Disabled_Tests @@ -3,3 +3,15 @@ pr57275.c.gcc-target-test-64 # Consistently crashes on Solidrun only in CI 20080723-1.c.gcc-target-test-32 + +# These tests fail because of things unrelated to the sse4.1 instructions +sse4_1-ceil-sfix-vec.c.gcc-target-test-32 +sse4_1-ceilf-sfix-vec.c.gcc-target-test-32 +sse4_1-floor-sfix-vec.c.gcc-target-test-32 +sse4_1-floorf-sfix-vec.c.gcc-target-test-32 +sse4_1-rint-sfix-vec.c.gcc-target-test-32 +sse4_1-rintf-sfix-vec.c.gcc-target-test-32 +sse4_1-round-sfix-vec.c.gcc-target-test-32 +sse4_1-roundf-sfix-vec.c.gcc-target-test-32 +sse4_1-rint-vec.c.gcc-target-test-32 +sse4_1-roundf-vec.c.gcc-target-test-32 diff --git a/unittests/gcc-target-tests-32/Known_Failures b/unittests/gcc-target-tests-32/Known_Failures index 7359ccf33..797932e9d 100644 --- a/unittests/gcc-target-tests-32/Known_Failures +++ b/unittests/gcc-target-tests-32/Known_Failures @@ -7,3 +7,15 @@ pr57275.c.gcc-target-test-32 # Consistently crashes on Solidrun only in CI 20080723-1.c.gcc-target-test-32 + +# These tests fail because of things unrelated to the sse4.1 instructions +sse4_1-ceil-sfix-vec.c.gcc-target-test-32 +sse4_1-ceilf-sfix-vec.c.gcc-target-test-32 +sse4_1-floor-sfix-vec.c.gcc-target-test-32 +sse4_1-floorf-sfix-vec.c.gcc-target-test-32 +sse4_1-rint-sfix-vec.c.gcc-target-test-32 +sse4_1-rintf-sfix-vec.c.gcc-target-test-32 +sse4_1-round-sfix-vec.c.gcc-target-test-32 +sse4_1-roundf-sfix-vec.c.gcc-target-test-32 +sse4_1-rint-vec.c.gcc-target-test-32 +sse4_1-roundf-vec.c.gcc-target-test-32 diff --git a/unittests/gcc-target-tests-64/Disabled_Tests b/unittests/gcc-target-tests-64/Disabled_Tests index 2f33b3dd9..a82e9b6b3 100644 --- a/unittests/gcc-target-tests-64/Disabled_Tests +++ b/unittests/gcc-target-tests-64/Disabled_Tests @@ -30,3 +30,13 @@ pr88240.c.gcc-target-test-64 # This relies on SIGPROF which means we need real signal support to handle this # Crashes or hangs depending on which runner is running it mcount_pic.c.gcc-target-test-64 + +# These tests fail because of things unrelated to the sse4.1 instructions +sse4_1-ceil-sfix-vec.c.gcc-target-test-64 +sse4_1-ceilf-sfix-vec.c.gcc-target-test-64 +sse4_1-floor-sfix-vec.c.gcc-target-test-64 +sse4_1-floorf-sfix-vec.c.gcc-target-test-64 +sse4_1-rint-sfix-vec.c.gcc-target-test-64 +sse4_1-rintf-sfix-vec.c.gcc-target-test-64 +sse4_1-round-sfix-vec.c.gcc-target-test-64 +sse4_1-roundf-sfix-vec.c.gcc-target-test-64 diff --git a/unittests/gcc-target-tests-64/Known_Failures b/unittests/gcc-target-tests-64/Known_Failures index 2f33b3dd9..a82e9b6b3 100644 --- a/unittests/gcc-target-tests-64/Known_Failures +++ b/unittests/gcc-target-tests-64/Known_Failures @@ -30,3 +30,13 @@ pr88240.c.gcc-target-test-64 # This relies on SIGPROF which means we need real signal support to handle this # Crashes or hangs depending on which runner is running it mcount_pic.c.gcc-target-test-64 + +# These tests fail because of things unrelated to the sse4.1 instructions +sse4_1-ceil-sfix-vec.c.gcc-target-test-64 +sse4_1-ceilf-sfix-vec.c.gcc-target-test-64 +sse4_1-floor-sfix-vec.c.gcc-target-test-64 +sse4_1-floorf-sfix-vec.c.gcc-target-test-64 +sse4_1-rint-sfix-vec.c.gcc-target-test-64 +sse4_1-rintf-sfix-vec.c.gcc-target-test-64 +sse4_1-round-sfix-vec.c.gcc-target-test-64 +sse4_1-roundf-sfix-vec.c.gcc-target-test-64