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 {