comparison m68k_to_x86.c @ 545:67cf0ce57d8d

Generate handle_cycle_limit at runtime so it can use the generated save/load_context functions. Since the hand written versions of save/load are no longer used they have been removed.
author Michael Pavone <pavone@retrodev.com>
date Sun, 16 Feb 2014 19:54:27 -0800
parents 8a26567852b7
children 90aca661542b
comparison
equal deleted inserted replaced
544:8a26567852b7 545:67cf0ce57d8d
28 28
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();
34 void m68k_invalid(); 33 void m68k_invalid();
35 void set_sr(); 34 void set_sr();
36 void set_ccr(); 35 void set_ccr();
37 void get_sr(); 36 void get_sr();
38 void do_sync();
39 void bcd_add(); 37 void bcd_add();
40 void bcd_sub(); 38 void bcd_sub();
41 39
42 uint8_t * cycles(uint8_t * dst, uint32_t num) 40 uint8_t * cycles(uint8_t * dst, uint32_t num)
43 { 41 {
54 dst = call(dst, opts->handle_cycle_limit_int); 52 dst = call(dst, opts->handle_cycle_limit_int);
55 *jmp_off = dst - (jmp_off+1); 53 *jmp_off = dst - (jmp_off+1);
56 return dst; 54 return dst;
57 } 55 }
58 56
59 uint8_t * check_cycles(uint8_t * dst) 57 uint8_t * check_cycles(uint8_t * dst, x86_68k_options * opts)
60 { 58 {
61 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); 59 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
62 uint8_t * jmp_off = dst+1; 60 uint8_t * jmp_off = dst+1;
63 dst = jcc(dst, CC_NC, dst + 7); 61 dst = jcc(dst, CC_NC, dst + 7);
64 dst = call(dst, (uint8_t *)handle_cycle_limit); 62 dst = call(dst, opts->handle_cycle_limit);
65 *jmp_off = dst - (jmp_off+1); 63 *jmp_off = dst - (jmp_off+1);
66 return dst; 64 return dst;
67 } 65 }
68 66
69 int8_t native_reg(m68k_op_info * op, x86_68k_options * opts) 67 int8_t native_reg(m68k_op_info * op, x86_68k_options * opts)
2848 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_B); 2846 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_B);
2849 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_B); 2847 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_B);
2850 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_B); 2848 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_B);
2851 } 2849 }
2852 if (inst->src.params.immed & 0x700) { 2850 if (inst->src.params.immed & 0x700) {
2853 dst = call(dst, (uint8_t *)do_sync); 2851 dst = call(dst, opts->do_sync);
2854 } 2852 }
2855 } 2853 }
2856 break; 2854 break;
2857 case M68K_ASL: 2855 case M68K_ASL:
2858 case M68K_LSL: 2856 case M68K_LSL:
3164 dst = xor_irdisp8(dst, 1, CONTEXT, 0, SZ_B); 3162 dst = xor_irdisp8(dst, 1, CONTEXT, 0, SZ_B);
3165 } 3163 }
3166 if (inst->op == M68K_ORI_SR) { 3164 if (inst->op == M68K_ORI_SR) {
3167 dst = xor_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B); 3165 dst = xor_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B);
3168 if (inst->src.params.immed & 0x700) { 3166 if (inst->src.params.immed & 0x700) {
3169 dst = call(dst, (uint8_t *)do_sync); 3167 dst = call(dst, opts->do_sync);
3170 } 3168 }
3171 } 3169 }
3172 break; 3170 break;
3173 case M68K_EXG: 3171 case M68K_EXG:
3174 dst = cycles(dst, 6); 3172 dst = cycles(dst, 6);
3223 //leave supervisor mode 3221 //leave supervisor mode
3224 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3222 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3225 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); 3223 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D);
3226 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); 3224 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
3227 } 3225 }
3228 dst = call(dst, (uint8_t *)do_sync); 3226 dst = call(dst, opts->do_sync);
3229 } 3227 }
3230 dst = cycles(dst, 12); 3228 dst = cycles(dst, 12);
3231 } else { 3229 } else {
3232 if (src_op.base != SCRATCH1) { 3230 if (src_op.base != SCRATCH1) {
3233 if (src_op.mode == MODE_REG_DIRECT) { 3231 if (src_op.mode == MODE_REG_DIRECT) {
3412 dst = mov_irind(dst, 1, CONTEXT, SZ_B); 3410 dst = mov_irind(dst, 1, CONTEXT, SZ_B);
3413 } 3411 }
3414 if (inst->op == M68K_ORI_SR) { 3412 if (inst->op == M68K_ORI_SR) {
3415 dst = or_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B); 3413 dst = or_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B);
3416 if (inst->src.params.immed & 0x700) { 3414 if (inst->src.params.immed & 0x700) {
3417 dst = call(dst, (uint8_t *)do_sync); 3415 dst = call(dst, opts->do_sync);
3418 } 3416 }
3419 } 3417 }
3420 break; 3418 break;
3421 case M68K_RESET: 3419 case M68K_RESET:
3422 dst = call(dst, opts->save_context); 3420 dst = call(dst, opts->save_context);
3712 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3710 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3713 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); 3711 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D);
3714 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); 3712 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
3715 } 3713 }
3716 uint8_t * loop_top = dst; 3714 uint8_t * loop_top = dst;
3717 dst = call(dst, (uint8_t *)do_sync); 3715 dst = call(dst, opts->do_sync);
3718 dst = cmp_rr(dst, LIMIT, CYCLES, SZ_D); 3716 dst = cmp_rr(dst, LIMIT, CYCLES, SZ_D);
3719 uint8_t * normal_cycle_up = dst + 1; 3717 uint8_t * normal_cycle_up = dst + 1;
3720 dst = jcc(dst, CC_A, dst+2); 3718 dst = jcc(dst, CC_A, dst+2);
3721 dst = cycles(dst, BUS); 3719 dst = cycles(dst, BUS);
3722 uint8_t * after_cycle_up = dst + 1; 3720 uint8_t * after_cycle_up = dst + 1;
4114 4112
4115 uint8_t * gen_mem_fun(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, ftype fun_type) 4113 uint8_t * gen_mem_fun(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, ftype fun_type)
4116 { 4114 {
4117 uint8_t * dst = opts->cur_code; 4115 uint8_t * dst = opts->cur_code;
4118 uint8_t * start = dst; 4116 uint8_t * start = dst;
4119 dst = check_cycles(dst); 4117 dst = check_cycles(dst, opts);
4120 dst = cycles(dst, BUS); 4118 dst = cycles(dst, BUS);
4121 dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D); 4119 dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D);
4122 uint8_t *lb_jcc = NULL, *ub_jcc = NULL; 4120 uint8_t *lb_jcc = NULL, *ub_jcc = NULL;
4123 uint8_t is_write = fun_type == WRITE_16 || fun_type == WRITE_8; 4121 uint8_t is_write = fun_type == WRITE_16 || fun_type == WRITE_8;
4124 uint8_t adr_reg = is_write ? SCRATCH2 : SCRATCH1; 4122 uint8_t adr_reg = is_write ? SCRATCH2 : SCRATCH1;
4434 dst = mov_rr(dst, RAX, SCRATCH1, SZ_Q); //move result to scratch reg 4432 dst = mov_rr(dst, RAX, SCRATCH1, SZ_Q); //move result to scratch reg
4435 dst = pop_r(dst, CONTEXT); 4433 dst = pop_r(dst, CONTEXT);
4436 dst = call(dst, opts->load_context); 4434 dst = call(dst, opts->load_context);
4437 dst = retn(dst); 4435 dst = retn(dst);
4438 4436
4437 opts->handle_cycle_limit = dst;
4438 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D);
4439 uint8_t * skip_sync = dst+1;
4440 dst = jcc(dst, CC_C, dst+2);
4441 opts->do_sync = dst;
4442 dst = push_r(dst, SCRATCH1);
4443 dst = push_r(dst, SCRATCH2);
4444 dst = call(dst, opts->save_context);
4445 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
4446 dst = xor_rr(dst, RSI, RSI, SZ_D);
4447 dst = test_ir(dst, 8, RSP, SZ_D);
4448 uint8_t *adjust_rsp = dst+1;
4449 dst = jcc(dst, CC_NZ, dst+2);
4450 dst = call(dst, (uint8_t *)sync_components);
4451 uint8_t *no_adjust = dst+1;
4452 dst = jmp(dst, dst+2);
4453 *adjust_rsp = dst - (adjust_rsp + 1);
4454 dst = sub_ir(dst, 8, RSP, SZ_Q);
4455 dst = call(dst, (uint8_t *)sync_components);
4456 dst = add_ir(dst, 8, RSP, SZ_Q);
4457 *no_adjust = dst - (no_adjust+1);
4458 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
4459 dst = call(dst, opts->load_context);
4460 dst = pop_r(dst, SCRATCH2);
4461 dst = pop_r(dst, SCRATCH1);
4462 *skip_sync = dst - (skip_sync+1);
4463 dst = retn(dst);
4464
4439 opts->cur_code = dst; 4465 opts->cur_code = dst;
4440 4466
4441 opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16); 4467 opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16);
4442 opts->read_8 = gen_mem_fun(opts, memmap, num_chunks, READ_8); 4468 opts->read_8 = gen_mem_fun(opts, memmap, num_chunks, READ_8);
4443 opts->write_16 = gen_mem_fun(opts, memmap, num_chunks, WRITE_16); 4469 opts->write_16 = gen_mem_fun(opts, memmap, num_chunks, WRITE_16);
4482 opts->handle_cycle_limit_int = dst; 4508 opts->handle_cycle_limit_int = dst;
4483 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); 4509 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D);
4484 uint8_t * do_int = dst+1; 4510 uint8_t * do_int = dst+1;
4485 dst = jcc(dst, CC_NC, dst+2); 4511 dst = jcc(dst, CC_NC, dst+2);
4486 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); 4512 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D);
4487 uint8_t * skip_sync = dst+1; 4513 skip_sync = dst+1;
4488 dst = jcc(dst, CC_C, dst+2); 4514 dst = jcc(dst, CC_C, dst+2);
4489 dst = call(dst, opts->save_context); 4515 dst = call(dst, opts->save_context);
4490 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); 4516 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
4491 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); 4517 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D);
4492 dst = test_ir(dst, 8, RSP, SZ_D); 4518 dst = test_ir(dst, 8, RSP, SZ_D);
4493 uint8_t *adjust_rsp = dst+1; 4519 adjust_rsp = dst+1;
4494 dst = jcc(dst, CC_NZ, dst+2); 4520 dst = jcc(dst, CC_NZ, dst+2);
4495 dst = call(dst, (uint8_t *)sync_components); 4521 dst = call(dst, (uint8_t *)sync_components);
4496 uint8_t *no_adjust = dst+1; 4522 no_adjust = dst+1;
4497 dst = jmp(dst, dst+2); 4523 dst = jmp(dst, dst+2);
4498 *adjust_rsp = dst - (adjust_rsp + 1); 4524 *adjust_rsp = dst - (adjust_rsp + 1);
4499 dst = sub_ir(dst, 8, RSP, SZ_Q); 4525 dst = sub_ir(dst, 8, RSP, SZ_Q);
4500 dst = call(dst, (uint8_t *)sync_components); 4526 dst = call(dst, (uint8_t *)sync_components);
4501 dst = add_ir(dst, 8, RSP, SZ_Q); 4527 dst = add_ir(dst, 8, RSP, SZ_Q);