BizHawk/waterbox/ares64/ares/nall/recompiler/generic/generic.hpp

70 lines
2.0 KiB
C++

#pragma once
#if defined(SLJIT)
namespace nall::recompiler {
struct generic {
static constexpr bool supported = Architecture::amd64 | Architecture::arm64 | Architecture::ppc64;
bump_allocator& allocator;
sljit_compiler* compiler = nullptr;
sljit_label* epilogue = nullptr;
generic(bump_allocator& alloc) : allocator(alloc) {}
~generic() { resetCompiler(); }
auto beginFunction(int args) -> void {
assert(args <= 3);
resetCompiler();
compiler = sljit_create_compiler(nullptr, &allocator);
sljit_s32 options = 0;
if(args >= 1) options |= SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_W, 1);
if(args >= 2) options |= SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_W, 2);
if(args >= 3) options |= SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_W, 3);
sljit_emit_enter(compiler, 0, options, 4, 3, 0, 0, 0);
sljit_jump* entry = sljit_emit_jump(compiler, SLJIT_JUMP);
epilogue = sljit_emit_label(compiler);
sljit_emit_return_void(compiler);
sljit_set_label(entry, sljit_emit_label(compiler));
}
auto endFunction() -> u8* {
u8* code = (u8*)sljit_generate_code(compiler);
resetCompiler();
return code;
}
auto resetCompiler() -> void {
if(compiler) sljit_free_compiler(compiler);
compiler = nullptr;
epilogue = nullptr;
}
auto testJumpEpilog() -> void {
sljit_set_label(sljit_emit_cmp(compiler, SLJIT_NOT_EQUAL | SLJIT_32, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0), epilogue);
}
auto jumpEpilog() -> void {
sljit_set_label(sljit_emit_jump(compiler, SLJIT_JUMP), epilogue);
}
auto setLabel(sljit_jump* jump) -> void {
sljit_set_label(jump, sljit_emit_label(compiler));
}
auto jump() -> sljit_jump* {
return sljit_emit_jump(compiler, SLJIT_JUMP);
}
auto jump(sljit_s32 flag) -> sljit_jump* {
return sljit_emit_jump(compiler, flag);
}
#include "constants.hpp"
#include "encoder-instructions.hpp"
#include "encoder-calls.hpp"
};
}
#endif