Mercurial > repos > blastem
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); |