Mercurial > repos > blastem
comparison m68k_to_x86.c @ 181:3b4ef459aa8d
Fix signed division with negative result, fix address reg destination with word-sized operand, fix cmpm decoding and code generation, fix unbalanced pop in bit instructions
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 09 Jan 2013 21:08:37 -0800 |
parents | 68af8a56ab7a |
children | 924af8b2f7a0 |
comparison
equal
deleted
inserted
replaced
180:8b846bcff6a2 | 181:3b4ef459aa8d |
---|---|
103 int8_t reg = native_reg(&(inst->src), opts); | 103 int8_t reg = native_reg(&(inst->src), opts); |
104 uint8_t sec_reg; | 104 uint8_t sec_reg; |
105 int32_t dec_amount,inc_amount; | 105 int32_t dec_amount,inc_amount; |
106 if (reg >= 0) { | 106 if (reg >= 0) { |
107 ea->mode = MODE_REG_DIRECT; | 107 ea->mode = MODE_REG_DIRECT; |
108 ea->base = reg; | 108 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) { |
109 out = movsx_rr(out, reg, SCRATCH1, SZ_W, SZ_D); | |
110 ea->base = SCRATCH1; | |
111 } else { | |
112 ea->base = reg; | |
113 } | |
109 return out; | 114 return out; |
110 } | 115 } |
111 switch (inst->src.addr_mode) | 116 switch (inst->src.addr_mode) |
112 { | 117 { |
113 case MODE_REG: | 118 case MODE_REG: |
120 | 125 |
121 ea->mode = MODE_REG_DISPLACE8; | 126 ea->mode = MODE_REG_DISPLACE8; |
122 ea->base = CONTEXT; | 127 ea->base = CONTEXT; |
123 ea->disp = reg_offset(&(inst->src)); | 128 ea->disp = reg_offset(&(inst->src)); |
124 } else { | 129 } else { |
125 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, inst->extra.size); | 130 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) { |
131 out = movsx_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_W, SZ_D); | |
132 } else { | |
133 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, inst->extra.size); | |
134 } | |
126 ea->mode = MODE_REG_DIRECT; | 135 ea->mode = MODE_REG_DIRECT; |
127 ea->base = SCRATCH1; | 136 ea->base = SCRATCH1; |
137 //we're explicitly handling the areg dest here, so we exit immediately | |
138 return out; | |
128 } | 139 } |
129 break; | 140 break; |
130 case MODE_AREG_PREDEC: | 141 case MODE_AREG_PREDEC: |
131 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : 1); | 142 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : 1); |
132 out = cycles(out, PREDEC_PENALTY); | 143 out = cycles(out, PREDEC_PENALTY); |
343 if (inst->variant != VAR_QUICK) { | 354 if (inst->variant != VAR_QUICK) { |
344 out = cycles(out, (inst->extra.size == OPSIZE_LONG && inst->src.addr_mode == MODE_IMMEDIATE) ? BUS*2 : BUS); | 355 out = cycles(out, (inst->extra.size == OPSIZE_LONG && inst->src.addr_mode == MODE_IMMEDIATE) ? BUS*2 : BUS); |
345 } | 356 } |
346 ea->mode = MODE_IMMED; | 357 ea->mode = MODE_IMMED; |
347 ea->disp = inst->src.params.immed; | 358 ea->disp = inst->src.params.immed; |
348 break; | 359 return out; |
349 default: | 360 default: |
350 m68k_disasm(inst, disasm_buf); | 361 m68k_disasm(inst, disasm_buf); |
351 printf("%X: %s\naddress mode %d not implemented (src)\n", inst->address, disasm_buf, inst->src.addr_mode); | 362 printf("%X: %s\naddress mode %d not implemented (src)\n", inst->address, disasm_buf, inst->src.addr_mode); |
352 exit(1); | 363 exit(1); |
364 } | |
365 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) { | |
366 if (ea->mode == MODE_REG_DIRECT) { | |
367 out = movsx_rr(out, ea->base, SCRATCH1, SZ_W, SZ_D); | |
368 } else { | |
369 out = movsx_rdisp8r(out, ea->base, ea->disp, SCRATCH1, SZ_W, SZ_D); | |
370 ea->mode = MODE_REG_DIRECT; | |
371 } | |
372 ea->base = SCRATCH1; | |
353 } | 373 } |
354 return out; | 374 return out; |
355 } | 375 } |
356 | 376 |
357 uint8_t * translate_m68k_dst(m68kinst * inst, x86_ea * ea, uint8_t * out, x86_68k_options * opts, uint8_t fake_read) | 377 uint8_t * translate_m68k_dst(m68kinst * inst, x86_ea * ea, uint8_t * out, x86_68k_options * opts, uint8_t fake_read) |
734 } | 754 } |
735 src.mode = MODE_REG_DIRECT; | 755 src.mode = MODE_REG_DIRECT; |
736 flags_reg = src.base = SCRATCH1; | 756 flags_reg = src.base = SCRATCH1; |
737 } | 757 } |
738 } | 758 } |
759 uint8_t size = inst->extra.size; | |
739 switch(inst->dst.addr_mode) | 760 switch(inst->dst.addr_mode) |
740 { | 761 { |
762 case MODE_AREG: | |
763 size = OPSIZE_LONG; | |
741 case MODE_REG: | 764 case MODE_REG: |
742 case MODE_AREG: | |
743 if (reg >= 0) { | 765 if (reg >= 0) { |
744 if (src.mode == MODE_REG_DIRECT) { | 766 if (src.mode == MODE_REG_DIRECT) { |
745 dst = mov_rr(dst, src.base, reg, inst->extra.size); | 767 dst = mov_rr(dst, src.base, reg, size); |
746 } else if (src.mode == MODE_REG_DISPLACE8) { | 768 } else if (src.mode == MODE_REG_DISPLACE8) { |
747 dst = mov_rdisp8r(dst, src.base, src.disp, reg, inst->extra.size); | 769 dst = mov_rdisp8r(dst, src.base, src.disp, reg, size); |
748 } else { | 770 } else { |
749 dst = mov_ir(dst, src.disp, reg, inst->extra.size); | 771 dst = mov_ir(dst, src.disp, reg, size); |
750 } | 772 } |
751 } else if(src.mode == MODE_REG_DIRECT) { | 773 } else if(src.mode == MODE_REG_DIRECT) { |
752 dst = mov_rrdisp8(dst, src.base, CONTEXT, reg_offset(&(inst->dst)), inst->extra.size); | 774 dst = mov_rrdisp8(dst, src.base, CONTEXT, reg_offset(&(inst->dst)), size); |
753 } else { | 775 } else { |
754 dst = mov_irdisp8(dst, src.disp, CONTEXT, reg_offset(&(inst->dst)), inst->extra.size); | 776 dst = mov_irdisp8(dst, src.disp, CONTEXT, reg_offset(&(inst->dst)), size); |
755 } | 777 } |
756 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); | 778 dst = cmp_ir(dst, 0, flags_reg, size); |
757 dst = setcc_r(dst, CC_Z, FLAG_Z); | 779 dst = setcc_r(dst, CC_Z, FLAG_Z); |
758 dst = setcc_r(dst, CC_S, FLAG_N); | 780 dst = setcc_r(dst, CC_S, FLAG_N); |
759 break; | 781 break; |
760 case MODE_AREG_PREDEC: | 782 case MODE_AREG_PREDEC: |
761 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : 1); | 783 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : 1); |
2381 dst = add_ir(dst, 2, SCRATCH1, SZ_D); | 2403 dst = add_ir(dst, 2, SCRATCH1, SZ_D); |
2382 dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); | 2404 dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); |
2383 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst)), SZ_B); | 2405 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst)), SZ_B); |
2384 } | 2406 } |
2385 } | 2407 } |
2408 return dst; | |
2409 } | |
2410 | |
2411 uint8_t * translate_m68k_cmp(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | |
2412 { | |
2413 uint8_t size = inst->extra.size; | |
2414 x86_ea src_op, dst_op; | |
2415 dst = translate_m68k_src(inst, &src_op, dst, opts); | |
2416 if (inst->dst.addr_mode == MODE_AREG_POSTINC) { | |
2417 dst = push_r(dst, SCRATCH1); | |
2418 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 0); | |
2419 dst = pop_r(dst, SCRATCH2); | |
2420 src_op.base = SCRATCH2; | |
2421 } else { | |
2422 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 0); | |
2423 if (inst->dst.addr_mode == MODE_AREG && size == OPSIZE_WORD) { | |
2424 size = OPSIZE_LONG; | |
2425 } | |
2426 } | |
2427 dst = cycles(dst, BUS); | |
2428 if (src_op.mode == MODE_REG_DIRECT) { | |
2429 if (dst_op.mode == MODE_REG_DIRECT) { | |
2430 dst = cmp_rr(dst, src_op.base, dst_op.base, size); | |
2431 } else { | |
2432 dst = cmp_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); | |
2433 } | |
2434 } else if (src_op.mode == MODE_REG_DISPLACE8) { | |
2435 dst = cmp_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, size); | |
2436 } else { | |
2437 if (dst_op.mode == MODE_REG_DIRECT) { | |
2438 dst = cmp_ir(dst, src_op.disp, dst_op.base, size); | |
2439 } else { | |
2440 dst = cmp_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size); | |
2441 } | |
2442 } | |
2443 dst = setcc_r(dst, CC_C, FLAG_C); | |
2444 dst = setcc_r(dst, CC_Z, FLAG_Z); | |
2445 dst = setcc_r(dst, CC_S, FLAG_N); | |
2446 dst = setcc_r(dst, CC_O, FLAG_V); | |
2386 return dst; | 2447 return dst; |
2387 } | 2448 } |
2388 | 2449 |
2389 typedef uint8_t * (*shift_ir_t)(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size); | 2450 typedef uint8_t * (*shift_ir_t)(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size); |
2390 typedef uint8_t * (*shift_irdisp8_t)(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size); | 2451 typedef uint8_t * (*shift_irdisp8_t)(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size); |
2525 } else if(inst->op == M68K_MOVEP) { | 2586 } else if(inst->op == M68K_MOVEP) { |
2526 return translate_m68k_movep(dst, inst, opts); | 2587 return translate_m68k_movep(dst, inst, opts); |
2527 } else if(inst->op == M68K_INVALID) { | 2588 } else if(inst->op == M68K_INVALID) { |
2528 dst = mov_ir(dst, inst->address, SCRATCH1, SZ_D); | 2589 dst = mov_ir(dst, inst->address, SCRATCH1, SZ_D); |
2529 return call(dst, (uint8_t *)m68k_invalid); | 2590 return call(dst, (uint8_t *)m68k_invalid); |
2591 } else if(inst->op == M68K_CMP) { | |
2592 return translate_m68k_cmp(dst, inst, opts); | |
2530 } | 2593 } |
2531 x86_ea src_op, dst_op; | 2594 x86_ea src_op, dst_op; |
2532 if (inst->src.addr_mode != MODE_UNUSED) { | 2595 if (inst->src.addr_mode != MODE_UNUSED) { |
2533 dst = translate_m68k_src(inst, &src_op, dst, opts); | 2596 dst = translate_m68k_src(inst, &src_op, dst, opts); |
2534 } | 2597 } |
2535 if (inst->dst.addr_mode != MODE_UNUSED) { | 2598 if (inst->dst.addr_mode != MODE_UNUSED) { |
2536 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 0); | 2599 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 0); |
2537 } | 2600 } |
2601 uint8_t size; | |
2538 switch(inst->op) | 2602 switch(inst->op) |
2539 { | 2603 { |
2540 //case M68K_ABCD: | 2604 //case M68K_ABCD: |
2541 // break; | 2605 // break; |
2542 case M68K_ADD: | 2606 case M68K_ADD: |
2543 dst = cycles(dst, BUS); | 2607 dst = cycles(dst, BUS); |
2608 size = inst->dst.addr_mode == MODE_AREG ? OPSIZE_LONG : inst->extra.size; | |
2544 if (src_op.mode == MODE_REG_DIRECT) { | 2609 if (src_op.mode == MODE_REG_DIRECT) { |
2545 if (dst_op.mode == MODE_REG_DIRECT) { | 2610 if (dst_op.mode == MODE_REG_DIRECT) { |
2546 dst = add_rr(dst, src_op.base, dst_op.base, inst->extra.size); | 2611 dst = add_rr(dst, src_op.base, dst_op.base, size); |
2547 } else { | 2612 } else { |
2548 dst = add_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); | 2613 dst = add_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); |
2549 } | 2614 } |
2550 } else if (src_op.mode == MODE_REG_DISPLACE8) { | 2615 } else if (src_op.mode == MODE_REG_DISPLACE8) { |
2551 dst = add_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, inst->extra.size); | 2616 dst = add_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, size); |
2552 } else { | 2617 } else { |
2553 if (dst_op.mode == MODE_REG_DIRECT) { | 2618 if (dst_op.mode == MODE_REG_DIRECT) { |
2554 dst = add_ir(dst, src_op.disp, dst_op.base, inst->extra.size); | 2619 dst = add_ir(dst, src_op.disp, dst_op.base, size); |
2555 } else { | 2620 } else { |
2556 dst = add_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); | 2621 dst = add_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size); |
2557 } | 2622 } |
2558 } | 2623 } |
2559 dst = setcc_r(dst, CC_C, FLAG_C); | 2624 dst = setcc_r(dst, CC_C, FLAG_C); |
2560 dst = setcc_r(dst, CC_Z, FLAG_Z); | 2625 dst = setcc_r(dst, CC_Z, FLAG_Z); |
2561 dst = setcc_r(dst, CC_S, FLAG_N); | 2626 dst = setcc_r(dst, CC_S, FLAG_N); |
2733 dst = btc_rr(dst, src_op.base, dst_op.base, inst->extra.size); | 2798 dst = btc_rr(dst, src_op.base, dst_op.base, inst->extra.size); |
2734 } else { | 2799 } else { |
2735 dst = btc_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); | 2800 dst = btc_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); |
2736 } | 2801 } |
2737 } | 2802 } |
2738 } | 2803 if (src_op.base == SCRATCH2) { |
2739 if (src_op.base == SCRATCH2) { | 2804 dst = pop_r(dst, SCRATCH2); |
2740 dst = pop_r(dst, SCRATCH2); | 2805 } |
2741 } | 2806 } |
2742 //x86 sets the carry flag to the value of the bit tested | 2807 //x86 sets the carry flag to the value of the bit tested |
2743 //68K sets the zero flag to the complement of the bit tested | 2808 //68K sets the zero flag to the complement of the bit tested |
2744 dst = setcc_r(dst, CC_NC, FLAG_Z); | 2809 dst = setcc_r(dst, CC_NC, FLAG_Z); |
2745 if (inst->op != M68K_BTST) { | 2810 if (inst->op != M68K_BTST) { |
2746 dst = m68k_save_result(inst, dst, opts); | 2811 dst = m68k_save_result(inst, dst, opts); |
2747 } | 2812 } |
2748 break; | 2813 break; |
2749 /*case M68K_CHK: | 2814 /*case M68K_CHK: |
2750 break;*/ | 2815 break;*/ |
2751 case M68K_CMP: | |
2752 dst = cycles(dst, BUS); | |
2753 if (src_op.mode == MODE_REG_DIRECT) { | |
2754 if (dst_op.mode == MODE_REG_DIRECT) { | |
2755 dst = cmp_rr(dst, src_op.base, dst_op.base, inst->extra.size); | |
2756 } else { | |
2757 dst = cmp_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); | |
2758 } | |
2759 } else if (src_op.mode == MODE_REG_DISPLACE8) { | |
2760 dst = cmp_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, inst->extra.size); | |
2761 } else { | |
2762 if (dst_op.mode == MODE_REG_DIRECT) { | |
2763 dst = cmp_ir(dst, src_op.disp, dst_op.base, inst->extra.size); | |
2764 } else { | |
2765 dst = cmp_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); | |
2766 } | |
2767 } | |
2768 dst = setcc_r(dst, CC_C, FLAG_C); | |
2769 dst = setcc_r(dst, CC_Z, FLAG_Z); | |
2770 dst = setcc_r(dst, CC_S, FLAG_N); | |
2771 dst = setcc_r(dst, CC_O, FLAG_V); | |
2772 break; | |
2773 case M68K_DIVS: | 2816 case M68K_DIVS: |
2774 case M68K_DIVU: | 2817 case M68K_DIVU: |
2775 //TODO: Trap on division by zero | 2818 //TODO: Trap on division by zero |
2776 dst = cycles(dst, inst->op == M68K_DIVS ? 158 : 140); | 2819 dst = cycles(dst, inst->op == M68K_DIVS ? 158 : 140); |
2777 dst = push_r(dst, RDX); | 2820 dst = push_r(dst, RDX); |
2805 dst = idiv_r(dst, SCRATCH2, SZ_D); | 2848 dst = idiv_r(dst, SCRATCH2, SZ_D); |
2806 } else { | 2849 } else { |
2807 dst = div_r(dst, SCRATCH2, SZ_D); | 2850 dst = div_r(dst, SCRATCH2, SZ_D); |
2808 } | 2851 } |
2809 dst = cmp_ir(dst, 0x10000, RAX, SZ_D); | 2852 dst = cmp_ir(dst, 0x10000, RAX, SZ_D); |
2810 norm_off = dst+1; | 2853 if (inst->op == M68K_DIVS) { |
2811 dst = jcc(dst, CC_NC, dst+2); | 2854 uint8_t * skip_sec_check = dst + 1; |
2855 dst = jcc(dst, CC_C, dst+2); | |
2856 dst = cmp_ir(dst, -0x10000, RAX, SZ_D); | |
2857 norm_off = dst+1; | |
2858 dst = jcc(dst, CC_LE, dst+2); | |
2859 *skip_sec_check = dst - (skip_sec_check+1); | |
2860 } else { | |
2861 norm_off = dst+1; | |
2862 dst = jcc(dst, CC_NC, dst+2); | |
2863 } | |
2812 if (dst_op.mode == MODE_REG_DIRECT) { | 2864 if (dst_op.mode == MODE_REG_DIRECT) { |
2813 dst = mov_rr(dst, RDX, dst_op.base, SZ_W); | 2865 dst = mov_rr(dst, RDX, dst_op.base, SZ_W); |
2814 dst = shl_ir(dst, 16, dst_op.base, SZ_D); | 2866 dst = shl_ir(dst, 16, dst_op.base, SZ_D); |
2815 dst = mov_rr(dst, RAX, dst_op.base, SZ_W); | 2867 dst = mov_rr(dst, RAX, dst_op.base, SZ_W); |
2816 } else { | 2868 } else { |
3366 break; | 3418 break; |
3367 /*case M68K_SBCD: | 3419 /*case M68K_SBCD: |
3368 case M68K_STOP: | 3420 case M68K_STOP: |
3369 break;*/ | 3421 break;*/ |
3370 case M68K_SUB: | 3422 case M68K_SUB: |
3423 size = inst->dst.addr_mode == MODE_AREG ? OPSIZE_LONG : inst->extra.size; | |
3371 dst = cycles(dst, BUS); | 3424 dst = cycles(dst, BUS); |
3372 if (src_op.mode == MODE_REG_DIRECT) { | 3425 if (src_op.mode == MODE_REG_DIRECT) { |
3373 if (dst_op.mode == MODE_REG_DIRECT) { | 3426 if (dst_op.mode == MODE_REG_DIRECT) { |
3374 dst = sub_rr(dst, src_op.base, dst_op.base, inst->extra.size); | 3427 dst = sub_rr(dst, src_op.base, dst_op.base, size); |
3375 } else { | 3428 } else { |
3376 dst = sub_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); | 3429 dst = sub_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); |
3377 } | 3430 } |
3378 } else if (src_op.mode == MODE_REG_DISPLACE8) { | 3431 } else if (src_op.mode == MODE_REG_DISPLACE8) { |
3379 dst = sub_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, inst->extra.size); | 3432 dst = sub_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, size); |
3380 } else { | 3433 } else { |
3381 if (dst_op.mode == MODE_REG_DIRECT) { | 3434 if (dst_op.mode == MODE_REG_DIRECT) { |
3382 dst = sub_ir(dst, src_op.disp, dst_op.base, inst->extra.size); | 3435 dst = sub_ir(dst, src_op.disp, dst_op.base, size); |
3383 } else { | 3436 } else { |
3384 dst = sub_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); | 3437 dst = sub_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size); |
3385 } | 3438 } |
3386 } | 3439 } |
3387 dst = setcc_r(dst, CC_C, FLAG_C); | 3440 dst = setcc_r(dst, CC_C, FLAG_C); |
3388 dst = setcc_r(dst, CC_Z, FLAG_Z); | 3441 dst = setcc_r(dst, CC_Z, FLAG_Z); |
3389 dst = setcc_r(dst, CC_S, FLAG_N); | 3442 dst = setcc_r(dst, CC_S, FLAG_N); |
3440 if (src_op.mode == MODE_REG_DIRECT) { | 3493 if (src_op.mode == MODE_REG_DIRECT) { |
3441 dst = cmp_ir(dst, 0, src_op.base, inst->extra.size); | 3494 dst = cmp_ir(dst, 0, src_op.base, inst->extra.size); |
3442 } else { //M68000 doesn't support immedate operand for tst, so this must be MODE_REG_DISPLACE8 | 3495 } else { //M68000 doesn't support immedate operand for tst, so this must be MODE_REG_DISPLACE8 |
3443 dst = cmp_irdisp8(dst, 0, src_op.base, src_op.disp, inst->extra.size); | 3496 dst = cmp_irdisp8(dst, 0, src_op.base, src_op.disp, inst->extra.size); |
3444 } | 3497 } |
3445 dst = setcc_r(dst, CC_C, FLAG_C); | 3498 dst = mov_ir(dst, 0, FLAG_C, SZ_B); |
3446 dst = setcc_r(dst, CC_Z, FLAG_Z); | 3499 dst = setcc_r(dst, CC_Z, FLAG_Z); |
3447 dst = setcc_r(dst, CC_S, FLAG_N); | 3500 dst = setcc_r(dst, CC_S, FLAG_N); |
3448 dst = setcc_r(dst, CC_O, FLAG_V); | 3501 dst = mov_ir(dst, 0, FLAG_V, SZ_B); |
3449 break; | 3502 break; |
3450 case M68K_UNLK: | 3503 case M68K_UNLK: |
3451 dst = cycles(dst, BUS); | 3504 dst = cycles(dst, BUS); |
3452 if (dst_op.mode == MODE_REG_DIRECT) { | 3505 if (dst_op.mode == MODE_REG_DIRECT) { |
3453 dst = mov_rr(dst, dst_op.base, opts->aregs[7], SZ_D); | 3506 dst = mov_rr(dst, dst_op.base, opts->aregs[7], SZ_D); |