[dynarmic] jit fix branch v2 (#203)

Co-authored-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/203
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
This commit is contained in:
crueter 2025-08-27 06:49:50 +02:00
parent c9a3baab5d
commit 21cd44ec04
No known key found for this signature in database
GPG key ID: 425ACD2D4830EBC6
67 changed files with 1214 additions and 876 deletions

View file

@ -0,0 +1,64 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <catch2/catch_test_macros.hpp>
#include <oaknut/oaknut.hpp>
#include <immintrin.h>
#include "../A64/testenv.h"
#include "dynarmic/common/fp/fpsr.h"
#include "dynarmic/interface/exclusive_monitor.h"
using namespace Dynarmic;
using namespace oaknut::util;
TEST_CASE("X86: Preserve XMM regs", "[x86]") {
A64TestEnv env;
A64::UserConfig jit_user_config{};
jit_user_config.callbacks = &env;
A64::Jit jit{jit_user_config};
oaknut::VectorCodeGenerator code{env.code_mem, nullptr};
code.SMINP(V2.S2(), V0.S2(), V1.S2());
code.UMINP(V3.S2(), V0.S2(), V1.S2());
code.SMINP(V4.S4(), V0.S4(), V1.S4());
code.UMINP(V5.S4(), V0.S4(), V1.S4());
code.SMAXP(V6.S2(), V0.S2(), V1.S2());
code.UMAXP(V7.S2(), V0.S2(), V1.S2());
code.SMAXP(V8.S4(), V0.S4(), V1.S4());
code.UMAXP(V9.S4(), V0.S4(), V1.S4());
constexpr std::array<Vector, 12> vectors = {
// initial input vectors [0-1]
Vector{0x00000003'00000002, 0xF1234567'01234567},
Vector{0x80000000'7FFFFFFF, 0x76543210'76543209},
// expected output vectors [2-9]
Vector{0x80000000'00000002, 0},
Vector{0x7FFFFFFF'00000002, 0},
Vector{0xF1234567'00000002, 0x76543209'80000000},
Vector{0x01234567'00000002, 0x76543209'7FFFFFFF},
Vector{0x7FFFFFFF'00000003, 0},
Vector{0x80000000'00000003, 0},
Vector{0x01234567'00000003, 0x76543210'7FFFFFFF},
Vector{0xF1234567'00000003, 0x76543210'80000000},
// input vectors with elements swapped pairwise [10-11]
Vector{0x00000002'00000003, 0x01234567'F1234567},
Vector{0x7FFFFFFF'80000000, 0x76543209'76543210},
};
jit.SetPC(0);
jit.SetVector(0, vectors[0]);
jit.SetVector(1, vectors[1]);
env.ticks_left = env.code_mem.size();
CheckedRun([&]() { jit.Run(); });
CHECK(jit.GetVector(2) == vectors[2]);
CHECK(jit.GetVector(3) == vectors[3]);
CHECK(jit.GetVector(4) == vectors[4]);
CHECK(jit.GetVector(5) == vectors[5]);
CHECK(jit.GetVector(6) == vectors[6]);
CHECK(jit.GetVector(7) == vectors[7]);
CHECK(jit.GetVector(8) == vectors[8]);
CHECK(jit.GetVector(9) == vectors[9]);
}

View file

@ -0,0 +1,50 @@
#pragma once
#include <catch2/catch_test_macros.hpp>
#ifdef __AVX__
#include <immintrin.h>
#endif
template<typename F>
void CheckedRun(F&& fn) {
#ifdef __AVX__
__m256i xmm0 = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, 0);
__m256i xmm1 = _mm256_set_epi32(1, 1, 0, 0, 0, 0, 0, 1);
__m256i xmm2 = _mm256_set_epi32(2, 2, 0, 0, 0, 0, 0, 2);
__m256i xmm3 = _mm256_set_epi32(3, 3, 0, 0, 0, 0, 0, 3);
__m256i xmm4 = _mm256_set_epi32(4, 4, 0, 0, 0, 0, 0, 4);
__m256i xmm5 = _mm256_set_epi32(4, 4, 0, 0, 0, 0, 0, 5);
__m256i xmm6 = _mm256_set_epi32(4, 4, 0, 0, 0, 0, 0, 6);
__m256i xmm7 = _mm256_set_epi32(4, 4, 0, 0, 0, 0, 0, 7);
__m256i xmm8 = _mm256_set_epi32(4, 4, 0, 0, 0, 0, 0, 8);
__m256i xmm9 = _mm256_set_epi32(4, 4, 0, 0, 0, 0, 0, 9);
__m256i xmm10 = _mm256_set_epi32(4, 4, 0, 0, 0, 0, 0, 10);
__m256i xmm11 = _mm256_set_epi32(4, 4, 0, 0, 0, 0, 0, 11);
asm volatile(""
: "+x"(xmm0), "+x"(xmm1), "+x"(xmm2), "+x"(xmm3)
, "+x"(xmm4), "+x"(xmm5), "+x"(xmm6), "+x"(xmm7)
, "+x"(xmm8), "+x"(xmm9), "+x"(xmm10), "+x"(xmm11)
:
);
fn();
asm volatile(""
: "+x"(xmm0), "+x"(xmm1), "+x"(xmm2), "+x"(xmm3)
, "+x"(xmm4), "+x"(xmm5), "+x"(xmm6), "+x"(xmm7)
, "+x"(xmm8), "+x"(xmm9), "+x"(xmm10), "+x"(xmm11)
:
);
CHECK(std::bit_cast<std::uint64_t>(xmm0[0]) == 0);
CHECK(std::bit_cast<std::uint64_t>(xmm1[0]) == 1);
CHECK(std::bit_cast<std::uint64_t>(xmm2[0]) == 2);
CHECK(std::bit_cast<std::uint64_t>(xmm3[0]) == 3);
CHECK(std::bit_cast<std::uint64_t>(xmm4[0]) == 4);
CHECK(std::bit_cast<std::uint64_t>(xmm5[0]) == 5);
CHECK(std::bit_cast<std::uint64_t>(xmm6[0]) == 6);
CHECK(std::bit_cast<std::uint64_t>(xmm7[0]) == 7);
CHECK(std::bit_cast<std::uint64_t>(xmm8[0]) == 8);
CHECK(std::bit_cast<std::uint64_t>(xmm9[0]) == 9);
CHECK(std::bit_cast<std::uint64_t>(xmm10[0]) == 10);
CHECK(std::bit_cast<std::uint64_t>(xmm11[0]) == 11);
#else
fn();
#endif
}