comparison m68k_to_x86.c @ 487:c08a4efeee7f opengl

Update opengl branch from default. Fix build breakage unrelated to merge
author Mike Pavone <pavone@retrodev.com>
date Sat, 26 Oct 2013 22:38:47 -0700
parents b449af228c63
children 7f54f1773e84
comparison
equal deleted inserted replaced
449:7696d824489d 487:c08a4efeee7f
1 /*
2 Copyright 2013 Michael Pavone
3 This file is part of BlastEm.
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
5 */
1 #include "gen_x86.h" 6 #include "gen_x86.h"
2 #include "m68k_to_x86.h" 7 #include "m68k_to_x86.h"
3 #include "68kinst.h" 8 #include "68kinst.h"
4 #include "mem.h" 9 #include "mem.h"
5 #include "x86_backend.h" 10 #include "x86_backend.h"
121 case MODE_REG: 126 case MODE_REG:
122 case MODE_AREG: 127 case MODE_AREG:
123 //We only get one memory parameter, so if the dst operand is a register in memory, 128 //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 129 //we need to copy this to a temp register first
125 reg = native_reg(&(inst->dst), opts); 130 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) 131 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) { 132 || inst->op == M68K_EXG) {
128 133
129 ea->mode = MODE_REG_DISPLACE8; 134 ea->mode = MODE_REG_DISPLACE8;
130 ea->base = CONTEXT; 135 ea->base = CONTEXT;
131 ea->disp = reg_offset(&(inst->src)); 136 ea->disp = reg_offset(&(inst->src));
132 } else { 137 } else {
133 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) { 138 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); 153 out = sub_ir(out, dec_amount, opts->aregs[inst->src.params.regs.pri], SZ_D);
149 } else { 154 } else {
150 out = sub_irdisp8(out, dec_amount, CONTEXT, reg_offset(&(inst->src)), SZ_D); 155 out = sub_irdisp8(out, dec_amount, CONTEXT, reg_offset(&(inst->src)), SZ_D);
151 } 156 }
152 case MODE_AREG_INDIRECT: 157 case MODE_AREG_INDIRECT:
153 case MODE_AREG_POSTINC: 158 case MODE_AREG_POSTINC:
154 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 159 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
155 out = mov_rr(out, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 160 out = mov_rr(out, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
156 } else { 161 } else {
157 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 162 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D);
158 } 163 }
166 break; 171 break;
167 case OPSIZE_LONG: 172 case OPSIZE_LONG:
168 out = call(out, opts->read_32); 173 out = call(out, opts->read_32);
169 break; 174 break;
170 } 175 }
171 176
172 if (inst->src.addr_mode == MODE_AREG_POSTINC) { 177 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)); 178 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) { 179 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); 180 out = add_ir(out, inc_amount, opts->aregs[inst->src.params.regs.pri], SZ_D);
176 } else { 181 } else {
439 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); 444 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D);
440 } else { 445 } else {
441 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); 446 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D);
442 } 447 }
443 } 448 }
444 449
445 if (inst->dst.addr_mode == MODE_AREG_POSTINC) { 450 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)); 451 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) { 452 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); 453 out = add_ir(out, inc_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D);
449 } else { 454 } else {
779 if (inst->dst.addr_mode != MODE_AREG) { 784 if (inst->dst.addr_mode != MODE_AREG) {
780 //update statically set flags 785 //update statically set flags
781 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 786 dst = mov_ir(dst, 0, FLAG_V, SZ_B);
782 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 787 dst = mov_ir(dst, 0, FLAG_C, SZ_B);
783 } 788 }
784 789
785 if (inst->dst.addr_mode != MODE_AREG) { 790 if (inst->dst.addr_mode != MODE_AREG) {
786 if (src.mode == MODE_REG_DIRECT) { 791 if (src.mode == MODE_REG_DIRECT) {
787 flags_reg = src.base; 792 flags_reg = src.base;
788 } else { 793 } else {
789 if (reg >= 0) { 794 if (reg >= 0) {
2457 dst = push_r(dst, SCRATCH2); 2462 dst = push_r(dst, SCRATCH2);
2458 dst = call(dst, opts->write_8); 2463 dst = call(dst, opts->write_8);
2459 dst = pop_r(dst, SCRATCH2); 2464 dst = pop_r(dst, SCRATCH2);
2460 dst = mov_rr(dst, reg, SCRATCH1, SZ_D); 2465 dst = mov_rr(dst, reg, SCRATCH1, SZ_D);
2461 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); 2466 dst = shr_ir(dst, 16, SCRATCH1, SZ_D);
2462 2467
2463 } else { 2468 } else {
2464 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+3, SCRATCH1, SZ_B); 2469 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+3, SCRATCH1, SZ_B);
2465 dst = push_r(dst, SCRATCH2); 2470 dst = push_r(dst, SCRATCH2);
2466 dst = call(dst, opts->write_8); 2471 dst = call(dst, opts->write_8);
2467 dst = pop_r(dst, SCRATCH2); 2472 dst = pop_r(dst, SCRATCH2);
2525 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2530 dst = add_ir(dst, 2, SCRATCH1, SZ_D);
2526 } 2531 }
2527 dst = push_r(dst, SCRATCH1); 2532 dst = push_r(dst, SCRATCH1);
2528 dst = call(dst, opts->read_8); 2533 dst = call(dst, opts->read_8);
2529 if (reg >= 0) { 2534 if (reg >= 0) {
2530 2535
2531 dst = shl_ir(dst, 8, SCRATCH1, SZ_W); 2536 dst = shl_ir(dst, 8, SCRATCH1, SZ_W);
2532 dst = mov_rr(dst, SCRATCH1, reg, SZ_W); 2537 dst = mov_rr(dst, SCRATCH1, reg, SZ_W);
2533 dst = pop_r(dst, SCRATCH1); 2538 dst = pop_r(dst, SCRATCH1);
2534 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2539 dst = add_ir(dst, 2, SCRATCH1, SZ_D);
2535 dst = call(dst, opts->read_8); 2540 dst = call(dst, opts->read_8);
2626 if (src_op->mode == MODE_REG_DIRECT) { 2631 if (src_op->mode == MODE_REG_DIRECT) {
2627 dst = mov_rr(dst, src_op->base, RCX, SZ_B); 2632 dst = mov_rr(dst, src_op->base, RCX, SZ_B);
2628 } else { 2633 } else {
2629 dst = mov_rdisp8r(dst, src_op->base, src_op->disp, RCX, SZ_B); 2634 dst = mov_rdisp8r(dst, src_op->base, src_op->disp, RCX, SZ_B);
2630 } 2635 }
2631 2636
2632 } 2637 }
2633 dst = and_ir(dst, 63, RCX, SZ_D); 2638 dst = and_ir(dst, 63, RCX, SZ_D);
2634 nz_off = dst+1; 2639 nz_off = dst+1;
2635 dst = jcc(dst, CC_NZ, dst+2); 2640 dst = jcc(dst, CC_NZ, dst+2);
2636 //Flag behavior for shift count of 0 is different for x86 than 68K 2641 //Flag behavior for shift count of 0 is different for x86 than 68K
2674 dst = jcc(dst, CC_L, dst+2); 2679 dst = jcc(dst, CC_L, dst+2);
2675 if (special) { 2680 if (special) {
2676 if (inst->extra.size == OPSIZE_LONG) { 2681 if (inst->extra.size == OPSIZE_LONG) {
2677 uint8_t * neq_32_off = dst + 1; 2682 uint8_t * neq_32_off = dst + 1;
2678 dst = jcc(dst, CC_NZ, dst+2); 2683 dst = jcc(dst, CC_NZ, dst+2);
2679 2684
2680 //set the carry bit to the lsb 2685 //set the carry bit to the lsb
2681 if (dst_op->mode == MODE_REG_DIRECT) { 2686 if (dst_op->mode == MODE_REG_DIRECT) {
2682 dst = special(dst, 1, dst_op->base, SZ_D); 2687 dst = special(dst, 1, dst_op->base, SZ_D);
2683 } else { 2688 } else {
2684 dst = special_disp8(dst, 1, dst_op->base, dst_op->disp, SZ_D); 2689 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); 2706 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size);
2702 } else { 2707 } else {
2703 dst = shift_irdisp8(dst, 31, dst_op->base, dst_op->disp, inst->extra.size); 2708 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); 2709 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size);
2705 } 2710 }
2706 2711
2707 } 2712 }
2708 end_off = dst+1; 2713 end_off = dst+1;
2709 dst = jmp(dst, dst+2); 2714 dst = jmp(dst, dst+2);
2710 *norm_shift_off = dst - (norm_shift_off+1); 2715 *norm_shift_off = dst - (norm_shift_off+1);
2711 if (dst_op->mode == MODE_REG_DIRECT) { 2716 if (dst_op->mode == MODE_REG_DIRECT) {
2713 } else { 2718 } else {
2714 dst = shift_clrdisp8(dst, dst_op->base, dst_op->disp, inst->extra.size); 2719 dst = shift_clrdisp8(dst, dst_op->base, dst_op->disp, inst->extra.size);
2715 } 2720 }
2716 } 2721 }
2717 } 2722 }
2718 2723
2719 } 2724 }
2720 if (!special && end_off) { 2725 if (!special && end_off) {
2721 *end_off = dst - (end_off + 1); 2726 *end_off = dst - (end_off + 1);
2722 } 2727 }
2723 dst = setcc_r(dst, CC_C, FLAG_C); 2728 dst = setcc_r(dst, CC_C, FLAG_C);
2950 break; 2955 break;
2951 case M68K_BCHG: 2956 case M68K_BCHG:
2952 case M68K_BCLR: 2957 case M68K_BCLR:
2953 case M68K_BSET: 2958 case M68K_BSET:
2954 case M68K_BTST: 2959 case M68K_BTST:
2955 dst = cycles(dst, inst->extra.size == OPSIZE_BYTE ? 4 : 6); 2960 dst = cycles(dst, inst->extra.size == OPSIZE_BYTE ? 4 : (
2961 inst->op == M68K_BTST ? 6 : (inst->op == M68K_BCLR ? 10 : 8))
2962 );
2956 if (src_op.mode == MODE_IMMED) { 2963 if (src_op.mode == MODE_IMMED) {
2957 if (inst->extra.size == OPSIZE_BYTE) { 2964 if (inst->extra.size == OPSIZE_BYTE) {
2958 src_op.disp &= 0x7; 2965 src_op.disp &= 0x7;
2959 } 2966 }
2960 if (inst->op == M68K_BTST) { 2967 if (inst->op == M68K_BTST) {
3082 isize = 6; 3089 isize = 6;
3083 break; 3090 break;
3084 default: 3091 default:
3085 isize = 2; 3092 isize = 2;
3086 } 3093 }
3087 uint8_t * passed = dst+1; 3094 uint8_t * passed = dst+1;
3088 dst = jcc(dst, CC_GE, dst+2); 3095 dst = jcc(dst, CC_GE, dst+2);
3089 dst = mov_ir(dst, 1, FLAG_N, SZ_B); 3096 dst = mov_ir(dst, 1, FLAG_N, SZ_B);
3090 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D); 3097 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D);
3091 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D); 3098 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D);
3092 dst = jmp(dst, opts->trap); 3099 dst = jmp(dst, opts->trap);
3320 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W); 3327 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W);
3321 } 3328 }
3322 } 3329 }
3323 dst = call(dst, (uint8_t *)(inst->op == M68K_MOVE_SR ? set_sr : set_ccr)); 3330 dst = call(dst, (uint8_t *)(inst->op == M68K_MOVE_SR ? set_sr : set_ccr));
3324 dst = cycles(dst, 12); 3331 dst = cycles(dst, 12);
3325 3332
3326 } 3333 }
3327 break; 3334 break;
3328 case M68K_MOVE_USP: 3335 case M68K_MOVE_USP:
3329 dst = cycles(dst, BUS); 3336 dst = cycles(dst, BUS);
3330 //TODO: Trap if not in supervisor mode 3337 //TODO: Trap if not in supervisor mode
3444 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); 3451 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size);
3445 } else { 3452 } else {
3446 dst = not_rdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3453 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); 3454 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size);
3448 } 3455 }
3449 3456
3450 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 3457 dst = mov_ir(dst, 0, FLAG_C, SZ_B);
3451 dst = setcc_r(dst, CC_Z, FLAG_Z); 3458 dst = setcc_r(dst, CC_Z, FLAG_Z);
3452 dst = setcc_r(dst, CC_S, FLAG_N); 3459 dst = setcc_r(dst, CC_S, FLAG_N);
3453 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 3460 dst = mov_ir(dst, 0, FLAG_V, SZ_B);
3454 dst = m68k_save_result(inst, dst, opts); 3461 dst = m68k_save_result(inst, dst, opts);
3555 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D); 3562 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D);
3556 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D); 3563 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D);
3557 dst = cmp_ir(dst, 32, SCRATCH1, SZ_B); 3564 dst = cmp_ir(dst, 32, SCRATCH1, SZ_B);
3558 norm_off = dst+1; 3565 norm_off = dst+1;
3559 dst = jcc(dst, CC_L, dst+2); 3566 dst = jcc(dst, CC_L, dst+2);
3567 dst = sub_ir(dst, 32, SCRATCH1, SZ_B);
3560 if (dst_op.mode == MODE_REG_DIRECT) { 3568 if (dst_op.mode == MODE_REG_DIRECT) {
3561 if (inst->op == M68K_ROL) { 3569 if (inst->op == M68K_ROL) {
3562 dst = rol_ir(dst, 31, dst_op.base, inst->extra.size); 3570 dst = rol_ir(dst, 31, dst_op.base, inst->extra.size);
3563 dst = rol_ir(dst, 1, dst_op.base, inst->extra.size); 3571 dst = rol_ir(dst, 1, dst_op.base, inst->extra.size);
3564 } else { 3572 } else {
3572 } else { 3580 } else {
3573 dst = ror_irdisp8(dst, 31, dst_op.base, dst_op.disp, inst->extra.size); 3581 dst = ror_irdisp8(dst, 31, dst_op.base, dst_op.disp, inst->extra.size);
3574 dst = ror_irdisp8(dst, 1, dst_op.base, dst_op.disp, inst->extra.size); 3582 dst = ror_irdisp8(dst, 1, dst_op.base, dst_op.disp, inst->extra.size);
3575 } 3583 }
3576 } 3584 }
3577 dst = sub_ir(dst, 32, SCRATCH1, SZ_B);
3578 *norm_off = dst - (norm_off+1); 3585 *norm_off = dst - (norm_off+1);
3579 if (dst_op.mode == MODE_REG_DIRECT) { 3586 if (dst_op.mode == MODE_REG_DIRECT) {
3580 if (inst->op == M68K_ROL) { 3587 if (inst->op == M68K_ROL) {
3581 dst = rol_clr(dst, dst_op.base, inst->extra.size); 3588 dst = rol_clr(dst, dst_op.base, inst->extra.size);
3582 } else { 3589 } else {
3779 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_B); 3786 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_B);
3780 } 3787 }
3781 } 3788 }
3782 dst = m68k_save_result(inst, dst, opts); 3789 dst = m68k_save_result(inst, dst, opts);
3783 break; 3790 break;
3784 /*case M68K_STOP: 3791 case M68K_STOP: {
3785 break;*/ 3792 //TODO: Trap if not in system mode
3793 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction
3794 //possibly even 12 since that's how long MOVE to SR takes
3795 dst = cycles(dst, BUS*2);
3796 dst = mov_ir(dst, src_op.disp & 0x1, FLAG_C, SZ_B);
3797 dst = mov_ir(dst, (src_op.disp >> 1) & 0x1, FLAG_V, SZ_B);
3798 dst = mov_ir(dst, (src_op.disp >> 2) & 0x1, FLAG_Z, SZ_B);
3799 dst = mov_ir(dst, (src_op.disp >> 3) & 0x1, FLAG_N, SZ_B);
3800 dst = mov_irind(dst, (src_op.disp >> 4) & 0x1, CONTEXT, SZ_B);
3801 dst = mov_irdisp8(dst, (src_op.disp >> 8), CONTEXT, offsetof(m68k_context, status), SZ_B);
3802 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
3803 //leave supervisor mode
3804 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3805 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D);
3806 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
3807 }
3808 uint8_t * loop_top = dst;
3809 dst = call(dst, (uint8_t *)do_sync);
3810 dst = cmp_rr(dst, LIMIT, CYCLES, SZ_D);
3811 uint8_t * normal_cycle_up = dst + 1;
3812 dst = jcc(dst, CC_A, dst+2);
3813 dst = cycles(dst, BUS);
3814 uint8_t * after_cycle_up = dst + 1;
3815 dst = jmp(dst, dst+2);
3816 *normal_cycle_up = dst - (normal_cycle_up + 1);
3817 dst = mov_rr(dst, LIMIT, CYCLES, SZ_D);
3818 *after_cycle_up = dst - (after_cycle_up+1);
3819 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D);
3820 dst = jcc(dst, CC_C, loop_top);
3821 break;
3822 }
3786 case M68K_SUB: 3823 case M68K_SUB:
3787 size = inst->dst.addr_mode == MODE_AREG ? OPSIZE_LONG : inst->extra.size; 3824 size = inst->dst.addr_mode == MODE_AREG ? OPSIZE_LONG : inst->extra.size;
3788 dst = cycles(dst, BUS); 3825 dst = cycles(dst, BUS);
3789 if (src_op.mode == MODE_REG_DIRECT) { 3826 if (src_op.mode == MODE_REG_DIRECT) {
3790 if (dst_op.mode == MODE_REG_DIRECT) { 3827 if (dst_op.mode == MODE_REG_DIRECT) {
3838 break; 3875 break;
3839 case M68K_SWAP: 3876 case M68K_SWAP:
3840 dst = cycles(dst, BUS); 3877 dst = cycles(dst, BUS);
3841 if (src_op.mode == MODE_REG_DIRECT) { 3878 if (src_op.mode == MODE_REG_DIRECT) {
3842 dst = rol_ir(dst, 16, src_op.base, SZ_D); 3879 dst = rol_ir(dst, 16, src_op.base, SZ_D);
3880 dst = cmp_ir(dst, 0, src_op.base, SZ_D);
3843 } else{ 3881 } else{
3844 dst = rol_irdisp8(dst, 16, src_op.base, src_op.disp, SZ_D); 3882 dst = rol_irdisp8(dst, 16, src_op.base, src_op.disp, SZ_D);
3845 } 3883 dst = cmp_irdisp8(dst, 0, src_op.base, src_op.disp, SZ_D);
3884 }
3885
3846 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 3886 dst = mov_ir(dst, 0, FLAG_C, SZ_B);
3847 dst = setcc_r(dst, CC_Z, FLAG_Z); 3887 dst = setcc_r(dst, CC_Z, FLAG_Z);
3848 dst = setcc_r(dst, CC_S, FLAG_N); 3888 dst = setcc_r(dst, CC_S, FLAG_N);
3849 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 3889 dst = mov_ir(dst, 0, FLAG_V, SZ_B);
3850 break; 3890 break;
3910 uint8_t * translate_m68k_stream(uint32_t address, m68k_context * context) 3950 uint8_t * translate_m68k_stream(uint32_t address, m68k_context * context)
3911 { 3951 {
3912 m68kinst instbuf; 3952 m68kinst instbuf;
3913 x86_68k_options * opts = context->options; 3953 x86_68k_options * opts = context->options;
3914 uint8_t * dst = opts->cur_code; 3954 uint8_t * dst = opts->cur_code;
3915 uint8_t * dst_end = opts->code_end; 3955 uint8_t * dst_end = opts->code_end;
3916 address &= 0xFFFFFF; 3956 address &= 0xFFFFFF;
3917 if(get_native_address(opts->native_code_map, address)) { 3957 if(get_native_address(opts->native_code_map, address)) {
3918 return dst; 3958 return dst;
3919 } 3959 }
3920 char disbuf[1024]; 3960 char disbuf[1024];
4038 } 4078 }
4039 m68k_handle_deferred(context); 4079 m68k_handle_deferred(context);
4040 return orig_start; 4080 return orig_start;
4041 } 4081 }
4042 } 4082 }
4043 4083
4044 map_native_address(context, instbuf.address, dst, (after-inst)*2, MAX_NATIVE_SIZE); 4084 map_native_address(context, instbuf.address, dst, (after-inst)*2, MAX_NATIVE_SIZE);
4045 opts->cur_code = dst+MAX_NATIVE_SIZE; 4085 opts->cur_code = dst+MAX_NATIVE_SIZE;
4046 jmp(orig_start, dst); 4086 jmp(orig_start, dst);
4047 if (!m68k_is_terminal(&instbuf)) { 4087 if (!m68k_is_terminal(&instbuf)) {
4048 jmp(native_end, get_native_address_trans(context, orig + (after-inst)*2)); 4088 jmp(native_end, get_native_address_trans(context, orig + (after-inst)*2));
4085 dst = alloc_code(&size); 4125 dst = alloc_code(&size);
4086 opts->code_end = dst_end = dst + size; 4126 opts->code_end = dst_end = dst + size;
4087 } 4127 }
4088 bp_stub = dst; 4128 bp_stub = dst;
4089 native = call(native, bp_stub); 4129 native = call(native, bp_stub);
4090 4130
4091 //Calculate length of prologue 4131 //Calculate length of prologue
4092 dst = check_cycles_int(dst, address, opts); 4132 dst = check_cycles_int(dst, address, opts);
4093 int check_int_size = dst-bp_stub; 4133 int check_int_size = dst-bp_stub;
4094 dst = bp_stub; 4134 dst = bp_stub;
4095 4135
4096 //Save context and call breakpoint handler 4136 //Save context and call breakpoint handler
4097 dst = call(dst, (uint8_t *)m68k_save_context); 4137 dst = call(dst, (uint8_t *)m68k_save_context);
4098 dst = push_r(dst, SCRATCH1); 4138 dst = push_r(dst, SCRATCH1);
4099 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); 4139 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
4100 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); 4140 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D);
4168 if (memmap[chunk].end < 0x1000000) { 4208 if (memmap[chunk].end < 0x1000000) {
4169 dst = cmp_ir(dst, memmap[chunk].end, adr_reg, SZ_D); 4209 dst = cmp_ir(dst, memmap[chunk].end, adr_reg, SZ_D);
4170 ub_jcc = dst + 1; 4210 ub_jcc = dst + 1;
4171 dst = jcc(dst, CC_NC, dst+2); 4211 dst = jcc(dst, CC_NC, dst+2);
4172 } 4212 }
4173 4213
4174 if (memmap[chunk].mask != 0xFFFFFF) { 4214 if (memmap[chunk].mask != 0xFFFFFF) {
4175 dst = and_ir(dst, memmap[chunk].mask, adr_reg, SZ_D); 4215 dst = and_ir(dst, memmap[chunk].mask, adr_reg, SZ_D);
4176 } 4216 }
4177 void * cfun; 4217 void * cfun;
4178 switch (fun_type) 4218 switch (fun_type)
4204 dst = mov_rr(dst, SCRATCH1, RDX, size); 4244 dst = mov_rr(dst, SCRATCH1, RDX, size);
4205 } else { 4245 } else {
4206 dst = push_r(dst, CONTEXT); 4246 dst = push_r(dst, CONTEXT);
4207 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D); 4247 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D);
4208 } 4248 }
4249 dst = test_ir(dst, 8, RSP, SZ_D);
4250 uint8_t *adjust_rsp = dst+1;
4251 dst = jcc(dst, CC_NZ, dst+2);
4209 dst = call(dst, cfun); 4252 dst = call(dst, cfun);
4253 uint8_t *no_adjust = dst+1;
4254 dst = jmp(dst, dst+2);
4255 *adjust_rsp = dst - (adjust_rsp + 1);
4256 dst = sub_ir(dst, 8, RSP, SZ_Q);
4257 dst = call(dst, cfun);
4258 dst = add_ir(dst, 8, RSP, SZ_Q);
4259 *no_adjust = dst - (no_adjust + 1);
4210 if (is_write) { 4260 if (is_write) {
4211 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); 4261 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
4212 } else { 4262 } else {
4213 dst = pop_r(dst, CONTEXT); 4263 dst = pop_r(dst, CONTEXT);
4214 dst = mov_rr(dst, RAX, SCRATCH1, size); 4264 dst = mov_rr(dst, RAX, SCRATCH1, size);
4215 } 4265 }
4216 dst = jmp(dst, (uint8_t *)m68k_load_context); 4266 dst = jmp(dst, (uint8_t *)m68k_load_context);
4217 4267
4218 *not_null = dst - (not_null + 1); 4268 *not_null = dst - (not_null + 1);
4219 } 4269 }
4220 if (size == SZ_B) { 4270 if (size == SZ_B) {
4221 dst = xor_ir(dst, 1, adr_reg, SZ_D); 4271 dst = xor_ir(dst, 1, adr_reg, SZ_D);
4222 } 4272 }
4223 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, adr_reg, SZ_Q); 4273 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, adr_reg, SZ_Q);
4224 if (is_write) { 4274 if (is_write) {
4225 dst = mov_rrind(dst, SCRATCH1, SCRATCH2, size); 4275 dst = mov_rrind(dst, SCRATCH1, SCRATCH2, size);
4226 4276
4227 } else { 4277 } else {
4228 dst = mov_rindr(dst, SCRATCH1, SCRATCH1, size); 4278 dst = mov_rindr(dst, SCRATCH1, SCRATCH1, size);
4229 } 4279 }
4230 } else { 4280 } else {
4231 uint8_t tmp_size = size; 4281 uint8_t tmp_size = size;
4297 dst = mov_rr(dst, SCRATCH1, RDX, size); 4347 dst = mov_rr(dst, SCRATCH1, RDX, size);
4298 } else { 4348 } else {
4299 dst = push_r(dst, CONTEXT); 4349 dst = push_r(dst, CONTEXT);
4300 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D); 4350 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D);
4301 } 4351 }
4352 dst = test_ir(dst, 8, RSP, SZ_D);
4353 uint8_t *adjust_rsp = dst+1;
4354 dst = jcc(dst, CC_NZ, dst+2);
4302 dst = call(dst, cfun); 4355 dst = call(dst, cfun);
4356 uint8_t *no_adjust = dst+1;
4357 dst = jmp(dst, dst+2);
4358 *adjust_rsp = dst - (adjust_rsp + 1);
4359 dst = sub_ir(dst, 8, RSP, SZ_Q);
4360 dst = call(dst, cfun);
4361 dst = add_ir(dst, 8, RSP, SZ_Q);
4362 *no_adjust = dst - (no_adjust+1);
4303 if (is_write) { 4363 if (is_write) {
4304 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); 4364 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
4305 } else { 4365 } else {
4306 dst = pop_r(dst, CONTEXT); 4366 dst = pop_r(dst, CONTEXT);
4307 dst = mov_rr(dst, RAX, SCRATCH1, size); 4367 dst = mov_rr(dst, RAX, SCRATCH1, size);
4331 return start; 4391 return start;
4332 } 4392 }
4333 4393
4334 void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks) 4394 void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks)
4335 { 4395 {
4336 opts->flags = 0; 4396 memset(opts, 0, sizeof(*opts));
4337 for (int i = 0; i < 8; i++) 4397 for (int i = 0; i < 8; i++)
4338 opts->dregs[i] = opts->aregs[i] = -1; 4398 opts->dregs[i] = opts->aregs[i] = -1;
4339 opts->dregs[0] = R10; 4399 opts->dregs[0] = R10;
4340 opts->dregs[1] = R11; 4400 opts->dregs[1] = R11;
4341 opts->dregs[2] = R12; 4401 opts->dregs[2] = R12;
4350 size_t size = 1024 * 1024; 4410 size_t size = 1024 * 1024;
4351 opts->cur_code = alloc_code(&size); 4411 opts->cur_code = alloc_code(&size);
4352 opts->code_end = opts->cur_code + size; 4412 opts->code_end = opts->cur_code + size;
4353 opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); 4413 opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64);
4354 memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64); 4414 memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64);
4355 4415
4356 opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16); 4416 opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16);
4357 opts->read_8 = gen_mem_fun(opts, memmap, num_chunks, READ_8); 4417 opts->read_8 = gen_mem_fun(opts, memmap, num_chunks, READ_8);
4358 opts->write_16 = gen_mem_fun(opts, memmap, num_chunks, WRITE_16); 4418 opts->write_16 = gen_mem_fun(opts, memmap, num_chunks, WRITE_16);
4359 opts->write_8 = gen_mem_fun(opts, memmap, num_chunks, WRITE_8); 4419 opts->write_8 = gen_mem_fun(opts, memmap, num_chunks, WRITE_8);
4360 4420
4361 uint8_t * dst = opts->cur_code; 4421 uint8_t * dst = opts->cur_code;
4362 4422
4363 opts->read_32 = dst; 4423 opts->read_32 = dst;
4364 dst = push_r(dst, SCRATCH1); 4424 dst = push_r(dst, SCRATCH1);
4365 dst = call(dst, opts->read_16); 4425 dst = call(dst, opts->read_16);
4366 dst = mov_rr(dst, SCRATCH1, SCRATCH2, SZ_W); 4426 dst = mov_rr(dst, SCRATCH1, SCRATCH2, SZ_W);
4367 dst = pop_r(dst, SCRATCH1); 4427 dst = pop_r(dst, SCRATCH1);
4371 dst = pop_r(dst, SCRATCH2); 4431 dst = pop_r(dst, SCRATCH2);
4372 dst = movzx_rr(dst, SCRATCH1, SCRATCH1, SZ_W, SZ_D); 4432 dst = movzx_rr(dst, SCRATCH1, SCRATCH1, SZ_W, SZ_D);
4373 dst = shl_ir(dst, 16, SCRATCH2, SZ_D); 4433 dst = shl_ir(dst, 16, SCRATCH2, SZ_D);
4374 dst = or_rr(dst, SCRATCH2, SCRATCH1, SZ_D); 4434 dst = or_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
4375 dst = retn(dst); 4435 dst = retn(dst);
4376 4436
4377 opts->write_32_lowfirst = dst; 4437 opts->write_32_lowfirst = dst;
4378 dst = push_r(dst, SCRATCH2); 4438 dst = push_r(dst, SCRATCH2);
4379 dst = push_r(dst, SCRATCH1); 4439 dst = push_r(dst, SCRATCH1);
4380 dst = add_ir(dst, 2, SCRATCH2, SZ_D); 4440 dst = add_ir(dst, 2, SCRATCH2, SZ_D);
4381 dst = call(dst, opts->write_16); 4441 dst = call(dst, opts->write_16);
4382 dst = pop_r(dst, SCRATCH1); 4442 dst = pop_r(dst, SCRATCH1);
4383 dst = pop_r(dst, SCRATCH2); 4443 dst = pop_r(dst, SCRATCH2);
4384 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); 4444 dst = shr_ir(dst, 16, SCRATCH1, SZ_D);
4385 dst = jmp(dst, opts->write_16); 4445 dst = jmp(dst, opts->write_16);
4386 4446
4387 opts->write_32_highfirst = dst; 4447 opts->write_32_highfirst = dst;
4388 dst = push_r(dst, SCRATCH1); 4448 dst = push_r(dst, SCRATCH1);
4389 dst = push_r(dst, SCRATCH2); 4449 dst = push_r(dst, SCRATCH2);
4390 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); 4450 dst = shr_ir(dst, 16, SCRATCH1, SZ_D);
4391 dst = call(dst, opts->write_16); 4451 dst = call(dst, opts->write_16);
4392 dst = pop_r(dst, SCRATCH2); 4452 dst = pop_r(dst, SCRATCH2);
4393 dst = pop_r(dst, SCRATCH1); 4453 dst = pop_r(dst, SCRATCH1);
4394 dst = add_ir(dst, 2, SCRATCH2, SZ_D); 4454 dst = add_ir(dst, 2, SCRATCH2, SZ_D);
4395 dst = jmp(dst, opts->write_16); 4455 dst = jmp(dst, opts->write_16);
4396 4456
4397 opts->handle_cycle_limit_int = dst; 4457 opts->handle_cycle_limit_int = dst;
4398 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); 4458 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D);
4399 uint8_t * do_int = dst+1; 4459 uint8_t * do_int = dst+1;
4400 dst = jcc(dst, CC_NC, dst+2); 4460 dst = jcc(dst, CC_NC, dst+2);
4401 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); 4461 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D);
4402 uint8_t * skip_sync = dst+1; 4462 uint8_t * skip_sync = dst+1;
4403 dst = jcc(dst, CC_C, dst+2); 4463 dst = jcc(dst, CC_C, dst+2);
4404 dst = call(dst, (uint8_t *)m68k_save_context); 4464 dst = call(dst, (uint8_t *)m68k_save_context);
4405 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); 4465 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
4406 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); 4466 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D);
4467 dst = test_ir(dst, 8, RSP, SZ_D);
4468 uint8_t *adjust_rsp = dst+1;
4469 dst = jcc(dst, CC_NZ, dst+2);
4407 dst = call(dst, (uint8_t *)sync_components); 4470 dst = call(dst, (uint8_t *)sync_components);
4471 uint8_t *no_adjust = dst+1;
4472 dst = jmp(dst, dst+2);
4473 *adjust_rsp = dst - (adjust_rsp + 1);
4474 dst = sub_ir(dst, 8, RSP, SZ_Q);
4475 dst = call(dst, (uint8_t *)sync_components);
4476 dst = add_ir(dst, 8, RSP, SZ_Q);
4477 *no_adjust = dst - (no_adjust+1);
4408 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); 4478 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
4409 dst = jmp(dst, (uint8_t *)m68k_load_context); 4479 dst = jmp(dst, (uint8_t *)m68k_load_context);
4410 *skip_sync = dst - (skip_sync+1); 4480 *skip_sync = dst - (skip_sync+1);
4411 dst = retn(dst); 4481 dst = retn(dst);
4412 *do_int = dst - (do_int+1); 4482 *do_int = dst - (do_int+1);
4443 dst = call(dst, (uint8_t *)m68k_native_addr_and_sync); 4513 dst = call(dst, (uint8_t *)m68k_native_addr_and_sync);
4444 dst = cycles(dst, 24); 4514 dst = cycles(dst, 24);
4445 //discard function return address 4515 //discard function return address
4446 dst = pop_r(dst, SCRATCH2); 4516 dst = pop_r(dst, SCRATCH2);
4447 dst = jmp_r(dst, SCRATCH1); 4517 dst = jmp_r(dst, SCRATCH1);
4448 4518
4449 opts->trap = dst; 4519 opts->trap = dst;
4450 dst = push_r(dst, SCRATCH2); 4520 dst = push_r(dst, SCRATCH2);
4451 //swap USP and SSP if not already in supervisor mode 4521 //swap USP and SSP if not already in supervisor mode
4452 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B); 4522 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B);
4453 already_supervisor = dst+1; 4523 already_supervisor = dst+1;
4472 dst = shl_ir(dst, 2, SCRATCH1, SZ_D); 4542 dst = shl_ir(dst, 2, SCRATCH1, SZ_D);
4473 dst = call(dst, opts->read_32); 4543 dst = call(dst, opts->read_32);
4474 dst = call(dst, (uint8_t *)m68k_native_addr_and_sync); 4544 dst = call(dst, (uint8_t *)m68k_native_addr_and_sync);
4475 dst = cycles(dst, 18); 4545 dst = cycles(dst, 18);
4476 dst = jmp_r(dst, SCRATCH1); 4546 dst = jmp_r(dst, SCRATCH1);
4477 4547
4478 opts->cur_code = dst; 4548 opts->cur_code = dst;
4479 } 4549 }
4480 4550
4481 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) 4551 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts)
4482 { 4552 {