2021-01-26 12:16:48 +00:00
|
|
|
/*
|
|
|
|
Copyright 2021 flyinghead
|
|
|
|
|
|
|
|
This file is part of Flycast.
|
|
|
|
|
|
|
|
Flycast is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
Flycast is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2021-05-22 08:43:41 +00:00
|
|
|
#pragma once
|
2021-01-26 12:16:48 +00:00
|
|
|
|
|
|
|
#include <xbyak/xbyak.h>
|
|
|
|
#include <xbyak/xbyak_util.h>
|
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
#include "hw/sh4/dyna/ngen.h"
|
|
|
|
#include "x86_regalloc.h"
|
|
|
|
#include "rec-x64/xbyak_base.h"
|
|
|
|
|
|
|
|
class X86Compiler : public BaseXbyakRec<X86Compiler, false>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using BaseCompiler = BaseXbyakRec<X86Compiler, false>;
|
|
|
|
|
2023-09-12 14:52:25 +00:00
|
|
|
X86Compiler(Sh4CodeBuffer& codeBuffer) : BaseCompiler(codeBuffer), regalloc(this) { }
|
|
|
|
X86Compiler(Sh4CodeBuffer& codeBuffer, u8 *code_ptr) : BaseCompiler(codeBuffer, code_ptr), regalloc(this) { }
|
2021-01-26 12:16:48 +00:00
|
|
|
|
|
|
|
void compile(RuntimeBlockInfo* block, bool force_checks, bool optimise);
|
|
|
|
|
|
|
|
void ngen_CC_Start(const shil_opcode& op)
|
|
|
|
{
|
|
|
|
CC_stackSize = 0;
|
|
|
|
}
|
|
|
|
void ngen_CC_param(const shil_opcode& op, const shil_param& param, CanonicalParamType tp);
|
|
|
|
void ngen_CC_Call(const shil_opcode& op, void* function)
|
|
|
|
{
|
|
|
|
genCallCdecl((void (*)())function);
|
|
|
|
}
|
2021-08-01 15:07:17 +00:00
|
|
|
void ngen_CC_Finish(const shil_opcode &op);
|
2021-01-26 12:16:48 +00:00
|
|
|
|
|
|
|
void regPreload(u32 reg, Xbyak::Operand::Code nreg)
|
|
|
|
{
|
|
|
|
DEBUG_LOG(DYNAREC, "RegPreload reg %d -> %s", reg, Xbyak::Reg32(nreg).toString());
|
|
|
|
mov(Xbyak::Reg32(nreg), dword[GetRegPtr(reg)]);
|
|
|
|
}
|
|
|
|
void regWriteback(u32 reg, Xbyak::Operand::Code nreg)
|
|
|
|
{
|
|
|
|
DEBUG_LOG(DYNAREC, "RegWriteback reg %d <- %s", reg, Xbyak::Reg32(nreg).toString());
|
|
|
|
mov(dword[GetRegPtr(reg)], Xbyak::Reg32(nreg));
|
|
|
|
}
|
|
|
|
void regPreload_FPU(u32 reg, s8 nreg)
|
|
|
|
{
|
|
|
|
DEBUG_LOG(DYNAREC, "RegPreload_FPU reg %d -> xmm%d", reg, nreg);
|
|
|
|
movss(Xbyak::Xmm(nreg), dword[GetRegPtr(reg)]);
|
|
|
|
}
|
|
|
|
void regWriteback_FPU(u32 reg, s8 nreg)
|
|
|
|
{
|
|
|
|
DEBUG_LOG(DYNAREC, "RegWriteback_FPU reg %d <- xmm%d", reg, nreg);
|
|
|
|
movss(dword[GetRegPtr(reg)], Xbyak::Xmm(nreg));
|
|
|
|
}
|
|
|
|
|
|
|
|
void genMainloop();
|
|
|
|
u32 relinkBlock(RuntimeBlockInfo *block);
|
2021-01-30 15:14:44 +00:00
|
|
|
bool rewriteMemAccess(host_context_t &context);
|
2021-01-26 12:16:48 +00:00
|
|
|
|
2023-01-28 18:22:36 +00:00
|
|
|
static void (*handleException)();
|
|
|
|
|
2021-01-26 12:16:48 +00:00
|
|
|
private:
|
|
|
|
void genOpcode(RuntimeBlockInfo *block, bool optimise, shil_opcode& op);
|
|
|
|
|
|
|
|
bool genReadMemImmediate(const shil_opcode& op, RuntimeBlockInfo *block);
|
|
|
|
bool genWriteMemImmediate(const shil_opcode& op, RuntimeBlockInfo *block);
|
2021-01-28 15:29:21 +00:00
|
|
|
void genMemHandlers();
|
2021-08-01 15:07:17 +00:00
|
|
|
void alignStack(int amount);
|
2023-01-28 18:22:36 +00:00
|
|
|
void genMmuLookup(RuntimeBlockInfo* block, const shil_opcode& op, u32 write);
|
2021-01-26 12:16:48 +00:00
|
|
|
|
|
|
|
void checkBlock(bool smc_checks, RuntimeBlockInfo *block);
|
|
|
|
void freezeXMM();
|
|
|
|
void thawXMM();
|
|
|
|
|
|
|
|
template<class Ret, class... Params>
|
|
|
|
void genCallCdecl(Ret (*function)(Params...))
|
|
|
|
{
|
|
|
|
freezeXMM();
|
|
|
|
call((void *)function);
|
|
|
|
thawXMM();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class Ret, class... Params>
|
|
|
|
void genCall(Ret (DYNACALL *function)(Params...))
|
|
|
|
{
|
|
|
|
genCallCdecl((Ret (*)(Params...))function);
|
|
|
|
}
|
|
|
|
|
|
|
|
X86RegAlloc regalloc;
|
|
|
|
size_t current_opid;
|
|
|
|
u32 CC_stackSize;
|
|
|
|
|
|
|
|
friend class BaseXbyakRec<X86Compiler, false>;
|
|
|
|
};
|