fixed bitrot in recc

removed armv3 software interrupt callback
removed circular dependency between jit <-> x64_dispatch
This commit is contained in:
Anthony Pesch 2017-08-07 22:27:06 -04:00
parent 89541723f7
commit 648041696f
30 changed files with 329 additions and 322 deletions

View File

@ -26,7 +26,7 @@ struct arm7 {
/* jit */
struct jit *jit;
struct armv3_guest *guest;
struct jit_guest *guest;
struct jit_frontend *frontend;
struct jit_backend *backend;
@ -92,17 +92,6 @@ static void arm7_restore_mode(void *data) {
arm7_update_pending_interrupts(arm);
}
static void arm7_software_interrupt(void *data) {
struct arm7 *arm = data;
uint32_t newsr = (arm->ctx.r[CPSR] & ~M_MASK);
newsr |= I_MASK | MODE_SVC;
arm7_switch_mode(arm, newsr);
arm->ctx.r[14] = arm->ctx.r[15] + 4;
arm->ctx.r[15] = 0x08;
}
static void arm7_update_pending_interrupts(struct arm7 *arm) {
uint32_t interrupt_mask = 0;
@ -113,7 +102,7 @@ static void arm7_update_pending_interrupts(struct arm7 *arm) {
arm->ctx.pending_interrupts = arm->requested_interrupts & interrupt_mask;
}
void arm7_check_pending_interrupts(void *data) {
static void arm7_check_interrupts(void *data) {
struct arm7 *arm = data;
if (!arm->ctx.pending_interrupts) {
@ -132,6 +121,14 @@ void arm7_check_pending_interrupts(void *data) {
}
}
static void arm7_link_code(struct arm7 *arm, void *branch, uint32_t target) {
jit_link_code(arm->jit, branch, target);
}
static void arm7_compile_code(struct arm7 *arm, uint32_t addr) {
jit_compile_code(arm->jit, addr);
}
void arm7_raise_interrupt(struct arm7 *arm, enum arm7_interrupt intr) {
arm->requested_interrupts |= intr;
arm7_update_pending_interrupts(arm);
@ -140,7 +137,7 @@ void arm7_raise_interrupt(struct arm7 *arm, enum arm7_interrupt intr) {
void arm7_reset(struct arm7 *arm) {
LOG_INFO("arm7_reset");
jit_free_blocks(arm->jit);
jit_free_code(arm->jit);
/* reset context */
memset(&arm->ctx, 0, sizeof(arm->ctx));
@ -174,49 +171,58 @@ static void arm7_run(struct device *dev, int64_t ns) {
PROF_LEAVE();
}
static void arm7_guest_destroy(struct jit_guest *guest) {
free((struct armv3_guest *)guest);
}
static struct jit_guest *arm7_guest_create(struct arm7 *arm) {
struct armv3_guest *guest = calloc(1, sizeof(struct armv3_guest));
/* dispatch cache */
guest->addr_mask = 0x001ffffc;
/* memory interface */
guest->ctx = &arm->ctx;
guest->mem = as_translate(arm->memory_if->space, 0x0);
guest->space = arm->memory_if->space;
guest->lookup = &as_lookup;
guest->r8 = &as_read8;
guest->r16 = &as_read16;
guest->r32 = &as_read32;
guest->w8 = &as_write8;
guest->w16 = &as_write16;
guest->w32 = &as_write32;
/* runtime interface */
guest->data = arm;
guest->offset_pc = (int)offsetof(struct armv3_context, r[15]);
guest->offset_cycles = (int)offsetof(struct armv3_context, run_cycles);
guest->offset_instrs = (int)offsetof(struct armv3_context, ran_instrs);
guest->offset_interrupts =
(int)offsetof(struct armv3_context, pending_interrupts);
guest->compile_code = (jit_compile_cb)&arm7_compile_code;
guest->link_code = (jit_link_cb)&arm7_link_code;
guest->check_interrupts = (jit_interrupt_cb)&arm7_check_interrupts;
guest->switch_mode = (armv3_switch_mode_cb)&arm7_switch_mode;
guest->restore_mode = (armv3_restore_mode_cb)&arm7_restore_mode;
return (struct jit_guest *)guest;
}
static int arm7_init(struct device *dev) {
struct arm7 *arm = (struct arm7 *)dev;
struct dreamcast *dc = arm->dc;
/* initialize jit and its interfaces */
arm->frontend = armv3_frontend_create();
/* initialize jit */
arm->guest = arm7_guest_create(arm);
arm->frontend = armv3_frontend_create(arm->guest);
#if ARCH_X64
DEFINE_JIT_CODE_BUFFER(arm7_code);
arm->backend = x64_backend_create(arm7_code, sizeof(arm7_code));
arm->backend = x64_backend_create(arm->guest, arm7_code, sizeof(arm7_code));
#else
arm->backend = interp_backend_create();
arm->backend = interp_backend_create(arm->guest, arm->frontend);
#endif
{
arm->guest = armv3_guest_create();
arm->guest->addr_mask = 0x001ffffc;
arm->guest->offset_pc = (int)offsetof(struct armv3_context, r[15]);
arm->guest->offset_cycles = (int)offsetof(struct armv3_context, run_cycles);
arm->guest->offset_instrs = (int)offsetof(struct armv3_context, ran_instrs);
arm->guest->offset_interrupts =
(int)offsetof(struct armv3_context, pending_interrupts);
arm->guest->data = arm;
arm->guest->check_interrupts = &arm7_check_pending_interrupts;
arm->guest->ctx = &arm->ctx;
arm->guest->mem = as_translate(arm->memory_if->space, 0x0);
arm->guest->space = arm->memory_if->space;
arm->guest->switch_mode = &arm7_switch_mode;
arm->guest->restore_mode = &arm7_restore_mode;
arm->guest->software_interrupt = &arm7_software_interrupt;
arm->guest->lookup = &as_lookup;
arm->guest->r8 = &as_read8;
arm->guest->r16 = &as_read16;
arm->guest->r32 = &as_read32;
arm->guest->w8 = &as_write8;
arm->guest->w16 = &as_write16;
arm->guest->w32 = &as_write32;
}
arm->jit = jit_create("arm7", arm->frontend, arm->backend,
(struct jit_guest *)arm->guest);
arm->jit = jit_create("arm7", arm->frontend, arm->backend);
arm->wave_ram = memory_translate(dc->memory, "aica wave ram", 0x0);
@ -225,7 +231,7 @@ static int arm7_init(struct device *dev) {
void arm7_destroy(struct arm7 *arm) {
jit_destroy(arm->jit);
armv3_guest_destroy(arm->guest);
arm7_guest_destroy(arm->guest);
arm->frontend->destroy(arm->frontend);
arm->backend->destroy(arm->backend);

View File

@ -153,6 +153,14 @@ static void sh4_check_interrupts(struct sh4 *sh4) {
sh4_sr_updated(sh4, sh4->ctx.ssr);
}
static void sh4_link_code(struct sh4 *sh4, void *branch, uint32_t target) {
jit_link_code(sh4->jit, branch, target);
}
static void sh4_compile_code(struct sh4 *sh4, uint32_t addr) {
jit_compile_code(sh4->jit, addr);
}
static void sh4_invalid_instr(struct sh4 *sh4) {
sh4_exception(sh4, SH4_EXC_ILLINSTR);
}
@ -174,53 +182,62 @@ static void sh4_run(struct device *dev, int64_t ns) {
PROF_LEAVE();
}
static void sh4_guest_destroy(struct jit_guest *guest) {
free((struct sh4_guest *)guest);
}
static struct jit_guest *sh4_guest_create(struct sh4 *sh4) {
struct sh4_guest *guest = calloc(1, sizeof(struct sh4_guest));
/* dispatch cache */
guest->addr_mask = 0x00fffffe;
/* memory interface */
guest->ctx = &sh4->ctx;
guest->mem = as_translate(sh4->memory_if->space, 0x0);
guest->space = sh4->memory_if->space;
guest->lookup = &as_lookup;
guest->r8 = &as_read8;
guest->r16 = &as_read16;
guest->r32 = &as_read32;
guest->w8 = &as_write8;
guest->w16 = &as_write16;
guest->w32 = &as_write32;
/* runtime interface */
guest->data = sh4;
guest->offset_pc = (int)offsetof(struct sh4_context, pc);
guest->offset_cycles = (int)offsetof(struct sh4_context, run_cycles);
guest->offset_instrs = (int)offsetof(struct sh4_context, ran_instrs);
guest->offset_interrupts =
(int)offsetof(struct sh4_context, pending_interrupts);
guest->compile_code = (jit_compile_cb)&sh4_compile_code;
guest->link_code = (jit_link_cb)&sh4_link_code;
guest->check_interrupts = (jit_interrupt_cb)&sh4_check_interrupts;
guest->invalid_instr = (sh4_invalid_instr_cb)&sh4_invalid_instr;
guest->ltlb = (sh4_ltlb_cb)&sh4_mmu_ltlb;
guest->pref = (sh4_pref_cb)&sh4_ccn_pref;
guest->sleep = (sh4_sleep_cb)&sh4_sleep;
guest->sr_updated = (sh4_sr_updated_cb)&sh4_sr_updated;
guest->fpscr_updated = (sh4_fpscr_updated_cb)&sh4_fpscr_updated;
return (struct jit_guest *)guest;
}
static int sh4_init(struct device *dev) {
struct sh4 *sh4 = (struct sh4 *)dev;
struct dreamcast *dc = sh4->dc;
/* initialize jit and its interfaces */
sh4->frontend = sh4_frontend_create();
/* initialize jit */
sh4->guest = sh4_guest_create(sh4);
sh4->frontend = sh4_frontend_create(sh4->guest);
#if ARCH_X64
DEFINE_JIT_CODE_BUFFER(sh4_code);
sh4->backend = x64_backend_create(sh4_code, sizeof(sh4_code));
sh4->backend = x64_backend_create(sh4->guest, sh4_code, sizeof(sh4_code));
#else
sh4->backend = interp_backend_create();
sh4->backend = interp_backend_create(sh4->guest, sh4->frontend);
#endif
{
sh4->guest = sh4_guest_create();
sh4->guest->addr_mask = 0x00fffffe;
sh4->guest->data = sh4;
sh4->guest->offset_pc = (int)offsetof(struct sh4_context, pc);
sh4->guest->offset_cycles = (int)offsetof(struct sh4_context, run_cycles);
sh4->guest->offset_instrs = (int)offsetof(struct sh4_context, ran_instrs);
sh4->guest->offset_interrupts =
(int)offsetof(struct sh4_context, pending_interrupts);
sh4->guest->check_interrupts = (jit_interrupt_cb)&sh4_check_interrupts;
sh4->guest->ctx = &sh4->ctx;
sh4->guest->mem = as_translate(sh4->memory_if->space, 0x0);
sh4->guest->space = sh4->memory_if->space;
sh4->guest->invalid_instr = (sh4_invalid_instr_cb)&sh4_invalid_instr;
sh4->guest->ltlb = (sh4_ltlb_cb)&sh4_mmu_ltlb;
sh4->guest->pref = (sh4_pref_cb)&sh4_ccn_pref;
sh4->guest->sleep = (sh4_sleep_cb)&sh4_sleep;
sh4->guest->sr_updated = (sh4_sr_updated_cb)&sh4_sr_updated;
sh4->guest->fpscr_updated = (sh4_fpscr_updated_cb)&sh4_fpscr_updated;
sh4->guest->lookup = &as_lookup;
sh4->guest->r8 = &as_read8;
sh4->guest->r16 = &as_read16;
sh4->guest->r32 = &as_read32;
sh4->guest->w8 = &as_write8;
sh4->guest->w16 = &as_write16;
sh4->guest->w32 = &as_write32;
}
sh4->jit = jit_create("sh4", sh4->frontend, sh4->backend,
(struct jit_guest *)sh4->guest);
sh4->jit = jit_create("sh4", sh4->frontend, sh4->backend);
return 1;
}
@ -242,7 +259,7 @@ void sh4_set_exception_handler(struct sh4 *sh4,
}
void sh4_reset(struct sh4 *sh4, uint32_t pc) {
jit_free_blocks(sh4->jit);
jit_free_code(sh4->jit);
/* reset context */
memset(&sh4->ctx, 0, sizeof(sh4->ctx));
@ -276,17 +293,17 @@ void sh4_debug_menu(struct sh4 *sh4) {
if (igBeginMainMenuBar()) {
if (igBeginMenu("SH4", 1)) {
if (igMenuItem("clear cache", NULL, 0, 1)) {
jit_invalidate_blocks(sh4->jit);
jit_invalidate_code(sh4->jit);
}
if (!jit->dump_blocks) {
if (igMenuItem("start dumping blocks", NULL, 0, 1)) {
jit->dump_blocks = 1;
jit_invalidate_blocks(jit);
if (!jit->dump_code) {
if (igMenuItem("start dumping code", NULL, 0, 1)) {
jit->dump_code = 1;
jit_invalidate_code(jit);
}
} else {
if (igMenuItem("stop dumping blocks", NULL, 1, 1)) {
jit->dump_blocks = 0;
if (igMenuItem("stop dumping code", NULL, 1, 1)) {
jit->dump_code = 0;
}
}

View File

@ -12,7 +12,7 @@ struct dreamcast;
struct jit;
struct jit_backend;
struct jit_frontend;
struct sh4_guest;
struct jit_guest;
#define SH4_CLOCK_FREQ INT64_C(200000000)
@ -58,7 +58,7 @@ struct sh4 {
/* jit */
struct jit *jit;
struct sh4_guest *guest;
struct jit_guest *guest;
struct jit_frontend *frontend;
struct jit_backend *backend;

View File

@ -25,7 +25,7 @@ static void sh4_ccn_reset(struct sh4 *sh4) {
end the block */
LOG_INFO("sh4_ccn_reset");
jit_invalidate_blocks(sh4->jit);
jit_invalidate_code(sh4->jit);
}
void sh4_ccn_pref(struct sh4 *sh4, uint32_t addr) {

View File

@ -111,7 +111,7 @@ void sh4_dbg_remove_breakpoint(struct device *dev, int type, uint32_t addr) {
as_write16(sh4->memory_if->space, addr, bp->instr);
/* free code cache to remove block containing the invalid instruction */
jit_free_blocks(sh4->jit);
jit_free_code(sh4->jit);
destroy_breakpoint(sh4, bp);
}
@ -126,7 +126,7 @@ void sh4_dbg_add_breakpoint(struct device *dev, int type, uint32_t addr) {
as_write16(sh4->memory_if->space, addr, 0);
/* free code cache to remove block containing the original instruction */
jit_free_blocks(sh4->jit);
jit_free_code(sh4->jit);
}
void sh4_dbg_step(struct device *dev) {

View File

@ -1,16 +1,20 @@
#include <stdlib.h>
#include "jit/backend/jit_backend.h"
#include "jit/frontend/jit_frontend.h"
#include "jit/jit.h"
#include "jit/jit_backend.h"
#include "jit/jit_frontend.h"
#include "jit/jit_guest.h"
struct interp_backend {
struct jit_backend;
/* used to resolve the fallback handler for each instruction */
struct jit_frontend *frontend;
};
static void interp_backend_run_code(struct jit_backend *base, int cycles) {
struct interp_backend *backend = (struct interp_backend *)base;
struct jit *jit = backend->jit;
struct jit_guest *guest = jit->guest;
struct jit_frontend *frontend = backend->frontend;
struct jit_guest *guest = backend->guest;
uint8_t *ctx = guest->ctx;
uint32_t *pc = (uint32_t *)(ctx + guest->offset_pc);
int32_t *run_cycles = (int32_t *)(ctx + guest->offset_cycles);
@ -27,8 +31,7 @@ static void interp_backend_run_code(struct jit_backend *base, int cycles) {
do {
uint32_t addr = *pc;
uint32_t data = guest->r32(guest->space, addr);
const struct jit_opdef *def =
jit->frontend->lookup_op(jit->frontend, &data);
const struct jit_opdef *def = frontend->lookup_op(frontend, &data);
def->fallback(guest, addr, data);
cycles += def->cycles;
instrs += 1;
@ -57,14 +60,10 @@ static void interp_backend_destroy(struct jit_backend *base) {
free(backend);
}
static void interp_backend_init(struct jit_backend *base) {
struct interp_backend *backend = (struct interp_backend *)base;
}
struct jit_backend *interp_backend_create() {
struct jit_backend *interp_backend_create(struct jit_frontend *frontend) {
struct interp_backend *backend = calloc(1, sizeof(struct interp_backend));
backend->init = &interp_backend_init;
backend->frontend = frontend;
backend->destroy = &interp_backend_destroy;
/* compile interface */

View File

@ -1,8 +1,10 @@
#ifndef INTERP_BACKEND_H
#define INTERP_BACKEND_H
#include "jit/backend/jit_backend.h"
#include "jit/jit_backend.h"
struct jit_backend *interp_backend_create();
struct jit_frontend;
struct jit_backend *interp_backend_create(struct jit_frontend *frontend);
#endif

View File

@ -4,11 +4,12 @@ extern "C" {
#include "core/exception_handler.h"
#include "core/memory.h"
#include "core/profiler.h"
#include "jit/backend/jit_backend.h"
#include "jit/backend/x64/x64_backend.h"
#include "jit/backend/x64/x64_disassembler.h"
#include "jit/ir/ir.h"
#include "jit/jit.h"
#include "jit/jit_backend.h"
#include "jit/jit_guest.h"
}
/*
@ -309,8 +310,7 @@ static void x64_backend_emit_epilogue(struct x64_backend *backend,
static void x64_backend_emit_prologue(struct x64_backend *backend,
struct jit_block *block) {
struct jit *jit = backend->base.jit;
struct jit_guest *guest = jit->guest;
struct jit_guest *guest = backend->base.guest;
auto &e = *backend->codegen;
@ -479,7 +479,7 @@ static void x64_backend_emit_constants(struct x64_backend *backend) {
static int x64_backend_handle_exception(struct jit_backend *base,
struct exception_state *ex) {
struct x64_backend *backend = container_of(base, struct x64_backend, base);
struct jit_guest *guest = backend->base.jit->guest;
struct jit_guest *guest = backend->base.guest;
const uint8_t *data = (const uint8_t *)ex->thread_state.rip;
@ -631,27 +631,13 @@ static void x64_backend_destroy(struct jit_backend *base) {
free(backend);
}
static void x64_backend_init(struct jit_backend *base) {
struct x64_backend *backend = container_of(base, struct x64_backend, base);
x64_dispatch_init(backend);
/* emit thunks into a fixed amount of space to speed up resets */
x64_dispatch_emit_thunks(backend);
x64_backend_emit_thunks(backend);
x64_backend_emit_constants(backend);
CHECK_LT(backend->codegen->getSize(), X64_THUNK_SIZE);
}
struct jit_backend *x64_backend_create(void *code, int code_size) {
struct jit_backend *x64_backend_create(struct jit_guest *guest, void *code,
int code_size) {
struct x64_backend *backend =
(struct x64_backend *)calloc(1, sizeof(struct x64_backend));
Xbyak::util::Cpu cpu;
int r = protect_pages(code, code_size, ACC_READWRITEEXEC);
CHECK(r);
backend->base.init = &x64_backend_init;
backend->base.guest = guest;
backend->base.destroy = &x64_backend_destroy;
/* compile interface */
@ -672,11 +658,23 @@ struct jit_backend *x64_backend_create(void *code, int code_size) {
backend->base.patch_edge = &x64_dispatch_patch_edge;
backend->base.restore_edge = &x64_dispatch_restore_edge;
/* setup codegen buffer */
int r = protect_pages(code, code_size, ACC_READWRITEEXEC);
CHECK(r);
backend->codegen = new Xbyak::CodeGenerator(code_size, code);
backend->use_avx = cpu.has(Xbyak::util::Cpu::tAVX2);
/* create disassembler */
int res = cs_open(CS_ARCH_X86, CS_MODE_64, &backend->capstone_handle);
CHECK_EQ(res, CS_ERR_OK);
/* emit initial thunks */
x64_dispatch_init(backend);
x64_dispatch_emit_thunks(backend);
x64_backend_emit_thunks(backend);
x64_backend_emit_constants(backend);
CHECK_LT(backend->codegen->getSize(), X64_THUNK_SIZE);
return &backend->base;
}

View File

@ -1,8 +1,11 @@
#ifndef X64_BACKEND_H
#define X64_BACKEND_H
#include "jit/backend/jit_backend.h"
#include "jit/jit_backend.h"
struct jit_backend *x64_backend_create(void *code, int code_size);
struct jit_guest;
struct jit_backend *x64_backend_create(struct jit_guest *guest, void *code,
int code_size);
#endif

View File

@ -4,6 +4,7 @@ extern "C" {
#include "core/assert.h"
#include "core/profiler.h"
#include "jit/jit.h"
#include "jit/jit_guest.h"
}
DEFINE_COUNTER(edges_patched);
@ -79,7 +80,7 @@ void x64_dispatch_run_code(struct jit_backend *base, int cycles) {
}
void x64_dispatch_emit_thunks(struct x64_backend *backend) {
struct jit *jit = backend->base.jit;
struct jit_guest *guest = backend->base.guest;
auto &e = *backend->codegen;
@ -98,7 +99,7 @@ void x64_dispatch_emit_thunks(struct x64_backend *backend) {
/* invasively look into the jit's cache */
e.mov(e.rax, (uint64_t)backend->cache);
e.mov(e.ecx, e.dword[guestctx + jit->guest->offset_pc]);
e.mov(e.ecx, e.dword[guestctx + guest->offset_pc]);
e.and_(e.ecx, backend->cache_mask);
e.jmp(e.qword[e.rax + e.rcx * (sizeof(void *) >> backend->cache_shift)]);
}
@ -115,11 +116,11 @@ void x64_dispatch_emit_thunks(struct x64_backend *backend) {
backend->dispatch_static = e.getCurr<void *>();
#if LINK_STATIC_BRANCHES
e.mov(arg0, (uint64_t)jit);
e.mov(arg0, (uint64_t)guest->data);
e.pop(arg1);
e.sub(arg1, 5 /* sizeof jmp instr */);
e.mov(arg2, e.qword[guestctx + jit->guest->offset_pc]);
e.call(&jit_add_edge);
e.mov(arg2, e.qword[guestctx + guest->offset_pc]);
e.call(guest->link_code);
#else
e.pop(arg1);
#endif
@ -133,9 +134,9 @@ void x64_dispatch_emit_thunks(struct x64_backend *backend) {
backend->dispatch_compile = e.getCurr<void *>();
e.mov(arg0, (uint64_t)jit);
e.mov(arg1, e.dword[guestctx + jit->guest->offset_pc]);
e.call(&jit_compile_block);
e.mov(arg0, (uint64_t)guest->data);
e.mov(arg1, e.dword[guestctx + guest->offset_pc]);
e.call(guest->compile_code);
e.jmp(backend->dispatch_dynamic);
}
@ -146,8 +147,8 @@ void x64_dispatch_emit_thunks(struct x64_backend *backend) {
backend->dispatch_interrupt = e.getCurr<void *>();
e.mov(arg0, (uint64_t)jit->guest->data);
e.call(jit->guest->check_interrupts);
e.mov(arg0, (uint64_t)guest->data);
e.call(guest->check_interrupts);
e.jmp(backend->dispatch_dynamic);
}
@ -173,12 +174,12 @@ void x64_dispatch_emit_thunks(struct x64_backend *backend) {
e.sub(e.rsp, X64_STACK_SIZE + 8);
/* assign fixed registers */
e.mov(guestctx, (uint64_t)jit->guest->ctx);
e.mov(guestmem, (uint64_t)jit->guest->mem);
e.mov(guestctx, (uint64_t)guest->ctx);
e.mov(guestmem, (uint64_t)guest->mem);
/* reset run state */
e.mov(e.dword[guestctx + jit->guest->offset_cycles], arg0);
e.mov(e.dword[guestctx + jit->guest->offset_instrs], 0);
e.mov(e.dword[guestctx + guest->offset_cycles], arg0);
e.mov(e.dword[guestctx + guest->offset_instrs], 0);
e.jmp(backend->dispatch_dynamic);
}
@ -216,11 +217,11 @@ void x64_dispatch_shutdown(struct x64_backend *backend) {
}
void x64_dispatch_init(struct x64_backend *backend) {
struct jit *jit = backend->base.jit;
struct jit_guest *guest = backend->base.guest;
/* initialize code cache, one entry per possible block begin */
backend->cache_mask = jit->guest->addr_mask;
backend->cache_shift = ctz32(jit->guest->addr_mask);
backend->cache_mask = guest->addr_mask;
backend->cache_shift = ctz32(guest->addr_mask);
backend->cache_size = (backend->cache_mask >> backend->cache_shift) + 1;
backend->cache = (void **)malloc(backend->cache_size * sizeof(void *));
}

View File

@ -3,6 +3,7 @@
extern "C" {
#include "jit/ir/ir.h"
#include "jit/jit.h"
#include "jit/jit_guest.h"
}
#define EMITTER(op, constraints) \
@ -62,11 +63,13 @@ struct jit_emitter x64_emitters[IR_NUM_OPS];
EMITTER(SOURCE_INFO, CONSTRAINTS(NONE, IMM_I32, IMM_I32)) {
/*uint32_t addr = ARG0->i32;*/
int index = ARG1->i32;
block->source_map[index] = e.getCurr<void *>();
if (block->source_map) {
block->source_map[index] = e.getCurr<void *>();
}
}
EMITTER(FALLBACK, CONSTRAINTS(NONE, IMM_I64, IMM_I32, IMM_I32)) {
struct jit_guest *guest = backend->base.jit->guest;
struct jit_guest *guest = backend->base.guest;
void *fallback = (void *)ARG0->i64;
uint32_t addr = ARG1->i32;
uint32_t raw_instr = ARG2->i32;
@ -92,7 +95,7 @@ EMITTER(STORE_HOST, CONSTRAINTS(NONE, REG_I64, VAL_ALL)) {
}
EMITTER(LOAD_GUEST, CONSTRAINTS(REG_ALL, REG_I64 | IMM_I32)) {
struct jit_guest *guest = backend->base.jit->guest;
struct jit_guest *guest = backend->base.guest;
Xbyak::Reg dst = RES_REG;
struct ir_value *addr = ARG0;
@ -149,7 +152,7 @@ EMITTER(LOAD_GUEST, CONSTRAINTS(REG_ALL, REG_I64 | IMM_I32)) {
}
EMITTER(STORE_GUEST, CONSTRAINTS(NONE, REG_I64 | IMM_I32, VAL_ALL)) {
struct jit_guest *guest = backend->base.jit->guest;
struct jit_guest *guest = backend->base.guest;
struct ir_value *addr = ARG0;
struct ir_value *data = ARG1;
@ -903,7 +906,7 @@ EMITTER(LSHD, CONSTRAINTS(REG_ARG0, REG_I64, REG_I64)) {
}
EMITTER(BRANCH, CONSTRAINTS(NONE, REG_I64 | IMM_I32)) {
struct jit_guest *guest = backend->base.jit->guest;
struct jit_guest *guest = backend->base.guest;
if (ir_is_constant(ARG0)) {
uint32_t addr = ARG0->i32;
@ -917,7 +920,7 @@ EMITTER(BRANCH, CONSTRAINTS(NONE, REG_I64 | IMM_I32)) {
}
EMITTER(BRANCH_FALSE, CONSTRAINTS(NONE, REG_I64 | IMM_I32, REG_I64)) {
struct jit_guest *guest = backend->base.jit->guest;
struct jit_guest *guest = backend->base.guest;
Xbyak::Reg cond = ARG1_REG;
Xbyak::Label next;
@ -938,7 +941,7 @@ EMITTER(BRANCH_FALSE, CONSTRAINTS(NONE, REG_I64 | IMM_I32, REG_I64)) {
}
EMITTER(BRANCH_TRUE, CONSTRAINTS(NONE, REG_I64 | IMM_I32, REG_I64)) {
struct jit_guest *guest = backend->base.jit->guest;
struct jit_guest *guest = backend->base.guest;
Xbyak::Reg cond = ARG1_REG;
Xbyak::Label next;

View File

@ -9,7 +9,7 @@
#include <xbyak/xbyak_util.h>
extern "C" {
#include "jit/backend/jit_backend.h"
#include "jit/jit_backend.h"
}
enum xmm_constant {

View File

@ -2,7 +2,7 @@
#define ARMV3_DISASM_H
#include <stddef.h>
#include "jit/frontend/jit_frontend.h"
#include "jit/jit_frontend.h"
enum armv3_op_flag {
FLAG_SET_PC = 0x1,

View File

@ -781,10 +781,15 @@ FALLBACK(SWP) {
/*
* software interrupt
*/
FALLBACK(SWI) {
CHECK_COND();
REG(15) = addr + 4;
guest->software_interrupt(guest->data);
uint32_t oldsr = REG(CPSR);
uint32_t newsr = (oldsr & ~M_MASK) | I_MASK | MODE_SVC;
guest->switch_mode(guest->data, newsr);
REG(14) = addr + 4;
REG(15) = 0x8;
LOG_WARNING("SWI");
}

View File

@ -5,6 +5,7 @@
#include "jit/frontend/armv3/armv3_guest.h"
#include "jit/ir/ir.h"
#include "jit/jit.h"
#include "jit/jit_guest.h"
struct armv3_frontend {
struct jit_frontend;
@ -18,7 +19,7 @@ static const struct jit_opdef *armv3_frontend_lookup_op(
static void armv3_frontend_dump_code(struct jit_frontend *base,
const struct jit_block *block) {
struct armv3_frontend *frontend = (struct armv3_frontend *)base;
struct jit_guest *guest = frontend->jit->guest;
struct jit_guest *guest = frontend->guest;
char buffer[128];
@ -37,7 +38,7 @@ static void armv3_frontend_translate_code(struct jit_frontend *base,
struct jit_block *block,
struct ir *ir) {
struct armv3_frontend *frontend = (struct armv3_frontend *)base;
struct armv3_guest *guest = (struct armv3_guest *)frontend->jit->guest;
struct armv3_guest *guest = (struct armv3_guest *)frontend->guest;
for (int offset = 0; offset < block->guest_size; offset += 4) {
uint32_t addr = block->guest_addr + offset;
@ -52,7 +53,7 @@ static void armv3_frontend_translate_code(struct jit_frontend *base,
static void armv3_frontend_analyze_code(struct jit_frontend *base,
struct jit_block *block) {
struct armv3_frontend *frontend = (struct armv3_frontend *)base;
struct armv3_guest *guest = (struct armv3_guest *)frontend->jit->guest;
struct armv3_guest *guest = (struct armv3_guest *)frontend->guest;
uint32_t addr = block->guest_addr;
block->guest_size = 0;
@ -91,12 +92,10 @@ void armv3_frontend_destroy(struct jit_frontend *base) {
free(frontend);
}
static void armv3_frontend_init(struct jit_frontend *frontend) {}
struct jit_frontend *armv3_frontend_create() {
struct jit_frontend *armv3_frontend_create(struct jit_guest *guest) {
struct armv3_frontend *frontend = calloc(1, sizeof(struct armv3_frontend));
frontend->init = &armv3_frontend_init;
frontend->guest = guest;
frontend->destroy = &armv3_frontend_destroy;
frontend->analyze_code = &armv3_frontend_analyze_code;
frontend->translate_code = &armv3_frontend_translate_code;

View File

@ -1,12 +1,14 @@
#ifndef ARMV3_FRONTEND_H
#define ARMV3_FRONTEND_H
#include "jit/frontend/jit_frontend.h"
#include "jit/jit_frontend.h"
struct jit_guest;
enum armv3_block_flags {
PC_SET = 0x1,
};
struct jit_frontend *armv3_frontend_create();
struct jit_frontend *armv3_frontend_create(struct jit_guest *guest);
#endif

View File

@ -1,23 +1,18 @@
#ifndef ARMV3_GUEST_H
#define ARMV3_GUEST_H
#include "jit/jit.h"
#include <stdlib.h>
#include "jit/jit_guest.h"
typedef void (*armv3_switch_mode_cb)(void *, uint32_t);
typedef void (*armv3_restore_mode_cb)(void *);
struct armv3_guest {
struct jit_guest;
/* runtime interface */
void (*switch_mode)(void *, uint32_t);
void (*restore_mode)(void *);
void (*software_interrupt)(void *);
armv3_switch_mode_cb switch_mode;
armv3_restore_mode_cb restore_mode;
};
static inline struct armv3_guest *armv3_guest_create() {
return calloc(1, sizeof(struct armv3_guest));
}
static inline void armv3_guest_destroy(struct armv3_guest *guest) {
free(guest);
}
#endif

View File

@ -2,7 +2,7 @@
#define SH4_DISASM_H
#include <stddef.h>
#include "jit/frontend/jit_frontend.h"
#include "jit/jit_frontend.h"
enum {
SH4_FLAG_INVALID = 0x1,

View File

@ -1,12 +1,13 @@
#include "jit/frontend/sh4/sh4_frontend.h"
#include "core/profiler.h"
#include "jit/frontend/jit_frontend.h"
#include "jit/frontend/sh4/sh4_disasm.h"
#include "jit/frontend/sh4/sh4_fallback.h"
#include "jit/frontend/sh4/sh4_guest.h"
#include "jit/frontend/sh4/sh4_translate.h"
#include "jit/ir/ir.h"
#include "jit/jit.h"
#include "jit/jit_frontend.h"
#include "jit/jit_guest.h"
/*
* fsca estimate lookup table, used by the jit and interpreter
@ -27,7 +28,7 @@ static const struct jit_opdef *sh4_frontend_lookup_op(struct jit_frontend *base,
static void sh4_frontend_dump_code(struct jit_frontend *base,
const struct jit_block *block) {
struct sh4_frontend *frontend = (struct sh4_frontend *)base;
struct jit_guest *guest = frontend->jit->guest;
struct jit_guest *guest = frontend->guest;
char buffer[128];
@ -61,7 +62,7 @@ static void sh4_frontend_translate_code(struct jit_frontend *base,
struct jit_block *block,
struct ir *ir) {
struct sh4_frontend *frontend = (struct sh4_frontend *)base;
struct sh4_guest *guest = (struct sh4_guest *)frontend->jit->guest;
struct sh4_guest *guest = (struct sh4_guest *)frontend->guest;
struct sh4_context *ctx = (struct sh4_context *)guest->ctx;
PROF_ENTER("cpu", "sh4_frontend_translate_code");
@ -156,7 +157,7 @@ static void sh4_frontend_translate_code(struct jit_frontend *base,
static void sh4_frontend_analyze_code(struct jit_frontend *base,
struct jit_block *block) {
struct sh4_frontend *frontend = (struct sh4_frontend *)base;
struct sh4_guest *guest = (struct sh4_guest *)frontend->jit->guest;
struct sh4_guest *guest = (struct sh4_guest *)frontend->guest;
static int IDLE_MASK = SH4_FLAG_LOAD | SH4_FLAG_COND | SH4_FLAG_CMP;
int idle_loop = 1;
@ -294,12 +295,10 @@ static void sh4_frontend_destroy(struct jit_frontend *base) {
free(frontend);
}
static void sh4_frontend_init(struct jit_frontend *base) {}
struct jit_frontend *sh4_frontend_create() {
struct jit_frontend *sh4_frontend_create(struct jit_guest *guest) {
struct sh4_frontend *frontend = calloc(1, sizeof(struct sh4_frontend));
frontend->init = &sh4_frontend_init;
frontend->guest = guest;
frontend->destroy = &sh4_frontend_destroy;
frontend->analyze_code = &sh4_frontend_analyze_code;
frontend->translate_code = &sh4_frontend_translate_code;

View File

@ -1,7 +1,9 @@
#ifndef SH4_FRONTEND_H
#define SH4_FRONTEND_H
#include "jit/frontend/jit_frontend.h"
#include "jit/jit_frontend.h"
struct jit_guest;
enum {
SH4_DOUBLE_PR = 0x1,
@ -10,6 +12,6 @@ enum {
extern uint32_t sh4_fsca_table[];
struct jit_frontend *sh4_frontend_create();
struct jit_frontend *sh4_frontend_create(struct jit_guest *guest);
#endif

View File

@ -2,7 +2,8 @@
#define SH4_GUEST_H
#include <stdint.h>
#include "jit/jit.h"
#include <stdlib.h>
#include "jit/jit_guest.h"
/*
* sh4 guest context
@ -181,12 +182,4 @@ struct sh4_guest {
sh4_fpscr_updated_cb fpscr_updated;
};
static inline struct sh4_guest *sh4_guest_create() {
return calloc(1, sizeof(struct sh4_guest));
}
static inline void sh4_guest_destroy(struct sh4_guest *guest) {
free(guest);
}
#endif

View File

@ -5,9 +5,9 @@
#include "core/filesystem.h"
#include "core/option.h"
#include "core/profiler.h"
#include "jit/backend/jit_backend.h"
#include "jit/frontend/jit_frontend.h"
#include "jit/ir/ir.h"
#include "jit/jit_backend.h"
#include "jit/jit_frontend.h"
#include "jit/passes/constant_propagation_pass.h"
#include "jit/passes/dead_code_elimination_pass.h"
#include "jit/passes/expression_simplification_pass.h"
@ -203,7 +203,7 @@ static struct jit_block *jit_alloc_block(struct jit *jit) {
return block;
}
void jit_free_blocks(struct jit *jit) {
void jit_free_code(struct jit *jit) {
/* invalidate code pointers and remove block entries from lookup maps. this
is only safe to use when no code is currently executing */
struct rb_node *it = rb_first(&jit->blocks);
@ -221,7 +221,7 @@ void jit_free_blocks(struct jit *jit) {
jit->backend->reset(jit->backend);
}
void jit_invalidate_blocks(struct jit *jit) {
void jit_invalidate_code(struct jit *jit) {
/* invalidate code pointers, but don't remove block entries from lookup maps.
this is used when clearing the jit while code is currently executing */
struct rb_node *it = rb_first(&jit->blocks);
@ -238,7 +238,7 @@ void jit_invalidate_blocks(struct jit *jit) {
/* don't reset backend code buffers, code is still running */
}
void jit_add_edge(struct jit *jit, void *branch, uint32_t addr) {
void jit_link_code(struct jit *jit, void *branch, uint32_t addr) {
struct jit_block *src = jit_lookup_block_reverse(jit, branch);
struct jit_block *dst = jit_get_block(jit, addr);
@ -274,7 +274,7 @@ static void jit_dump_block(struct jit *jit, uint32_t guest_addr,
fclose(file);
}
void jit_compile_block(struct jit *jit, uint32_t guest_addr) {
void jit_compile_code(struct jit *jit, uint32_t guest_addr) {
PROF_ENTER("cpu", "jit_compile_block");
#if 0
@ -332,7 +332,7 @@ void jit_compile_block(struct jit *jit, uint32_t guest_addr) {
#endif
/* dump unoptimized block */
if (jit->dump_blocks) {
if (jit->dump_code) {
jit_dump_block(jit, guest_addr, &ir);
}
@ -364,7 +364,7 @@ void jit_compile_block(struct jit *jit, uint32_t guest_addr) {
/* if the backend overflowed, completely free the cache and let dispatch
try to compile again */
LOG_INFO("backend overflow, resetting code cache");
jit_free_blocks(jit);
jit_free_code(jit);
}
PROF_LEAVE();
@ -420,7 +420,7 @@ void jit_destroy(struct jit *jit) {
}
if (jit->backend) {
jit_free_blocks(jit);
jit_free_code(jit);
}
if (jit->dce) {
@ -447,23 +447,14 @@ void jit_destroy(struct jit *jit) {
}
struct jit *jit_create(const char *tag, struct jit_frontend *frontend,
struct jit_backend *backend, struct jit_guest *guest) {
struct jit_backend *backend) {
struct jit *jit = calloc(1, sizeof(struct jit));
strncpy(jit->tag, tag, sizeof(jit->tag));
jit->frontend = frontend;
frontend->jit = jit;
jit->backend = backend;
backend->jit = jit;
jit->guest = guest;
/* setup exception handler to deal with self-modifying code and fastmem
related exceptions */
jit->exc_handler = exception_handler_add(jit, &jit_handle_exception);
/* create optimization passes */
jit->lse = lse_create();
jit->cprop = cprop_create();
jit->esimp = esimp_create();
@ -471,6 +462,10 @@ struct jit *jit_create(const char *tag, struct jit_frontend *frontend,
jit->ra = ra_create(jit->backend->registers, jit->backend->num_registers,
jit->backend->emitters, jit->backend->num_emitters);
/* setup exception handler to deal with self-modifying code and fastmem
related exceptions */
jit->exc_handler = exception_handler_add(jit, &jit_handle_exception);
/* open perf map if enabled */
if (OPTION_perf) {
#if PLATFORM_DARWIN || PLATFORM_LINUX
@ -482,8 +477,5 @@ struct jit *jit_create(const char *tag, struct jit_frontend *frontend,
#endif
}
jit->frontend->init(jit->frontend);
jit->backend->init(jit->backend);
return jit;
}

View File

@ -14,10 +14,6 @@ struct lse;
struct ra;
struct val;
typedef void (*jit_interrupt_cb)(void *);
typedef uint32_t (*mem_read_cb)(void *, uint32_t, uint32_t);
typedef void (*mem_write_cb)(void *, uint32_t, uint32_t, uint32_t);
enum {
JIT_BRANCH_STATIC,
JIT_BRANCH_STATIC_TRUE,
@ -90,41 +86,11 @@ struct jit_edge {
struct list_node out_it;
};
struct jit_guest {
/* mask used to directly map each guest address to a block of code */
uint32_t addr_mask;
/* runtime interface used by the backend when compiling each block's
prologue / epilogue */
void *data;
int offset_pc;
int offset_cycles;
int offset_instrs;
int offset_interrupts;
jit_interrupt_cb check_interrupts;
/* memory interface */
void *ctx;
void *mem;
struct address_space *space;
void (*lookup)(struct address_space *, uint32_t, void **, void **,
mem_read_cb *, mem_write_cb *, uint32_t *);
uint8_t (*r8)(struct address_space *, uint32_t);
uint16_t (*r16)(struct address_space *, uint32_t);
uint32_t (*r32)(struct address_space *, uint32_t);
uint64_t (*r64)(struct address_space *, uint32_t);
void (*w8)(struct address_space *, uint32_t, uint8_t);
void (*w16)(struct address_space *, uint32_t, uint16_t);
void (*w32)(struct address_space *, uint32_t, uint32_t);
void (*w64)(struct address_space *, uint32_t, uint64_t);
};
struct jit {
char tag[32];
struct jit_frontend *frontend;
struct jit_backend *backend;
struct jit_guest *guest;
struct exception_handler *exc_handler;
/* passes */
@ -146,19 +112,19 @@ struct jit {
FILE *perf_map;
/* dump ir to application directory as blocks compile */
int dump_blocks;
int dump_code;
};
struct jit *jit_create(const char *tag, struct jit_frontend *frontend,
struct jit_backend *backend, struct jit_guest *guest);
struct jit_backend *backend);
void jit_destroy(struct jit *jit);
void jit_run(struct jit *jit, int cycles);
void jit_compile_block(struct jit *jit, uint32_t guest_addr);
void jit_add_edge(struct jit *jit, void *code, uint32_t dst);
void jit_compile_code(struct jit *jit, uint32_t guest_addr);
void jit_link_code(struct jit *jit, void *code, uint32_t target);
void jit_invalidate_blocks(struct jit *jit);
void jit_free_blocks(struct jit *jit);
void jit_invalidate_code(struct jit *jit);
void jit_free_code(struct jit *jit);
#endif

View File

@ -5,8 +5,8 @@
#include "jit/ir/ir.h"
struct exception_state;
struct jit;
struct jit_block;
struct jit_guest;
/* macro to help declare a code buffer for the backends to use
@ -70,7 +70,7 @@ struct jit_emitter {
};
struct jit_backend {
struct jit *jit;
struct jit_guest *guest;
const struct jit_register *registers;
int num_registers;
@ -78,7 +78,6 @@ struct jit_backend {
const struct jit_emitter *emitters;
int num_emitters;
void (*init)(struct jit_backend *);
void (*destroy)(struct jit_backend *);
/* compile interface */

View File

@ -4,7 +4,6 @@
#include <stdint.h>
struct ir;
struct jit;
struct jit_block;
struct jit_guest;
struct jit_frontend;
@ -22,9 +21,8 @@ struct jit_opdef {
};
struct jit_frontend {
struct jit *jit;
struct jit_guest *guest;
void (*init)(struct jit_frontend *);
void (*destroy)(struct jit_frontend *);
void (*analyze_code)(struct jit_frontend *, struct jit_block *);

45
src/jit/jit_guest.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef JIT_GUEST_H
#define JIT_GUEST_H
#include <stdint.h>
typedef uint32_t (*mem_read_cb)(void *, uint32_t, uint32_t);
typedef void (*mem_write_cb)(void *, uint32_t, uint32_t, uint32_t);
typedef void (*jit_compile_cb)(void *, uint32_t);
typedef void (*jit_link_cb)(void *, uint32_t);
typedef void (*jit_interrupt_cb)(void *);
struct address_space;
struct jit_guest {
/* mask used to directly map each guest address to a block of code */
uint32_t addr_mask;
/* memory interface used by both the frontend and backend */
void *ctx;
void *mem;
struct address_space *space;
void (*lookup)(struct address_space *, uint32_t, void **, void **,
mem_read_cb *, mem_write_cb *, uint32_t *);
uint8_t (*r8)(struct address_space *, uint32_t);
uint16_t (*r16)(struct address_space *, uint32_t);
uint32_t (*r32)(struct address_space *, uint32_t);
uint64_t (*r64)(struct address_space *, uint32_t);
void (*w8)(struct address_space *, uint32_t, uint8_t);
void (*w16)(struct address_space *, uint32_t, uint16_t);
void (*w32)(struct address_space *, uint32_t, uint32_t);
void (*w64)(struct address_space *, uint32_t, uint64_t);
/* runtime interface used by the backend and dispatch */
void *data;
int offset_pc;
int offset_cycles;
int offset_instrs;
int offset_interrupts;
jit_compile_cb compile_code;
jit_link_cb link_code;
jit_interrupt_cb check_interrupts;
};
#endif

View File

@ -15,7 +15,7 @@ void pass_stats_unregister(struct pass_stat *stat) {
void pass_stats_dump() {
LOG_INFO("===-----------------------------------------------------===");
LOG_INFO("Pass stats");
LOG_INFO("pass stats");
LOG_INFO("===-----------------------------------------------------===");
int w = 0;

View File

@ -2,8 +2,8 @@
#include "jit/passes/register_allocation_pass.h"
#include "core/list.h"
#include "core/math.h"
#include "jit/backend/jit_backend.h"
#include "jit/ir/ir.h"
#include "jit/jit_backend.h"
#include "jit/pass_stats.h"
/* second-chance binpacking register allocator based off of the paper "Quality

View File

@ -2,27 +2,24 @@
#include "core/log.h"
#include "core/option.h"
#include "jit/backend/x64/x64_backend.h"
#include "jit/frontend/sh4/sh4_disasm.h"
#include "jit/ir/ir.h"
#include "jit/jit.h"
#include "jit/jit_guest.h"
#include "jit/pass_stats.h"
#include "jit/passes/constant_propagation_pass.h"
#include "jit/passes/conversion_elimination_pass.h"
#include "jit/passes/dead_code_elimination_pass.h"
#include "jit/passes/expression_simplification_pass.h"
#include "jit/passes/load_store_elimination_pass.h"
#include "jit/passes/register_allocation_pass.h"
DEFINE_OPTION_INT(help, 0, "Show help");
DEFINE_OPTION_STRING(pass, "lse,cprop,cve,esimp,dce,ra",
DEFINE_OPTION_STRING(pass, "lse,cprop,esimp,dce,ra",
"Comma-separated list of passes to run");
DEFINE_STAT(ir_instrs_total, "total ir instructions");
DEFINE_STAT(ir_instrs_removed, "removed ir instructions");
DEFINE_JIT_CODE_BUFFER(code);
static uint8_t ir_buffer[1024 * 1024];
static uint8_t code[1024 * 1024];
static int code_size = sizeof(code);
static int get_num_instrs(const struct ir *ir) {
int n = 0;
@ -54,7 +51,7 @@ static void sanitize_ir(struct ir *ir) {
}
}
static void process_file(struct jit *jit, const char *filename,
static void process_file(struct jit_backend *backend, const char *filename,
int disable_dumps) {
struct ir ir = {0};
ir.buffer = ir_buffer;
@ -71,7 +68,7 @@ static void process_file(struct jit *jit, const char *filename,
sanitize_ir(&ir);
/* run optimization passes */
char passes[MAX_OPTION_LENGTH];
char passes[OPTION_MAX_LENGTH];
strncpy(passes, OPTION_pass, sizeof(passes));
int num_instrs_before = get_num_instrs(&ir);
@ -95,18 +92,18 @@ static void process_file(struct jit *jit, const char *filename,
esimp_run(esimp, &ir);
esimp_destroy(esimp);
} else if (!strcmp(name, "ra")) {
struct ra *ra =
ra_create(jit->backend->registers, jit->backend->num_registers);
struct ra *ra = ra_create(backend->registers, backend->num_registers,
backend->emitters, backend->num_emitters);
ra_run(ra, &ir);
ra_destroy(ra);
} else {
LOG_WARNING("Unknown pass %s", name);
LOG_WARNING("unknown pass %s", name);
}
/* print ir after each pass if requested */
if (!disable_dumps) {
LOG_INFO("===-----------------------------------------------------===");
LOG_INFO("IR after %s", name);
LOG_INFO("ir after %s", name);
LOG_INFO("===-----------------------------------------------------===");
ir_write(&ir, stdout);
LOG_INFO("");
@ -118,17 +115,16 @@ static void process_file(struct jit *jit, const char *filename,
int num_instrs_after = get_num_instrs(&ir);
/* assemble backend code */
struct jit_block block;
jit->backend->reset(jit->backend);
int res = jit->backend->assemble_code(jit->backend, &block, &ir);
struct jit_block block = {0};
backend->reset(backend);
int res = backend->assemble_code(backend, &block, &ir);
CHECK(res);
if (!disable_dumps) {
LOG_INFO("===-----------------------------------------------------===");
LOG_INFO("X64 code");
LOG_INFO("x64 code");
LOG_INFO("===-----------------------------------------------------===");
jit->backend->dump_code(jit->backend, block.host_addr, block.host_size);
backend->dump_code(backend, &block);
LOG_INFO("");
}
@ -137,11 +133,11 @@ static void process_file(struct jit *jit, const char *filename,
STAT_ir_instrs_removed += num_instrs_before - num_instrs_after;
}
static void process_dir(struct jit *jit, const char *path) {
static void process_dir(struct jit_backend *backend, const char *path) {
DIR *dir = opendir(path);
if (!dir) {
LOG_WARNING("Failed to open directory %s", path);
LOG_WARNING("failed to open directory %s", path);
return;
}
@ -156,48 +152,35 @@ static void process_dir(struct jit *jit, const char *path) {
snprintf(filename, sizeof(filename), "%s" PATH_SEPARATOR "%s", path,
ent->d_name);
LOG_INFO("Processing %s", filename);
LOG_INFO("processing %s", filename);
process_file(jit, filename, 1);
process_file(backend, filename, 1);
}
closedir(dir);
}
int main(int argc, char **argv) {
options_parse(&argc, &argv);
if (OPTION_help) {
options_print_help();
return EXIT_SUCCESS;
if (!options_parse(&argc, &argv)) {
return EXIT_FAILURE;
}
const char *path = argv[1];
struct jit_guest guest = {0};
guest.r8 = (void *)code;
guest.r16 = (void *)code;
guest.r32 = (void *)code;
guest.w8 = (void *)code;
guest.w16 = (void *)code;
guest.w32 = (void *)code;
guest.addr_mask = 0xff;
struct jit_backend *backend = x64_backend_create(code, code_size);
/* initailize jit, stubbing out guest interfaces that are used during
assembly to a valid address */
struct jit *jit = jit_create("recc", NULL, backend, &guest);
struct jit_backend *backend = x64_backend_create(&guest, code, sizeof(code));
if (fs_isfile(path)) {
process_file(jit, path, 0);
process_file(backend, path, 0);
} else {
process_dir(jit, path);
process_dir(backend, path);
}
LOG_INFO("");
pass_stats_dump();
jit_destroy(jit);
backend->destroy(backend);
return EXIT_SUCCESS;

View File

@ -2,8 +2,8 @@
#include <stdlib.h>
#include "core/assert.h"
#include "core/sort.h"
#include "file/trace.h"
#include "guest/pvr/tr.h"
#include "guest/pvr/trace.h"
struct depth_entry {
/* vertex index */