diff --git a/src/hw/aica/aica.c b/src/hw/aica/aica.c index 84c36e10..40355272 100644 --- a/src/hw/aica/aica.c +++ b/src/hw/aica/aica.c @@ -201,18 +201,6 @@ static void aica_timer_reschedule(struct aica *aica, int n, uint32_t period) { scheduler_start_timer(aica->scheduler, timer_cbs[n], aica, remaining); } -static void aica_timer_shutdown(struct aica *aica) { - for (int i = 0; i < 3; i++) { - scheduler_cancel_timer(aica->scheduler, aica->timers[i]); - } -} - -static void aica_timer_init(struct aica *aica) { - for (int i = 0; i < 3; i++) { - aica_timer_reschedule(aica, i, AICA_TIMER_PERIOD); - } -} - static uint32_t aica_rtc_reg_read(struct aica *aica, uint32_t addr, uint32_t data_mask) { switch (addr) { @@ -258,23 +246,6 @@ static void aica_rtc_timer(void *data) { scheduler_start_timer(aica->scheduler, &aica_rtc_timer, aica, NS_PER_SEC); } -static void aica_rtc_shutdown(struct aica *aica) { - scheduler_cancel_timer(aica->scheduler, aica->rtc_timer); - - /* persist clock */ - OPTION_rtc = *(int *)&aica->rtc; -} - -static void aica_rtc_init(struct aica *aica) { - /* seed clock from persistant options */ - CHECK(sizeof(aica->rtc) <= sizeof(OPTION_rtc)); - aica->rtc = *(uint32_t *)&OPTION_rtc; - - /* increment clock every second */ - aica->rtc_timer = - scheduler_start_timer(aica->scheduler, &aica_rtc_timer, aica, NS_PER_SEC); -} - static uint32_t aica_channel_step(struct aica_channel *ch) { /* by default, step the stream a single sample at a time */ uint32_t step = 1 << AICA_FNS_BITS; @@ -675,28 +646,66 @@ static int aica_init(struct device *dev) { aica->wave_ram = memory_translate(aica->memory, "aica wave ram", 0x00000000); - /* setup channel data aliases */ - for (int i = 0; i < AICA_NUM_CHANNELS; i++) { - struct aica_channel *ch = &aica->channels[i]; - ch->data = - (struct channel_data *)(aica->reg + sizeof(struct channel_data) * i); + /* init channels */ + { + for (int i = 0; i < AICA_NUM_CHANNELS; i++) { + struct aica_channel *ch = &aica->channels[i]; + ch->data = + (struct channel_data *)(aica->reg + sizeof(struct channel_data) * i); + } + aica->common_data = (struct common_data *)(aica->reg + 0x2800); + aica->sample_timer = + scheduler_start_timer(aica->scheduler, &aica_next_sample, aica, + HZ_TO_NANO(AICA_SAMPLE_FREQ / AICA_SAMPLE_BATCH)); } - aica->common_data = (struct common_data *)(aica->reg + 0x2800); - aica_timer_init(aica); - aica_rtc_init(aica); + /* init timers */ + { + for (int i = 0; i < 3; i++) { + aica_timer_reschedule(aica, i, AICA_TIMER_PERIOD); + } + } - aica->sample_timer = - scheduler_start_timer(aica->scheduler, &aica_next_sample, aica, - HZ_TO_NANO(AICA_SAMPLE_FREQ / AICA_SAMPLE_BATCH)); + /* init rtc */ + { + /* seed clock from persistant options */ + CHECK(sizeof(aica->rtc) <= sizeof(OPTION_rtc)); + aica->rtc = *(uint32_t *)&OPTION_rtc; + + /* increment clock every second */ + aica->rtc_timer = scheduler_start_timer(aica->scheduler, &aica_rtc_timer, + aica, NS_PER_SEC); + } return 1; } void aica_destroy(struct aica *aica) { - scheduler_cancel_timer(aica->scheduler, aica->sample_timer); - aica_rtc_shutdown(aica); - aica_timer_shutdown(aica); + /* shutdown rtc */ + { + if (aica->rtc_timer) { + scheduler_cancel_timer(aica->scheduler, aica->rtc_timer); + } + + /* persist clock */ + OPTION_rtc = *(int *)&aica->rtc; + } + + /* shutdown timers */ + { + for (int i = 0; i < 3; i++) { + if (aica->timers[i]) { + scheduler_cancel_timer(aica->scheduler, aica->timers[i]); + } + } + } + + /* shutdown channels */ + { + if (aica->sample_timer) { + scheduler_cancel_timer(aica->scheduler, aica->sample_timer); + } + } ringbuf_destroy(aica->frames); dc_destroy_window_interface(aica->window_if); diff --git a/src/hw/arm7/arm7.c b/src/hw/arm7/arm7.c index 764970e4..19ccc45f 100644 --- a/src/hw/arm7/arm7.c +++ b/src/hw/arm7/arm7.c @@ -25,8 +25,8 @@ struct arm7 { /* jit */ struct jit *jit; struct jit_guest guest; - struct jit_frontend *frontend; - struct jit_backend *backend; + struct armv3_frontend *frontend; + struct x64_backend *backend; /* interrupts */ uint32_t requested_interrupts; @@ -214,38 +214,46 @@ static int arm7_init(struct device *dev) { /* initialize jit and its interfaces */ arm->jit = jit_create("arm7"); - arm7_dispatch_init(arm, arm->jit, &arm->ctx, arm->memory_if->space->base); + { arm7_dispatch_init(arm, arm->jit, &arm->ctx, arm->memory_if->space->base); } - struct jit_guest *guest = &arm->guest; - guest->ctx = &arm->ctx; - guest->mem = arm->memory_if->space->base; - guest->space = arm->memory_if->space; - guest->lookup_code = &arm7_dispatch_lookup_code; - guest->cache_code = &arm7_dispatch_cache_code; - guest->invalidate_code = &arm7_dispatch_invalidate_code; - guest->patch_edge = &arm7_dispatch_patch_edge; - guest->restore_edge = &arm7_dispatch_restore_edge; - guest->r8 = &as_read8; - guest->r16 = &as_read16; - guest->r32 = &as_read32; - guest->w8 = &as_write8; - guest->w16 = &as_write16; - guest->w32 = &as_write32; + { + arm->guest.ctx = &arm->ctx; + arm->guest.mem = arm->memory_if->space->base; + arm->guest.space = arm->memory_if->space; + arm->guest.lookup_code = &arm7_dispatch_lookup_code; + arm->guest.cache_code = &arm7_dispatch_cache_code; + arm->guest.invalidate_code = &arm7_dispatch_invalidate_code; + arm->guest.patch_edge = &arm7_dispatch_patch_edge; + arm->guest.restore_edge = &arm7_dispatch_restore_edge; + 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; + } - struct armv3_frontend *frontend = - (struct armv3_frontend *)armv3_frontend_create(arm->jit); - frontend->data = arm; - frontend->translate = &arm7_translate; - frontend->switch_mode = &arm7_switch_mode; - frontend->restore_mode = &arm7_restore_mode; - frontend->software_interrupt = &arm7_software_interrupt; - arm->frontend = (struct jit_frontend *)frontend; + { + arm->frontend = armv3_frontend_create(arm->jit); - struct jit_backend *backend = - x64_backend_create(arm->jit, arm7_code, arm7_code_size, arm7_stack_size); - arm->backend = backend; + if (!arm->frontend) { + return 0; + } - if (!jit_init(arm->jit, &arm->guest, arm->frontend, arm->backend)) { + arm->frontend->data = arm; + arm->frontend->translate = &arm7_translate; + arm->frontend->switch_mode = &arm7_switch_mode; + arm->frontend->restore_mode = &arm7_restore_mode; + arm->frontend->software_interrupt = &arm7_software_interrupt; + } + + { + arm->backend = x64_backend_create(arm->jit, arm7_code, arm7_code_size, + arm7_stack_size); + } + + if (!jit_init(arm->jit, &arm->guest, (struct jit_frontend *)arm->frontend, + (struct jit_backend *)arm->backend)) { return 0; } diff --git a/src/hw/dreamcast.c b/src/hw/dreamcast.c index 3a088ee8..382a5351 100644 --- a/src/hw/dreamcast.c +++ b/src/hw/dreamcast.c @@ -70,12 +70,10 @@ void dc_suspend(struct dreamcast *dc) { int dc_init(struct dreamcast *dc) { if (dc->debugger && !debugger_init(dc->debugger)) { - dc_destroy(dc); return 0; } if (!memory_init(dc->memory)) { - dc_destroy(dc); return 0; } @@ -97,8 +95,6 @@ int dc_init(struct dreamcast *dc) { dev->ta = dc->ta; if (!dev->init(dev)) { - LOG_INFO("Device \"%s\" failed to initialize", dev->name); - dc_destroy(dc); return 0; } } diff --git a/src/hw/scheduler.c b/src/hw/scheduler.c index ed307fcb..3c77cb82 100644 --- a/src/hw/scheduler.c +++ b/src/hw/scheduler.c @@ -24,7 +24,9 @@ struct scheduler { }; void scheduler_cancel_timer(struct scheduler *sch, struct timer *timer) { - CHECK_EQ(timer->active, 1); + if (!timer->active) { + return; + } timer->active = 0; list_remove(&sch->live_timers, &timer->it); diff --git a/src/hw/sh4/sh4.c b/src/hw/sh4/sh4.c index b5e30dae..5e3d5a9b 100644 --- a/src/hw/sh4/sh4.c +++ b/src/hw/sh4/sh4.c @@ -167,8 +167,7 @@ static void sh4_translate(void *data, uint32_t addr, struct ir *ir, int fastmem, i += 2; } - sh4_emit_instr((struct sh4_frontend *)sh4->frontend, ir, as.flags, &instr, - &delay_instr); + sh4_emit_instr(sh4->frontend, ir, as.flags, &instr, &delay_instr); } /* if the block terminates before a branch, fallthrough to the next pc */ @@ -290,39 +289,51 @@ static int sh4_init(struct device *dev) { /* initialize jit and its interfaces */ sh4->jit = jit_create("sh4"); - sh4_dispatch_init(sh4, sh4->jit, &sh4->ctx, sh4->memory_if->space->base); + { sh4_dispatch_init(sh4, sh4->jit, &sh4->ctx, sh4->memory_if->space->base); } - struct jit_guest *guest = &sh4->guest; - guest->ctx = &sh4->ctx; - guest->mem = sh4->memory_if->space->base; - guest->space = sh4->memory_if->space; - guest->lookup_code = &sh4_dispatch_lookup_code; - guest->cache_code = &sh4_dispatch_cache_code; - guest->invalidate_code = &sh4_dispatch_invalidate_code; - guest->patch_edge = &sh4_dispatch_patch_edge; - guest->restore_edge = &sh4_dispatch_restore_edge; - guest->r8 = &as_read8; - guest->r16 = &as_read16; - guest->r32 = &as_read32; - guest->w8 = &as_write8; - guest->w16 = &as_write16; - guest->w32 = &as_write32; + { + sh4->guest.ctx = &sh4->ctx; + sh4->guest.mem = sh4->memory_if->space->base; + sh4->guest.space = sh4->memory_if->space; + sh4->guest.lookup_code = &sh4_dispatch_lookup_code; + sh4->guest.cache_code = &sh4_dispatch_cache_code; + sh4->guest.invalidate_code = &sh4_dispatch_invalidate_code; + sh4->guest.patch_edge = &sh4_dispatch_patch_edge; + sh4->guest.restore_edge = &sh4_dispatch_restore_edge; + 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; + } - struct sh4_frontend *frontend = - (struct sh4_frontend *)sh4_frontend_create(sh4->jit); - frontend->data = sh4; - frontend->translate = &sh4_translate; - frontend->invalid_instr = &sh4_invalid_instr; - frontend->sq_prefetch = &sh4_ccn_sq_prefetch; - frontend->sr_updated = &sh4_sr_updated; - frontend->fpscr_updated = &sh4_fpscr_updated; - sh4->frontend = (struct jit_frontend *)frontend; + { + sh4->frontend = sh4_frontend_create(sh4->jit); - struct jit_backend *backend = - x64_backend_create(sh4->jit, sh4_code, sh4_code_size, sh4_stack_size); - sh4->backend = backend; + if (!sh4->frontend) { + return 0; + } - if (!jit_init(sh4->jit, &sh4->guest, sh4->frontend, sh4->backend)) { + sh4->frontend->data = sh4; + sh4->frontend->translate = &sh4_translate; + sh4->frontend->invalid_instr = &sh4_invalid_instr; + sh4->frontend->sq_prefetch = &sh4_ccn_sq_prefetch; + sh4->frontend->sr_updated = &sh4_sr_updated; + sh4->frontend->fpscr_updated = &sh4_fpscr_updated; + } + + { + sh4->backend = + x64_backend_create(sh4->jit, sh4_code, sh4_code_size, sh4_stack_size); + + if (!sh4->backend) { + return 0; + } + } + + if (!jit_init(sh4->jit, &sh4->guest, (struct jit_frontend *)sh4->frontend, + (struct jit_backend *)sh4->backend)) { return 0; } diff --git a/src/hw/sh4/sh4.h b/src/hw/sh4/sh4.h index b5b79e19..80e3efdb 100644 --- a/src/hw/sh4/sh4.h +++ b/src/hw/sh4/sh4.h @@ -11,8 +11,8 @@ struct dreamcast; struct jit; struct jit_guest; -struct jit_frontend; -struct jit_backend; +struct sh4_frontend; +struct x64_backend; #define SH4_CLOCK_FREQ INT64_C(200000000) @@ -44,8 +44,8 @@ struct sh4 { /* jit */ struct jit *jit; struct jit_guest guest; - struct jit_frontend *frontend; - struct jit_backend *backend; + struct sh4_frontend *frontend; + struct x64_backend *backend; /* intc */ enum sh4_interrupt sorted_interrupts[NUM_SH_INTERRUPTS]; diff --git a/src/jit/backend/x64/x64_backend.cc b/src/jit/backend/x64/x64_backend.cc index ce2793bb..9e95e703 100644 --- a/src/jit/backend/x64/x64_backend.cc +++ b/src/jit/backend/x64/x64_backend.cc @@ -3,6 +3,7 @@ #define XBYAK_NO_OP_NAMES #include +#include extern "C" { #include "core/profiler.h" @@ -1643,9 +1644,7 @@ EMITTER(CALL_FALLBACK) { EMITTER(DEBUG_INFO) {} -void x64_backend_destroy(struct jit_backend *jit_backend) { - struct x64_backend *backend = (struct x64_backend *)jit_backend; - +void x64_backend_destroy(struct x64_backend *backend) { cs_close(&backend->capstone_handle); delete backend->codegen; @@ -1653,8 +1652,16 @@ void x64_backend_destroy(struct jit_backend *jit_backend) { free(backend); } -struct jit_backend *x64_backend_create(struct jit *jit, void *code, +struct x64_backend *x64_backend_create(struct jit *jit, void *code, int code_size, int stack_size) { + /* AVX is used instead of SSE purely because its 3 argument instructions + are easier to emit for */ + Xbyak::util::Cpu cpu; + if (!cpu.has(Xbyak::util::Cpu::tAVX)) { + LOG_WARNING("Failed to create x64 backend, CPU does not support AVX"); + return NULL; + } + struct x64_backend *backend = reinterpret_cast( calloc(1, sizeof(struct x64_backend))); @@ -1677,5 +1684,5 @@ struct jit_backend *x64_backend_create(struct jit *jit, void *code, /* do an initial reset to emit constants and thunks */ x64_backend_reset((jit_backend *)backend); - return (struct jit_backend *)backend; + return backend; } diff --git a/src/jit/backend/x64/x64_backend.h b/src/jit/backend/x64/x64_backend.h index d9ee25b0..a38ff120 100644 --- a/src/jit/backend/x64/x64_backend.h +++ b/src/jit/backend/x64/x64_backend.h @@ -6,8 +6,8 @@ extern const struct jit_register x64_registers[]; extern const int x64_num_registers; -struct jit_backend *x64_backend_create(struct jit *jit, void *code, +struct x64_backend *x64_backend_create(struct jit *jit, void *code, int code_size, int stack_size); -void x64_backend_destroy(struct jit_backend *b); +void x64_backend_destroy(struct x64_backend *backend); #endif diff --git a/src/jit/frontend/armv3/armv3_frontend.c b/src/jit/frontend/armv3/armv3_frontend.c index e44568f5..bf2bb9a4 100644 --- a/src/jit/frontend/armv3/armv3_frontend.c +++ b/src/jit/frontend/armv3/armv3_frontend.c @@ -28,18 +28,16 @@ static void armv3_frontend_dump_code(struct jit_frontend *base, uint32_t addr, } } -struct jit_frontend *armv3_frontend_create(struct jit *jit) { +void armv3_frontend_destroy(struct armv3_frontend *frontend) { + free(frontend); +} + +struct armv3_frontend *armv3_frontend_create(struct jit *jit) { struct armv3_frontend *frontend = calloc(1, sizeof(struct armv3_frontend)); frontend->jit = jit; frontend->translate_code = &armv3_frontend_translate_code; frontend->dump_code = &armv3_frontend_dump_code; - return (struct jit_frontend *)frontend; -} - -void armv3_frontend_destroy(struct jit_frontend *jit_frontend) { - struct armv3_frontend *frontend = (struct armv3_frontend *)jit_frontend; - - free(frontend); + return frontend; } diff --git a/src/jit/frontend/armv3/armv3_frontend.h b/src/jit/frontend/armv3/armv3_frontend.h index 737fc887..3466d7e5 100644 --- a/src/jit/frontend/armv3/armv3_frontend.h +++ b/src/jit/frontend/armv3/armv3_frontend.h @@ -4,7 +4,9 @@ #include "jit/frontend/jit_frontend.h" #include "jit/jit.h" -enum armv3_block_flags { PC_SET = 0x1 }; +enum armv3_block_flags { + PC_SET = 0x1, +}; struct armv3_frontend { struct jit_frontend; @@ -17,7 +19,7 @@ struct armv3_frontend { void (*software_interrupt)(void *); }; -struct jit_frontend *armv3_frontend_create(struct jit *jit); -void armv3_frontend_destroy(struct jit_frontend *frontend); +struct armv3_frontend *armv3_frontend_create(struct jit *jit); +void armv3_frontend_destroy(struct armv3_frontend *frontend); #endif diff --git a/src/jit/frontend/sh4/sh4_frontend.c b/src/jit/frontend/sh4/sh4_frontend.c index b36d0066..49654089 100644 --- a/src/jit/frontend/sh4/sh4_frontend.c +++ b/src/jit/frontend/sh4/sh4_frontend.c @@ -52,17 +52,16 @@ static void sh4_frontend_dump_code(struct jit_frontend *base, uint32_t addr, } } -struct jit_frontend *sh4_frontend_create(struct jit *jit) { +void sh4_frontend_destroy(struct sh4_frontend *frontend) { + free(frontend); +} + +struct sh4_frontend *sh4_frontend_create(struct jit *jit) { struct sh4_frontend *frontend = calloc(1, sizeof(struct sh4_frontend)); frontend->jit = jit; frontend->translate_code = &sh4_frontend_translate_code; frontend->dump_code = &sh4_frontend_dump_code; - return (struct jit_frontend *)frontend; -} - -void sh4_frontend_destroy(struct jit_frontend *base) { - struct sh4_frontend *frontend = (struct sh4_frontend *)base; - free(frontend); + return frontend; } diff --git a/src/jit/frontend/sh4/sh4_frontend.h b/src/jit/frontend/sh4/sh4_frontend.h index 1731992d..826033e3 100644 --- a/src/jit/frontend/sh4/sh4_frontend.h +++ b/src/jit/frontend/sh4/sh4_frontend.h @@ -25,7 +25,7 @@ struct sh4_frontend { void (*fpscr_updated)(void *, uint32_t); }; -struct jit_frontend *sh4_frontend_create(struct jit *jit); -void sh4_frontend_destroy(struct jit_frontend *frontend); +struct sh4_frontend *sh4_frontend_create(struct jit *jit); +void sh4_frontend_destroy(struct sh4_frontend *frontend); #endif diff --git a/src/jit/jit.c b/src/jit/jit.c index b155667e..b6979533 100644 --- a/src/jit/jit.c +++ b/src/jit/jit.c @@ -403,7 +403,9 @@ void jit_destroy(struct jit *jit) { } } - jit_free_blocks(jit); + if (jit->backend) { + jit_free_blocks(jit); + } if (jit->exc_handler) { exception_handler_remove(jit->exc_handler); diff --git a/src/ui/microprofile.cc b/src/ui/microprofile.cc index 14345e94..6419e12c 100644 --- a/src/ui/microprofile.cc +++ b/src/ui/microprofile.cc @@ -290,10 +290,9 @@ struct microprofile *mp_create(struct window *window) { g_MicroProfile.nBars |= MP_DRAW_TIMERS | MP_DRAW_AVERAGE | MP_DRAW_CALL_COUNT; /* register the font texture */ - mp->font_texture = - rb_create_texture(rb, PXL_RGBA, FILTER_NEAREST, WRAP_CLAMP_TO_EDGE, - WRAP_CLAMP_TO_EDGE, 0, FONT_WIDTH, FONT_HEIGHT, - reinterpret_cast(s_font_data)); + mp->font_texture = rb_create_texture( + rb, PXL_RGBA, FILTER_NEAREST, WRAP_CLAMP_TO_EDGE, WRAP_CLAMP_TO_EDGE, 0, + FONT_WIDTH, FONT_HEIGHT, reinterpret_cast(s_font_data)); return mp; } diff --git a/src/video/gl_backend.c b/src/video/gl_backend.c index 94968450..87511465 100644 --- a/src/video/gl_backend.c +++ b/src/video/gl_backend.c @@ -234,7 +234,7 @@ static void rb_print_shader_log(GLuint shader) { } static int rb_compile_shader(const char *source, GLenum shader_type, - GLuint *shader) { + GLuint *shader) { size_t sourceLength = strlen(source); *shader = glCreateShader(shader_type); @@ -267,8 +267,8 @@ static void rb_destroy_program(struct shader_program *program) { } static int rb_compile_program(struct shader_program *program, - const char *header, const char *vertex_source, - const char *fragment_source) { + const char *header, const char *vertex_source, + const char *fragment_source) { char buffer[16384] = {0}; memset(program, 0, sizeof(*program)); diff --git a/tools/recc/recc.c b/tools/recc/recc.c index dc21fe6d..55d11858 100644 --- a/tools/recc/recc.c +++ b/tools/recc/recc.c @@ -176,10 +176,10 @@ int main(int argc, char **argv) { guest.w16 = (void *)code; guest.w32 = (void *)code; - struct jit_backend *backend = + struct x64_backend *backend = x64_backend_create(jit, code, code_size, stack_size); - CHECK(jit_init(jit, &guest, NULL, backend)); + CHECK(jit_init(jit, &guest, NULL, (struct jit_backend *)backend)); if (fs_isfile(path)) { process_file(jit, path, 0);