diff --git a/Source/Android/PluginRSP/PluginRSP.vcxproj b/Source/Android/PluginRSP/PluginRSP.vcxproj index 48c0489aa..12d432ea7 100644 --- a/Source/Android/PluginRSP/PluginRSP.vcxproj +++ b/Source/Android/PluginRSP/PluginRSP.vcxproj @@ -45,12 +45,12 @@ - - {a72c9f08-ebb4-443d-9982-da21ae8b367d} - {731bd205-2826-4631-b7af-117658e88dbc} + + {236a7004-8169-4528-b829-7726737ffcf2} + {b4a4b994-9111-42b1-93c2-6f1ca8bc4421} diff --git a/Source/AsmJitLite/core/support.h b/Source/AsmJitLite/core/support.h index c371e209d..bccd13868 100644 --- a/Source/AsmJitLite/core/support.h +++ b/Source/AsmJitLite/core/support.h @@ -1,4 +1,10 @@ -#pragma once +// This file is part of AsmJit project +// +// 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 +static constexpr bool isUInt32(T x) noexcept { + typedef typename std::make_unsigned::type U; + + return std::is_signed::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 +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 diff --git a/Source/AsmJitLite/x86/x86emitter.cpp b/Source/AsmJitLite/x86/x86emitter.cpp index e84688176..60fbf1203 100644 --- a/Source/AsmJitLite/x86/x86emitter.cpp +++ b/Source/AsmJitLite/x86/x86emitter.cpp @@ -118,9 +118,38 @@ template<> Error EmitterExplicitT::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::and_(Mem const & o0, Imm const & o1) return kErrorInvalidRegType; } +Error EmitterExplicitT::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::call(Mem const & /*o0*/) { __debugbreak(); @@ -586,6 +634,17 @@ Error EmitterExplicitT::lea(Gp const & o0, Mem const & o1) Error EmitterExplicitT::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::mov(Gp const & o0, Mem const & o1) Error EmitterExplicitT::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::or_(Mem const & /*o0*/, Imm const & /*o1*/) Error EmitterExplicitT::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::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::sub(Gp const & /*o0*/, Mem const & /*o0*/) return 0; } -Error EmitterExplicitT::sub(Gp const & /*o0*/, Imm const & /*o1*/) +Error EmitterExplicitT::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::sub(Mem const & o0, Imm const & o1) diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x64.cpp b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x64.cpp index 7ac8088b8..a89935674 100644 --- a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x64.cpp +++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x64.cpp @@ -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))); diff --git a/Source/Project64-rsp-core/Recompiler/asmjit.h b/Source/Project64-rsp-core/Recompiler/asmjit.h index 24fbed39e..6b9f9864a 100644 --- a/Source/Project64-rsp-core/Recompiler/asmjit.h +++ b/Source/Project64-rsp-core/Recompiler/asmjit.h @@ -1,7 +1,7 @@ #pragma once #if defined(__amd64__) || defined(_M_X64) -//#define USE_ASMJITLITE +#define USE_ASMJITLITE #endif #ifdef USE_ASMJITLITE diff --git a/Source/Project64-rsp/Project64-rsp.vcxproj b/Source/Project64-rsp/Project64-rsp.vcxproj index 6e410fef5..bd629c1c5 100644 --- a/Source/Project64-rsp/Project64-rsp.vcxproj +++ b/Source/Project64-rsp/Project64-rsp.vcxproj @@ -58,12 +58,12 @@ - - {a72c9f08-ebb4-443d-9982-da21ae8b367d} - {731bd205-2826-4631-b7af-117658e88dbc} + + {236a7004-8169-4528-b829-7726737ffcf2} + {b4a4b994-9111-42b1-93c2-6f1ca8bc4421}