Mercurial > repos > blastem
comparison m68k_to_x86.c @ 447:e730fc040169
Fix performance regression from stop instruction work
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 20 Jul 2013 23:40:28 -0700 |
parents | 1e828ed04a7c |
children | 6a315728fede |
comparison
equal
deleted
inserted
replaced
446:1e828ed04a7c | 447:e730fc040169 |
---|---|
121 case MODE_REG: | 121 case MODE_REG: |
122 case MODE_AREG: | 122 case MODE_AREG: |
123 //We only get one memory parameter, so if the dst operand is a register in memory, | 123 //We only get one memory parameter, so if the dst operand is a register in memory, |
124 //we need to copy this to a temp register first | 124 //we need to copy this to a temp register first |
125 reg = native_reg(&(inst->dst), opts); | 125 reg = native_reg(&(inst->dst), opts); |
126 if (reg >= 0 || inst->dst.addr_mode == MODE_UNUSED || !(inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG) | 126 if (reg >= 0 || inst->dst.addr_mode == MODE_UNUSED || !(inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG) |
127 || inst->op == M68K_EXG) { | 127 || inst->op == M68K_EXG) { |
128 | 128 |
129 ea->mode = MODE_REG_DISPLACE8; | 129 ea->mode = MODE_REG_DISPLACE8; |
130 ea->base = CONTEXT; | 130 ea->base = CONTEXT; |
131 ea->disp = reg_offset(&(inst->src)); | 131 ea->disp = reg_offset(&(inst->src)); |
132 } else { | 132 } else { |
133 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) { | 133 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) { |
148 out = sub_ir(out, dec_amount, opts->aregs[inst->src.params.regs.pri], SZ_D); | 148 out = sub_ir(out, dec_amount, opts->aregs[inst->src.params.regs.pri], SZ_D); |
149 } else { | 149 } else { |
150 out = sub_irdisp8(out, dec_amount, CONTEXT, reg_offset(&(inst->src)), SZ_D); | 150 out = sub_irdisp8(out, dec_amount, CONTEXT, reg_offset(&(inst->src)), SZ_D); |
151 } | 151 } |
152 case MODE_AREG_INDIRECT: | 152 case MODE_AREG_INDIRECT: |
153 case MODE_AREG_POSTINC: | 153 case MODE_AREG_POSTINC: |
154 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | 154 if (opts->aregs[inst->src.params.regs.pri] >= 0) { |
155 out = mov_rr(out, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); | 155 out = mov_rr(out, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); |
156 } else { | 156 } else { |
157 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); | 157 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); |
158 } | 158 } |
166 break; | 166 break; |
167 case OPSIZE_LONG: | 167 case OPSIZE_LONG: |
168 out = call(out, opts->read_32); | 168 out = call(out, opts->read_32); |
169 break; | 169 break; |
170 } | 170 } |
171 | 171 |
172 if (inst->src.addr_mode == MODE_AREG_POSTINC) { | 172 if (inst->src.addr_mode == MODE_AREG_POSTINC) { |
173 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->src.params.regs.pri == 7 ? 2 : 1)); | 173 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->src.params.regs.pri == 7 ? 2 : 1)); |
174 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | 174 if (opts->aregs[inst->src.params.regs.pri] >= 0) { |
175 out = add_ir(out, inc_amount, opts->aregs[inst->src.params.regs.pri], SZ_D); | 175 out = add_ir(out, inc_amount, opts->aregs[inst->src.params.regs.pri], SZ_D); |
176 } else { | 176 } else { |
439 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); | 439 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); |
440 } else { | 440 } else { |
441 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); | 441 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); |
442 } | 442 } |
443 } | 443 } |
444 | 444 |
445 if (inst->dst.addr_mode == MODE_AREG_POSTINC) { | 445 if (inst->dst.addr_mode == MODE_AREG_POSTINC) { |
446 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); | 446 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); |
447 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { | 447 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { |
448 out = add_ir(out, inc_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D); | 448 out = add_ir(out, inc_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D); |
449 } else { | 449 } else { |
779 if (inst->dst.addr_mode != MODE_AREG) { | 779 if (inst->dst.addr_mode != MODE_AREG) { |
780 //update statically set flags | 780 //update statically set flags |
781 dst = mov_ir(dst, 0, FLAG_V, SZ_B); | 781 dst = mov_ir(dst, 0, FLAG_V, SZ_B); |
782 dst = mov_ir(dst, 0, FLAG_C, SZ_B); | 782 dst = mov_ir(dst, 0, FLAG_C, SZ_B); |
783 } | 783 } |
784 | 784 |
785 if (inst->dst.addr_mode != MODE_AREG) { | 785 if (inst->dst.addr_mode != MODE_AREG) { |
786 if (src.mode == MODE_REG_DIRECT) { | 786 if (src.mode == MODE_REG_DIRECT) { |
787 flags_reg = src.base; | 787 flags_reg = src.base; |
788 } else { | 788 } else { |
789 if (reg >= 0) { | 789 if (reg >= 0) { |
2457 dst = push_r(dst, SCRATCH2); | 2457 dst = push_r(dst, SCRATCH2); |
2458 dst = call(dst, opts->write_8); | 2458 dst = call(dst, opts->write_8); |
2459 dst = pop_r(dst, SCRATCH2); | 2459 dst = pop_r(dst, SCRATCH2); |
2460 dst = mov_rr(dst, reg, SCRATCH1, SZ_D); | 2460 dst = mov_rr(dst, reg, SCRATCH1, SZ_D); |
2461 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); | 2461 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); |
2462 | 2462 |
2463 } else { | 2463 } else { |
2464 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+3, SCRATCH1, SZ_B); | 2464 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+3, SCRATCH1, SZ_B); |
2465 dst = push_r(dst, SCRATCH2); | 2465 dst = push_r(dst, SCRATCH2); |
2466 dst = call(dst, opts->write_8); | 2466 dst = call(dst, opts->write_8); |
2467 dst = pop_r(dst, SCRATCH2); | 2467 dst = pop_r(dst, SCRATCH2); |
2525 dst = add_ir(dst, 2, SCRATCH1, SZ_D); | 2525 dst = add_ir(dst, 2, SCRATCH1, SZ_D); |
2526 } | 2526 } |
2527 dst = push_r(dst, SCRATCH1); | 2527 dst = push_r(dst, SCRATCH1); |
2528 dst = call(dst, opts->read_8); | 2528 dst = call(dst, opts->read_8); |
2529 if (reg >= 0) { | 2529 if (reg >= 0) { |
2530 | 2530 |
2531 dst = shl_ir(dst, 8, SCRATCH1, SZ_W); | 2531 dst = shl_ir(dst, 8, SCRATCH1, SZ_W); |
2532 dst = mov_rr(dst, SCRATCH1, reg, SZ_W); | 2532 dst = mov_rr(dst, SCRATCH1, reg, SZ_W); |
2533 dst = pop_r(dst, SCRATCH1); | 2533 dst = pop_r(dst, SCRATCH1); |
2534 dst = add_ir(dst, 2, SCRATCH1, SZ_D); | 2534 dst = add_ir(dst, 2, SCRATCH1, SZ_D); |
2535 dst = call(dst, opts->read_8); | 2535 dst = call(dst, opts->read_8); |
2626 if (src_op->mode == MODE_REG_DIRECT) { | 2626 if (src_op->mode == MODE_REG_DIRECT) { |
2627 dst = mov_rr(dst, src_op->base, RCX, SZ_B); | 2627 dst = mov_rr(dst, src_op->base, RCX, SZ_B); |
2628 } else { | 2628 } else { |
2629 dst = mov_rdisp8r(dst, src_op->base, src_op->disp, RCX, SZ_B); | 2629 dst = mov_rdisp8r(dst, src_op->base, src_op->disp, RCX, SZ_B); |
2630 } | 2630 } |
2631 | 2631 |
2632 } | 2632 } |
2633 dst = and_ir(dst, 63, RCX, SZ_D); | 2633 dst = and_ir(dst, 63, RCX, SZ_D); |
2634 nz_off = dst+1; | 2634 nz_off = dst+1; |
2635 dst = jcc(dst, CC_NZ, dst+2); | 2635 dst = jcc(dst, CC_NZ, dst+2); |
2636 //Flag behavior for shift count of 0 is different for x86 than 68K | 2636 //Flag behavior for shift count of 0 is different for x86 than 68K |
2674 dst = jcc(dst, CC_L, dst+2); | 2674 dst = jcc(dst, CC_L, dst+2); |
2675 if (special) { | 2675 if (special) { |
2676 if (inst->extra.size == OPSIZE_LONG) { | 2676 if (inst->extra.size == OPSIZE_LONG) { |
2677 uint8_t * neq_32_off = dst + 1; | 2677 uint8_t * neq_32_off = dst + 1; |
2678 dst = jcc(dst, CC_NZ, dst+2); | 2678 dst = jcc(dst, CC_NZ, dst+2); |
2679 | 2679 |
2680 //set the carry bit to the lsb | 2680 //set the carry bit to the lsb |
2681 if (dst_op->mode == MODE_REG_DIRECT) { | 2681 if (dst_op->mode == MODE_REG_DIRECT) { |
2682 dst = special(dst, 1, dst_op->base, SZ_D); | 2682 dst = special(dst, 1, dst_op->base, SZ_D); |
2683 } else { | 2683 } else { |
2684 dst = special_disp8(dst, 1, dst_op->base, dst_op->disp, SZ_D); | 2684 dst = special_disp8(dst, 1, dst_op->base, dst_op->disp, SZ_D); |
2701 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size); | 2701 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size); |
2702 } else { | 2702 } else { |
2703 dst = shift_irdisp8(dst, 31, dst_op->base, dst_op->disp, inst->extra.size); | 2703 dst = shift_irdisp8(dst, 31, dst_op->base, dst_op->disp, inst->extra.size); |
2704 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size); | 2704 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size); |
2705 } | 2705 } |
2706 | 2706 |
2707 } | 2707 } |
2708 end_off = dst+1; | 2708 end_off = dst+1; |
2709 dst = jmp(dst, dst+2); | 2709 dst = jmp(dst, dst+2); |
2710 *norm_shift_off = dst - (norm_shift_off+1); | 2710 *norm_shift_off = dst - (norm_shift_off+1); |
2711 if (dst_op->mode == MODE_REG_DIRECT) { | 2711 if (dst_op->mode == MODE_REG_DIRECT) { |
2713 } else { | 2713 } else { |
2714 dst = shift_clrdisp8(dst, dst_op->base, dst_op->disp, inst->extra.size); | 2714 dst = shift_clrdisp8(dst, dst_op->base, dst_op->disp, inst->extra.size); |
2715 } | 2715 } |
2716 } | 2716 } |
2717 } | 2717 } |
2718 | 2718 |
2719 } | 2719 } |
2720 if (!special && end_off) { | 2720 if (!special && end_off) { |
2721 *end_off = dst - (end_off + 1); | 2721 *end_off = dst - (end_off + 1); |
2722 } | 2722 } |
2723 dst = setcc_r(dst, CC_C, FLAG_C); | 2723 dst = setcc_r(dst, CC_C, FLAG_C); |
3082 isize = 6; | 3082 isize = 6; |
3083 break; | 3083 break; |
3084 default: | 3084 default: |
3085 isize = 2; | 3085 isize = 2; |
3086 } | 3086 } |
3087 uint8_t * passed = dst+1; | 3087 uint8_t * passed = dst+1; |
3088 dst = jcc(dst, CC_GE, dst+2); | 3088 dst = jcc(dst, CC_GE, dst+2); |
3089 dst = mov_ir(dst, 1, FLAG_N, SZ_B); | 3089 dst = mov_ir(dst, 1, FLAG_N, SZ_B); |
3090 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D); | 3090 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D); |
3091 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D); | 3091 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D); |
3092 dst = jmp(dst, opts->trap); | 3092 dst = jmp(dst, opts->trap); |
3320 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W); | 3320 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W); |
3321 } | 3321 } |
3322 } | 3322 } |
3323 dst = call(dst, (uint8_t *)(inst->op == M68K_MOVE_SR ? set_sr : set_ccr)); | 3323 dst = call(dst, (uint8_t *)(inst->op == M68K_MOVE_SR ? set_sr : set_ccr)); |
3324 dst = cycles(dst, 12); | 3324 dst = cycles(dst, 12); |
3325 | 3325 |
3326 } | 3326 } |
3327 break; | 3327 break; |
3328 case M68K_MOVE_USP: | 3328 case M68K_MOVE_USP: |
3329 dst = cycles(dst, BUS); | 3329 dst = cycles(dst, BUS); |
3330 //TODO: Trap if not in supervisor mode | 3330 //TODO: Trap if not in supervisor mode |
3444 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); | 3444 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); |
3445 } else { | 3445 } else { |
3446 dst = not_rdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); | 3446 dst = not_rdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); |
3447 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size); | 3447 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size); |
3448 } | 3448 } |
3449 | 3449 |
3450 dst = mov_ir(dst, 0, FLAG_C, SZ_B); | 3450 dst = mov_ir(dst, 0, FLAG_C, SZ_B); |
3451 dst = setcc_r(dst, CC_Z, FLAG_Z); | 3451 dst = setcc_r(dst, CC_Z, FLAG_Z); |
3452 dst = setcc_r(dst, CC_S, FLAG_N); | 3452 dst = setcc_r(dst, CC_S, FLAG_N); |
3453 dst = mov_ir(dst, 0, FLAG_V, SZ_B); | 3453 dst = mov_ir(dst, 0, FLAG_V, SZ_B); |
3454 dst = m68k_save_result(inst, dst, opts); | 3454 dst = m68k_save_result(inst, dst, opts); |
3798 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); | 3798 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); |
3799 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); | 3799 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); |
3800 } | 3800 } |
3801 uint8_t * loop_top = dst; | 3801 uint8_t * loop_top = dst; |
3802 dst = call(dst, (uint8_t *)do_sync); | 3802 dst = call(dst, (uint8_t *)do_sync); |
3803 dst = cmp_rr(dst, LIMIT, CYCLES, SZ_D); | |
3804 uint8_t * normal_cycle_up = dst + 1; | |
3805 dst = jcc(dst, CC_A, dst+2); | |
3806 dst = cycles(dst, BUS); | |
3807 uint8_t * after_cycle_up = dst + 1; | |
3808 dst = jmp(dst, dst+2); | |
3809 *normal_cycle_up = dst - (normal_cycle_up + 1); | |
3803 dst = mov_rr(dst, LIMIT, CYCLES, SZ_D); | 3810 dst = mov_rr(dst, LIMIT, CYCLES, SZ_D); |
3811 *after_cycle_up = dst - (after_cycle_up+1); | |
3804 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); | 3812 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); |
3805 dst = jcc(dst, CC_C, loop_top); | 3813 dst = jcc(dst, CC_C, loop_top); |
3806 break; | 3814 break; |
3807 } | 3815 } |
3808 case M68K_SUB: | 3816 case M68K_SUB: |
3865 dst = cmp_ir(dst, 0, src_op.base, SZ_D); | 3873 dst = cmp_ir(dst, 0, src_op.base, SZ_D); |
3866 } else{ | 3874 } else{ |
3867 dst = rol_irdisp8(dst, 16, src_op.base, src_op.disp, SZ_D); | 3875 dst = rol_irdisp8(dst, 16, src_op.base, src_op.disp, SZ_D); |
3868 dst = cmp_irdisp8(dst, 0, src_op.base, src_op.disp, SZ_D); | 3876 dst = cmp_irdisp8(dst, 0, src_op.base, src_op.disp, SZ_D); |
3869 } | 3877 } |
3870 | 3878 |
3871 dst = mov_ir(dst, 0, FLAG_C, SZ_B); | 3879 dst = mov_ir(dst, 0, FLAG_C, SZ_B); |
3872 dst = setcc_r(dst, CC_Z, FLAG_Z); | 3880 dst = setcc_r(dst, CC_Z, FLAG_Z); |
3873 dst = setcc_r(dst, CC_S, FLAG_N); | 3881 dst = setcc_r(dst, CC_S, FLAG_N); |
3874 dst = mov_ir(dst, 0, FLAG_V, SZ_B); | 3882 dst = mov_ir(dst, 0, FLAG_V, SZ_B); |
3875 break; | 3883 break; |
3935 uint8_t * translate_m68k_stream(uint32_t address, m68k_context * context) | 3943 uint8_t * translate_m68k_stream(uint32_t address, m68k_context * context) |
3936 { | 3944 { |
3937 m68kinst instbuf; | 3945 m68kinst instbuf; |
3938 x86_68k_options * opts = context->options; | 3946 x86_68k_options * opts = context->options; |
3939 uint8_t * dst = opts->cur_code; | 3947 uint8_t * dst = opts->cur_code; |
3940 uint8_t * dst_end = opts->code_end; | 3948 uint8_t * dst_end = opts->code_end; |
3941 address &= 0xFFFFFF; | 3949 address &= 0xFFFFFF; |
3942 if(get_native_address(opts->native_code_map, address)) { | 3950 if(get_native_address(opts->native_code_map, address)) { |
3943 return dst; | 3951 return dst; |
3944 } | 3952 } |
3945 char disbuf[1024]; | 3953 char disbuf[1024]; |
4063 } | 4071 } |
4064 m68k_handle_deferred(context); | 4072 m68k_handle_deferred(context); |
4065 return orig_start; | 4073 return orig_start; |
4066 } | 4074 } |
4067 } | 4075 } |
4068 | 4076 |
4069 map_native_address(context, instbuf.address, dst, (after-inst)*2, MAX_NATIVE_SIZE); | 4077 map_native_address(context, instbuf.address, dst, (after-inst)*2, MAX_NATIVE_SIZE); |
4070 opts->cur_code = dst+MAX_NATIVE_SIZE; | 4078 opts->cur_code = dst+MAX_NATIVE_SIZE; |
4071 jmp(orig_start, dst); | 4079 jmp(orig_start, dst); |
4072 if (!m68k_is_terminal(&instbuf)) { | 4080 if (!m68k_is_terminal(&instbuf)) { |
4073 jmp(native_end, get_native_address_trans(context, orig + (after-inst)*2)); | 4081 jmp(native_end, get_native_address_trans(context, orig + (after-inst)*2)); |
4110 dst = alloc_code(&size); | 4118 dst = alloc_code(&size); |
4111 opts->code_end = dst_end = dst + size; | 4119 opts->code_end = dst_end = dst + size; |
4112 } | 4120 } |
4113 bp_stub = dst; | 4121 bp_stub = dst; |
4114 native = call(native, bp_stub); | 4122 native = call(native, bp_stub); |
4115 | 4123 |
4116 //Calculate length of prologue | 4124 //Calculate length of prologue |
4117 dst = check_cycles_int(dst, address, opts); | 4125 dst = check_cycles_int(dst, address, opts); |
4118 int check_int_size = dst-bp_stub; | 4126 int check_int_size = dst-bp_stub; |
4119 dst = bp_stub; | 4127 dst = bp_stub; |
4120 | 4128 |
4121 //Save context and call breakpoint handler | 4129 //Save context and call breakpoint handler |
4122 dst = call(dst, (uint8_t *)m68k_save_context); | 4130 dst = call(dst, (uint8_t *)m68k_save_context); |
4123 dst = push_r(dst, SCRATCH1); | 4131 dst = push_r(dst, SCRATCH1); |
4124 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); | 4132 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); |
4125 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); | 4133 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); |
4193 if (memmap[chunk].end < 0x1000000) { | 4201 if (memmap[chunk].end < 0x1000000) { |
4194 dst = cmp_ir(dst, memmap[chunk].end, adr_reg, SZ_D); | 4202 dst = cmp_ir(dst, memmap[chunk].end, adr_reg, SZ_D); |
4195 ub_jcc = dst + 1; | 4203 ub_jcc = dst + 1; |
4196 dst = jcc(dst, CC_NC, dst+2); | 4204 dst = jcc(dst, CC_NC, dst+2); |
4197 } | 4205 } |
4198 | 4206 |
4199 if (memmap[chunk].mask != 0xFFFFFF) { | 4207 if (memmap[chunk].mask != 0xFFFFFF) { |
4200 dst = and_ir(dst, memmap[chunk].mask, adr_reg, SZ_D); | 4208 dst = and_ir(dst, memmap[chunk].mask, adr_reg, SZ_D); |
4201 } | 4209 } |
4202 void * cfun; | 4210 void * cfun; |
4203 switch (fun_type) | 4211 switch (fun_type) |
4237 } else { | 4245 } else { |
4238 dst = pop_r(dst, CONTEXT); | 4246 dst = pop_r(dst, CONTEXT); |
4239 dst = mov_rr(dst, RAX, SCRATCH1, size); | 4247 dst = mov_rr(dst, RAX, SCRATCH1, size); |
4240 } | 4248 } |
4241 dst = jmp(dst, (uint8_t *)m68k_load_context); | 4249 dst = jmp(dst, (uint8_t *)m68k_load_context); |
4242 | 4250 |
4243 *not_null = dst - (not_null + 1); | 4251 *not_null = dst - (not_null + 1); |
4244 } | 4252 } |
4245 if (size == SZ_B) { | 4253 if (size == SZ_B) { |
4246 dst = xor_ir(dst, 1, adr_reg, SZ_D); | 4254 dst = xor_ir(dst, 1, adr_reg, SZ_D); |
4247 } | 4255 } |
4248 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, adr_reg, SZ_Q); | 4256 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, adr_reg, SZ_Q); |
4249 if (is_write) { | 4257 if (is_write) { |
4250 dst = mov_rrind(dst, SCRATCH1, SCRATCH2, size); | 4258 dst = mov_rrind(dst, SCRATCH1, SCRATCH2, size); |
4251 | 4259 |
4252 } else { | 4260 } else { |
4253 dst = mov_rindr(dst, SCRATCH1, SCRATCH1, size); | 4261 dst = mov_rindr(dst, SCRATCH1, SCRATCH1, size); |
4254 } | 4262 } |
4255 } else { | 4263 } else { |
4256 uint8_t tmp_size = size; | 4264 uint8_t tmp_size = size; |
4375 size_t size = 1024 * 1024; | 4383 size_t size = 1024 * 1024; |
4376 opts->cur_code = alloc_code(&size); | 4384 opts->cur_code = alloc_code(&size); |
4377 opts->code_end = opts->cur_code + size; | 4385 opts->code_end = opts->cur_code + size; |
4378 opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); | 4386 opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); |
4379 memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64); | 4387 memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64); |
4380 | 4388 |
4381 opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16); | 4389 opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16); |
4382 opts->read_8 = gen_mem_fun(opts, memmap, num_chunks, READ_8); | 4390 opts->read_8 = gen_mem_fun(opts, memmap, num_chunks, READ_8); |
4383 opts->write_16 = gen_mem_fun(opts, memmap, num_chunks, WRITE_16); | 4391 opts->write_16 = gen_mem_fun(opts, memmap, num_chunks, WRITE_16); |
4384 opts->write_8 = gen_mem_fun(opts, memmap, num_chunks, WRITE_8); | 4392 opts->write_8 = gen_mem_fun(opts, memmap, num_chunks, WRITE_8); |
4385 | 4393 |
4386 uint8_t * dst = opts->cur_code; | 4394 uint8_t * dst = opts->cur_code; |
4387 | 4395 |
4388 opts->read_32 = dst; | 4396 opts->read_32 = dst; |
4389 dst = push_r(dst, SCRATCH1); | 4397 dst = push_r(dst, SCRATCH1); |
4390 dst = call(dst, opts->read_16); | 4398 dst = call(dst, opts->read_16); |
4391 dst = mov_rr(dst, SCRATCH1, SCRATCH2, SZ_W); | 4399 dst = mov_rr(dst, SCRATCH1, SCRATCH2, SZ_W); |
4392 dst = pop_r(dst, SCRATCH1); | 4400 dst = pop_r(dst, SCRATCH1); |
4396 dst = pop_r(dst, SCRATCH2); | 4404 dst = pop_r(dst, SCRATCH2); |
4397 dst = movzx_rr(dst, SCRATCH1, SCRATCH1, SZ_W, SZ_D); | 4405 dst = movzx_rr(dst, SCRATCH1, SCRATCH1, SZ_W, SZ_D); |
4398 dst = shl_ir(dst, 16, SCRATCH2, SZ_D); | 4406 dst = shl_ir(dst, 16, SCRATCH2, SZ_D); |
4399 dst = or_rr(dst, SCRATCH2, SCRATCH1, SZ_D); | 4407 dst = or_rr(dst, SCRATCH2, SCRATCH1, SZ_D); |
4400 dst = retn(dst); | 4408 dst = retn(dst); |
4401 | 4409 |
4402 opts->write_32_lowfirst = dst; | 4410 opts->write_32_lowfirst = dst; |
4403 dst = push_r(dst, SCRATCH2); | 4411 dst = push_r(dst, SCRATCH2); |
4404 dst = push_r(dst, SCRATCH1); | 4412 dst = push_r(dst, SCRATCH1); |
4405 dst = add_ir(dst, 2, SCRATCH2, SZ_D); | 4413 dst = add_ir(dst, 2, SCRATCH2, SZ_D); |
4406 dst = call(dst, opts->write_16); | 4414 dst = call(dst, opts->write_16); |
4407 dst = pop_r(dst, SCRATCH1); | 4415 dst = pop_r(dst, SCRATCH1); |
4408 dst = pop_r(dst, SCRATCH2); | 4416 dst = pop_r(dst, SCRATCH2); |
4409 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); | 4417 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); |
4410 dst = jmp(dst, opts->write_16); | 4418 dst = jmp(dst, opts->write_16); |
4411 | 4419 |
4412 opts->write_32_highfirst = dst; | 4420 opts->write_32_highfirst = dst; |
4413 dst = push_r(dst, SCRATCH1); | 4421 dst = push_r(dst, SCRATCH1); |
4414 dst = push_r(dst, SCRATCH2); | 4422 dst = push_r(dst, SCRATCH2); |
4415 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); | 4423 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); |
4416 dst = call(dst, opts->write_16); | 4424 dst = call(dst, opts->write_16); |
4417 dst = pop_r(dst, SCRATCH2); | 4425 dst = pop_r(dst, SCRATCH2); |
4418 dst = pop_r(dst, SCRATCH1); | 4426 dst = pop_r(dst, SCRATCH1); |
4419 dst = add_ir(dst, 2, SCRATCH2, SZ_D); | 4427 dst = add_ir(dst, 2, SCRATCH2, SZ_D); |
4420 dst = jmp(dst, opts->write_16); | 4428 dst = jmp(dst, opts->write_16); |
4421 | 4429 |
4422 opts->handle_cycle_limit_int = dst; | 4430 opts->handle_cycle_limit_int = dst; |
4423 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); | 4431 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); |
4424 uint8_t * do_int = dst+1; | 4432 uint8_t * do_int = dst+1; |
4425 dst = jcc(dst, CC_NC, dst+2); | 4433 dst = jcc(dst, CC_NC, dst+2); |
4426 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); | 4434 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); |
4468 dst = call(dst, (uint8_t *)m68k_native_addr_and_sync); | 4476 dst = call(dst, (uint8_t *)m68k_native_addr_and_sync); |
4469 dst = cycles(dst, 24); | 4477 dst = cycles(dst, 24); |
4470 //discard function return address | 4478 //discard function return address |
4471 dst = pop_r(dst, SCRATCH2); | 4479 dst = pop_r(dst, SCRATCH2); |
4472 dst = jmp_r(dst, SCRATCH1); | 4480 dst = jmp_r(dst, SCRATCH1); |
4473 | 4481 |
4474 opts->trap = dst; | 4482 opts->trap = dst; |
4475 dst = push_r(dst, SCRATCH2); | 4483 dst = push_r(dst, SCRATCH2); |
4476 //swap USP and SSP if not already in supervisor mode | 4484 //swap USP and SSP if not already in supervisor mode |
4477 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B); | 4485 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B); |
4478 already_supervisor = dst+1; | 4486 already_supervisor = dst+1; |
4497 dst = shl_ir(dst, 2, SCRATCH1, SZ_D); | 4505 dst = shl_ir(dst, 2, SCRATCH1, SZ_D); |
4498 dst = call(dst, opts->read_32); | 4506 dst = call(dst, opts->read_32); |
4499 dst = call(dst, (uint8_t *)m68k_native_addr_and_sync); | 4507 dst = call(dst, (uint8_t *)m68k_native_addr_and_sync); |
4500 dst = cycles(dst, 18); | 4508 dst = cycles(dst, 18); |
4501 dst = jmp_r(dst, SCRATCH1); | 4509 dst = jmp_r(dst, SCRATCH1); |
4502 | 4510 |
4503 opts->cur_code = dst; | 4511 opts->cur_code = dst; |
4504 } | 4512 } |
4505 | 4513 |
4506 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) | 4514 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) |
4507 { | 4515 { |