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