comparison m68k_core_x86.c @ 576:a6f2db4df70d

Small refactor to flag handling in 68K core
author Michael Pavone <pavone@retrodev.com>
date Tue, 04 Mar 2014 00:02:20 -0800
parents 1594525e2157
children 0f367276a80c
comparison
equal deleted inserted replaced
575:f90da1c2ba86 576:a6f2db4df70d
113 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, flags) + flag2, SZ_B); 113 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, flags) + flag2, SZ_B);
114 pop_r(code, opts->gen.scratch1); 114 pop_r(code, opts->gen.scratch1);
115 } 115 }
116 } 116 }
117 117
118 void update_flags(m68k_options *opts, uint32_t update_mask)
119 {
120 uint8_t native_flags[] = {0, CC_S, CC_Z, CC_O, CC_C};
121 for (int8_t flag = FLAG_C; flag >= FLAG_X; --flag)
122 {
123 if (update_mask & X0 << (flag*3)) {
124 set_flag(opts, 0, flag);
125 } else if(update_mask & X1 << (flag*3)) {
126 set_flag(opts, 1, flag);
127 } else if(update_mask & X << (flag*3)) {
128 if (flag == FLAG_X) {
129 if (opts->flag_regs[FLAG_C] >= 0 || !(update_mask & (C0|C1|C))) {
130 flag_to_flag(opts, FLAG_C, FLAG_X);
131 } else if(update_mask & C0) {
132 set_flag(opts, 0, flag);
133 } else if(update_mask & C1) {
134 set_flag(opts, 1, flag);
135 } else {
136 set_flag_cond(opts, CC_C, flag);
137 }
138 } else {
139 set_flag_cond(opts, native_flags[flag], flag);
140 }
141 }
142 }
143 }
144
118 void flag_to_carry(m68k_options * opts, uint8_t flag) 145 void flag_to_carry(m68k_options * opts, uint8_t flag)
119 { 146 {
120 if (opts->flag_regs[flag] >= 0) { 147 if (opts->flag_regs[flag] >= 0) {
121 bt_ir(&opts->gen.code, 0, opts->flag_regs[flag], SZ_B); 148 bt_ir(&opts->gen.code, 0, opts->flag_regs[flag], SZ_B);
122 } else { 149 } else {
510 int32_t offset; 537 int32_t offset;
511 int32_t inc_amount, dec_amount; 538 int32_t inc_amount, dec_amount;
512 x86_ea src; 539 x86_ea src;
513 translate_m68k_op(inst, &src, opts, 0); 540 translate_m68k_op(inst, &src, opts, 0);
514 reg = native_reg(&(inst->dst), opts); 541 reg = native_reg(&(inst->dst), opts);
515 if (inst->dst.addr_mode != MODE_AREG) {
516 //update statically set flags
517 set_flag(opts, 0, FLAG_V);
518 set_flag(opts, 0, FLAG_C);
519 }
520 542
521 if (inst->dst.addr_mode != MODE_AREG) { 543 if (inst->dst.addr_mode != MODE_AREG) {
522 if (src.mode == MODE_REG_DIRECT) { 544 if (src.mode == MODE_REG_DIRECT) {
523 flags_reg = src.base; 545 flags_reg = src.base;
524 } else { 546 } else {
552 } else if(src.mode == MODE_REG_DIRECT) { 574 } else if(src.mode == MODE_REG_DIRECT) {
553 mov_rrdisp(code, src.base, opts->gen.context_reg, reg_offset(&(inst->dst)), size); 575 mov_rrdisp(code, src.base, opts->gen.context_reg, reg_offset(&(inst->dst)), size);
554 } else { 576 } else {
555 mov_irdisp(code, src.disp, opts->gen.context_reg, reg_offset(&(inst->dst)), size); 577 mov_irdisp(code, src.disp, opts->gen.context_reg, reg_offset(&(inst->dst)), size);
556 } 578 }
557 if (inst->dst.addr_mode != MODE_AREG) {
558 cmp_ir(code, 0, flags_reg, size);
559 set_flag_cond(opts, CC_Z, FLAG_Z);
560 set_flag_cond(opts, CC_S, FLAG_N);
561 }
562 break; 579 break;
563 case MODE_AREG_PREDEC: 580 case MODE_AREG_PREDEC:
564 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); 581 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1));
565 subi_areg(opts, dec_amount, inst->dst.params.regs.pri); 582 subi_areg(opts, dec_amount, inst->dst.params.regs.pri);
566 case MODE_AREG_INDIRECT: 583 case MODE_AREG_INDIRECT:
573 } else if (src.mode == MODE_REG_DISPLACE8) { 590 } else if (src.mode == MODE_REG_DISPLACE8) {
574 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size); 591 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
575 } else { 592 } else {
576 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size); 593 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
577 } 594 }
578 if (inst->dst.addr_mode != MODE_AREG) {
579 cmp_ir(code, 0, flags_reg, inst->extra.size);
580 set_flag_cond(opts, CC_Z, FLAG_Z);
581 set_flag_cond(opts, CC_S, FLAG_N);
582 }
583 m68k_write_size(opts, inst->extra.size);
584
585 if (inst->dst.addr_mode == MODE_AREG_POSTINC) {
586 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1));
587 addi_areg(opts, inc_amount, inst->dst.params.regs.pri);
588 }
589 break; 595 break;
590 case MODE_AREG_DISPLACE: 596 case MODE_AREG_DISPLACE:
591 cycles(&opts->gen, BUS); 597 cycles(&opts->gen, BUS);
592 calc_areg_displace(opts, &inst->dst, opts->gen.scratch2); 598 calc_areg_displace(opts, &inst->dst, opts->gen.scratch2);
593 if (src.mode == MODE_REG_DIRECT) { 599 if (src.mode == MODE_REG_DIRECT) {
597 } else if (src.mode == MODE_REG_DISPLACE8) { 603 } else if (src.mode == MODE_REG_DISPLACE8) {
598 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size); 604 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
599 } else { 605 } else {
600 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size); 606 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
601 } 607 }
602 if (inst->dst.addr_mode != MODE_AREG) {
603 cmp_ir(code, 0, flags_reg, inst->extra.size);
604 set_flag_cond(opts, CC_Z, FLAG_Z);
605 set_flag_cond(opts, CC_S, FLAG_N);
606 }
607 m68k_write_size(opts, inst->extra.size);
608 break; 608 break;
609 case MODE_AREG_INDEX_DISP8: 609 case MODE_AREG_INDEX_DISP8:
610 cycles(&opts->gen, 6);//TODO: Check to make sure this is correct 610 cycles(&opts->gen, 6);//TODO: Check to make sure this is correct
611 //calc_areg_index_disp8 will clober scratch1 when a 16-bit index is used 611 //calc_areg_index_disp8 will clober scratch1 when a 16-bit index is used
612 if (src.base == opts->gen.scratch1 && !(inst->dst.params.regs.sec & 1)) { 612 if (src.base == opts->gen.scratch1 && !(inst->dst.params.regs.sec & 1)) {
623 } else if (src.mode == MODE_REG_DISPLACE8) { 623 } else if (src.mode == MODE_REG_DISPLACE8) {
624 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size); 624 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
625 } else { 625 } else {
626 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size); 626 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
627 } 627 }
628 if (inst->dst.addr_mode != MODE_AREG) {
629 cmp_ir(code, 0, flags_reg, inst->extra.size);
630 set_flag_cond(opts, CC_Z, FLAG_Z);
631 set_flag_cond(opts, CC_S, FLAG_N);
632 }
633 m68k_write_size(opts, inst->extra.size);
634 break; 628 break;
635 case MODE_PC_DISPLACE: 629 case MODE_PC_DISPLACE:
636 cycles(&opts->gen, BUS); 630 cycles(&opts->gen, BUS);
637 mov_ir(code, inst->dst.params.regs.displacement + inst->address+2, opts->gen.scratch2, SZ_D); 631 mov_ir(code, inst->dst.params.regs.displacement + inst->address+2, opts->gen.scratch2, SZ_D);
638 if (src.mode == MODE_REG_DIRECT) { 632 if (src.mode == MODE_REG_DIRECT) {
642 } else if (src.mode == MODE_REG_DISPLACE8) { 636 } else if (src.mode == MODE_REG_DISPLACE8) {
643 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size); 637 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
644 } else { 638 } else {
645 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size); 639 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
646 } 640 }
647 if (inst->dst.addr_mode != MODE_AREG) {
648 cmp_ir(code, 0, flags_reg, inst->extra.size);
649 set_flag_cond(opts, CC_Z, FLAG_Z);
650 set_flag_cond(opts, CC_S, FLAG_N);
651 }
652 m68k_write_size(opts, inst->extra.size);
653 break; 641 break;
654 case MODE_PC_INDEX_DISP8: 642 case MODE_PC_INDEX_DISP8:
655 cycles(&opts->gen, 6);//TODO: Check to make sure this is correct 643 cycles(&opts->gen, 6);//TODO: Check to make sure this is correct
656 mov_ir(code, inst->address, opts->gen.scratch2, SZ_D); 644 mov_ir(code, inst->address, opts->gen.scratch2, SZ_D);
657 if (src.base == opts->gen.scratch1 && !(inst->dst.params.regs.sec & 1)) { 645 if (src.base == opts->gen.scratch1 && !(inst->dst.params.regs.sec & 1)) {
668 } else if (src.mode == MODE_REG_DISPLACE8) { 656 } else if (src.mode == MODE_REG_DISPLACE8) {
669 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size); 657 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
670 } else { 658 } else {
671 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size); 659 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
672 } 660 }
673 if (inst->dst.addr_mode != MODE_AREG) {
674 cmp_ir(code, 0, flags_reg, inst->extra.size);
675 set_flag_cond(opts, CC_Z, FLAG_Z);
676 set_flag_cond(opts, CC_S, FLAG_N);
677 }
678 m68k_write_size(opts, inst->extra.size);
679 break; 661 break;
680 case MODE_ABSOLUTE: 662 case MODE_ABSOLUTE:
681 case MODE_ABSOLUTE_SHORT: 663 case MODE_ABSOLUTE_SHORT:
682 if (src.mode == MODE_REG_DIRECT) { 664 if (src.mode == MODE_REG_DIRECT) {
683 if (src.base != opts->gen.scratch1) { 665 if (src.base != opts->gen.scratch1) {
692 cycles(&opts->gen, BUS*2); 674 cycles(&opts->gen, BUS*2);
693 } else { 675 } else {
694 cycles(&opts->gen, BUS); 676 cycles(&opts->gen, BUS);
695 } 677 }
696 mov_ir(code, inst->dst.params.immed, opts->gen.scratch2, SZ_D); 678 mov_ir(code, inst->dst.params.immed, opts->gen.scratch2, SZ_D);
697 if (inst->dst.addr_mode != MODE_AREG) {
698 cmp_ir(code, 0, flags_reg, inst->extra.size);
699 set_flag_cond(opts, CC_Z, FLAG_Z);
700 set_flag_cond(opts, CC_S, FLAG_N);
701 }
702 m68k_write_size(opts, inst->extra.size);
703 break; 679 break;
704 default: 680 default:
705 m68k_disasm(inst, disasm_buf); 681 m68k_disasm(inst, disasm_buf);
706 printf("%X: %s\naddress mode %d not implemented (move dst)\n", inst->address, disasm_buf, inst->dst.addr_mode); 682 printf("%X: %s\naddress mode %d not implemented (move dst)\n", inst->address, disasm_buf, inst->dst.addr_mode);
707 exit(1); 683 exit(1);
684 }
685
686 if (inst->dst.addr_mode != MODE_AREG) {
687 cmp_ir(code, 0, flags_reg, inst->extra.size);
688 update_flags(opts, N|Z|V0|C0);
689 }
690 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) {
691 m68k_write_size(opts, inst->extra.size);
692 if (inst->dst.addr_mode == MODE_AREG_POSTINC) {
693 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1));
694 addi_areg(opts, inc_amount, inst->dst.params.regs.pri);
695 }
708 } 696 }
709 697
710 //add cycles for prefetch 698 //add cycles for prefetch
711 cycles(&opts->gen, BUS); 699 cycles(&opts->gen, BUS);
712 } 700 }
854 } 842 }
855 843
856 void translate_m68k_clr(m68k_options * opts, m68kinst * inst) 844 void translate_m68k_clr(m68k_options * opts, m68kinst * inst)
857 { 845 {
858 code_info *code = &opts->gen.code; 846 code_info *code = &opts->gen.code;
859 set_flag(opts, 0, FLAG_N); 847 update_flags(opts, N0|V0|C0|Z1);
860 set_flag(opts, 0, FLAG_V);
861 set_flag(opts, 0, FLAG_C);
862 set_flag(opts, 1, FLAG_Z);
863 int8_t reg = native_reg(&(inst->dst), opts); 848 int8_t reg = native_reg(&(inst->dst), opts);
864 if (reg >= 0) { 849 if (reg >= 0) {
865 cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 6 : 4)); 850 cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 6 : 4));
866 xor_rr(code, reg, reg, inst->extra.size); 851 xor_rr(code, reg, reg, inst->extra.size);
867 return; 852 return;
868 } 853 }
869 x86_ea dst_op; 854 x86_ea dst_op;
855 //TODO: fix timing
870 translate_m68k_op(inst, &dst_op, opts, 1); 856 translate_m68k_op(inst, &dst_op, opts, 1);
871 if (dst_op.mode == MODE_REG_DIRECT) { 857 if (dst_op.mode == MODE_REG_DIRECT) {
872 xor_rr(code, dst_op.base, dst_op.base, inst->extra.size); 858 xor_rr(code, dst_op.base, dst_op.base, inst->extra.size);
873 } else { 859 } else {
874 mov_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size); 860 mov_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size);
890 movsx_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch1, inst->extra.size, dst_size); 876 movsx_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch1, inst->extra.size, dst_size);
891 cmp_ir(code, 0, opts->gen.scratch1, dst_size); 877 cmp_ir(code, 0, opts->gen.scratch1, dst_size);
892 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, dst_size); 878 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, dst_size);
893 } 879 }
894 inst->extra.size = dst_size; 880 inst->extra.size = dst_size;
895 set_flag(opts, 0, FLAG_V); 881 update_flags(opts, N|V0|C0|Z);
896 set_flag(opts, 0, FLAG_C);
897 set_flag_cond(opts, CC_Z, FLAG_Z);
898 set_flag_cond(opts, CC_S, FLAG_N);
899 //M68K EXT only operates on registers so no need for a call to save result here 882 //M68K EXT only operates on registers so no need for a call to save result here
900 } 883 }
901 884
902 uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc) 885 uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc)
903 { 886 {
1170 cmp_ir(code, src_op.disp, dst_op.base, size); 1153 cmp_ir(code, src_op.disp, dst_op.base, size);
1171 } else { 1154 } else {
1172 cmp_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, size); 1155 cmp_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, size);
1173 } 1156 }
1174 } 1157 }
1175 set_flag_cond(opts, CC_C, FLAG_C); 1158 update_flags(opts, N|Z|V|C);
1176 set_flag_cond(opts, CC_Z, FLAG_Z);
1177 set_flag_cond(opts, CC_S, FLAG_N);
1178 set_flag_cond(opts, CC_O, FLAG_V);
1179 } 1159 }
1180 1160
1181 typedef void (*shift_ir_t)(code_info *code, uint8_t val, uint8_t dst, uint8_t size); 1161 typedef void (*shift_ir_t)(code_info *code, uint8_t val, uint8_t dst, uint8_t size);
1182 typedef void (*shift_irdisp_t)(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size); 1162 typedef void (*shift_irdisp_t)(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size);
1183 typedef void (*shift_clr_t)(code_info *code, uint8_t dst, uint8_t size); 1163 typedef void (*shift_clr_t)(code_info *code, uint8_t dst, uint8_t size);
1458 } else { 1438 } else {
1459 add_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, size); 1439 add_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, size);
1460 } 1440 }
1461 } 1441 }
1462 if (inst->dst.addr_mode != MODE_AREG) { 1442 if (inst->dst.addr_mode != MODE_AREG) {
1463 set_flag_cond(opts, CC_C, FLAG_C); 1443 update_flags(opts, X|N|Z|V|C);
1464 set_flag_cond(opts, CC_Z, FLAG_Z);
1465 set_flag_cond(opts, CC_S, FLAG_N);
1466 set_flag_cond(opts, CC_O, FLAG_V);
1467 if (opts->flag_regs[FLAG_C] >= 0) {
1468 flag_to_flag(opts, FLAG_C, FLAG_X);
1469 } else {
1470 set_flag_cond(opts, CC_C, FLAG_X);
1471 }
1472 } 1444 }
1473 m68k_save_result(inst, opts); 1445 m68k_save_result(inst, opts);
1474 break; 1446 break;
1475 case M68K_ADDX: { 1447 case M68K_ADDX: {
1476 cycles(&opts->gen, BUS); 1448 cycles(&opts->gen, BUS);
1522 and_ir(code, src_op.disp, dst_op.base, inst->extra.size); 1494 and_ir(code, src_op.disp, dst_op.base, inst->extra.size);
1523 } else { 1495 } else {
1524 and_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 1496 and_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
1525 } 1497 }
1526 } 1498 }
1527 set_flag(opts, 0, FLAG_C); 1499 update_flags(opts, N|Z|V0|C0);
1528 set_flag_cond(opts, CC_Z, FLAG_Z);
1529 set_flag_cond(opts, CC_S, FLAG_N);
1530 set_flag(opts, 0, FLAG_V);
1531 m68k_save_result(inst, opts); 1500 m68k_save_result(inst, opts);
1532 break; 1501 break;
1533 case M68K_ANDI_CCR: 1502 case M68K_ANDI_CCR:
1534 case M68K_ANDI_SR: 1503 case M68K_ANDI_SR: {
1535 cycles(&opts->gen, 20); 1504 cycles(&opts->gen, 20);
1536 //TODO: If ANDI to SR, trap if not in supervisor mode 1505 //TODO: If ANDI to SR, trap if not in supervisor mode
1506 uint32_t flag_mask = 0;
1537 if (!(inst->src.params.immed & 0x1)) { 1507 if (!(inst->src.params.immed & 0x1)) {
1538 set_flag(opts, 0, FLAG_C); 1508 flag_mask |= C0;
1539 } 1509 }
1540 if (!(inst->src.params.immed & 0x2)) { 1510 if (!(inst->src.params.immed & 0x2)) {
1541 set_flag(opts, 0, FLAG_V); 1511 flag_mask |= V0;
1542 } 1512 }
1543 if (!(inst->src.params.immed & 0x4)) { 1513 if (!(inst->src.params.immed & 0x4)) {
1544 set_flag(opts, 0, FLAG_Z); 1514 flag_mask |= Z0;
1545 } 1515 }
1546 if (!(inst->src.params.immed & 0x8)) { 1516 if (!(inst->src.params.immed & 0x8)) {
1547 set_flag(opts, 0, FLAG_N); 1517 flag_mask |= N0;
1548 } 1518 }
1549 if (!(inst->src.params.immed & 0x10)) { 1519 if (!(inst->src.params.immed & 0x10)) {
1550 set_flag(opts, 0, FLAG_X); 1520 flag_mask |= X0;
1551 } 1521 }
1522 update_flags(opts, flag_mask);
1552 if (inst->op == M68K_ANDI_SR) { 1523 if (inst->op == M68K_ANDI_SR) {
1553 and_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 1524 and_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
1554 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 1525 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
1555 //leave supervisor mode 1526 //leave supervisor mode
1556 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_B); 1527 swap_ssp_usp(opts);
1557 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_B);
1558 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_B);
1559 } 1528 }
1560 if (inst->src.params.immed & 0x700) { 1529 if (inst->src.params.immed & 0x700) {
1561 call(code, opts->do_sync); 1530 call(code, opts->do_sync);
1562 } 1531 }
1563 } 1532 }
1564 break; 1533 break;
1534 }
1565 case M68K_ASL: 1535 case M68K_ASL:
1566 case M68K_LSL: 1536 case M68K_LSL:
1567 translate_shift(opts, inst, &src_op, &dst_op, shl_ir, shl_irdisp, shl_clr, shl_clrdisp, shr_ir, shr_irdisp); 1537 translate_shift(opts, inst, &src_op, &dst_op, shl_ir, shl_irdisp, shl_clr, shl_clrdisp, shr_ir, shr_irdisp);
1568 break; 1538 break;
1569 case M68K_ASR: 1539 case M68K_ASR:
1848 xor_ir(code, src_op.disp, dst_op.base, inst->extra.size); 1818 xor_ir(code, src_op.disp, dst_op.base, inst->extra.size);
1849 } else { 1819 } else {
1850 xor_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 1820 xor_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
1851 } 1821 }
1852 } 1822 }
1853 set_flag(opts, 0, FLAG_C); 1823 update_flags(opts, N|Z|V0|C0);
1854 set_flag_cond(opts, CC_Z, FLAG_Z);
1855 set_flag_cond(opts, CC_S, FLAG_N);
1856 set_flag(opts, 0, FLAG_V);
1857 m68k_save_result(inst, opts); 1824 m68k_save_result(inst, opts);
1858 break; 1825 break;
1859 case M68K_EORI_CCR: 1826 case M68K_EORI_CCR:
1860 case M68K_EORI_SR: 1827 case M68K_EORI_SR:
1861 cycles(&opts->gen, 20); 1828 cycles(&opts->gen, 20);
1926 break; 1893 break;
1927 case M68K_MOVE_CCR: 1894 case M68K_MOVE_CCR:
1928 case M68K_MOVE_SR: 1895 case M68K_MOVE_SR:
1929 //TODO: Privilege check for MOVE to SR 1896 //TODO: Privilege check for MOVE to SR
1930 if (src_op.mode == MODE_IMMED) { 1897 if (src_op.mode == MODE_IMMED) {
1931 set_flag(opts, src_op.disp & 0x1, FLAG_C); 1898 uint32_t flag_mask = src_op.disp & 0x10 ? X1 : X0;
1932 set_flag(opts, (src_op.disp >> 1) & 0x1, FLAG_V); 1899 flag_mask |= src_op.disp & 0x8 ? N1 : N0;
1933 set_flag(opts, (src_op.disp >> 2) & 0x1, FLAG_Z); 1900 flag_mask |= src_op.disp & 0x4 ? Z1 : Z0;
1934 set_flag(opts, (src_op.disp >> 3) & 0x1, FLAG_N); 1901 flag_mask |= src_op.disp & 0x2 ? V1 : V0;
1935 set_flag(opts, (src_op.disp >> 4) & 0x1, FLAG_X); 1902 flag_mask |= src_op.disp & 0x1 ? C1 : C0;
1903 update_flags(opts, flag_mask);
1936 if (inst->op == M68K_MOVE_SR) { 1904 if (inst->op == M68K_MOVE_SR) {
1937 mov_irdisp(code, (src_op.disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 1905 mov_irdisp(code, (src_op.disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
1938 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 1906 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
1939 //leave supervisor mode 1907 //leave supervisor mode
1940 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D); 1908 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D);
2010 } 1978 }
2011 imul_rr(code, opts->gen.scratch1, dst_reg, SZ_D); 1979 imul_rr(code, opts->gen.scratch1, dst_reg, SZ_D);
2012 if (dst_op.mode == MODE_REG_DISPLACE8) { 1980 if (dst_op.mode == MODE_REG_DISPLACE8) {
2013 mov_rrdisp(code, dst_reg, dst_op.base, dst_op.disp, SZ_D); 1981 mov_rrdisp(code, dst_reg, dst_op.base, dst_op.disp, SZ_D);
2014 } 1982 }
2015 set_flag(opts, 0, FLAG_V);
2016 set_flag(opts, 0, FLAG_C);
2017 cmp_ir(code, 0, dst_reg, SZ_D); 1983 cmp_ir(code, 0, dst_reg, SZ_D);
2018 set_flag_cond(opts, CC_Z, FLAG_Z); 1984 update_flags(opts, N|Z|V0|C0);
2019 set_flag_cond(opts, CC_S, FLAG_N);
2020 break; 1985 break;
2021 //case M68K_NBCD: 1986 //case M68K_NBCD:
2022 case M68K_NEG: 1987 case M68K_NEG:
2023 cycles(&opts->gen, BUS); 1988 cycles(&opts->gen, BUS);
2024 if (dst_op.mode == MODE_REG_DIRECT) { 1989 if (dst_op.mode == MODE_REG_DIRECT) {
2025 neg_r(code, dst_op.base, inst->extra.size); 1990 neg_r(code, dst_op.base, inst->extra.size);
2026 } else { 1991 } else {
2027 neg_rdisp(code, dst_op.base, dst_op.disp, inst->extra.size); 1992 neg_rdisp(code, dst_op.base, dst_op.disp, inst->extra.size);
2028 } 1993 }
2029 set_flag_cond(opts, CC_C, FLAG_C); 1994 update_flags(opts, X|N|Z|V|C);
2030 set_flag_cond(opts, CC_Z, FLAG_Z);
2031 set_flag_cond(opts, CC_S, FLAG_N);
2032 set_flag_cond(opts, CC_O, FLAG_V);
2033 if (opts->flag_regs[FLAG_C] >= 0) {
2034 flag_to_flag(opts, FLAG_C, FLAG_X);
2035 } else {
2036 set_flag_cond(opts, CC_C, FLAG_X);
2037 }
2038 m68k_save_result(inst, opts); 1995 m68k_save_result(inst, opts);
2039 break; 1996 break;
2040 case M68K_NEGX: { 1997 case M68K_NEGX: {
2041 cycles(&opts->gen, BUS); 1998 cycles(&opts->gen, BUS);
2042 if (dst_op.mode == MODE_REG_DIRECT) { 1999 if (dst_op.mode == MODE_REG_DIRECT) {
2084 } else { 2041 } else {
2085 not_rdisp(code, dst_op.base, dst_op.disp, inst->extra.size); 2042 not_rdisp(code, dst_op.base, dst_op.disp, inst->extra.size);
2086 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size); 2043 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size);
2087 } 2044 }
2088 2045
2089 set_flag(opts, 0, FLAG_C); 2046 update_flags(opts, N|Z|V0|C0);
2090 set_flag_cond(opts, CC_Z, FLAG_Z);
2091 set_flag_cond(opts, CC_S, FLAG_N);
2092 set_flag(opts, 0, FLAG_V);
2093 m68k_save_result(inst, opts); 2047 m68k_save_result(inst, opts);
2094 break; 2048 break;
2095 case M68K_OR: 2049 case M68K_OR:
2096 cycles(&opts->gen, BUS); 2050 cycles(&opts->gen, BUS);
2097 if (src_op.mode == MODE_REG_DIRECT) { 2051 if (src_op.mode == MODE_REG_DIRECT) {
2107 or_ir(code, src_op.disp, dst_op.base, inst->extra.size); 2061 or_ir(code, src_op.disp, dst_op.base, inst->extra.size);
2108 } else { 2062 } else {
2109 or_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2063 or_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
2110 } 2064 }
2111 } 2065 }
2112 set_flag(opts, 0, FLAG_C); 2066 update_flags(opts, N|Z|V0|C0);
2113 set_flag_cond(opts, CC_Z, FLAG_Z);
2114 set_flag_cond(opts, CC_S, FLAG_N);
2115 set_flag(opts, 0, FLAG_V);
2116 m68k_save_result(inst, opts); 2067 m68k_save_result(inst, opts);
2117 break; 2068 break;
2118 case M68K_ORI_CCR: 2069 case M68K_ORI_CCR:
2119 case M68K_ORI_SR: 2070 case M68K_ORI_SR:
2120 cycles(&opts->gen, 20); 2071 cycles(&opts->gen, 20);
2121 //TODO: If ANDI to SR, trap if not in supervisor mode 2072 //TODO: If ORI to SR, trap if not in supervisor mode
2073 uint32_t flag_mask = 0;
2122 if (inst->src.params.immed & 0x1) { 2074 if (inst->src.params.immed & 0x1) {
2123 set_flag(opts, 1, FLAG_C); 2075 flag_mask |= C1;
2124 } 2076 }
2125 if (inst->src.params.immed & 0x2) { 2077 if (inst->src.params.immed & 0x2) {
2126 set_flag(opts, 1, FLAG_V); 2078 flag_mask |= V1;
2127 } 2079 }
2128 if (inst->src.params.immed & 0x4) { 2080 if (inst->src.params.immed & 0x4) {
2129 set_flag(opts, 1, FLAG_Z); 2081 flag_mask |= Z1;
2130 } 2082 }
2131 if (inst->src.params.immed & 0x8) { 2083 if (inst->src.params.immed & 0x8) {
2132 set_flag(opts, 1, FLAG_N); 2084 flag_mask |= N1;
2133 } 2085 }
2134 if (inst->src.params.immed & 0x10) { 2086 if (inst->src.params.immed & 0x10) {
2135 set_flag(opts, 1, FLAG_X); 2087 flag_mask |= X1;
2136 } 2088 }
2089 update_flags(opts, flag_mask);
2137 if (inst->op == M68K_ORI_SR) { 2090 if (inst->op == M68K_ORI_SR) {
2138 or_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 2091 or_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
2139 if (inst->src.params.immed & 0x700) { 2092 if (inst->src.params.immed & 0x700) {
2140 call(code, opts->do_sync); 2093 call(code, opts->do_sync);
2141 } 2094 }
2429 case M68K_STOP: { 2382 case M68K_STOP: {
2430 //TODO: Trap if not in system mode 2383 //TODO: Trap if not in system mode
2431 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction 2384 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction
2432 //possibly even 12 since that's how long MOVE to SR takes 2385 //possibly even 12 since that's how long MOVE to SR takes
2433 cycles(&opts->gen, BUS*2); 2386 cycles(&opts->gen, BUS*2);
2434 set_flag(opts, src_op.disp & 0x1, FLAG_C); 2387 uint32_t flag_mask = src_op.disp & 0x10 ? X1 : X0;
2435 set_flag(opts, (src_op.disp >> 1) & 0x1, FLAG_V); 2388 flag_mask |= src_op.disp & 0x8 ? N1 : N0;
2436 set_flag(opts, (src_op.disp >> 2) & 0x1, FLAG_Z); 2389 flag_mask |= src_op.disp & 0x4 ? Z1 : Z0;
2437 set_flag(opts, (src_op.disp >> 3) & 0x1, FLAG_N); 2390 flag_mask |= src_op.disp & 0x2 ? V1 : V0;
2438 set_flag(opts, (src_op.disp >> 4) & 0x1, FLAG_X); 2391 flag_mask |= src_op.disp & 0x1 ? C1 : C0;
2392 update_flags(opts, flag_mask);
2439 mov_irdisp(code, (src_op.disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 2393 mov_irdisp(code, (src_op.disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
2440 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 2394 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
2441 //leave supervisor mode 2395 //leave supervisor mode
2442 swap_ssp_usp(opts); 2396 swap_ssp_usp(opts);
2443 } 2397 }
2473 } else { 2427 } else {
2474 sub_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, size); 2428 sub_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, size);
2475 } 2429 }
2476 } 2430 }
2477 if (inst->dst.addr_mode != MODE_AREG) { 2431 if (inst->dst.addr_mode != MODE_AREG) {
2478 set_flag_cond(opts, CC_C, FLAG_C); 2432 update_flags(opts, X|N|Z|V|C);
2479 set_flag_cond(opts, CC_Z, FLAG_Z);
2480 set_flag_cond(opts, CC_S, FLAG_N);
2481 set_flag_cond(opts, CC_O, FLAG_V);
2482 if (opts->flag_regs[FLAG_C] >= 0) {
2483 flag_to_flag(opts, FLAG_C, FLAG_X);
2484 } else {
2485 set_flag_cond(opts, CC_C, FLAG_X);
2486 }
2487 } 2433 }
2488 m68k_save_result(inst, opts); 2434 m68k_save_result(inst, opts);
2489 break; 2435 break;
2490 case M68K_SUBX: { 2436 case M68K_SUBX: {
2491 cycles(&opts->gen, BUS); 2437 cycles(&opts->gen, BUS);
2529 } else{ 2475 } else{
2530 rol_irdisp(code, 16, src_op.base, src_op.disp, SZ_D); 2476 rol_irdisp(code, 16, src_op.base, src_op.disp, SZ_D);
2531 cmp_irdisp(code, 0, src_op.base, src_op.disp, SZ_D); 2477 cmp_irdisp(code, 0, src_op.base, src_op.disp, SZ_D);
2532 } 2478 }
2533 2479
2534 set_flag(opts, 0, FLAG_C); 2480 update_flags(opts, N|Z|V0|C0);
2535 set_flag_cond(opts, CC_Z, FLAG_Z);
2536 set_flag_cond(opts, CC_S, FLAG_N);
2537 set_flag(opts, 0, FLAG_V);
2538 break; 2481 break;
2539 //case M68K_TAS: 2482 //case M68K_TAS:
2540 case M68K_TRAP: 2483 case M68K_TRAP:
2541 translate_m68k_trap(opts, inst); 2484 translate_m68k_trap(opts, inst);
2542 break; 2485 break;
2546 if (src_op.mode == MODE_REG_DIRECT) { 2489 if (src_op.mode == MODE_REG_DIRECT) {
2547 cmp_ir(code, 0, src_op.base, inst->extra.size); 2490 cmp_ir(code, 0, src_op.base, inst->extra.size);
2548 } else { //M68000 doesn't support immedate operand for tst, so this must be MODE_REG_DISPLACE8 2491 } else { //M68000 doesn't support immedate operand for tst, so this must be MODE_REG_DISPLACE8
2549 cmp_irdisp(code, 0, src_op.base, src_op.disp, inst->extra.size); 2492 cmp_irdisp(code, 0, src_op.base, src_op.disp, inst->extra.size);
2550 } 2493 }
2551 set_flag(opts, 0, FLAG_C); 2494 update_flags(opts, N|Z|V0|C0);
2552 set_flag_cond(opts, CC_Z, FLAG_Z);
2553 set_flag_cond(opts, CC_S, FLAG_N);
2554 set_flag(opts, 0, FLAG_V);
2555 break; 2495 break;
2556 default: 2496 default:
2557 m68k_disasm(inst, disasm_buf); 2497 m68k_disasm(inst, disasm_buf);
2558 printf("%X: %s\ninstruction %d not yet implemented\n", inst->address, disasm_buf, inst->op); 2498 printf("%X: %s\ninstruction %d not yet implemented\n", inst->address, disasm_buf, inst->op);
2559 exit(1); 2499 exit(1);