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}