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);