added check for AVX support to x64_backend_create

fixed bitrot around shutdown process
This commit is contained in:
Anthony Pesch 2016-12-27 15:37:52 -08:00
parent 9eb56d1ab2
commit 2d717d0166
16 changed files with 183 additions and 150 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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];

View File

@ -3,6 +3,7 @@
#define XBYAK_NO_OP_NAMES
#include <xbyak/xbyak.h>
#include <xbyak/xbyak_util.h>
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<struct x64_backend *>(
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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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<const uint8_t *>(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<const uint8_t *>(s_font_data));
return mp;
}

View File

@ -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));

View File

@ -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);