RSP: get it to use asm jit lite

This commit is contained in:
zilmar 2025-05-01 22:22:19 +09:30
parent 6ba97eb4eb
commit fbbf7c7837
7 changed files with 160 additions and 19 deletions

View File

@ -45,12 +45,12 @@
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\3rdParty\asmjit\asmjit.vcxproj">
<Project>{a72c9f08-ebb4-443d-9982-da21ae8b367d}</Project>
</ProjectReference>
<ProjectReference Include="..\..\3rdParty\zlib\zlib.vcxproj">
<Project>{731bd205-2826-4631-b7af-117658e88dbc}</Project>
</ProjectReference>
<ProjectReference Include="..\..\AsmJitLite\AsmJitLite.vcxproj">
<Project>{236a7004-8169-4528-b829-7726737ffcf2}</Project>
</ProjectReference>
<ProjectReference Include="..\..\Common\Common.vcxproj">
<Project>{b4a4b994-9111-42b1-93c2-6f1ca8bc4421}</Project>
</ProjectReference>

View File

@ -1,4 +1,10 @@
#pragma once
// This file is part of AsmJit project <https://asmjit.com>
//
// See asmjit.h or LICENSE.md for license and copyright information
// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_SUPPORT_H_INCLUDED
#define ASMJIT_CORE_SUPPORT_H_INCLUDED
#include "../core/globals.h"
@ -368,6 +374,21 @@ static constexpr bool isInt32(T x) noexcept {
: sizeof(T) <= 2 || U(x) <= U(2147483647u);
}
//! Checks whether the given integer `x` can be casted to a 32-bit unsigned integer.
template<typename T>
static constexpr bool isUInt32(T x) noexcept {
typedef typename std::make_unsigned<T>::type U;
return std::is_signed<T>::value ? (sizeof(T) <= 4 || T(x) <= T(4294967295u)) && x >= T(0)
: (sizeof(T) <= 4 || U(x) <= U(4294967295u));
}
//! Checks whether the given integer `x` can be casted to a 32-bit unsigned integer.
template<typename T>
static constexpr bool isIntOrUInt32(T x) noexcept {
return sizeof(T) <= 4 ? true : (uint32_t(uint64_t(x) >> 32) + 1u) <= 1u;
}
static bool inline isEncodableOffset32(int32_t offset, uint32_t nBits) noexcept {
uint32_t nRev = 32 - nBits;
return Support::sar(Support::shl(offset, nRev), nRev) == offset;
@ -703,3 +724,5 @@ struct Temporary {
//! \}
ASMJIT_END_NAMESPACE
#endif // ASMJIT_CORE_SUPPORT_H_INCLUDED

View File

@ -118,9 +118,38 @@ template<>
Error EmitterExplicitT<Assembler>::add(Gp const & o0, Imm const & o1)
{
X86BufferWriter writer(_emitter);
int32_t immValue = (uint32_t)o1.value();
if (o0.size() == 8)
{
int64_t immValue = o1.value();
if (!Support::isInt32(immValue))
{
__debugbreak();
return kErrorInvalidRegType;
}
if ((o0.id() & ~7) != 0)
{
__debugbreak();
return kErrorInvalidRegType;
}
CPU_Message("add %s, 0x%X", x86_Name(o0), (uint32_t)immValue);
writer.emit8(0x48);
if (Support::isInt8(immValue))
{
writer.emit8(0x83);
writer.emit8(0xC0 + (o0.id() & 7));
writer.emit8((uint8_t)immValue);
}
else
{
writer.emit8(0x81);
writer.emit8(0xC0 + (o0.id() & 7));
writer.emit32(immValue);
}
return kErrorOk;
}
if (o0.size() == 4)
{
int32_t immValue = (uint32_t)o1.value();
CPU_Message("add %s, 0x%X", x86_Name(o0), immValue);
if (Support::isInt8(immValue))
{
@ -221,6 +250,25 @@ Error EmitterExplicitT<Assembler>::and_(Mem const & o0, Imm const & o1)
return kErrorInvalidRegType;
}
Error EmitterExplicitT<Assembler>::call(Gp const & o0)
{
X86BufferWriter writer(_emitter);
if (o0.size() == 8)
{
if ((o0.id() & ~7) != 0)
{
__debugbreak();
return kErrorInvalidRegType;
}
CPU_Message("call %s", x86_Name(o0));
writer.emit8(0xFF);
writer.emit8(0xD0 + (o0.id() & 7));
return kErrorOk;
}
__debugbreak();
return 0;
}
Error EmitterExplicitT<Assembler>::call(Mem const & /*o0*/)
{
__debugbreak();
@ -586,6 +634,17 @@ Error EmitterExplicitT<Assembler>::lea(Gp const & o0, Mem const & o1)
Error EmitterExplicitT<Assembler>::mov(Gp const & o0, Gp const & o1)
{
X86BufferWriter writer(_emitter);
if (o0.size() == 8 && o1.size() == 8)
{
if ((o0.id() & ~7) != 0 || (o1.id() & ~7) != 0)
{
__debugbreak();
return kErrorInvalidRegType;
}
writer.emit8(0x48);
writer.emit16(0xC089 + ((o0.id() & 7) << 8) + ((o1.id() & 7) << 11));
return kErrorOk;
}
if (o0.size() == 4 && o1.size() == 4)
{
CPU_Message("mov %s, %s", x86_Name(o0), x86_Name(o1));
@ -641,11 +700,26 @@ Error EmitterExplicitT<Assembler>::mov(Gp const & o0, Mem const & o1)
Error EmitterExplicitT<Assembler>::mov(Gp const & o0, Imm const & o1)
{
X86BufferWriter writer(_emitter);
int32_t immValue = (uint32_t)o1.value();
CPU_Message("mov %s, %Xh", x86_Name(o0), immValue);
if (o0.size() == 8)
{
int64_t immValue = o1.value();
if (Support::isInt32(immValue))
{
CPU_Message("mov %s, %Xh", x86_Name(o0), (uint32_t)immValue);
writer.emit8(0x48 | ((o0.id() & 0x08) >> 3));
writer.emit16(0xC0C7 | ((o0.id() & 7) << 8));
writer.emit32((uint32_t)immValue);
return kErrorOk;
}
__debugbreak();
return kErrorInvalidRegType;
}
if (o0.size() == 4)
{
int32_t immValue = (uint32_t)o1.value();
CPU_Message("mov %s, %Xh", x86_Name(o0), immValue);
if (Support::isInt8(immValue))
{
__debugbreak();
@ -804,8 +878,19 @@ Error EmitterExplicitT<Assembler>::or_(Mem const & /*o0*/, Imm const & /*o1*/)
Error EmitterExplicitT<Assembler>::pop(Gp const & o0)
{
CPU_Message("pop %s", x86_Name(o0));
X86BufferWriter writer(_emitter);
CPU_Message("pop %s", x86_Name(o0));
if (o0.size() == 8)
{
if ((o0.id() & ~7) != 0)
{
__debugbreak();
return kErrorInvalidRegType;
}
writer.emit8(0x58 | (o0.id() & 7));
return kErrorOk;
}
if (o0.size() == 4)
{
@ -831,7 +916,12 @@ Error EmitterExplicitT<Assembler>::push(Gp const & o0)
if (o0.size() == 4 || o0.size() == 8)
{
writer.emit8(0x50 | o0.id());
if ((o0.id() & ~7) != 0)
{
__debugbreak();
return kErrorInvalidRegType;
}
writer.emit8(0x50 | (o0.id() & 7));
return kErrorOk;
}
__debugbreak();
@ -1047,10 +1137,38 @@ Error EmitterExplicitT<Assembler>::sub(Gp const & /*o0*/, Mem const & /*o0*/)
return 0;
}
Error EmitterExplicitT<Assembler>::sub(Gp const & /*o0*/, Imm const & /*o1*/)
Error EmitterExplicitT<Assembler>::sub(Gp const & o0, Imm const & o1)
{
X86BufferWriter writer(_emitter);
if (o0.size() == 8)
{
int64_t immValue = o1.value();
if (!Support::isInt32(immValue))
{
__debugbreak();
return kErrorInvalidRegType;
}
if ((o0.id() & ~7) != 0)
{
__debugbreak();
return kErrorInvalidRegType;
}
CPU_Message("sub %s, 0x%X", x86_Name(o0), (uint32_t)immValue);
writer.emit8(0x48);
if (Support::isInt8(immValue))
{
writer.emit16(0xE883 | ((o0.id() & 7) << 8));
writer.emit8((uint8_t)immValue);
}
else
{
writer.emit16(0xE881 | ((o0.id() & 7) << 8));
writer.emit32((uint32_t)immValue);
}
return kErrorOk;
}
__debugbreak();
return 0;
return kErrorInvalidRegType;
}
Error EmitterExplicitT<Assembler>::sub(Mem const & o0, Imm const & o1)

View File

@ -59,9 +59,10 @@ void * CRSPRecompiler::CompileHLETask(uint32_t Address)
m_CodeHolder.reset();
m_CodeHolder.init(m_Environment);
m_CodeHolder.setErrorHandler(this);
m_CodeHolder.setLogger(nullptr);
m_CodeHolder.setLogger(LogAsmCode ? nullptr : nullptr);
m_Assembler = new RspAssembler(&m_CodeHolder, m_CodeLog);
m_Assembler->setLogger(LogAsmCode ? m_Assembler : nullptr);
m_Assembler->push(asmjit::x86::rbp);
m_Assembler->mov(asmjit::x86::rbp, asmjit::x86::rsp);
m_Assembler->sub(asmjit::x86::rsp, 0x30);
@ -69,8 +70,8 @@ void * CRSPRecompiler::CompileHLETask(uint32_t Address)
m_Assembler->mov(asmjit::x86::rax, asmjit::imm(AddressOf(&StartTimer)));
m_Assembler->call(asmjit::x86::rax);
m_Assembler->mov(asmjit::x86::rcx, asmjit::imm((uintptr_t)&m_System));
m_Assembler->mov(asmjit::x86::edx, asmjit::imm(0x10000));
m_Assembler->mov(asmjit::x86::r8d, asmjit::imm(0x118));
m_Assembler->mov(asmjit::x86::rdx, asmjit::imm(0x10000));
m_Assembler->mov(asmjit::x86::r8, asmjit::imm(0x118));
m_Assembler->mov(asmjit::x86::rax, asmjit::imm(AddressOf(&CRSPSystem::ExecuteOps)));
m_Assembler->call(asmjit::x86::rax);
m_Assembler->mov(asmjit::x86::rax, asmjit::imm(AddressOf(&StopTimer)));

View File

@ -1,7 +1,7 @@
#pragma once
#if defined(__amd64__) || defined(_M_X64)
//#define USE_ASMJITLITE
#define USE_ASMJITLITE
#endif
#ifdef USE_ASMJITLITE

View File

@ -139,7 +139,6 @@ public:
RSPFlag VCE;
};
#if defined(__i386__) || defined(_M_IX86)
extern const char * x86_Strings[8];
#define x86_Name(Reg) (x86_Strings[(Reg)])

View File

@ -58,12 +58,12 @@
<ClInclude Include="Rsp.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\3rdParty\asmjit\asmjit.vcxproj">
<Project>{a72c9f08-ebb4-443d-9982-da21ae8b367d}</Project>
</ProjectReference>
<ProjectReference Include="..\3rdParty\zlib\zlib.vcxproj">
<Project>{731bd205-2826-4631-b7af-117658e88dbc}</Project>
</ProjectReference>
<ProjectReference Include="..\AsmJitLite\AsmJitLite.vcxproj">
<Project>{236a7004-8169-4528-b829-7726737ffcf2}</Project>
</ProjectReference>
<ProjectReference Include="..\Common\Common.vcxproj">
<Project>{b4a4b994-9111-42b1-93c2-6f1ca8bc4421}</Project>
</ProjectReference>