diff options
-rw-r--r-- | m68k_to_x86.c | 343 |
1 files changed, 102 insertions, 241 deletions
diff --git a/m68k_to_x86.c b/m68k_to_x86.c index 5781fef..4ff1dec 100644 --- a/m68k_to_x86.c +++ b/m68k_to_x86.c @@ -4139,135 +4139,99 @@ void m68k_reset(m68k_context * context) start_68k_context(context, address); } -void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks) +typedef enum { + READ_16, + READ_8, + WRITE_16, + WRITE_8 +} ftype; + +uint8_t * gen_mem_fun(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, ftype fun_type) { - opts->flags = 0; - for (int i = 0; i < 8; i++) - opts->dregs[i] = opts->aregs[i] = -1; - opts->dregs[0] = R10; - opts->dregs[1] = R11; - opts->dregs[2] = R12; - opts->aregs[0] = R13; - opts->aregs[1] = R14; - opts->aregs[7] = R15; - opts->native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); - memset(opts->native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); - opts->deferred = NULL; - size_t size = 1024 * 1024; - opts->cur_code = alloc_code(&size); - opts->code_end = opts->cur_code + size; - opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); - memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64); - uint8_t * dst = opts->read_16 = opts->cur_code; + uint8_t * dst = opts->cur_code; + uint8_t * start = dst; dst = check_cycles(dst); dst = cycles(dst, BUS); dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D); uint8_t *lb_jcc = NULL, *ub_jcc = NULL; + uint8_t is_write = fun_type == WRITE_16 || fun_type == WRITE_8; + uint8_t adr_reg = is_write ? SCRATCH2 : SCRATCH1; + uint16_t access_flag = is_write ? MMAP_WRITE : MMAP_READ; + uint8_t size = (fun_type == READ_16 || fun_type == WRITE_16) ? SZ_W : SZ_B; for (uint32_t chunk = 0; chunk < num_chunks; chunk++) { - if (lb_jcc) { - *lb_jcc = dst - (lb_jcc+1); - lb_jcc = NULL; - } - if (ub_jcc) { - *ub_jcc = dst - (ub_jcc+1); - ub_jcc = NULL; - } if (memmap[chunk].start > 0) { - dst = cmp_ir(dst, memmap[chunk].start, SCRATCH1, SZ_D); + dst = cmp_ir(dst, memmap[chunk].start, adr_reg, SZ_D); lb_jcc = dst + 1; dst = jcc(dst, CC_C, dst+2); } if (memmap[chunk].end < 0x1000000) { - dst = cmp_ir(dst, memmap[chunk].end, SCRATCH1, SZ_D); + dst = cmp_ir(dst, memmap[chunk].end, adr_reg, SZ_D); ub_jcc = dst + 1; dst = jcc(dst, CC_NC, dst+2); } if (memmap[chunk].mask != 0xFFFFFF) { - dst = and_ir(dst, memmap[chunk].mask, SCRATCH1, SZ_D); + dst = and_ir(dst, memmap[chunk].mask, adr_reg, SZ_D); } - - if (memmap[chunk].read_16) { + void * cfun; + switch (fun_type) + { + case READ_16: + cfun = memmap[chunk].read_16; + break; + case READ_8: + cfun = memmap[chunk].read_8; + break; + case WRITE_16: + cfun = memmap[chunk].write_16; + break; + case WRITE_8: + cfun = memmap[chunk].write_8; + break; + default: + cfun = NULL; + } + if (cfun) { dst = call(dst, (uint8_t *)m68k_save_context); - dst = push_r(dst, CONTEXT); - dst = mov_rr(dst, SCRATCH1, RDI, SZ_D); - dst = call(dst, (uint8_t *)memmap[chunk].read_16); - dst = pop_r(dst, CONTEXT); - dst = mov_rr(dst, RAX, SCRATCH1, SZ_W); - dst = jmp(dst, (uint8_t *)m68k_load_context); - } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_READ) { - if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) { - dst = mov_rdisp32r(dst, SCRATCH1, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_W); + if (is_write) { + //SCRATCH2 is RDI, so no need to move it there + dst = mov_rr(dst, SCRATCH1, RDX, size); } else { - dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH2, SZ_Q); - dst = mov_rindexr(dst, SCRATCH2, SCRATCH1, 1, SCRATCH1, SZ_W); + dst = push_r(dst, CONTEXT); + dst = mov_rr(dst, SCRATCH1, RDI, SZ_D); + } + dst = call(dst, cfun); + if (is_write) { + dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); + } else { + dst = pop_r(dst, CONTEXT); + dst = mov_rr(dst, RAX, SCRATCH1, size); } - dst = retn(dst); - } else { - //Not sure the best course of action here - dst = mov_ir(dst, 0xFFFF, SCRATCH1, SZ_W); - dst = retn(dst); - } - } - if (lb_jcc) { - *lb_jcc = dst - (lb_jcc+1); - lb_jcc = NULL; - } - if (ub_jcc) { - *ub_jcc = dst - (ub_jcc+1); - ub_jcc = NULL; - } - dst = mov_ir(dst, 0xFFFF, SCRATCH1, SZ_W); - dst = retn(dst); - - opts->write_16 = dst; - dst = check_cycles(dst); - dst = cycles(dst, BUS); - dst = and_ir(dst, 0xFFFFFF, SCRATCH2, SZ_D); - for (uint32_t chunk = 0; chunk < num_chunks; chunk++) - { - if (lb_jcc) { - *lb_jcc = dst - (lb_jcc+1); - lb_jcc = NULL; - } - if (ub_jcc) { - *ub_jcc = dst - (ub_jcc+1); - ub_jcc = NULL; - } - if (memmap[chunk].start > 0) { - dst = cmp_ir(dst, memmap[chunk].start, SCRATCH2, SZ_D); - lb_jcc = dst + 1; - dst = jcc(dst, CC_C, dst+2); - } - if (memmap[chunk].end < 0x1000000) { - dst = cmp_ir(dst, memmap[chunk].end, SCRATCH2, SZ_D); - ub_jcc = dst + 1; - dst = jcc(dst, CC_NC, dst+2); - } - - if (memmap[chunk].mask != 0xFFFFFF) { - dst = and_ir(dst, memmap[chunk].mask, SCRATCH2, SZ_D); - } - - if (memmap[chunk].write_16) { - dst = call(dst, (uint8_t *)m68k_save_context); - //SCRATCH2 is RDI, so no need to move it there - dst = mov_rr(dst, SCRATCH1, RDX, SZ_W); - dst = call(dst, (uint8_t *)memmap[chunk].write_16); - dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); dst = jmp(dst, (uint8_t *)m68k_load_context); - } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_WRITE) { + } else if(memmap[chunk].buffer && memmap[chunk].flags & access_flag) { + if (size == SZ_B) { + dst = xor_ir(dst, 1, adr_reg, SZ_D); + } if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) { - dst = mov_rrdisp32(dst, SCRATCH1, SCRATCH2, (int64_t)memmap[chunk].buffer, SZ_W); + if (is_write) { + dst = mov_rrdisp32(dst, SCRATCH1, SCRATCH2, (int64_t)memmap[chunk].buffer, size); + } else { + dst = mov_rdisp32r(dst, SCRATCH1, (int64_t)memmap[chunk].buffer, SCRATCH1, size); + } } else { - dst = push_r(dst, SCRATCH1); - dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_Q); - dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_Q); - dst = pop_r(dst, SCRATCH1); - dst = mov_rrind(dst, SCRATCH1, SCRATCH2, SZ_W); + if (is_write) { + dst = push_r(dst, SCRATCH1); + dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_Q); + dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_Q); + dst = pop_r(dst, SCRATCH1); + dst = mov_rrind(dst, SCRATCH1, SCRATCH2, size); + } else { + dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH2, SZ_Q); + dst = mov_rindexr(dst, SCRATCH2, SCRATCH1, 1, SCRATCH1, size); + } } - if (memmap[chunk].flags & MMAP_CODE) { + if (is_write && (memmap[chunk].flags & MMAP_CODE)) { dst = mov_rr(dst, SCRATCH2, SCRATCH1, SZ_D); dst = shr_ir(dst, 11, SCRATCH1, SZ_D); dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D); @@ -4282,88 +4246,11 @@ void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t n dst = retn(dst); } else { //Not sure the best course of action here - dst = retn(dst); - } - } - if (lb_jcc) { - *lb_jcc = dst - (lb_jcc+1); - lb_jcc = NULL; - } - if (ub_jcc) { - *ub_jcc = dst - (ub_jcc+1); - ub_jcc = NULL; - } - dst = retn(dst); - - opts->read_8 = dst; - dst = check_cycles(dst); - dst = cycles(dst, BUS); - dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D); - for (uint32_t chunk = 0; chunk < num_chunks; chunk++) - { - if (lb_jcc) { - *lb_jcc = dst - (lb_jcc+1); - lb_jcc = NULL; - } - if (ub_jcc) { - *ub_jcc = dst - (ub_jcc+1); - ub_jcc = NULL; - } - if (memmap[chunk].start > 0) { - dst = cmp_ir(dst, memmap[chunk].start, SCRATCH1, SZ_D); - lb_jcc = dst + 1; - dst = jcc(dst, CC_C, dst+2); - } - if (memmap[chunk].end < 0x1000000) { - dst = cmp_ir(dst, memmap[chunk].end, SCRATCH1, SZ_D); - ub_jcc = dst + 1; - dst = jcc(dst, CC_NC, dst+2); - } - - if (memmap[chunk].mask != 0xFFFFFF) { - dst = and_ir(dst, memmap[chunk].mask, SCRATCH1, SZ_D); - } - - if (memmap[chunk].read_8) { - dst = call(dst, (uint8_t *)m68k_save_context); - dst = push_r(dst, CONTEXT); - dst = mov_rr(dst, SCRATCH1, RDI, SZ_D); - dst = call(dst, (uint8_t *)memmap[chunk].read_8); - dst = pop_r(dst, CONTEXT); - dst = mov_rr(dst, RAX, SCRATCH1, SZ_B); - dst = jmp(dst, (uint8_t *)m68k_load_context); - } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_READ) { - dst = xor_ir(dst, 1, SCRATCH1, SZ_D); - if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) { - dst = mov_rdisp32r(dst, SCRATCH1, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_B); - } else { - dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH2, SZ_Q); - dst = mov_rindexr(dst, SCRATCH2, SCRATCH1, 1, SCRATCH1, SZ_B); + if (!is_write) { + dst = mov_ir(dst, size == SZ_B ? 0xFF : 0xFFFF, SCRATCH1, size); } dst = retn(dst); - } else { - //Not sure the best course of action here - dst = mov_ir(dst, 0xFF, SCRATCH1, SZ_B); - dst = retn(dst); } - } - if (lb_jcc) { - *lb_jcc = dst - (lb_jcc+1); - lb_jcc = NULL; - } - if (ub_jcc) { - *ub_jcc = dst - (ub_jcc+1); - ub_jcc = NULL; - } - dst = mov_ir(dst, 0xFFFF, SCRATCH1, SZ_W); - dst = retn(dst); - - opts->write_8 = dst; - dst = check_cycles(dst); - dst = cycles(dst, BUS); - dst = and_ir(dst, 0xFFFFFF, SCRATCH2, SZ_D); - for (uint32_t chunk = 0; chunk < num_chunks; chunk++) - { if (lb_jcc) { *lb_jcc = dst - (lb_jcc+1); lb_jcc = NULL; @@ -4372,67 +4259,41 @@ void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t n *ub_jcc = dst - (ub_jcc+1); ub_jcc = NULL; } - if (memmap[chunk].start > 0) { - dst = cmp_ir(dst, memmap[chunk].start, SCRATCH2, SZ_D); - lb_jcc = dst + 1; - dst = jcc(dst, CC_C, dst+2); - } - if (memmap[chunk].end < 0x1000000) { - dst = cmp_ir(dst, memmap[chunk].end, SCRATCH2, SZ_D); - ub_jcc = dst + 1; - dst = jcc(dst, CC_NC, dst+2); - } - - if (memmap[chunk].mask != 0xFFFFFF) { - dst = and_ir(dst, memmap[chunk].mask, SCRATCH2, SZ_D); - } - - if (memmap[chunk].write_8) { - dst = call(dst, (uint8_t *)m68k_save_context); - //SCRATCH2 is RDI, so no need to move it there - dst = mov_rr(dst, SCRATCH1, RDX, SZ_B); - dst = call(dst, (uint8_t *)memmap[chunk].write_8); - dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); - dst = jmp(dst, (uint8_t *)m68k_load_context); - } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_WRITE) { - dst = xor_ir(dst, 1, SCRATCH2, SZ_D); - if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) { - dst = mov_rrdisp32(dst, SCRATCH1, SCRATCH2, (int64_t)memmap[chunk].buffer, SZ_B); - } else { - dst = push_r(dst, SCRATCH1); - dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_Q); - dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_Q); - dst = pop_r(dst, SCRATCH1); - dst = mov_rrind(dst, SCRATCH1, SCRATCH2, SZ_B); - } - if (memmap[chunk].flags & MMAP_CODE) { - dst = mov_rr(dst, SCRATCH2, SCRATCH1, SZ_D); - dst = shr_ir(dst, 11, SCRATCH1, SZ_D); - dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D); - uint8_t * not_code = dst+1; - dst = jcc(dst, CC_NC, dst+2); - dst = xor_ir(dst, 1, SCRATCH2, SZ_D); - dst = call(dst, (uint8_t *)m68k_save_context); - dst = call(dst, (uint8_t *)m68k_handle_code_write); - dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); - dst = call(dst, (uint8_t *)m68k_load_context); - *not_code = dst - (not_code+1); - } - dst = retn(dst); - } else { - //Not sure the best course of action here - dst = retn(dst); - } - } - if (lb_jcc) { - *lb_jcc = dst - (lb_jcc+1); - lb_jcc = NULL; } - if (ub_jcc) { - *ub_jcc = dst - (ub_jcc+1); - ub_jcc = NULL; + if (!is_write) { + dst = mov_ir(dst, size == SZ_B ? 0xFF : 0xFFFF, SCRATCH1, size); } dst = retn(dst); + opts->cur_code = dst; + return start; +} + +void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks) +{ + opts->flags = 0; + for (int i = 0; i < 8; i++) + opts->dregs[i] = opts->aregs[i] = -1; + opts->dregs[0] = R10; + opts->dregs[1] = R11; + opts->dregs[2] = R12; + opts->aregs[0] = R13; + opts->aregs[1] = R14; + opts->aregs[7] = R15; + opts->native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); + memset(opts->native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); + opts->deferred = NULL; + size_t size = 1024 * 1024; + opts->cur_code = alloc_code(&size); + opts->code_end = opts->cur_code + size; + opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); + memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64); + + opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16); + opts->read_8 = gen_mem_fun(opts, memmap, num_chunks, READ_8); + opts->write_16 = gen_mem_fun(opts, memmap, num_chunks, WRITE_16); + opts->write_8 = gen_mem_fun(opts, memmap, num_chunks, WRITE_8); + + uint8_t * dst = opts->cur_code; opts->read_32 = dst; dst = push_r(dst, SCRATCH1); |