mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-04 03:46:42 +01:00
x64Emitter: Generify ABI_CallFunction variants
Gets rid of the need to cast to void* just to use the functions.
This commit is contained in:
parent
081cad709a
commit
13506d3c12
@ -135,6 +135,7 @@
|
|||||||
<ClInclude Include="TraversalProto.h" />
|
<ClInclude Include="TraversalProto.h" />
|
||||||
<ClInclude Include="x64ABI.h" />
|
<ClInclude Include="x64ABI.h" />
|
||||||
<ClInclude Include="x64Emitter.h" />
|
<ClInclude Include="x64Emitter.h" />
|
||||||
|
<ClInclude Include="x64Reg.h" />
|
||||||
<ClInclude Include="Crypto\bn.h" />
|
<ClInclude Include="Crypto\bn.h" />
|
||||||
<ClInclude Include="Crypto\ec.h" />
|
<ClInclude Include="Crypto\ec.h" />
|
||||||
<ClInclude Include="Logging\ConsoleListener.h" />
|
<ClInclude Include="Logging\ConsoleListener.h" />
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
<ClInclude Include="Timer.h" />
|
<ClInclude Include="Timer.h" />
|
||||||
<ClInclude Include="x64ABI.h" />
|
<ClInclude Include="x64ABI.h" />
|
||||||
<ClInclude Include="x64Emitter.h" />
|
<ClInclude Include="x64Emitter.h" />
|
||||||
|
<ClInclude Include="x64Reg.h" />
|
||||||
<ClInclude Include="Logging\ConsoleListener.h">
|
<ClInclude Include="Logging\ConsoleListener.h">
|
||||||
<Filter>Logging</Filter>
|
<Filter>Logging</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -85,111 +85,6 @@ void XEmitter::ABI_PopRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignmen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common functions
|
|
||||||
void XEmitter::ABI_CallFunction(const void* func)
|
|
||||||
{
|
|
||||||
u64 distance = u64(func) - (u64(code) + 5);
|
|
||||||
if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL)
|
|
||||||
{
|
|
||||||
// Far call
|
|
||||||
MOV(64, R(RAX), Imm64((u64)func));
|
|
||||||
CALLptr(R(RAX));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CALL(func);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionC16(const void* func, u16 param1)
|
|
||||||
{
|
|
||||||
MOV(32, R(ABI_PARAM1), Imm32((u32)param1));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionCC16(const void* func, u32 param1, u16 param2)
|
|
||||||
{
|
|
||||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
|
||||||
MOV(32, R(ABI_PARAM2), Imm32((u32)param2));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionC(const void* func, u32 param1)
|
|
||||||
{
|
|
||||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionCC(const void* func, u32 param1, u32 param2)
|
|
||||||
{
|
|
||||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
|
||||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionCP(const void* func, u32 param1, void* param2)
|
|
||||||
{
|
|
||||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
|
||||||
MOV(64, R(ABI_PARAM2), Imm64((u64)param2));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionCCC(const void* func, u32 param1, u32 param2, u32 param3)
|
|
||||||
{
|
|
||||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
|
||||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
|
||||||
MOV(32, R(ABI_PARAM3), Imm32(param3));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionCCP(const void* func, u32 param1, u32 param2, void* param3)
|
|
||||||
{
|
|
||||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
|
||||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
|
||||||
MOV(64, R(ABI_PARAM3), Imm64((u64)param3));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionCCCP(const void* func, u32 param1, u32 param2, u32 param3,
|
|
||||||
void* param4)
|
|
||||||
{
|
|
||||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
|
||||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
|
||||||
MOV(32, R(ABI_PARAM3), Imm32(param3));
|
|
||||||
MOV(64, R(ABI_PARAM4), Imm64((u64)param4));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionPC(const void* func, void* param1, u32 param2)
|
|
||||||
{
|
|
||||||
MOV(64, R(ABI_PARAM1), Imm64((u64)param1));
|
|
||||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionPPC(const void* func, void* param1, void* param2, u32 param3)
|
|
||||||
{
|
|
||||||
MOV(64, R(ABI_PARAM1), Imm64((u64)param1));
|
|
||||||
MOV(64, R(ABI_PARAM2), Imm64((u64)param2));
|
|
||||||
MOV(32, R(ABI_PARAM3), Imm32(param3));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass a register as a parameter.
|
|
||||||
void XEmitter::ABI_CallFunctionR(const void* func, X64Reg reg1)
|
|
||||||
{
|
|
||||||
if (reg1 != ABI_PARAM1)
|
|
||||||
MOV(32, R(ABI_PARAM1), R(reg1));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass two registers as parameters.
|
|
||||||
void XEmitter::ABI_CallFunctionRR(const void* func, X64Reg reg1, X64Reg reg2)
|
|
||||||
{
|
|
||||||
MOVTwo(64, ABI_PARAM1, reg1, 0, ABI_PARAM2, reg2);
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::MOVTwo(int bits, Gen::X64Reg dst1, Gen::X64Reg src1, s32 offset1, Gen::X64Reg dst2,
|
void XEmitter::MOVTwo(int bits, Gen::X64Reg dst1, Gen::X64Reg src1, s32 offset1, Gen::X64Reg dst2,
|
||||||
Gen::X64Reg src2)
|
Gen::X64Reg src2)
|
||||||
{
|
{
|
||||||
@ -222,18 +117,3 @@ void XEmitter::MOVTwo(int bits, Gen::X64Reg dst1, Gen::X64Reg src1, s32 offset1,
|
|||||||
ADD(bits, R(dst1), Imm32(offset1));
|
ADD(bits, R(dst1), Imm32(offset1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionAC(int bits, const void* func, const Gen::OpArg& arg1, u32 param2)
|
|
||||||
{
|
|
||||||
if (!arg1.IsSimpleReg(ABI_PARAM1))
|
|
||||||
MOV(bits, R(ABI_PARAM1), arg1);
|
|
||||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XEmitter::ABI_CallFunctionA(int bits, const void* func, const Gen::OpArg& arg1)
|
|
||||||
{
|
|
||||||
if (!arg1.IsSimpleReg(ABI_PARAM1))
|
|
||||||
MOV(bits, R(ABI_PARAM1), arg1);
|
|
||||||
ABI_CallFunction(func);
|
|
||||||
}
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common/BitSet.h"
|
#include "Common/BitSet.h"
|
||||||
#include "Common/x64Emitter.h"
|
#include "Common/x64Reg.h"
|
||||||
|
|
||||||
// x64 ABI:s, and helpers to help follow them when JIT-ing code.
|
// x64 ABI:s, and helpers to help follow them when JIT-ing code.
|
||||||
// All convensions return values in EAX (+ possibly EDX).
|
// All convensions return values in EAX (+ possibly EDX).
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/x64Emitter.h"
|
#include "Common/x64Emitter.h"
|
||||||
|
#include "Common/x64Reg.h"
|
||||||
|
|
||||||
namespace Gen
|
namespace Gen
|
||||||
{
|
{
|
||||||
|
@ -9,101 +9,16 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/BitSet.h"
|
#include "Common/BitSet.h"
|
||||||
#include "Common/CodeBlock.h"
|
#include "Common/CodeBlock.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/x64ABI.h"
|
||||||
|
|
||||||
namespace Gen
|
namespace Gen
|
||||||
{
|
{
|
||||||
enum X64Reg
|
|
||||||
{
|
|
||||||
EAX = 0,
|
|
||||||
EBX = 3,
|
|
||||||
ECX = 1,
|
|
||||||
EDX = 2,
|
|
||||||
ESI = 6,
|
|
||||||
EDI = 7,
|
|
||||||
EBP = 5,
|
|
||||||
ESP = 4,
|
|
||||||
|
|
||||||
RAX = 0,
|
|
||||||
RBX = 3,
|
|
||||||
RCX = 1,
|
|
||||||
RDX = 2,
|
|
||||||
RSI = 6,
|
|
||||||
RDI = 7,
|
|
||||||
RBP = 5,
|
|
||||||
RSP = 4,
|
|
||||||
R8 = 8,
|
|
||||||
R9 = 9,
|
|
||||||
R10 = 10,
|
|
||||||
R11 = 11,
|
|
||||||
R12 = 12,
|
|
||||||
R13 = 13,
|
|
||||||
R14 = 14,
|
|
||||||
R15 = 15,
|
|
||||||
|
|
||||||
AL = 0,
|
|
||||||
BL = 3,
|
|
||||||
CL = 1,
|
|
||||||
DL = 2,
|
|
||||||
SIL = 6,
|
|
||||||
DIL = 7,
|
|
||||||
BPL = 5,
|
|
||||||
SPL = 4,
|
|
||||||
AH = 0x104,
|
|
||||||
BH = 0x107,
|
|
||||||
CH = 0x105,
|
|
||||||
DH = 0x106,
|
|
||||||
|
|
||||||
AX = 0,
|
|
||||||
BX = 3,
|
|
||||||
CX = 1,
|
|
||||||
DX = 2,
|
|
||||||
SI = 6,
|
|
||||||
DI = 7,
|
|
||||||
BP = 5,
|
|
||||||
SP = 4,
|
|
||||||
|
|
||||||
XMM0 = 0,
|
|
||||||
XMM1,
|
|
||||||
XMM2,
|
|
||||||
XMM3,
|
|
||||||
XMM4,
|
|
||||||
XMM5,
|
|
||||||
XMM6,
|
|
||||||
XMM7,
|
|
||||||
XMM8,
|
|
||||||
XMM9,
|
|
||||||
XMM10,
|
|
||||||
XMM11,
|
|
||||||
XMM12,
|
|
||||||
XMM13,
|
|
||||||
XMM14,
|
|
||||||
XMM15,
|
|
||||||
|
|
||||||
YMM0 = 0,
|
|
||||||
YMM1,
|
|
||||||
YMM2,
|
|
||||||
YMM3,
|
|
||||||
YMM4,
|
|
||||||
YMM5,
|
|
||||||
YMM6,
|
|
||||||
YMM7,
|
|
||||||
YMM8,
|
|
||||||
YMM9,
|
|
||||||
YMM10,
|
|
||||||
YMM11,
|
|
||||||
YMM12,
|
|
||||||
YMM13,
|
|
||||||
YMM14,
|
|
||||||
YMM15,
|
|
||||||
|
|
||||||
INVALID_REG = 0xFFFFFFFF
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CCFlags
|
enum CCFlags
|
||||||
{
|
{
|
||||||
CC_O = 0,
|
CC_O = 0,
|
||||||
@ -1090,29 +1005,148 @@ public:
|
|||||||
// Utility functions
|
// Utility functions
|
||||||
// The difference between this and CALL is that this aligns the stack
|
// The difference between this and CALL is that this aligns the stack
|
||||||
// where appropriate.
|
// where appropriate.
|
||||||
void ABI_CallFunction(const void* func);
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunction(FunctionPointer func)
|
||||||
|
{
|
||||||
|
static_assert(std::is_pointer<FunctionPointer>() &&
|
||||||
|
std::is_function<std::remove_pointer_t<FunctionPointer>>(),
|
||||||
|
"Supplied type must be a function pointer.");
|
||||||
|
|
||||||
void ABI_CallFunctionC16(const void* func, u16 param1);
|
const void* ptr = reinterpret_cast<const void*>(func);
|
||||||
void ABI_CallFunctionCC16(const void* func, u32 param1, u16 param2);
|
const u64 address = reinterpret_cast<u64>(ptr);
|
||||||
|
const u64 distance = address - (reinterpret_cast<u64>(code) + 5);
|
||||||
|
|
||||||
// These only support u32 parameters, but that's enough for a lot of uses.
|
if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL)
|
||||||
// These will destroy the 1 or 2 first "parameter regs".
|
{
|
||||||
void ABI_CallFunctionC(const void* func, u32 param1);
|
// Far call
|
||||||
void ABI_CallFunctionCC(const void* func, u32 param1, u32 param2);
|
MOV(64, R(RAX), Imm64(address));
|
||||||
void ABI_CallFunctionCP(const void* func, u32 param1, void* param2);
|
CALLptr(R(RAX));
|
||||||
void ABI_CallFunctionCCC(const void* func, u32 param1, u32 param2, u32 param3);
|
}
|
||||||
void ABI_CallFunctionCCP(const void* func, u32 param1, u32 param2, void* param3);
|
else
|
||||||
void ABI_CallFunctionCCCP(const void* func, u32 param1, u32 param2, u32 param3, void* param4);
|
{
|
||||||
void ABI_CallFunctionPC(const void* func, void* param1, u32 param2);
|
CALL(ptr);
|
||||||
void ABI_CallFunctionPPC(const void* func, void* param1, void* param2, u32 param3);
|
}
|
||||||
void ABI_CallFunctionAC(int bits, const void* func, const OpArg& arg1, u32 param2);
|
}
|
||||||
void ABI_CallFunctionA(int bits, const void* func, const OpArg& arg1);
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionC16(FunctionPointer func, u16 param1)
|
||||||
|
{
|
||||||
|
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionCC16(FunctionPointer func, u32 param1, u16 param2)
|
||||||
|
{
|
||||||
|
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||||
|
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionC(FunctionPointer func, u32 param1)
|
||||||
|
{
|
||||||
|
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionCC(FunctionPointer func, u32 param1, u32 param2)
|
||||||
|
{
|
||||||
|
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||||
|
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionCP(FunctionPointer func, u32 param1, const void* param2)
|
||||||
|
{
|
||||||
|
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||||
|
MOV(64, R(ABI_PARAM2), Imm64(reinterpret_cast<u64>(param2)));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionCCC(FunctionPointer func, u32 param1, u32 param2, u32 param3)
|
||||||
|
{
|
||||||
|
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||||
|
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||||
|
MOV(32, R(ABI_PARAM3), Imm32(param3));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionCCP(FunctionPointer func, u32 param1, u32 param2, const void* param3)
|
||||||
|
{
|
||||||
|
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||||
|
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||||
|
MOV(64, R(ABI_PARAM3), Imm64(reinterpret_cast<u64>(param3)));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionCCCP(FunctionPointer func, u32 param1, u32 param2, u32 param3,
|
||||||
|
const void* param4)
|
||||||
|
{
|
||||||
|
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||||
|
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||||
|
MOV(32, R(ABI_PARAM3), Imm32(param3));
|
||||||
|
MOV(64, R(ABI_PARAM4), Imm64(reinterpret_cast<u64>(param4)));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionPC(FunctionPointer func, const void* param1, u32 param2)
|
||||||
|
{
|
||||||
|
MOV(64, R(ABI_PARAM1), Imm64(reinterpret_cast<u64>(param1)));
|
||||||
|
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionPPC(FunctionPointer func, const void* param1, const void* param2, u32 param3)
|
||||||
|
{
|
||||||
|
MOV(64, R(ABI_PARAM1), Imm64(reinterpret_cast<u64>(param1)));
|
||||||
|
MOV(64, R(ABI_PARAM2), Imm64(reinterpret_cast<u64>(param2)));
|
||||||
|
MOV(32, R(ABI_PARAM3), Imm32(param3));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
// Pass a register as a parameter.
|
// Pass a register as a parameter.
|
||||||
void ABI_CallFunctionR(const void* func, X64Reg reg1);
|
template <typename FunctionPointer>
|
||||||
void ABI_CallFunctionRR(const void* func, X64Reg reg1, X64Reg reg2);
|
void ABI_CallFunctionR(FunctionPointer func, X64Reg reg1)
|
||||||
|
{
|
||||||
|
if (reg1 != ABI_PARAM1)
|
||||||
|
MOV(32, R(ABI_PARAM1), R(reg1));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
// Helper method for the above, or can be used separately.
|
// Pass two registers as parameters.
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionRR(FunctionPointer func, X64Reg reg1, X64Reg reg2)
|
||||||
|
{
|
||||||
|
MOVTwo(64, ABI_PARAM1, reg1, 0, ABI_PARAM2, reg2);
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionAC(int bits, FunctionPointer func, const Gen::OpArg& arg1, u32 param2)
|
||||||
|
{
|
||||||
|
if (!arg1.IsSimpleReg(ABI_PARAM1))
|
||||||
|
MOV(bits, R(ABI_PARAM1), arg1);
|
||||||
|
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FunctionPointer>
|
||||||
|
void ABI_CallFunctionA(int bits, FunctionPointer func, const Gen::OpArg& arg1)
|
||||||
|
{
|
||||||
|
if (!arg1.IsSimpleReg(ABI_PARAM1))
|
||||||
|
MOV(bits, R(ABI_PARAM1), arg1);
|
||||||
|
ABI_CallFunction(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method for ABI functions related to calling functions. May be used by itself as well.
|
||||||
void MOVTwo(int bits, X64Reg dst1, X64Reg src1, s32 offset, X64Reg dst2, X64Reg src2);
|
void MOVTwo(int bits, X64Reg dst1, X64Reg src1, s32 offset, X64Reg dst2, X64Reg src2);
|
||||||
|
|
||||||
// Saves/restores the registers and adjusts the stack to be aligned as
|
// Saves/restores the registers and adjusts the stack to be aligned as
|
||||||
@ -1138,7 +1172,7 @@ public:
|
|||||||
void ABI_CallLambdaC(const std::function<T(Args...)>* f, u32 p1)
|
void ABI_CallLambdaC(const std::function<T(Args...)>* f, u32 p1)
|
||||||
{
|
{
|
||||||
auto trampoline = &XEmitter::CallLambdaTrampoline<T, Args...>;
|
auto trampoline = &XEmitter::CallLambdaTrampoline<T, Args...>;
|
||||||
ABI_CallFunctionPC((void*)trampoline, const_cast<void*>((const void*)f), p1);
|
ABI_CallFunctionPC(trampoline, reinterpret_cast<const void*>(f), p1);
|
||||||
}
|
}
|
||||||
}; // class XEmitter
|
}; // class XEmitter
|
||||||
|
|
||||||
|
96
Source/Core/Common/x64Reg.h
Normal file
96
Source/Core/Common/x64Reg.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// Copyright 2016 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Gen
|
||||||
|
{
|
||||||
|
enum X64Reg
|
||||||
|
{
|
||||||
|
EAX = 0,
|
||||||
|
EBX = 3,
|
||||||
|
ECX = 1,
|
||||||
|
EDX = 2,
|
||||||
|
ESI = 6,
|
||||||
|
EDI = 7,
|
||||||
|
EBP = 5,
|
||||||
|
ESP = 4,
|
||||||
|
|
||||||
|
RAX = 0,
|
||||||
|
RBX = 3,
|
||||||
|
RCX = 1,
|
||||||
|
RDX = 2,
|
||||||
|
RSI = 6,
|
||||||
|
RDI = 7,
|
||||||
|
RBP = 5,
|
||||||
|
RSP = 4,
|
||||||
|
R8 = 8,
|
||||||
|
R9 = 9,
|
||||||
|
R10 = 10,
|
||||||
|
R11 = 11,
|
||||||
|
R12 = 12,
|
||||||
|
R13 = 13,
|
||||||
|
R14 = 14,
|
||||||
|
R15 = 15,
|
||||||
|
|
||||||
|
AL = 0,
|
||||||
|
BL = 3,
|
||||||
|
CL = 1,
|
||||||
|
DL = 2,
|
||||||
|
SIL = 6,
|
||||||
|
DIL = 7,
|
||||||
|
BPL = 5,
|
||||||
|
SPL = 4,
|
||||||
|
AH = 0x104,
|
||||||
|
BH = 0x107,
|
||||||
|
CH = 0x105,
|
||||||
|
DH = 0x106,
|
||||||
|
|
||||||
|
AX = 0,
|
||||||
|
BX = 3,
|
||||||
|
CX = 1,
|
||||||
|
DX = 2,
|
||||||
|
SI = 6,
|
||||||
|
DI = 7,
|
||||||
|
BP = 5,
|
||||||
|
SP = 4,
|
||||||
|
|
||||||
|
XMM0 = 0,
|
||||||
|
XMM1,
|
||||||
|
XMM2,
|
||||||
|
XMM3,
|
||||||
|
XMM4,
|
||||||
|
XMM5,
|
||||||
|
XMM6,
|
||||||
|
XMM7,
|
||||||
|
XMM8,
|
||||||
|
XMM9,
|
||||||
|
XMM10,
|
||||||
|
XMM11,
|
||||||
|
XMM12,
|
||||||
|
XMM13,
|
||||||
|
XMM14,
|
||||||
|
XMM15,
|
||||||
|
|
||||||
|
YMM0 = 0,
|
||||||
|
YMM1,
|
||||||
|
YMM2,
|
||||||
|
YMM3,
|
||||||
|
YMM4,
|
||||||
|
YMM5,
|
||||||
|
YMM6,
|
||||||
|
YMM7,
|
||||||
|
YMM8,
|
||||||
|
YMM9,
|
||||||
|
YMM10,
|
||||||
|
YMM11,
|
||||||
|
YMM12,
|
||||||
|
YMM13,
|
||||||
|
YMM14,
|
||||||
|
YMM15,
|
||||||
|
|
||||||
|
INVALID_REG = 0xFFFFFFFF
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Gen
|
@ -89,7 +89,7 @@ void DSPEmitter::checkExceptions(u32 retval)
|
|||||||
|
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(gpr);
|
||||||
gpr.SaveRegs();
|
gpr.SaveRegs();
|
||||||
ABI_CallFunction((void*)&DSPCore_CheckExceptions);
|
ABI_CallFunction(DSPCore_CheckExceptions);
|
||||||
MOV(32, R(EAX), Imm32(retval));
|
MOV(32, R(EAX), Imm32(retval));
|
||||||
JMP(returnDispatcher, true);
|
JMP(returnDispatcher, true);
|
||||||
gpr.LoadRegs(false);
|
gpr.LoadRegs(false);
|
||||||
@ -121,7 +121,7 @@ void DSPEmitter::FallBackToInterpreter(UDSPInstruction inst)
|
|||||||
// Fall back to interpreter
|
// Fall back to interpreter
|
||||||
gpr.PushRegs();
|
gpr.PushRegs();
|
||||||
_assert_msg_(DSPLLE, opTable[inst]->intFunc, "No function for %04x", inst);
|
_assert_msg_(DSPLLE, opTable[inst]->intFunc, "No function for %04x", inst);
|
||||||
ABI_CallFunctionC16((void*)opTable[inst]->intFunc, inst);
|
ABI_CallFunctionC16(opTable[inst]->intFunc, inst);
|
||||||
gpr.PopRegs();
|
gpr.PopRegs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
|||||||
{
|
{
|
||||||
// Fall back to interpreter
|
// Fall back to interpreter
|
||||||
gpr.PushRegs();
|
gpr.PushRegs();
|
||||||
ABI_CallFunctionC16((void*)extOpTable[inst & 0x7F]->intFunc, inst);
|
ABI_CallFunctionC16(extOpTable[inst & 0x7F]->intFunc, inst);
|
||||||
gpr.PopRegs();
|
gpr.PopRegs();
|
||||||
INFO_LOG(DSPLLE, "Instruction not JITed(ext part): %04x\n", inst);
|
INFO_LOG(DSPLLE, "Instruction not JITed(ext part): %04x\n", inst);
|
||||||
ext_is_jit = false;
|
ext_is_jit = false;
|
||||||
@ -156,7 +156,7 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
|||||||
{
|
{
|
||||||
// Fall back to interpreter
|
// Fall back to interpreter
|
||||||
gpr.PushRegs();
|
gpr.PushRegs();
|
||||||
ABI_CallFunctionC16((void*)extOpTable[inst & 0xFF]->intFunc, inst);
|
ABI_CallFunctionC16(extOpTable[inst & 0xFF]->intFunc, inst);
|
||||||
gpr.PopRegs();
|
gpr.PopRegs();
|
||||||
INFO_LOG(DSPLLE, "Instruction not JITed(ext part): %04x\n", inst);
|
INFO_LOG(DSPLLE, "Instruction not JITed(ext part): %04x\n", inst);
|
||||||
ext_is_jit = false;
|
ext_is_jit = false;
|
||||||
@ -188,7 +188,7 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
|||||||
// need to call the online cleanup function because
|
// need to call the online cleanup function because
|
||||||
// the writeBackLog gets populated at runtime
|
// the writeBackLog gets populated at runtime
|
||||||
gpr.PushRegs();
|
gpr.PushRegs();
|
||||||
ABI_CallFunction((void*)::applyWriteBackLog);
|
ABI_CallFunction(::applyWriteBackLog);
|
||||||
gpr.PopRegs();
|
gpr.PopRegs();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -376,7 +376,7 @@ void DSPEmitter::Compile(u16 start_addr)
|
|||||||
const u8* DSPEmitter::CompileStub()
|
const u8* DSPEmitter::CompileStub()
|
||||||
{
|
{
|
||||||
const u8* entryPoint = AlignCode16();
|
const u8* entryPoint = AlignCode16();
|
||||||
ABI_CallFunction((void*)&CompileCurrent);
|
ABI_CallFunction(CompileCurrent);
|
||||||
XOR(32, R(EAX), R(EAX)); // Return 0 cycles executed
|
XOR(32, R(EAX), R(EAX)); // Return 0 cycles executed
|
||||||
JMP(returnDispatcher);
|
JMP(returnDispatcher);
|
||||||
return entryPoint;
|
return entryPoint;
|
||||||
|
@ -518,7 +518,7 @@ void DSPEmitter::dmem_write(X64Reg value)
|
|||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(gpr);
|
||||||
X64Reg abisafereg = gpr.MakeABICallSafe(value);
|
X64Reg abisafereg = gpr.MakeABICallSafe(value);
|
||||||
gpr.PushRegs();
|
gpr.PushRegs();
|
||||||
ABI_CallFunctionRR((void*)gdsp_ifx_write, EAX, abisafereg);
|
ABI_CallFunctionRR(gdsp_ifx_write, EAX, abisafereg);
|
||||||
gpr.PopRegs();
|
gpr.PopRegs();
|
||||||
gpr.FlushRegs(c);
|
gpr.FlushRegs(c);
|
||||||
SetJumpTarget(end);
|
SetJumpTarget(end);
|
||||||
@ -538,7 +538,7 @@ void DSPEmitter::dmem_write_imm(u16 address, X64Reg value)
|
|||||||
MOV(16, R(EAX), Imm16(address));
|
MOV(16, R(EAX), Imm16(address));
|
||||||
X64Reg abisafereg = gpr.MakeABICallSafe(value);
|
X64Reg abisafereg = gpr.MakeABICallSafe(value);
|
||||||
gpr.PushRegs();
|
gpr.PushRegs();
|
||||||
ABI_CallFunctionRR((void*)gdsp_ifx_write, EAX, abisafereg);
|
ABI_CallFunctionRR(gdsp_ifx_write, EAX, abisafereg);
|
||||||
gpr.PopRegs();
|
gpr.PopRegs();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -604,7 +604,7 @@ void DSPEmitter::dmem_read(X64Reg address)
|
|||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(gpr);
|
||||||
X64Reg abisafereg = gpr.MakeABICallSafe(address);
|
X64Reg abisafereg = gpr.MakeABICallSafe(address);
|
||||||
gpr.PushRegs();
|
gpr.PushRegs();
|
||||||
ABI_CallFunctionR((void*)gdsp_ifx_read, abisafereg);
|
ABI_CallFunctionR(gdsp_ifx_read, abisafereg);
|
||||||
gpr.PopRegs();
|
gpr.PopRegs();
|
||||||
gpr.FlushRegs(c);
|
gpr.FlushRegs(c);
|
||||||
SetJumpTarget(end);
|
SetJumpTarget(end);
|
||||||
@ -628,7 +628,7 @@ void DSPEmitter::dmem_read_imm(u16 address)
|
|||||||
case 0xf: // Fxxx HW regs
|
case 0xf: // Fxxx HW regs
|
||||||
{
|
{
|
||||||
gpr.PushRegs();
|
gpr.PushRegs();
|
||||||
ABI_CallFunctionC16((void*)gdsp_ifx_read, address);
|
ABI_CallFunctionC16(gdsp_ifx_read, address);
|
||||||
gpr.PopRegs();
|
gpr.PopRegs();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ void Jit64::FallBackToInterpreter(UGeckoInstruction inst)
|
|||||||
}
|
}
|
||||||
Interpreter::Instruction instr = GetInterpreterOp(inst);
|
Interpreter::Instruction instr = GetInterpreterOp(inst);
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunctionC((void*)instr, inst.hex);
|
ABI_CallFunctionC(instr, inst.hex);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
if (js.op->opinfo->flags & FL_ENDBLOCK)
|
if (js.op->opinfo->flags & FL_ENDBLOCK)
|
||||||
{
|
{
|
||||||
@ -312,7 +312,7 @@ void Jit64::HLEFunction(UGeckoInstruction _inst)
|
|||||||
gpr.Flush();
|
gpr.Flush();
|
||||||
fpr.Flush();
|
fpr.Flush();
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunctionCC((void*)&HLE::Execute, js.compilerPC, _inst.hex);
|
ABI_CallFunctionCC(HLE::Execute, js.compilerPC, _inst.hex);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +352,7 @@ bool Jit64::Cleanup()
|
|||||||
if (jo.optimizeGatherPipe && js.fifoBytesThisBlock > 0)
|
if (jo.optimizeGatherPipe && js.fifoBytesThisBlock > 0)
|
||||||
{
|
{
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunction((void*)&GPFifo::FastCheckGatherPipe);
|
ABI_CallFunction(GPFifo::FastCheckGatherPipe);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
did_something = true;
|
did_something = true;
|
||||||
}
|
}
|
||||||
@ -361,8 +361,8 @@ bool Jit64::Cleanup()
|
|||||||
if (MMCR0.Hex || MMCR1.Hex)
|
if (MMCR0.Hex || MMCR1.Hex)
|
||||||
{
|
{
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunctionCCC((void*)&PowerPC::UpdatePerformanceMonitor, js.downcountAmount,
|
ABI_CallFunctionCCC(PowerPC::UpdatePerformanceMonitor, js.downcountAmount, js.numLoadStoreInst,
|
||||||
js.numLoadStoreInst, js.numFloatingPointInst);
|
js.numFloatingPointInst);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
did_something = true;
|
did_something = true;
|
||||||
}
|
}
|
||||||
@ -462,7 +462,7 @@ void Jit64::WriteRfiExitDestInRSCRATCH()
|
|||||||
MOV(32, PPCSTATE(npc), R(RSCRATCH));
|
MOV(32, PPCSTATE(npc), R(RSCRATCH));
|
||||||
Cleanup();
|
Cleanup();
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunction(reinterpret_cast<void*>(&PowerPC::CheckExceptions));
|
ABI_CallFunction(PowerPC::CheckExceptions);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, true);
|
||||||
@ -474,7 +474,7 @@ void Jit64::WriteExceptionExit()
|
|||||||
MOV(32, R(RSCRATCH), PPCSTATE(pc));
|
MOV(32, R(RSCRATCH), PPCSTATE(pc));
|
||||||
MOV(32, PPCSTATE(npc), R(RSCRATCH));
|
MOV(32, PPCSTATE(npc), R(RSCRATCH));
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunction(reinterpret_cast<void*>(&PowerPC::CheckExceptions));
|
ABI_CallFunction(PowerPC::CheckExceptions);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, true);
|
||||||
@ -486,7 +486,7 @@ void Jit64::WriteExternalExceptionExit()
|
|||||||
MOV(32, R(RSCRATCH), PPCSTATE(pc));
|
MOV(32, R(RSCRATCH), PPCSTATE(pc));
|
||||||
MOV(32, PPCSTATE(npc), R(RSCRATCH));
|
MOV(32, PPCSTATE(npc), R(RSCRATCH));
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunction(reinterpret_cast<void*>(&PowerPC::CheckExternalExceptions));
|
ABI_CallFunction(PowerPC::CheckExternalExceptions);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, true);
|
||||||
@ -620,11 +620,11 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc
|
|||||||
const u8* normalEntry = GetCodePtr();
|
const u8* normalEntry = GetCodePtr();
|
||||||
b->normalEntry = normalEntry;
|
b->normalEntry = normalEntry;
|
||||||
|
|
||||||
|
// Used to get a trace of the last few blocks before a crash, sometimes VERY useful
|
||||||
if (ImHereDebug)
|
if (ImHereDebug)
|
||||||
{
|
{
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunction((void*)&ImHere); // Used to get a trace of the last few blocks before a crash,
|
ABI_CallFunction(ImHere);
|
||||||
// sometimes VERY useful
|
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,7 +672,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc
|
|||||||
const u8* target = GetCodePtr();
|
const u8* target = GetCodePtr();
|
||||||
MOV(32, PPCSTATE(pc), Imm32(js.blockStart));
|
MOV(32, PPCSTATE(pc), Imm32(js.blockStart));
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunctionC((void*)&JitInterface::CompileExceptionCheck,
|
ABI_CallFunctionC(JitInterface::CompileExceptionCheck,
|
||||||
(u32)JitInterface::ExceptionType::EXCEPTIONS_PAIRED_QUANTIZE);
|
(u32)JitInterface::ExceptionType::EXCEPTIONS_PAIRED_QUANTIZE);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, true);
|
||||||
@ -731,7 +731,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc
|
|||||||
js.mustCheckFifo = false;
|
js.mustCheckFifo = false;
|
||||||
BitSet32 registersInUse = CallerSavedRegistersInUse();
|
BitSet32 registersInUse = CallerSavedRegistersInUse();
|
||||||
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
|
||||||
ABI_CallFunction((void*)&GPFifo::FastCheckGatherPipe);
|
ABI_CallFunction(GPFifo::FastCheckGatherPipe);
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
||||||
gatherPipeIntCheck = true;
|
gatherPipeIntCheck = true;
|
||||||
}
|
}
|
||||||
@ -820,7 +820,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc
|
|||||||
|
|
||||||
MOV(32, PPCSTATE(pc), Imm32(ops[i].address));
|
MOV(32, PPCSTATE(pc), Imm32(ops[i].address));
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunction(reinterpret_cast<void*>(&PowerPC::CheckBreakPoints));
|
ABI_CallFunction(PowerPC::CheckBreakPoints);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
TEST(32, M(CPU::GetStatePtr()), Imm32(0xFFFFFFFF));
|
TEST(32, M(CPU::GetStatePtr()), Imm32(0xFFFFFFFF));
|
||||||
FixupBranch noBreakpoint = J_CC(CC_Z);
|
FixupBranch noBreakpoint = J_CC(CC_Z);
|
||||||
|
@ -50,7 +50,7 @@ void Jit64AsmRoutineManager::Generate()
|
|||||||
|
|
||||||
const u8* outerLoop = GetCodePtr();
|
const u8* outerLoop = GetCodePtr();
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunction(reinterpret_cast<void*>(&CoreTiming::Advance));
|
ABI_CallFunction(CoreTiming::Advance);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
FixupBranch skipToRealDispatch =
|
FixupBranch skipToRealDispatch =
|
||||||
J(SConfig::GetInstance().bEnableDebugging); // skip the sync and compare first time
|
J(SConfig::GetInstance().bEnableDebugging); // skip the sync and compare first time
|
||||||
@ -80,7 +80,7 @@ void Jit64AsmRoutineManager::Generate()
|
|||||||
TEST(32, M(CPU::GetStatePtr()), Imm32(CPU::CPU_STEPPING));
|
TEST(32, M(CPU::GetStatePtr()), Imm32(CPU::CPU_STEPPING));
|
||||||
FixupBranch notStepping = J_CC(CC_Z);
|
FixupBranch notStepping = J_CC(CC_Z);
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunction(reinterpret_cast<void*>(&PowerPC::CheckBreakPoints));
|
ABI_CallFunction(PowerPC::CheckBreakPoints);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
TEST(32, M(CPU::GetStatePtr()), Imm32(0xFFFFFFFF));
|
TEST(32, M(CPU::GetStatePtr()), Imm32(0xFFFFFFFF));
|
||||||
dbg_exit = J_CC(CC_NZ, true);
|
dbg_exit = J_CC(CC_NZ, true);
|
||||||
@ -154,7 +154,7 @@ void Jit64AsmRoutineManager::Generate()
|
|||||||
|
|
||||||
// Ok, no block, let's call the slow dispatcher
|
// Ok, no block, let's call the slow dispatcher
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunction(reinterpret_cast<void*>(&JitBase::Dispatch));
|
ABI_CallFunction(JitBase::Dispatch);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
// JMPptr(R(ABI_RETURN));
|
// JMPptr(R(ABI_RETURN));
|
||||||
JMP(dispatcherNoCheck, true);
|
JMP(dispatcherNoCheck, true);
|
||||||
|
@ -149,7 +149,7 @@ void Jit64::lXXx(UGeckoInstruction inst)
|
|||||||
BitSet32 registersInUse = CallerSavedRegistersInUse();
|
BitSet32 registersInUse = CallerSavedRegistersInUse();
|
||||||
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
|
||||||
|
|
||||||
ABI_CallFunction((void*)&CoreTiming::Idle);
|
ABI_CallFunction(CoreTiming::Idle);
|
||||||
|
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ void Jit64::dcbx(UGeckoInstruction inst)
|
|||||||
SHL(32, R(ABI_PARAM1), Imm8(5));
|
SHL(32, R(ABI_PARAM1), Imm8(5));
|
||||||
MOV(32, R(ABI_PARAM2), Imm32(32));
|
MOV(32, R(ABI_PARAM2), Imm32(32));
|
||||||
XOR(32, R(ABI_PARAM3), R(ABI_PARAM3));
|
XOR(32, R(ABI_PARAM3), R(ABI_PARAM3));
|
||||||
ABI_CallFunction((void*)JitInterface::InvalidateICache);
|
ABI_CallFunction(JitInterface::InvalidateICache);
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
||||||
asm_routines.ResetStack(*this);
|
asm_routines.ResetStack(*this);
|
||||||
c = J(true);
|
c = J(true);
|
||||||
@ -325,7 +325,7 @@ void Jit64::dcbx(UGeckoInstruction inst)
|
|||||||
SetJumpTarget(c);
|
SetJumpTarget(c);
|
||||||
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
|
||||||
SHL(32, R(addr), Imm8(5));
|
SHL(32, R(addr), Imm8(5));
|
||||||
ABI_CallFunctionR((void*)DSP::FlushInstantDMA, addr);
|
ABI_CallFunctionR(DSP::FlushInstantDMA, addr);
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
||||||
c = J(true);
|
c = J(true);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
@ -384,7 +384,7 @@ void Jit64::dcbz(UGeckoInstruction inst)
|
|||||||
MOV(32, M(&PC), Imm32(jit->js.compilerPC));
|
MOV(32, M(&PC), Imm32(jit->js.compilerPC));
|
||||||
BitSet32 registersInUse = CallerSavedRegistersInUse();
|
BitSet32 registersInUse = CallerSavedRegistersInUse();
|
||||||
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
|
||||||
ABI_CallFunctionR((void*)&PowerPC::ClearCacheLine, RSCRATCH);
|
ABI_CallFunctionR(PowerPC::ClearCacheLine, RSCRATCH);
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
||||||
FixupBranch exit = J(true);
|
FixupBranch exit = J(true);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
|
@ -243,7 +243,7 @@ void Jit64::mtspr(UGeckoInstruction inst)
|
|||||||
FixupBranch dont_reset_icache = J_CC(CC_NC);
|
FixupBranch dont_reset_icache = J_CC(CC_NC);
|
||||||
BitSet32 regs = CallerSavedRegistersInUse();
|
BitSet32 regs = CallerSavedRegistersInUse();
|
||||||
ABI_PushRegistersAndAdjustStack(regs, 0);
|
ABI_PushRegistersAndAdjustStack(regs, 0);
|
||||||
ABI_CallFunction((void*)DoICacheReset);
|
ABI_CallFunction(DoICacheReset);
|
||||||
ABI_PopRegistersAndAdjustStack(regs, 0);
|
ABI_PopRegistersAndAdjustStack(regs, 0);
|
||||||
SetJumpTarget(dont_reset_icache);
|
SetJumpTarget(dont_reset_icache);
|
||||||
break;
|
break;
|
||||||
|
@ -101,7 +101,7 @@ void CommonAsmRoutines::GenFrsqrte()
|
|||||||
SetJumpTarget(complex2);
|
SetJumpTarget(complex2);
|
||||||
SetJumpTarget(complex3);
|
SetJumpTarget(complex3);
|
||||||
ABI_PushRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
ABI_PushRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
||||||
ABI_CallFunction((void*)&MathUtil::ApproximateReciprocalSquareRoot);
|
ABI_CallFunction(MathUtil::ApproximateReciprocalSquareRoot);
|
||||||
ABI_PopRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
ABI_PopRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ void CommonAsmRoutines::GenFres()
|
|||||||
|
|
||||||
SetJumpTarget(complex);
|
SetJumpTarget(complex);
|
||||||
ABI_PushRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
ABI_PushRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
||||||
ABI_CallFunction((void*)&MathUtil::ApproximateReciprocal);
|
ABI_CallFunction(MathUtil::ApproximateReciprocal);
|
||||||
ABI_PopRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
ABI_PopRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
@ -984,7 +984,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
|||||||
regSpillCallerSaved(RI);
|
regSpillCallerSaved(RI);
|
||||||
Jit->MOV(32, PPCSTATE(pc), Imm32(InstLoc));
|
Jit->MOV(32, PPCSTATE(pc), Imm32(InstLoc));
|
||||||
Jit->MOV(32, PPCSTATE(npc), Imm32(InstLoc + 4));
|
Jit->MOV(32, PPCSTATE(npc), Imm32(InstLoc + 4));
|
||||||
Jit->ABI_CallFunctionC((void*)GetInterpreterOp(InstCode), InstCode);
|
Jit->ABI_CallFunctionC(GetInterpreterOp(InstCode), InstCode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LoadGReg:
|
case LoadGReg:
|
||||||
@ -1940,7 +1940,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
|||||||
Jit->MOVSD(XMM0, loc2);
|
Jit->MOVSD(XMM0, loc2);
|
||||||
Jit->MOVSD(M(isSNANTemp[1]), XMM0);
|
Jit->MOVSD(M(isSNANTemp[1]), XMM0);
|
||||||
}
|
}
|
||||||
Jit->ABI_CallFunction((void*)checkIsSNAN);
|
Jit->ABI_CallFunction(checkIsSNAN);
|
||||||
Jit->TEST(8, R(ABI_RETURN), R(ABI_RETURN));
|
Jit->TEST(8, R(ABI_RETURN), R(ABI_RETURN));
|
||||||
FixupBranch ok = Jit->J_CC(CC_Z);
|
FixupBranch ok = Jit->J_CC(CC_Z);
|
||||||
Jit->OR(32, PPCSTATE(fpscr), Imm32(FPSCR_FX)); // FPSCR.FX = 1;
|
Jit->OR(32, PPCSTATE(fpscr), Imm32(FPSCR_FX)); // FPSCR.FX = 1;
|
||||||
@ -1969,7 +1969,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
|||||||
Jit->MOVSD(XMM0, loc2);
|
Jit->MOVSD(XMM0, loc2);
|
||||||
Jit->MOVSD(M(isSNANTemp[1]), XMM0);
|
Jit->MOVSD(M(isSNANTemp[1]), XMM0);
|
||||||
}
|
}
|
||||||
Jit->ABI_CallFunction((void*)checkIsSNAN);
|
Jit->ABI_CallFunction(checkIsSNAN);
|
||||||
Jit->TEST(8, R(ABI_RETURN), R(ABI_RETURN));
|
Jit->TEST(8, R(ABI_RETURN), R(ABI_RETURN));
|
||||||
FixupBranch finish = Jit->J_CC(CC_Z);
|
FixupBranch finish = Jit->J_CC(CC_Z);
|
||||||
Jit->OR(32, PPCSTATE(fpscr), Imm32(FPSCR_FX)); // FPSCR.FX = 1;
|
Jit->OR(32, PPCSTATE(fpscr), Imm32(FPSCR_FX)); // FPSCR.FX = 1;
|
||||||
@ -2123,7 +2123,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
|||||||
FixupBranch noidle = Jit->J_CC(CC_NZ);
|
FixupBranch noidle = Jit->J_CC(CC_NZ);
|
||||||
|
|
||||||
RI.Jit->Cleanup(); // is it needed?
|
RI.Jit->Cleanup(); // is it needed?
|
||||||
Jit->ABI_CallFunction((void*)&CoreTiming::Idle);
|
Jit->ABI_CallFunction(CoreTiming::Idle);
|
||||||
|
|
||||||
Jit->MOV(32, PPCSTATE(pc), Imm32(ibuild->GetImmValue(getOp2(I))));
|
Jit->MOV(32, PPCSTATE(pc), Imm32(ibuild->GetImmValue(getOp2(I))));
|
||||||
Jit->WriteExceptionExit();
|
Jit->WriteExceptionExit();
|
||||||
@ -2209,7 +2209,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
|||||||
case ShortIdleLoop:
|
case ShortIdleLoop:
|
||||||
{
|
{
|
||||||
unsigned InstLoc = ibuild->GetImmValue(getOp1(I));
|
unsigned InstLoc = ibuild->GetImmValue(getOp1(I));
|
||||||
Jit->ABI_CallFunction((void*)&CoreTiming::Idle);
|
Jit->ABI_CallFunction(CoreTiming::Idle);
|
||||||
Jit->MOV(32, PPCSTATE(pc), Imm32(InstLoc));
|
Jit->MOV(32, PPCSTATE(pc), Imm32(InstLoc));
|
||||||
Jit->WriteExceptionExit();
|
Jit->WriteExceptionExit();
|
||||||
break;
|
break;
|
||||||
@ -2307,7 +2307,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
|||||||
unsigned InstLoc = ibuild->GetImmValue(getOp1(I));
|
unsigned InstLoc = ibuild->GetImmValue(getOp1(I));
|
||||||
|
|
||||||
Jit->MOV(32, PPCSTATE(pc), Imm32(InstLoc));
|
Jit->MOV(32, PPCSTATE(pc), Imm32(InstLoc));
|
||||||
Jit->ABI_CallFunction(reinterpret_cast<void*>(&PowerPC::CheckBreakPoints));
|
Jit->ABI_CallFunction(PowerPC::CheckBreakPoints);
|
||||||
Jit->TEST(32, M(CPU::GetStatePtr()), Imm32(0xFFFFFFFF));
|
Jit->TEST(32, M(CPU::GetStatePtr()), Imm32(0xFFFFFFFF));
|
||||||
FixupBranch noBreakpoint = Jit->J_CC(CC_Z);
|
FixupBranch noBreakpoint = Jit->J_CC(CC_Z);
|
||||||
Jit->WriteExit(InstLoc);
|
Jit->WriteExit(InstLoc);
|
||||||
|
@ -310,7 +310,7 @@ void JitIL::FallBackToInterpreter(UGeckoInstruction _inst)
|
|||||||
|
|
||||||
void JitIL::HLEFunction(UGeckoInstruction _inst)
|
void JitIL::HLEFunction(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
ABI_CallFunctionCC((void*)&HLE::Execute, js.compilerPC, _inst.hex);
|
ABI_CallFunctionCC(HLE::Execute, js.compilerPC, _inst.hex);
|
||||||
MOV(32, R(RSCRATCH), PPCSTATE(npc));
|
MOV(32, R(RSCRATCH), PPCSTATE(npc));
|
||||||
WriteExitDestInOpArg(R(RSCRATCH));
|
WriteExitDestInOpArg(R(RSCRATCH));
|
||||||
}
|
}
|
||||||
@ -353,7 +353,7 @@ void JitIL::Cleanup()
|
|||||||
{
|
{
|
||||||
// SPEED HACK: MMCR0/MMCR1 should be checked at run-time, not at compile time.
|
// SPEED HACK: MMCR0/MMCR1 should be checked at run-time, not at compile time.
|
||||||
if (MMCR0.Hex || MMCR1.Hex)
|
if (MMCR0.Hex || MMCR1.Hex)
|
||||||
ABI_CallFunctionCCC((void*)&PowerPC::UpdatePerformanceMonitor, js.downcountAmount,
|
ABI_CallFunctionCCC(PowerPC::UpdatePerformanceMonitor, js.downcountAmount,
|
||||||
jit->js.numLoadStoreInst, jit->js.numFloatingPointInst);
|
jit->js.numLoadStoreInst, jit->js.numFloatingPointInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +362,7 @@ void JitIL::WriteExit(u32 destination)
|
|||||||
Cleanup();
|
Cleanup();
|
||||||
if (SConfig::GetInstance().bJITILTimeProfiling)
|
if (SConfig::GetInstance().bJITILTimeProfiling)
|
||||||
{
|
{
|
||||||
ABI_CallFunction((void*)JitILProfiler::End);
|
ABI_CallFunction(JitILProfiler::End);
|
||||||
}
|
}
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
|
|
||||||
@ -385,7 +385,7 @@ void JitIL::WriteExitDestInOpArg(const OpArg& arg)
|
|||||||
Cleanup();
|
Cleanup();
|
||||||
if (SConfig::GetInstance().bJITILTimeProfiling)
|
if (SConfig::GetInstance().bJITILTimeProfiling)
|
||||||
{
|
{
|
||||||
ABI_CallFunction((void*)JitILProfiler::End);
|
ABI_CallFunction(JitILProfiler::End);
|
||||||
}
|
}
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, true);
|
||||||
@ -398,9 +398,9 @@ void JitIL::WriteRfiExitDestInOpArg(const OpArg& arg)
|
|||||||
Cleanup();
|
Cleanup();
|
||||||
if (SConfig::GetInstance().bJITILTimeProfiling)
|
if (SConfig::GetInstance().bJITILTimeProfiling)
|
||||||
{
|
{
|
||||||
ABI_CallFunction((void*)JitILProfiler::End);
|
ABI_CallFunction(JitILProfiler::End);
|
||||||
}
|
}
|
||||||
ABI_CallFunction(reinterpret_cast<void*>(&PowerPC::CheckExceptions));
|
ABI_CallFunction(PowerPC::CheckExceptions);
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, true);
|
||||||
}
|
}
|
||||||
@ -410,11 +410,11 @@ void JitIL::WriteExceptionExit()
|
|||||||
Cleanup();
|
Cleanup();
|
||||||
if (SConfig::GetInstance().bJITILTimeProfiling)
|
if (SConfig::GetInstance().bJITILTimeProfiling)
|
||||||
{
|
{
|
||||||
ABI_CallFunction((void*)JitILProfiler::End);
|
ABI_CallFunction(JitILProfiler::End);
|
||||||
}
|
}
|
||||||
MOV(32, R(EAX), PPCSTATE(pc));
|
MOV(32, R(EAX), PPCSTATE(pc));
|
||||||
MOV(32, PPCSTATE(npc), R(EAX));
|
MOV(32, PPCSTATE(npc), R(EAX));
|
||||||
ABI_CallFunction(reinterpret_cast<void*>(&PowerPC::CheckExceptions));
|
ABI_CallFunction(PowerPC::CheckExceptions);
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, true);
|
||||||
}
|
}
|
||||||
@ -537,9 +537,9 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc
|
|||||||
const u8* normalEntry = GetCodePtr();
|
const u8* normalEntry = GetCodePtr();
|
||||||
b->normalEntry = normalEntry;
|
b->normalEntry = normalEntry;
|
||||||
|
|
||||||
|
// Used to get a trace of the last few blocks before a crash, sometimes VERY useful.
|
||||||
if (ImHereDebug)
|
if (ImHereDebug)
|
||||||
ABI_CallFunction((void*)&ImHere); // Used to get a trace of the last few blocks before a crash,
|
ABI_CallFunction(ImHere);
|
||||||
// sometimes VERY useful
|
|
||||||
|
|
||||||
if (js.fpa.any)
|
if (js.fpa.any)
|
||||||
{
|
{
|
||||||
@ -573,7 +573,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc
|
|||||||
if (SConfig::GetInstance().bJITILTimeProfiling)
|
if (SConfig::GetInstance().bJITILTimeProfiling)
|
||||||
{
|
{
|
||||||
JitILProfiler::Block& block = JitILProfiler::Add(codeHash);
|
JitILProfiler::Block& block = JitILProfiler::Add(codeHash);
|
||||||
ABI_CallFunctionC((void*)JitILProfiler::Begin, block.index);
|
ABI_CallFunctionC(JitILProfiler::Begin, block.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start up IR builder (structure that collects the
|
// Start up IR builder (structure that collects the
|
||||||
|
@ -325,16 +325,16 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress,
|
|||||||
switch (accessSize)
|
switch (accessSize)
|
||||||
{
|
{
|
||||||
case 64:
|
case 64:
|
||||||
ABI_CallFunctionR((void*)&PowerPC::Read_U64, reg_addr);
|
ABI_CallFunctionR(PowerPC::Read_U64, reg_addr);
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
ABI_CallFunctionR((void*)&PowerPC::Read_U32, reg_addr);
|
ABI_CallFunctionR(PowerPC::Read_U32, reg_addr);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
ABI_CallFunctionR((void*)&PowerPC::Read_U16_ZX, reg_addr);
|
ABI_CallFunctionR(PowerPC::Read_U16_ZX, reg_addr);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
ABI_CallFunctionR((void*)&PowerPC::Read_U8_ZX, reg_addr);
|
ABI_CallFunctionR(PowerPC::Read_U8_ZX, reg_addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, rsp_alignment);
|
ABI_PopRegistersAndAdjustStack(registersInUse, rsp_alignment);
|
||||||
@ -385,16 +385,16 @@ void EmuCodeBlock::SafeLoadToRegImmediate(X64Reg reg_value, u32 address, int acc
|
|||||||
switch (accessSize)
|
switch (accessSize)
|
||||||
{
|
{
|
||||||
case 64:
|
case 64:
|
||||||
ABI_CallFunctionC(reinterpret_cast<void*>(&PowerPC::Read_U64), address);
|
ABI_CallFunctionC(PowerPC::Read_U64, address);
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
ABI_CallFunctionC(reinterpret_cast<void*>(&PowerPC::Read_U32), address);
|
ABI_CallFunctionC(PowerPC::Read_U32, address);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
ABI_CallFunctionC(reinterpret_cast<void*>(&PowerPC::Read_U16_ZX), address);
|
ABI_CallFunctionC(PowerPC::Read_U16_ZX, address);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
ABI_CallFunctionC(reinterpret_cast<void*>(&PowerPC::Read_U8_ZX), address);
|
ABI_CallFunctionC(PowerPC::Read_U8_ZX, address);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
||||||
@ -507,16 +507,16 @@ bool EmuCodeBlock::WriteToConstAddress(int accessSize, OpArg arg, u32 address,
|
|||||||
switch (accessSize)
|
switch (accessSize)
|
||||||
{
|
{
|
||||||
case 64:
|
case 64:
|
||||||
ABI_CallFunctionAC(64, (void*)&PowerPC::Write_U64, arg, address);
|
ABI_CallFunctionAC(64, PowerPC::Write_U64, arg, address);
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
ABI_CallFunctionAC(32, (void*)&PowerPC::Write_U32, arg, address);
|
ABI_CallFunctionAC(32, PowerPC::Write_U32, arg, address);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
ABI_CallFunctionAC(16, (void*)&PowerPC::Write_U16, arg, address);
|
ABI_CallFunctionAC(16, PowerPC::Write_U16, arg, address);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
ABI_CallFunctionAC(8, (void*)&PowerPC::Write_U8, arg, address);
|
ABI_CallFunctionAC(8, PowerPC::Write_U8, arg, address);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
||||||
@ -613,19 +613,16 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
|
|||||||
switch (accessSize)
|
switch (accessSize)
|
||||||
{
|
{
|
||||||
case 64:
|
case 64:
|
||||||
ABI_CallFunctionRR(swap ? ((void*)&PowerPC::Write_U64) : ((void*)&PowerPC::Write_U64_Swap), reg,
|
ABI_CallFunctionRR(swap ? PowerPC::Write_U64 : PowerPC::Write_U64_Swap, reg, reg_addr);
|
||||||
reg_addr);
|
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
ABI_CallFunctionRR(swap ? ((void*)&PowerPC::Write_U32) : ((void*)&PowerPC::Write_U32_Swap), reg,
|
ABI_CallFunctionRR(swap ? PowerPC::Write_U32 : PowerPC::Write_U32_Swap, reg, reg_addr);
|
||||||
reg_addr);
|
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
ABI_CallFunctionRR(swap ? ((void*)&PowerPC::Write_U16) : ((void*)&PowerPC::Write_U16_Swap), reg,
|
ABI_CallFunctionRR(swap ? PowerPC::Write_U16 : PowerPC::Write_U16_Swap, reg, reg_addr);
|
||||||
reg_addr);
|
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
ABI_CallFunctionRR((void*)&PowerPC::Write_U8, reg, reg_addr);
|
ABI_CallFunctionRR(PowerPC::Write_U8, reg, reg_addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, rsp_alignment);
|
ABI_PopRegistersAndAdjustStack(registersInUse, rsp_alignment);
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#if defined(_M_X86_64)
|
#if defined(_M_X86_64)
|
||||||
|
|
||||||
#define PROFILER_QUERY_PERFORMANCE_COUNTER(pt) \
|
#define PROFILER_QUERY_PERFORMANCE_COUNTER(pt) \
|
||||||
MOV(64, R(ABI_PARAM1), Imm64((u64)pt)); \
|
MOV(64, R(ABI_PARAM1), Imm64(reinterpret_cast<u64>(pt))); \
|
||||||
ABI_CallFunction((const void*)QueryPerformanceCounter)
|
ABI_CallFunction(QueryPerformanceCounter)
|
||||||
|
|
||||||
// block->ticCounter += block->ticStop - block->ticStart
|
// block->ticCounter += block->ticStop - block->ticStart
|
||||||
#define PROFILER_UPDATE_TIME(block) \
|
#define PROFILER_UPDATE_TIME(block) \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user