Mercurial > repos > blastem
comparison m68k_to_x86.c @ 539:c2716b502a81
Generate save_context and load_context functions at runtime
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 14 Feb 2014 19:56:18 -0800 |
parents | 7f54f1773e84 |
children | 4ca826862174 |
comparison
equal
deleted
inserted
replaced
538:71b7cf543040 | 539:c2716b502a81 |
---|---|
29 char disasm_buf[1024]; | 29 char disasm_buf[1024]; |
30 | 30 |
31 m68k_context * sync_components(m68k_context * context, uint32_t address); | 31 m68k_context * sync_components(m68k_context * context, uint32_t address); |
32 | 32 |
33 void handle_cycle_limit(); | 33 void handle_cycle_limit(); |
34 void m68k_save_context(); | |
35 void m68k_load_context(); | |
36 void m68k_modified_ret_addr(); | 34 void m68k_modified_ret_addr(); |
37 void m68k_native_addr(); | 35 void m68k_native_addr(); |
38 void m68k_native_addr_and_sync(); | 36 void m68k_native_addr_and_sync(); |
39 void m68k_invalid(); | 37 void m68k_invalid(); |
40 void m68k_retrans_stub(); | 38 void m68k_retrans_stub(); |
3284 dst = mov_rrdisp8(dst, SCRATCH2, src_op.base, src_op.disp, SZ_D); | 3282 dst = mov_rrdisp8(dst, SCRATCH2, src_op.base, src_op.disp, SZ_D); |
3285 } | 3283 } |
3286 } | 3284 } |
3287 break; | 3285 break; |
3288 case M68K_ILLEGAL: | 3286 case M68K_ILLEGAL: |
3289 dst = call(dst, (uint8_t *)m68k_save_context); | 3287 dst = call(dst, opts->save_context); |
3290 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); | 3288 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); |
3291 dst = call(dst, (uint8_t *)print_regs_exit); | 3289 dst = call(dst, (uint8_t *)print_regs_exit); |
3292 break; | 3290 break; |
3293 case M68K_MOVE_FROM_SR: | 3291 case M68K_MOVE_FROM_SR: |
3294 //TODO: Trap if not in system mode | 3292 //TODO: Trap if not in system mode |
3511 dst = call(dst, (uint8_t *)do_sync); | 3509 dst = call(dst, (uint8_t *)do_sync); |
3512 } | 3510 } |
3513 } | 3511 } |
3514 break; | 3512 break; |
3515 case M68K_RESET: | 3513 case M68K_RESET: |
3516 dst = call(dst, (uint8_t *)m68k_save_context); | 3514 dst = call(dst, opts->save_context); |
3517 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); | 3515 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); |
3518 dst = call(dst, (uint8_t *)print_regs_exit); | 3516 dst = call(dst, (uint8_t *)print_regs_exit); |
3519 break; | 3517 break; |
3520 case M68K_ROL: | 3518 case M68K_ROL: |
3521 case M68K_ROR: | 3519 case M68K_ROR: |
4134 dst = check_cycles_int(dst, address, opts); | 4132 dst = check_cycles_int(dst, address, opts); |
4135 int check_int_size = dst-bp_stub; | 4133 int check_int_size = dst-bp_stub; |
4136 dst = bp_stub; | 4134 dst = bp_stub; |
4137 | 4135 |
4138 //Save context and call breakpoint handler | 4136 //Save context and call breakpoint handler |
4139 dst = call(dst, (uint8_t *)m68k_save_context); | 4137 dst = call(dst, opts->save_context); |
4140 dst = push_r(dst, SCRATCH1); | 4138 dst = push_r(dst, SCRATCH1); |
4141 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); | 4139 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); |
4142 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); | 4140 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); |
4143 dst = call(dst, bp_handler); | 4141 dst = call(dst, bp_handler); |
4144 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); | 4142 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); |
4145 //Restore context | 4143 //Restore context |
4146 dst = call(dst, (uint8_t *)m68k_load_context); | 4144 dst = call(dst, opts->load_context); |
4147 dst = pop_r(dst, SCRATCH1); | 4145 dst = pop_r(dst, SCRATCH1); |
4148 //do prologue stuff | 4146 //do prologue stuff |
4149 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); | 4147 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); |
4150 uint8_t * jmp_off = dst+1; | 4148 uint8_t * jmp_off = dst+1; |
4151 dst = jcc(dst, CC_NC, dst + 7); | 4149 dst = jcc(dst, CC_NC, dst + 7); |
4238 if (memmap[chunk].flags & MMAP_PTR_IDX) { | 4236 if (memmap[chunk].flags & MMAP_PTR_IDX) { |
4239 if (memmap[chunk].flags & MMAP_FUNC_NULL) { | 4237 if (memmap[chunk].flags & MMAP_FUNC_NULL) { |
4240 dst = cmp_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, SZ_Q); | 4238 dst = cmp_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, SZ_Q); |
4241 uint8_t * not_null = dst+1; | 4239 uint8_t * not_null = dst+1; |
4242 dst = jcc(dst, CC_NZ, dst+2); | 4240 dst = jcc(dst, CC_NZ, dst+2); |
4243 dst = call(dst, (uint8_t *)m68k_save_context); | 4241 dst = call(dst, opts->save_context); |
4244 if (is_write) { | 4242 if (is_write) { |
4245 //SCRATCH2 is RDI, so no need to move it there | 4243 //SCRATCH2 is RDI, so no need to move it there |
4246 dst = mov_rr(dst, SCRATCH1, RDX, size); | 4244 dst = mov_rr(dst, SCRATCH1, RDX, size); |
4247 } else { | 4245 } else { |
4248 dst = push_r(dst, CONTEXT); | 4246 dst = push_r(dst, CONTEXT); |
4263 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); | 4261 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); |
4264 } else { | 4262 } else { |
4265 dst = pop_r(dst, CONTEXT); | 4263 dst = pop_r(dst, CONTEXT); |
4266 dst = mov_rr(dst, RAX, SCRATCH1, size); | 4264 dst = mov_rr(dst, RAX, SCRATCH1, size); |
4267 } | 4265 } |
4268 dst = jmp(dst, (uint8_t *)m68k_load_context); | 4266 dst = jmp(dst, opts->load_context); |
4269 | 4267 |
4270 *not_null = dst - (not_null + 1); | 4268 *not_null = dst - (not_null + 1); |
4271 } | 4269 } |
4272 if (size == SZ_B) { | 4270 if (size == SZ_B) { |
4273 dst = xor_ir(dst, 1, adr_reg, SZ_D); | 4271 dst = xor_ir(dst, 1, adr_reg, SZ_D); |
4333 dst = mov_rr(dst, SCRATCH2, SCRATCH1, SZ_D); | 4331 dst = mov_rr(dst, SCRATCH2, SCRATCH1, SZ_D); |
4334 dst = shr_ir(dst, 11, SCRATCH1, SZ_D); | 4332 dst = shr_ir(dst, 11, SCRATCH1, SZ_D); |
4335 dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D); | 4333 dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D); |
4336 uint8_t * not_code = dst+1; | 4334 uint8_t * not_code = dst+1; |
4337 dst = jcc(dst, CC_NC, dst+2); | 4335 dst = jcc(dst, CC_NC, dst+2); |
4338 dst = call(dst, (uint8_t *)m68k_save_context); | 4336 dst = call(dst, opts->save_context); |
4339 dst = call(dst, (uint8_t *)m68k_handle_code_write); | 4337 dst = call(dst, (uint8_t *)m68k_handle_code_write); |
4340 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); | 4338 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); |
4341 dst = call(dst, (uint8_t *)m68k_load_context); | 4339 dst = call(dst, opts->load_context); |
4342 *not_code = dst - (not_code+1); | 4340 *not_code = dst - (not_code+1); |
4343 } | 4341 } |
4344 dst = retn(dst); | 4342 dst = retn(dst); |
4345 } else if (cfun) { | 4343 } else if (cfun) { |
4346 dst = call(dst, (uint8_t *)m68k_save_context); | 4344 dst = call(dst, opts->save_context); |
4347 if (is_write) { | 4345 if (is_write) { |
4348 //SCRATCH2 is RDI, so no need to move it there | 4346 //SCRATCH2 is RDI, so no need to move it there |
4349 dst = mov_rr(dst, SCRATCH1, RDX, size); | 4347 dst = mov_rr(dst, SCRATCH1, RDX, size); |
4350 } else { | 4348 } else { |
4351 dst = push_r(dst, CONTEXT); | 4349 dst = push_r(dst, CONTEXT); |
4366 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); | 4364 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); |
4367 } else { | 4365 } else { |
4368 dst = pop_r(dst, CONTEXT); | 4366 dst = pop_r(dst, CONTEXT); |
4369 dst = mov_rr(dst, RAX, SCRATCH1, size); | 4367 dst = mov_rr(dst, RAX, SCRATCH1, size); |
4370 } | 4368 } |
4371 dst = jmp(dst, (uint8_t *)m68k_load_context); | 4369 dst = jmp(dst, opts->load_context); |
4372 } else { | 4370 } else { |
4373 //Not sure the best course of action here | 4371 //Not sure the best course of action here |
4374 if (!is_write) { | 4372 if (!is_write) { |
4375 dst = mov_ir(dst, size == SZ_B ? 0xFF : 0xFFFF, SCRATCH1, size); | 4373 dst = mov_ir(dst, size == SZ_B ? 0xFF : 0xFFFF, SCRATCH1, size); |
4376 } | 4374 } |
4404 opts->dregs[3] = R8; | 4402 opts->dregs[3] = R8; |
4405 opts->aregs[0] = R13; | 4403 opts->aregs[0] = R13; |
4406 opts->aregs[1] = R14; | 4404 opts->aregs[1] = R14; |
4407 opts->aregs[2] = R9; | 4405 opts->aregs[2] = R9; |
4408 opts->aregs[7] = R15; | 4406 opts->aregs[7] = R15; |
4407 | |
4408 opts->flag_regs[0] = -1; | |
4409 opts->flag_regs[1] = RBX; | |
4410 opts->flag_regs[2] = RDX; | |
4411 opts->flag_regs[3] = BH; | |
4412 opts->flag_regs[4] = DH; | |
4409 opts->native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); | 4413 opts->native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); |
4410 memset(opts->native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); | 4414 memset(opts->native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); |
4411 opts->deferred = NULL; | 4415 opts->deferred = NULL; |
4412 size_t size = 1024 * 1024; | 4416 size_t size = 1024 * 1024; |
4413 opts->cur_code = alloc_code(&size); | 4417 opts->cur_code = alloc_code(&size); |
4414 opts->code_end = opts->cur_code + size; | 4418 opts->code_end = opts->cur_code + size; |
4415 opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); | 4419 opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); |
4416 memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64); | 4420 memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64); |
4417 | 4421 |
4422 uint8_t * dst = opts->cur_code; | |
4423 | |
4424 opts->save_context = dst; | |
4425 for (int i = 0; i < 5; i++) | |
4426 if (opts->flag_regs[i] >= 0) { | |
4427 dst = mov_rrdisp8(dst, opts->flag_regs[i], CONTEXT, offsetof(m68k_context, flags) + i, SZ_B); | |
4428 } | |
4429 for (int i = 0; i < 8; i++) | |
4430 { | |
4431 if (opts->dregs[i] >= 0) { | |
4432 dst = mov_rrdisp8(dst, opts->dregs[i], CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * i, SZ_D); | |
4433 } | |
4434 if (opts->aregs[i] >= 0) { | |
4435 dst = mov_rrdisp8(dst, opts->aregs[i], CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, SZ_D); | |
4436 } | |
4437 } | |
4438 dst = mov_rrdisp8(dst, CYCLES, CONTEXT, offsetof(m68k_context, current_cycle), SZ_D); | |
4439 dst = retn(dst); | |
4440 | |
4441 opts->load_context = dst; | |
4442 for (int i = 0; i < 5; i++) | |
4443 if (opts->flag_regs[i] >= 0) { | |
4444 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + i, opts->flag_regs[i], SZ_B); | |
4445 } | |
4446 for (int i = 0; i < 8; i++) | |
4447 { | |
4448 if (opts->dregs[i] >= 0) { | |
4449 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * i, opts->dregs[i], SZ_D); | |
4450 } | |
4451 if (opts->aregs[i] >= 0) { | |
4452 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, opts->aregs[i], SZ_D); | |
4453 } | |
4454 } | |
4455 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, current_cycle), CYCLES, SZ_D); | |
4456 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, target_cycle), LIMIT, SZ_D); | |
4457 dst = retn(dst); | |
4458 | |
4459 opts->cur_code = dst; | |
4460 | |
4418 opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16); | 4461 opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16); |
4419 opts->read_8 = gen_mem_fun(opts, memmap, num_chunks, READ_8); | 4462 opts->read_8 = gen_mem_fun(opts, memmap, num_chunks, READ_8); |
4420 opts->write_16 = gen_mem_fun(opts, memmap, num_chunks, WRITE_16); | 4463 opts->write_16 = gen_mem_fun(opts, memmap, num_chunks, WRITE_16); |
4421 opts->write_8 = gen_mem_fun(opts, memmap, num_chunks, WRITE_8); | 4464 opts->write_8 = gen_mem_fun(opts, memmap, num_chunks, WRITE_8); |
4422 | 4465 |
4423 uint8_t * dst = opts->cur_code; | 4466 dst = opts->cur_code; |
4424 | 4467 |
4425 opts->read_32 = dst; | 4468 opts->read_32 = dst; |
4426 dst = push_r(dst, SCRATCH1); | 4469 dst = push_r(dst, SCRATCH1); |
4427 dst = call(dst, opts->read_16); | 4470 dst = call(dst, opts->read_16); |
4428 dst = mov_rr(dst, SCRATCH1, SCRATCH2, SZ_W); | 4471 dst = mov_rr(dst, SCRATCH1, SCRATCH2, SZ_W); |
4461 uint8_t * do_int = dst+1; | 4504 uint8_t * do_int = dst+1; |
4462 dst = jcc(dst, CC_NC, dst+2); | 4505 dst = jcc(dst, CC_NC, dst+2); |
4463 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); | 4506 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); |
4464 uint8_t * skip_sync = dst+1; | 4507 uint8_t * skip_sync = dst+1; |
4465 dst = jcc(dst, CC_C, dst+2); | 4508 dst = jcc(dst, CC_C, dst+2); |
4466 dst = call(dst, (uint8_t *)m68k_save_context); | 4509 dst = call(dst, opts->save_context); |
4467 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); | 4510 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); |
4468 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); | 4511 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); |
4469 dst = test_ir(dst, 8, RSP, SZ_D); | 4512 dst = test_ir(dst, 8, RSP, SZ_D); |
4470 uint8_t *adjust_rsp = dst+1; | 4513 uint8_t *adjust_rsp = dst+1; |
4471 dst = jcc(dst, CC_NZ, dst+2); | 4514 dst = jcc(dst, CC_NZ, dst+2); |
4476 dst = sub_ir(dst, 8, RSP, SZ_Q); | 4519 dst = sub_ir(dst, 8, RSP, SZ_Q); |
4477 dst = call(dst, (uint8_t *)sync_components); | 4520 dst = call(dst, (uint8_t *)sync_components); |
4478 dst = add_ir(dst, 8, RSP, SZ_Q); | 4521 dst = add_ir(dst, 8, RSP, SZ_Q); |
4479 *no_adjust = dst - (no_adjust+1); | 4522 *no_adjust = dst - (no_adjust+1); |
4480 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); | 4523 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); |
4481 dst = jmp(dst, (uint8_t *)m68k_load_context); | 4524 dst = jmp(dst, opts->load_context); |
4482 *skip_sync = dst - (skip_sync+1); | 4525 *skip_sync = dst - (skip_sync+1); |
4483 dst = retn(dst); | 4526 dst = retn(dst); |
4484 *do_int = dst - (do_int+1); | 4527 *do_int = dst - (do_int+1); |
4485 //set target cycle to sync cycle | 4528 //set target cycle to sync cycle |
4486 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), LIMIT, SZ_D); | 4529 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), LIMIT, SZ_D); |