comparison m68k_to_x86.c @ 546:90aca661542b

Make references to flags in the M68K core respect the flag_regs options array so that flags can be moved out of registers for the 32-bit port. set/get ccr/sr still need to be updated to support this, but everything else should be done.
author Michael Pavone <pavone@retrodev.com>
date Mon, 17 Feb 2014 19:58:37 -0800
parents 67cf0ce57d8d
children 3090d016c9e9
comparison
equal deleted inserted replaced
545:67cf0ce57d8d 546:90aca661542b
19 #define LIMIT RBP 19 #define LIMIT RBP
20 #define SCRATCH1 RCX 20 #define SCRATCH1 RCX
21 #define SCRATCH2 RDI 21 #define SCRATCH2 RDI
22 #define CONTEXT RSI 22 #define CONTEXT RSI
23 23
24 /*
24 #define FLAG_N RBX 25 #define FLAG_N RBX
25 #define FLAG_V BH 26 #define FLAG_V BH
26 #define FLAG_Z RDX 27 #define FLAG_Z RDX
27 #define FLAG_C DH 28 #define FLAG_C DH
29 */
30 enum {
31 FLAG_X,
32 FLAG_N,
33 FLAG_Z,
34 FLAG_V,
35 FLAG_C
36 };
28 37
29 char disasm_buf[1024]; 38 char disasm_buf[1024];
30 39
31 m68k_context * sync_components(m68k_context * context, uint32_t address); 40 m68k_context * sync_components(m68k_context * context, uint32_t address);
32 41
59 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); 68 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
60 uint8_t * jmp_off = dst+1; 69 uint8_t * jmp_off = dst+1;
61 dst = jcc(dst, CC_NC, dst + 7); 70 dst = jcc(dst, CC_NC, dst + 7);
62 dst = call(dst, opts->handle_cycle_limit); 71 dst = call(dst, opts->handle_cycle_limit);
63 *jmp_off = dst - (jmp_off+1); 72 *jmp_off = dst - (jmp_off+1);
73 return dst;
74 }
75
76 uint8_t * set_flag(uint8_t * dst, uint8_t val, uint8_t flag, x86_68k_options * opts)
77 {
78 if (opts->flag_regs[flag] >= 0) {
79 dst = mov_ir(dst, val, opts->flag_regs[flag], SZ_B);
80 } else {
81 int8_t offset = offsetof(m68k_context, flags) + flag;
82 if (offset) {
83 dst = mov_irdisp8(dst, val, CONTEXT, offset, SZ_B);
84 } else {
85 dst = mov_irind(dst, val, CONTEXT, SZ_B);
86 }
87 }
88
89 return dst;
90 }
91
92 uint8_t * set_flag_cond(uint8_t * dst, uint8_t cond, uint8_t flag, x86_68k_options *opts)
93 {
94 if (opts->flag_regs[flag] >= 0) {
95 dst = setcc_r(dst, cond, opts->flag_regs[flag]);
96 } else {
97 int8_t offset = offsetof(m68k_context, flags) + flag;
98 if (offset) {
99 dst = setcc_rdisp8(dst, cond, CONTEXT, offset);
100 } else {
101 dst = setcc_rind(dst, cond, CONTEXT);
102 }
103 }
104
105 return dst;
106 }
107
108 uint8_t * check_flag(uint8_t *dst, uint8_t flag, x86_68k_options *opts)
109 {
110 if (opts->flag_regs[flag] >= 0) {
111 dst = cmp_ir(dst, 0, opts->flag_regs[flag], SZ_B);
112 } else {
113 dst = cmp_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B);
114 }
115 return dst;
116 }
117
118 uint8_t * flag_to_reg(uint8_t *dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
119 {
120 if (opts->flag_regs[flag] >= 0) {
121 dst = mov_rr(dst, opts->flag_regs[flag], reg, SZ_B);
122 } else {
123 int8_t offset = offsetof(m68k_context, flags) + flag;
124 if (offset) {
125 dst = mov_rdisp8r(dst, CONTEXT, offset, reg, SZ_B);
126 } else {
127 dst = mov_rindr(dst, CONTEXT, reg, SZ_B);
128 }
129 }
130 return dst;
131 }
132
133 uint8_t * reg_to_flag(uint8_t *dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
134 {
135 if (opts->flag_regs[flag] >= 0) {
136 dst = mov_rr(dst, reg, opts->flag_regs[flag], SZ_B);
137 } else {
138 int8_t offset = offsetof(m68k_context, flags) + flag;
139 if (offset) {
140 dst = mov_rrdisp8(dst, reg, CONTEXT, offset, SZ_B);
141 } else {
142 dst = mov_rrind(dst, reg, CONTEXT, SZ_B);
143 }
144 }
145 return dst;
146 }
147
148 uint8_t * flag_to_flag(uint8_t *dst, uint8_t flag1, uint8_t flag2, x86_68k_options *opts)
149 {
150 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) {
151 dst = mov_rr(dst, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B);
152 } else if(opts->flag_regs[flag1] >= 0) {
153 dst = mov_rrdisp8(dst, opts->flag_regs[flag1], CONTEXT, offsetof(m68k_context, flags) + flag2, SZ_B);
154 } else if (opts->flag_regs[flag2] >= 0) {
155 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag1, opts->flag_regs[flag2], SZ_B);
156 } else {
157 dst = push_r(dst, SCRATCH1);
158 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag1, SCRATCH1, SZ_B);
159 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, flags) + flag2, SZ_B);
160 dst = pop_r(dst, SCRATCH1);
161 }
162 return dst;
163 }
164
165 uint8_t * flag_to_carry(uint8_t *dst, uint8_t flag, x86_68k_options * opts)
166 {
167 if (opts->flag_regs[flag] >= 0) {
168 dst = bt_ir(dst, 0, opts->flag_regs[flag], SZ_B);
169 } else {
170 dst = bt_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B);
171 }
172 return dst;
173 }
174
175 uint8_t * or_flag_to_reg(uint8_t *dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
176 {
177 if (opts->flag_regs[flag] >= 0) {
178 dst = or_rr(dst, opts->flag_regs[flag], reg, SZ_B);
179 } else {
180 dst = or_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, reg, SZ_B);
181 }
182 return dst;
183 }
184
185 uint8_t * xor_flag_to_reg(uint8_t *dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
186 {
187 if (opts->flag_regs[flag] >= 0) {
188 dst = xor_rr(dst, opts->flag_regs[flag], reg, SZ_B);
189 } else {
190 dst = xor_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, reg, SZ_B);
191 }
192 return dst;
193 }
194
195 uint8_t * xor_flag(uint8_t *dst, uint8_t val, uint8_t flag, x86_68k_options *opts)
196 {
197 if (opts->flag_regs[flag] >= 0) {
198 dst = xor_ir(dst, val, opts->flag_regs[flag], SZ_B);
199 } else {
200 dst = xor_irdisp8(dst, val, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B);
201 }
202 return dst;
203 }
204
205 uint8_t * cmp_flags(uint8_t *dst, uint8_t flag1, uint8_t flag2, x86_68k_options *opts)
206 {
207 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) {
208 dst = cmp_rr(dst, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B);
209 } else if(opts->flag_regs[flag1] >= 0 || opts->flag_regs[flag2] >= 0) {
210 if (opts->flag_regs[flag2] >= 0) {
211 uint8_t tmp = flag1;
212 flag1 = flag2;
213 flag2 = tmp;
214 }
215 dst = cmp_rrdisp8(dst, opts->flag_regs[flag1], CONTEXT, offsetof(m68k_context, flags) + flag2, SZ_B);
216 } else {
217 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag1, SCRATCH1, SZ_B);
218 dst = cmp_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, flags) + flag2, SZ_B);
219 }
64 return dst; 220 return dst;
65 } 221 }
66 222
67 int8_t native_reg(m68k_op_info * op, x86_68k_options * opts) 223 int8_t native_reg(m68k_op_info * op, x86_68k_options * opts)
68 { 224 {
771 x86_ea src; 927 x86_ea src;
772 dst = translate_m68k_src(inst, &src, dst, opts); 928 dst = translate_m68k_src(inst, &src, dst, opts);
773 reg = native_reg(&(inst->dst), opts); 929 reg = native_reg(&(inst->dst), opts);
774 if (inst->dst.addr_mode != MODE_AREG) { 930 if (inst->dst.addr_mode != MODE_AREG) {
775 //update statically set flags 931 //update statically set flags
776 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 932 dst = set_flag(dst, 0, FLAG_V, opts);
777 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 933 dst = set_flag(dst, 0, FLAG_C, opts);
778 } 934 }
779 935
780 if (inst->dst.addr_mode != MODE_AREG) { 936 if (inst->dst.addr_mode != MODE_AREG) {
781 if (src.mode == MODE_REG_DIRECT) { 937 if (src.mode == MODE_REG_DIRECT) {
782 flags_reg = src.base; 938 flags_reg = src.base;
813 } else { 969 } else {
814 dst = mov_irdisp8(dst, src.disp, CONTEXT, reg_offset(&(inst->dst)), size); 970 dst = mov_irdisp8(dst, src.disp, CONTEXT, reg_offset(&(inst->dst)), size);
815 } 971 }
816 if (inst->dst.addr_mode != MODE_AREG) { 972 if (inst->dst.addr_mode != MODE_AREG) {
817 dst = cmp_ir(dst, 0, flags_reg, size); 973 dst = cmp_ir(dst, 0, flags_reg, size);
818 dst = setcc_r(dst, CC_Z, FLAG_Z); 974 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
819 dst = setcc_r(dst, CC_S, FLAG_N); 975 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
820 } 976 }
821 break; 977 break;
822 case MODE_AREG_PREDEC: 978 case MODE_AREG_PREDEC:
823 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); 979 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1));
824 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 980 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
842 } else { 998 } else {
843 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 999 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size);
844 } 1000 }
845 if (inst->dst.addr_mode != MODE_AREG) { 1001 if (inst->dst.addr_mode != MODE_AREG) {
846 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 1002 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size);
847 dst = setcc_r(dst, CC_Z, FLAG_Z); 1003 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
848 dst = setcc_r(dst, CC_S, FLAG_N); 1004 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
849 } 1005 }
850 switch (inst->extra.size) 1006 switch (inst->extra.size)
851 { 1007 {
852 case OPSIZE_BYTE: 1008 case OPSIZE_BYTE:
853 dst = call(dst, opts->write_8); 1009 dst = call(dst, opts->write_8);
885 } else { 1041 } else {
886 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 1042 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size);
887 } 1043 }
888 if (inst->dst.addr_mode != MODE_AREG) { 1044 if (inst->dst.addr_mode != MODE_AREG) {
889 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 1045 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size);
890 dst = setcc_r(dst, CC_Z, FLAG_Z); 1046 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
891 dst = setcc_r(dst, CC_S, FLAG_N); 1047 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
892 } 1048 }
893 switch (inst->extra.size) 1049 switch (inst->extra.size)
894 { 1050 {
895 case OPSIZE_BYTE: 1051 case OPSIZE_BYTE:
896 dst = call(dst, opts->write_8); 1052 dst = call(dst, opts->write_8);
959 } else { 1115 } else {
960 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 1116 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size);
961 } 1117 }
962 if (inst->dst.addr_mode != MODE_AREG) { 1118 if (inst->dst.addr_mode != MODE_AREG) {
963 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 1119 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size);
964 dst = setcc_r(dst, CC_Z, FLAG_Z); 1120 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
965 dst = setcc_r(dst, CC_S, FLAG_N); 1121 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
966 } 1122 }
967 switch (inst->extra.size) 1123 switch (inst->extra.size)
968 { 1124 {
969 case OPSIZE_BYTE: 1125 case OPSIZE_BYTE:
970 dst = call(dst, opts->write_8); 1126 dst = call(dst, opts->write_8);
989 } else { 1145 } else {
990 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 1146 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size);
991 } 1147 }
992 if (inst->dst.addr_mode != MODE_AREG) { 1148 if (inst->dst.addr_mode != MODE_AREG) {
993 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 1149 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size);
994 dst = setcc_r(dst, CC_Z, FLAG_Z); 1150 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
995 dst = setcc_r(dst, CC_S, FLAG_N); 1151 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
996 } 1152 }
997 switch (inst->extra.size) 1153 switch (inst->extra.size)
998 { 1154 {
999 case OPSIZE_BYTE: 1155 case OPSIZE_BYTE:
1000 dst = call(dst, opts->write_8); 1156 dst = call(dst, opts->write_8);
1059 } else { 1215 } else {
1060 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 1216 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size);
1061 } 1217 }
1062 if (inst->dst.addr_mode != MODE_AREG) { 1218 if (inst->dst.addr_mode != MODE_AREG) {
1063 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 1219 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size);
1064 dst = setcc_r(dst, CC_Z, FLAG_Z); 1220 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
1065 dst = setcc_r(dst, CC_S, FLAG_N); 1221 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
1066 } 1222 }
1067 switch (inst->extra.size) 1223 switch (inst->extra.size)
1068 { 1224 {
1069 case OPSIZE_BYTE: 1225 case OPSIZE_BYTE:
1070 dst = call(dst, opts->write_8); 1226 dst = call(dst, opts->write_8);
1094 dst = cycles(dst, BUS); 1250 dst = cycles(dst, BUS);
1095 } 1251 }
1096 dst = mov_ir(dst, inst->dst.params.immed, SCRATCH2, SZ_D); 1252 dst = mov_ir(dst, inst->dst.params.immed, SCRATCH2, SZ_D);
1097 if (inst->dst.addr_mode != MODE_AREG) { 1253 if (inst->dst.addr_mode != MODE_AREG) {
1098 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 1254 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size);
1099 dst = setcc_r(dst, CC_Z, FLAG_Z); 1255 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
1100 dst = setcc_r(dst, CC_S, FLAG_N); 1256 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
1101 } 1257 }
1102 switch (inst->extra.size) 1258 switch (inst->extra.size)
1103 { 1259 {
1104 case OPSIZE_BYTE: 1260 case OPSIZE_BYTE:
1105 dst = call(dst, opts->write_8); 1261 dst = call(dst, opts->write_8);
1451 return dst; 1607 return dst;
1452 } 1608 }
1453 1609
1454 uint8_t * translate_m68k_clr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1610 uint8_t * translate_m68k_clr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
1455 { 1611 {
1456 dst = mov_ir(dst, 0, FLAG_N, SZ_B); 1612 dst = set_flag(dst, 0, FLAG_N, opts);
1457 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 1613 dst = set_flag(dst, 0, FLAG_V, opts);
1458 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 1614 dst = set_flag(dst, 0, FLAG_C, opts);
1459 dst = mov_ir(dst, 1, FLAG_Z, SZ_B); 1615 dst = set_flag(dst, 1, FLAG_Z, opts);
1460 int8_t reg = native_reg(&(inst->dst), opts); 1616 int8_t reg = native_reg(&(inst->dst), opts);
1461 if (reg >= 0) { 1617 if (reg >= 0) {
1462 dst = cycles(dst, (inst->extra.size == OPSIZE_LONG ? 6 : 4)); 1618 dst = cycles(dst, (inst->extra.size == OPSIZE_LONG ? 6 : 4));
1463 return xor_rr(dst, reg, reg, inst->extra.size); 1619 return xor_rr(dst, reg, reg, inst->extra.size);
1464 } 1620 }
1486 dst = movsx_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, inst->extra.size, dst_size); 1642 dst = movsx_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, inst->extra.size, dst_size);
1487 dst = cmp_ir(dst, 0, SCRATCH1, dst_size); 1643 dst = cmp_ir(dst, 0, SCRATCH1, dst_size);
1488 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, dst_size); 1644 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, dst_size);
1489 } 1645 }
1490 inst->extra.size = dst_size; 1646 inst->extra.size = dst_size;
1491 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 1647 dst = set_flag(dst, 0, FLAG_V, opts);
1492 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 1648 dst = set_flag(dst, 0, FLAG_C, opts);
1493 dst = setcc_r(dst, CC_Z, FLAG_Z); 1649 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
1494 dst = setcc_r(dst, CC_S, FLAG_N); 1650 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
1495 //M68K EXT only operates on registers so no need for a call to save result here 1651 //M68K EXT only operates on registers so no need for a call to save result here
1496 return dst; 1652 return dst;
1497 } 1653 }
1498 1654
1499 uint8_t * translate_m68k_lea(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1655 uint8_t * translate_m68k_lea(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
1778 switch (inst->extra.cond) 1934 switch (inst->extra.cond)
1779 { 1935 {
1780 case COND_HIGH: 1936 case COND_HIGH:
1781 cond = CC_Z; 1937 cond = CC_Z;
1782 case COND_LOW_SAME: 1938 case COND_LOW_SAME:
1783 dst = mov_rr(dst, FLAG_Z, SCRATCH1, SZ_B); 1939 dst = flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
1784 dst = or_rr(dst, FLAG_C, SCRATCH1, SZ_B); 1940 dst = or_flag_to_reg(dst, FLAG_C, SCRATCH1, opts);
1785 break; 1941 break;
1786 case COND_CARRY_CLR: 1942 case COND_CARRY_CLR:
1787 cond = CC_Z; 1943 cond = CC_Z;
1788 case COND_CARRY_SET: 1944 case COND_CARRY_SET:
1789 dst = cmp_ir(dst, 0, FLAG_C, SZ_B); 1945 dst = check_flag(dst, FLAG_C, opts);
1790 break; 1946 break;
1791 case COND_NOT_EQ: 1947 case COND_NOT_EQ:
1792 cond = CC_Z; 1948 cond = CC_Z;
1793 case COND_EQ: 1949 case COND_EQ:
1794 dst = cmp_ir(dst, 0, FLAG_Z, SZ_B); 1950 dst = check_flag(dst, FLAG_Z, opts);
1795 break; 1951 break;
1796 case COND_OVERF_CLR: 1952 case COND_OVERF_CLR:
1797 cond = CC_Z; 1953 cond = CC_Z;
1798 case COND_OVERF_SET: 1954 case COND_OVERF_SET:
1799 dst = cmp_ir(dst, 0, FLAG_V, SZ_B); 1955 dst = check_flag(dst, FLAG_V, opts);
1800 break; 1956 break;
1801 case COND_PLUS: 1957 case COND_PLUS:
1802 cond = CC_Z; 1958 cond = CC_Z;
1803 case COND_MINUS: 1959 case COND_MINUS:
1804 dst = cmp_ir(dst, 0, FLAG_N, SZ_B); 1960 dst = check_flag(dst, FLAG_N, opts);
1805 break; 1961 break;
1806 case COND_GREATER_EQ: 1962 case COND_GREATER_EQ:
1807 cond = CC_Z; 1963 cond = CC_Z;
1808 case COND_LESS: 1964 case COND_LESS:
1809 dst = cmp_rr(dst, FLAG_N, FLAG_V, SZ_B); 1965 dst = cmp_flags(dst, FLAG_N, FLAG_V, opts);
1810 break; 1966 break;
1811 case COND_GREATER: 1967 case COND_GREATER:
1812 cond = CC_Z; 1968 cond = CC_Z;
1813 case COND_LESS_EQ: 1969 case COND_LESS_EQ:
1814 dst = mov_rr(dst, FLAG_V, SCRATCH1, SZ_B); 1970 dst = flag_to_reg(dst, FLAG_V, SCRATCH1, opts);
1815 dst = xor_rr(dst, FLAG_N, SCRATCH1, SZ_B); 1971 dst = xor_flag_to_reg(dst, FLAG_N, SCRATCH1, opts);
1816 dst = or_rr(dst, FLAG_Z, SCRATCH1, SZ_B); 1972 dst = or_flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
1817 break; 1973 break;
1818 } 1974 }
1819 if (!dest_addr) { 1975 if (!dest_addr) {
1820 opts->deferred = defer_address(opts->deferred, after + disp, dst + 2); 1976 opts->deferred = defer_address(opts->deferred, after + disp, dst + 2);
1821 //dummy address to be replaced later, make sure it generates a 4-byte displacement 1977 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1848 switch (cond) 2004 switch (cond)
1849 { 2005 {
1850 case COND_HIGH: 2006 case COND_HIGH:
1851 cc = CC_Z; 2007 cc = CC_Z;
1852 case COND_LOW_SAME: 2008 case COND_LOW_SAME:
1853 dst = mov_rr(dst, FLAG_Z, SCRATCH1, SZ_B); 2009 dst = flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
1854 dst = or_rr(dst, FLAG_C, SCRATCH1, SZ_B); 2010 dst = or_flag_to_reg(dst, FLAG_C, SCRATCH1, opts);
1855 break; 2011 break;
1856 case COND_CARRY_CLR: 2012 case COND_CARRY_CLR:
1857 cc = CC_Z; 2013 cc = CC_Z;
1858 case COND_CARRY_SET: 2014 case COND_CARRY_SET:
1859 dst = cmp_ir(dst, 0, FLAG_C, SZ_B); 2015 dst = check_flag(dst, FLAG_C, opts);
1860 break; 2016 break;
1861 case COND_NOT_EQ: 2017 case COND_NOT_EQ:
1862 cc = CC_Z; 2018 cc = CC_Z;
1863 case COND_EQ: 2019 case COND_EQ:
1864 dst = cmp_ir(dst, 0, FLAG_Z, SZ_B); 2020 dst = check_flag(dst, FLAG_Z, opts);
1865 break; 2021 break;
1866 case COND_OVERF_CLR: 2022 case COND_OVERF_CLR:
1867 cc = CC_Z; 2023 cc = CC_Z;
1868 case COND_OVERF_SET: 2024 case COND_OVERF_SET:
1869 dst = cmp_ir(dst, 0, FLAG_V, SZ_B); 2025 dst = check_flag(dst, FLAG_V, opts);
1870 break; 2026 break;
1871 case COND_PLUS: 2027 case COND_PLUS:
1872 cc = CC_Z; 2028 cc = CC_Z;
1873 case COND_MINUS: 2029 case COND_MINUS:
1874 dst = cmp_ir(dst, 0, FLAG_N, SZ_B); 2030 dst = check_flag(dst, FLAG_N, opts);
1875 break; 2031 break;
1876 case COND_GREATER_EQ: 2032 case COND_GREATER_EQ:
1877 cc = CC_Z; 2033 cc = CC_Z;
1878 case COND_LESS: 2034 case COND_LESS:
1879 dst = cmp_rr(dst, FLAG_N, FLAG_V, SZ_B); 2035 dst = cmp_flags(dst, FLAG_N, FLAG_V, opts);
1880 break; 2036 break;
1881 case COND_GREATER: 2037 case COND_GREATER:
1882 cc = CC_Z; 2038 cc = CC_Z;
1883 case COND_LESS_EQ: 2039 case COND_LESS_EQ:
1884 dst = mov_rr(dst, FLAG_V, SCRATCH1, SZ_B); 2040 dst = flag_to_reg(dst, FLAG_V, SCRATCH1, opts);
1885 dst = xor_rr(dst, FLAG_N, SCRATCH1, SZ_B); 2041 dst = xor_flag_to_reg(dst, FLAG_N, SCRATCH1, opts);
1886 dst = or_rr(dst, FLAG_Z, SCRATCH1, SZ_B); 2042 dst = or_flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
1887 break; 2043 break;
1888 } 2044 }
1889 uint8_t *true_off = dst + 1; 2045 uint8_t *true_off = dst + 1;
1890 dst = jcc(dst, cc, dst+2); 2046 dst = jcc(dst, cc, dst+2);
1891 dst = cycles(dst, BUS); 2047 dst = cycles(dst, BUS);
2258 switch (inst->extra.cond) 2414 switch (inst->extra.cond)
2259 { 2415 {
2260 case COND_HIGH: 2416 case COND_HIGH:
2261 cond = CC_Z; 2417 cond = CC_Z;
2262 case COND_LOW_SAME: 2418 case COND_LOW_SAME:
2263 dst = mov_rr(dst, FLAG_Z, SCRATCH1, SZ_B); 2419 dst = flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
2264 dst = or_rr(dst, FLAG_C, SCRATCH1, SZ_B); 2420 dst = or_flag_to_reg(dst, FLAG_C, SCRATCH1, opts);
2265 break; 2421 break;
2266 case COND_CARRY_CLR: 2422 case COND_CARRY_CLR:
2267 cond = CC_Z; 2423 cond = CC_Z;
2268 case COND_CARRY_SET: 2424 case COND_CARRY_SET:
2269 dst = cmp_ir(dst, 0, FLAG_C, SZ_B); 2425 dst = check_flag(dst, FLAG_C, opts);
2270 break; 2426 break;
2271 case COND_NOT_EQ: 2427 case COND_NOT_EQ:
2272 cond = CC_Z; 2428 cond = CC_Z;
2273 case COND_EQ: 2429 case COND_EQ:
2274 dst = cmp_ir(dst, 0, FLAG_Z, SZ_B); 2430 dst = check_flag(dst, FLAG_Z, opts);
2275 break; 2431 break;
2276 case COND_OVERF_CLR: 2432 case COND_OVERF_CLR:
2277 cond = CC_Z; 2433 cond = CC_Z;
2278 case COND_OVERF_SET: 2434 case COND_OVERF_SET:
2279 dst = cmp_ir(dst, 0, FLAG_V, SZ_B); 2435 dst = check_flag(dst, FLAG_V, opts);
2280 break; 2436 break;
2281 case COND_PLUS: 2437 case COND_PLUS:
2282 cond = CC_Z; 2438 cond = CC_Z;
2283 case COND_MINUS: 2439 case COND_MINUS:
2284 dst = cmp_ir(dst, 0, FLAG_N, SZ_B); 2440 dst = check_flag(dst, FLAG_N, opts);
2285 break; 2441 break;
2286 case COND_GREATER_EQ: 2442 case COND_GREATER_EQ:
2287 cond = CC_Z; 2443 cond = CC_Z;
2288 case COND_LESS: 2444 case COND_LESS:
2289 dst = cmp_rr(dst, FLAG_N, FLAG_V, SZ_B); 2445 dst = cmp_flags(dst, FLAG_N, FLAG_V, opts);
2290 break; 2446 break;
2291 case COND_GREATER: 2447 case COND_GREATER:
2292 cond = CC_Z; 2448 cond = CC_Z;
2293 case COND_LESS_EQ: 2449 case COND_LESS_EQ:
2294 dst = mov_rr(dst, FLAG_V, SCRATCH1, SZ_B); 2450 dst = flag_to_reg(dst, FLAG_V, SCRATCH1, opts);
2295 dst = xor_rr(dst, FLAG_N, SCRATCH1, SZ_B); 2451 dst = xor_flag_to_reg(dst, FLAG_N, SCRATCH1, opts);
2296 dst = or_rr(dst, FLAG_Z, SCRATCH1, SZ_B); 2452 dst = or_flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
2297 break; 2453 break;
2298 } 2454 }
2299 skip_loc = dst + 1; 2455 skip_loc = dst + 1;
2300 dst = jcc(dst, cond, dst + 2); 2456 dst = jcc(dst, cond, dst + 2);
2301 } 2457 }
2490 dst = cmp_ir(dst, src_op.disp, dst_op.base, size); 2646 dst = cmp_ir(dst, src_op.disp, dst_op.base, size);
2491 } else { 2647 } else {
2492 dst = cmp_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size); 2648 dst = cmp_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size);
2493 } 2649 }
2494 } 2650 }
2495 dst = setcc_r(dst, CC_C, FLAG_C); 2651 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
2496 dst = setcc_r(dst, CC_Z, FLAG_Z); 2652 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
2497 dst = setcc_r(dst, CC_S, FLAG_N); 2653 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
2498 dst = setcc_r(dst, CC_O, FLAG_V); 2654 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
2499 return dst; 2655 return dst;
2500 } 2656 }
2501 2657
2502 typedef uint8_t * (*shift_ir_t)(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size); 2658 typedef uint8_t * (*shift_ir_t)(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size);
2503 typedef uint8_t * (*shift_irdisp8_t)(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size); 2659 typedef uint8_t * (*shift_irdisp8_t)(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size);
2515 dst = shift_ir(dst, 1, dst_op->base, SZ_W); 2671 dst = shift_ir(dst, 1, dst_op->base, SZ_W);
2516 } else { 2672 } else {
2517 dst = cycles(dst, inst->extra.size == OPSIZE_LONG ? 8 : 6); 2673 dst = cycles(dst, inst->extra.size == OPSIZE_LONG ? 8 : 6);
2518 if (src_op->mode == MODE_IMMED) { 2674 if (src_op->mode == MODE_IMMED) {
2519 if (src_op->disp != 1 && inst->op == M68K_ASL) { 2675 if (src_op->disp != 1 && inst->op == M68K_ASL) {
2520 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 2676 dst = set_flag(dst, 0, FLAG_V, opts);
2521 for (int i = 0; i < src_op->disp; i++) { 2677 for (int i = 0; i < src_op->disp; i++) {
2522 if (dst_op->mode == MODE_REG_DIRECT) { 2678 if (dst_op->mode == MODE_REG_DIRECT) {
2523 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size); 2679 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size);
2524 } else { 2680 } else {
2525 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size); 2681 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size);
2526 } 2682 }
2527 //dst = setcc_r(dst, CC_O, FLAG_V); 2683 //dst = setcc_r(dst, CC_O, FLAG_V);
2528 dst = jcc(dst, CC_NO, dst+4); 2684 uint8_t *after_flag_set = dst+1;
2529 dst = mov_ir(dst, 1, FLAG_V, SZ_B); 2685 dst = jcc(dst, CC_NO, dst+2);
2686 dst = set_flag(dst, 1, FLAG_V, opts);
2687 *after_flag_set = dst - (after_flag_set+1);
2530 } 2688 }
2531 } else { 2689 } else {
2532 if (dst_op->mode == MODE_REG_DIRECT) { 2690 if (dst_op->mode == MODE_REG_DIRECT) {
2533 dst = shift_ir(dst, src_op->disp, dst_op->base, inst->extra.size); 2691 dst = shift_ir(dst, src_op->disp, dst_op->base, inst->extra.size);
2534 } else { 2692 } else {
2535 dst = shift_irdisp8(dst, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size); 2693 dst = shift_irdisp8(dst, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size);
2536 } 2694 }
2537 dst = setcc_r(dst, CC_O, FLAG_V); 2695 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
2538 } 2696 }
2539 } else { 2697 } else {
2540 if (src_op->base != RCX) { 2698 if (src_op->base != RCX) {
2541 if (src_op->mode == MODE_REG_DIRECT) { 2699 if (src_op->mode == MODE_REG_DIRECT) {
2542 dst = mov_rr(dst, src_op->base, RCX, SZ_B); 2700 dst = mov_rr(dst, src_op->base, RCX, SZ_B);
2552 if (dst_op->mode == MODE_REG_DIRECT) { 2710 if (dst_op->mode == MODE_REG_DIRECT) {
2553 dst = cmp_ir(dst, 0, dst_op->base, inst->extra.size); 2711 dst = cmp_ir(dst, 0, dst_op->base, inst->extra.size);
2554 } else { 2712 } else {
2555 dst = cmp_irdisp8(dst, 0, dst_op->base, dst_op->disp, inst->extra.size); 2713 dst = cmp_irdisp8(dst, 0, dst_op->base, dst_op->disp, inst->extra.size);
2556 } 2714 }
2557 dst = setcc_r(dst, CC_Z, FLAG_Z); 2715 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
2558 dst = setcc_r(dst, CC_S, FLAG_N); 2716 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
2559 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 2717 dst = set_flag(dst, 0, FLAG_C, opts);
2560 //For other instructions, this flag will be set below 2718 //For other instructions, this flag will be set below
2561 if (inst->op == M68K_ASL) { 2719 if (inst->op == M68K_ASL) {
2562 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 2720 dst = set_flag(dst, 0, FLAG_V, opts);
2563 } 2721 }
2564 z_off = dst+1; 2722 z_off = dst+1;
2565 dst = jmp(dst, dst+2); 2723 dst = jmp(dst, dst+2);
2566 *nz_off = dst - (nz_off + 1); 2724 *nz_off = dst - (nz_off + 1);
2567 //add 2 cycles for every bit shifted 2725 //add 2 cycles for every bit shifted
2568 dst = add_rr(dst, RCX, CYCLES, SZ_D); 2726 dst = add_rr(dst, RCX, CYCLES, SZ_D);
2569 dst = add_rr(dst, RCX, CYCLES, SZ_D); 2727 dst = add_rr(dst, RCX, CYCLES, SZ_D);
2570 if (inst->op == M68K_ASL) { 2728 if (inst->op == M68K_ASL) {
2571 //ASL has Overflow flag behavior that depends on all of the bits shifted through the MSB 2729 //ASL has Overflow flag behavior that depends on all of the bits shifted through the MSB
2572 //Easiest way to deal with this is to shift one bit at a time 2730 //Easiest way to deal with this is to shift one bit at a time
2573 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 2731 dst = set_flag(dst, 0, FLAG_V, opts);
2574 uint8_t * loop_start = dst; 2732 uint8_t * loop_start = dst;
2575 if (dst_op->mode == MODE_REG_DIRECT) { 2733 if (dst_op->mode == MODE_REG_DIRECT) {
2576 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size); 2734 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size);
2577 } else { 2735 } else {
2578 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size); 2736 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size);
2579 } 2737 }
2580 //dst = setcc_r(dst, CC_O, FLAG_V); 2738 //dst = setcc_r(dst, CC_O, FLAG_V);
2581 dst = jcc(dst, CC_NO, dst+4); 2739 uint8_t *after_flag_set = dst+1;
2582 dst = mov_ir(dst, 1, FLAG_V, SZ_B); 2740 dst = jcc(dst, CC_NO, dst+2);
2741 dst = set_flag(dst, 1, FLAG_V, opts);
2742 *after_flag_set = dst - (after_flag_set+1);
2583 dst = loop(dst, loop_start); 2743 dst = loop(dst, loop_start);
2584 } else { 2744 } else {
2585 //x86 shifts modulo 32 for operand sizes less than 64-bits 2745 //x86 shifts modulo 32 for operand sizes less than 64-bits
2586 //but M68K shifts modulo 64, so we need to check for large shifts here 2746 //but M68K shifts modulo 64, so we need to check for large shifts here
2587 dst = cmp_ir(dst, 32, RCX, SZ_B); 2747 dst = cmp_ir(dst, 32, RCX, SZ_B);
2588 uint8_t * norm_shift_off = dst + 1; 2748 uint8_t * norm_shift_off = dst + 1;
2589 dst = jcc(dst, CC_L, dst+2); 2749 dst = jcc(dst, CC_L, dst+2);
2590 if (special) { 2750 if (special) {
2751 uint8_t *after_flag_set = NULL;
2591 if (inst->extra.size == OPSIZE_LONG) { 2752 if (inst->extra.size == OPSIZE_LONG) {
2592 uint8_t * neq_32_off = dst + 1; 2753 uint8_t * neq_32_off = dst + 1;
2593 dst = jcc(dst, CC_NZ, dst+2); 2754 dst = jcc(dst, CC_NZ, dst+2);
2594 2755
2595 //set the carry bit to the lsb 2756 //set the carry bit to the lsb
2596 if (dst_op->mode == MODE_REG_DIRECT) { 2757 if (dst_op->mode == MODE_REG_DIRECT) {
2597 dst = special(dst, 1, dst_op->base, SZ_D); 2758 dst = special(dst, 1, dst_op->base, SZ_D);
2598 } else { 2759 } else {
2599 dst = special_disp8(dst, 1, dst_op->base, dst_op->disp, SZ_D); 2760 dst = special_disp8(dst, 1, dst_op->base, dst_op->disp, SZ_D);
2600 } 2761 }
2601 dst = setcc_r(dst, CC_C, FLAG_C); 2762 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
2602 dst = jmp(dst, dst+4); 2763 after_flag_set = dst+1;
2764 dst = jmp(dst, dst+2);
2603 *neq_32_off = dst - (neq_32_off+1); 2765 *neq_32_off = dst - (neq_32_off+1);
2604 } 2766 }
2605 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 2767 dst = set_flag(dst, 0, FLAG_C, opts);
2606 dst = mov_ir(dst, 1, FLAG_Z, SZ_B); 2768 if (after_flag_set) {
2607 dst = mov_ir(dst, 0, FLAG_N, SZ_B); 2769 *after_flag_set = dst - (after_flag_set+1);
2770 }
2771 dst = set_flag(dst, 1, FLAG_Z, opts);
2772 dst = set_flag(dst, 0, FLAG_N, opts);
2608 if (dst_op->mode == MODE_REG_DIRECT) { 2773 if (dst_op->mode == MODE_REG_DIRECT) {
2609 dst = xor_rr(dst, dst_op->base, dst_op->base, inst->extra.size); 2774 dst = xor_rr(dst, dst_op->base, dst_op->base, inst->extra.size);
2610 } else { 2775 } else {
2611 dst = mov_irdisp8(dst, 0, dst_op->base, dst_op->disp, inst->extra.size); 2776 dst = mov_irdisp8(dst, 0, dst_op->base, dst_op->disp, inst->extra.size);
2612 } 2777 }
2633 2798
2634 } 2799 }
2635 if (!special && end_off) { 2800 if (!special && end_off) {
2636 *end_off = dst - (end_off + 1); 2801 *end_off = dst - (end_off + 1);
2637 } 2802 }
2638 dst = setcc_r(dst, CC_C, FLAG_C); 2803 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
2639 dst = setcc_r(dst, CC_Z, FLAG_Z); 2804 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
2640 dst = setcc_r(dst, CC_S, FLAG_N); 2805 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
2641 if (special && end_off) { 2806 if (special && end_off) {
2642 *end_off = dst - (end_off + 1); 2807 *end_off = dst - (end_off + 1);
2643 } 2808 }
2644 //set X flag to same as C flag 2809 //set X flag to same as C flag
2645 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 2810 if (opts->flag_regs[FLAG_C] >= 0) {
2811 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts);
2812 } else {
2813 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
2814 }
2646 if (z_off) { 2815 if (z_off) {
2647 *z_off = dst - (z_off + 1); 2816 *z_off = dst - (z_off + 1);
2648 } 2817 }
2649 if (inst->op != M68K_ASL) { 2818 if (inst->op != M68K_ASL) {
2650 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 2819 dst = set_flag(dst, 0, FLAG_V, opts);
2651 } 2820 }
2652 if (inst->src.addr_mode == MODE_UNUSED) { 2821 if (inst->src.addr_mode == MODE_UNUSED) {
2653 dst = m68k_save_result(inst, dst, opts); 2822 dst = m68k_save_result(inst, dst, opts);
2654 } 2823 }
2655 return dst; 2824 return dst;
2724 dst = mov_rr(dst, dst_op.base, SCRATCH1, SZ_B); 2893 dst = mov_rr(dst, dst_op.base, SCRATCH1, SZ_B);
2725 } else { 2894 } else {
2726 dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, SZ_B); 2895 dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, SZ_B);
2727 } 2896 }
2728 } 2897 }
2729 dst = bt_irdisp8(dst, 0, CONTEXT, 0, SZ_B); 2898 dst = flag_to_carry(dst, FLAG_X, opts);
2730 dst = jcc(dst, CC_NC, dst+5); 2899 dst = jcc(dst, CC_NC, dst+5);
2731 dst = add_ir(dst, 1, SCRATCH1, SZ_B); 2900 dst = add_ir(dst, 1, SCRATCH1, SZ_B);
2732 dst = call(dst, (uint8_t *)bcd_add); 2901 dst = call(dst, (uint8_t *)bcd_add);
2733 dst = mov_rr(dst, CH, FLAG_C, SZ_B); 2902 dst = reg_to_flag(dst, CH, FLAG_C, opts);
2734 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 2903 dst = reg_to_flag(dst, CH, FLAG_X, opts);
2735 dst = cmp_ir(dst, 0, SCRATCH1, SZ_B); 2904 dst = cmp_ir(dst, 0, SCRATCH1, SZ_B);
2736 dst = jcc(dst, CC_Z, dst+4); 2905 dst = jcc(dst, CC_Z, dst+4);
2737 dst = mov_ir(dst, 0, FLAG_Z, SZ_B); 2906 dst = set_flag(dst, 0, FLAG_Z, opts);
2738 if (dst_op.base != SCRATCH1) { 2907 if (dst_op.base != SCRATCH1) {
2739 if (dst_op.mode == MODE_REG_DIRECT) { 2908 if (dst_op.mode == MODE_REG_DIRECT) {
2740 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_B); 2909 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_B);
2741 } else { 2910 } else {
2742 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_B); 2911 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_B);
2761 } else { 2930 } else {
2762 dst = add_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size); 2931 dst = add_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size);
2763 } 2932 }
2764 } 2933 }
2765 if (inst->dst.addr_mode != MODE_AREG) { 2934 if (inst->dst.addr_mode != MODE_AREG) {
2766 dst = setcc_r(dst, CC_C, FLAG_C); 2935 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
2767 dst = setcc_r(dst, CC_Z, FLAG_Z); 2936 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
2768 dst = setcc_r(dst, CC_S, FLAG_N); 2937 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
2769 dst = setcc_r(dst, CC_O, FLAG_V); 2938 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
2770 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 2939 if (opts->flag_regs[FLAG_C] >= 0) {
2940 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts);
2941 } else {
2942 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
2943 }
2771 } 2944 }
2772 dst = m68k_save_result(inst, dst, opts); 2945 dst = m68k_save_result(inst, dst, opts);
2773 break; 2946 break;
2774 case M68K_ADDX: 2947 case M68K_ADDX: {
2775 dst = cycles(dst, BUS); 2948 dst = cycles(dst, BUS);
2776 dst = bt_irdisp8(dst, 0, CONTEXT, 0, SZ_B); 2949 dst = flag_to_carry(dst, FLAG_X, opts);
2777 if (src_op.mode == MODE_REG_DIRECT) { 2950 if (src_op.mode == MODE_REG_DIRECT) {
2778 if (dst_op.mode == MODE_REG_DIRECT) { 2951 if (dst_op.mode == MODE_REG_DIRECT) {
2779 dst = adc_rr(dst, src_op.base, dst_op.base, inst->extra.size); 2952 dst = adc_rr(dst, src_op.base, dst_op.base, inst->extra.size);
2780 } else { 2953 } else {
2781 dst = adc_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); 2954 dst = adc_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size);
2787 dst = adc_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 2960 dst = adc_ir(dst, src_op.disp, dst_op.base, inst->extra.size);
2788 } else { 2961 } else {
2789 dst = adc_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2962 dst = adc_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
2790 } 2963 }
2791 } 2964 }
2792 dst = setcc_r(dst, CC_C, FLAG_C); 2965 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
2793 dst = jcc(dst, CC_Z, dst+4); 2966
2794 dst = mov_ir(dst, 0, FLAG_Z, SZ_B); 2967 uint8_t *after_flag_set = dst+1;
2795 dst = setcc_r(dst, CC_S, FLAG_N); 2968 dst = jcc(dst, CC_Z, dst+2);
2796 dst = setcc_r(dst, CC_O, FLAG_V); 2969 dst = set_flag(dst, 0, FLAG_Z, opts);
2797 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 2970 *after_flag_set = dst - (after_flag_set+1);
2971 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
2972 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
2973 if (opts->flag_regs[FLAG_C] >= 0) {
2974 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts);
2975 } else {
2976 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
2977 }
2798 dst = m68k_save_result(inst, dst, opts); 2978 dst = m68k_save_result(inst, dst, opts);
2799 break; 2979 break;
2980 }
2800 case M68K_AND: 2981 case M68K_AND:
2801 dst = cycles(dst, BUS); 2982 dst = cycles(dst, BUS);
2802 if (src_op.mode == MODE_REG_DIRECT) { 2983 if (src_op.mode == MODE_REG_DIRECT) {
2803 if (dst_op.mode == MODE_REG_DIRECT) { 2984 if (dst_op.mode == MODE_REG_DIRECT) {
2804 dst = and_rr(dst, src_op.base, dst_op.base, inst->extra.size); 2985 dst = and_rr(dst, src_op.base, dst_op.base, inst->extra.size);
2812 dst = and_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 2993 dst = and_ir(dst, src_op.disp, dst_op.base, inst->extra.size);
2813 } else { 2994 } else {
2814 dst = and_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2995 dst = and_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
2815 } 2996 }
2816 } 2997 }
2817 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 2998 dst = set_flag(dst, 0, FLAG_C, opts);
2818 dst = setcc_r(dst, CC_Z, FLAG_Z); 2999 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
2819 dst = setcc_r(dst, CC_S, FLAG_N); 3000 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
2820 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 3001 dst = set_flag(dst, 0, FLAG_V, opts);
2821 dst = m68k_save_result(inst, dst, opts); 3002 dst = m68k_save_result(inst, dst, opts);
2822 break; 3003 break;
2823 case M68K_ANDI_CCR: 3004 case M68K_ANDI_CCR:
2824 case M68K_ANDI_SR: 3005 case M68K_ANDI_SR:
2825 dst = cycles(dst, 20); 3006 dst = cycles(dst, 20);
2826 //TODO: If ANDI to SR, trap if not in supervisor mode 3007 //TODO: If ANDI to SR, trap if not in supervisor mode
2827 if (!(inst->src.params.immed & 0x1)) { 3008 if (!(inst->src.params.immed & 0x1)) {
2828 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 3009 dst = set_flag(dst, 0, FLAG_C, opts);
2829 } 3010 }
2830 if (!(inst->src.params.immed & 0x2)) { 3011 if (!(inst->src.params.immed & 0x2)) {
2831 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 3012 dst = set_flag(dst, 0, FLAG_V, opts);
2832 } 3013 }
2833 if (!(inst->src.params.immed & 0x4)) { 3014 if (!(inst->src.params.immed & 0x4)) {
2834 dst = mov_ir(dst, 0, FLAG_Z, SZ_B); 3015 dst = set_flag(dst, 0, FLAG_Z, opts);
2835 } 3016 }
2836 if (!(inst->src.params.immed & 0x8)) { 3017 if (!(inst->src.params.immed & 0x8)) {
2837 dst = mov_ir(dst, 0, FLAG_N, SZ_B); 3018 dst = set_flag(dst, 0, FLAG_N, opts);
2838 } 3019 }
2839 if (!(inst->src.params.immed & 0x10)) { 3020 if (!(inst->src.params.immed & 0x10)) {
2840 dst = mov_irind(dst, 0, CONTEXT, SZ_B); 3021 dst = set_flag(dst, 0, FLAG_X, opts);
2841 } 3022 }
2842 if (inst->op == M68K_ANDI_SR) { 3023 if (inst->op == M68K_ANDI_SR) {
2843 dst = and_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B); 3024 dst = and_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B);
2844 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 3025 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
2845 //leave supervisor mode 3026 //leave supervisor mode
2968 dst = pop_r(dst, SCRATCH2); 3149 dst = pop_r(dst, SCRATCH2);
2969 } 3150 }
2970 } 3151 }
2971 //x86 sets the carry flag to the value of the bit tested 3152 //x86 sets the carry flag to the value of the bit tested
2972 //68K sets the zero flag to the complement of the bit tested 3153 //68K sets the zero flag to the complement of the bit tested
2973 dst = setcc_r(dst, CC_NC, FLAG_Z); 3154 dst = set_flag_cond(dst, CC_NC, FLAG_Z, opts);
2974 if (inst->op != M68K_BTST) { 3155 if (inst->op != M68K_BTST) {
2975 dst = m68k_save_result(inst, dst, opts); 3156 dst = m68k_save_result(inst, dst, opts);
2976 } 3157 }
2977 break; 3158 break;
2978 case M68K_CHK: 3159 case M68K_CHK:
3000 default: 3181 default:
3001 isize = 2; 3182 isize = 2;
3002 } 3183 }
3003 uint8_t * passed = dst+1; 3184 uint8_t * passed = dst+1;
3004 dst = jcc(dst, CC_GE, dst+2); 3185 dst = jcc(dst, CC_GE, dst+2);
3005 dst = mov_ir(dst, 1, FLAG_N, SZ_B); 3186 dst = set_flag(dst, 1, FLAG_N, opts);
3006 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D); 3187 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D);
3007 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D); 3188 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D);
3008 dst = jmp(dst, opts->trap); 3189 dst = jmp(dst, opts->trap);
3009 *passed = dst - (passed+1); 3190 *passed = dst - (passed+1);
3010 if (dst_op.mode == MODE_REG_DIRECT) { 3191 if (dst_op.mode == MODE_REG_DIRECT) {
3022 dst = cmp_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3203 dst = cmp_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3023 } 3204 }
3024 } 3205 }
3025 passed = dst+1; 3206 passed = dst+1;
3026 dst = jcc(dst, CC_LE, dst+2); 3207 dst = jcc(dst, CC_LE, dst+2);
3027 dst = mov_ir(dst, 0, FLAG_N, SZ_B); 3208 dst = set_flag(dst, 0, FLAG_N, opts);
3028 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D); 3209 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D);
3029 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D); 3210 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D);
3030 dst = jmp(dst, opts->trap); 3211 dst = jmp(dst, opts->trap);
3031 *passed = dst - (passed+1); 3212 *passed = dst - (passed+1);
3032 dst = cycles(dst, 4); 3213 dst = cycles(dst, 4);
3035 case M68K_DIVS: 3216 case M68K_DIVS:
3036 case M68K_DIVU: 3217 case M68K_DIVU:
3037 { 3218 {
3038 //TODO: cycle exact division 3219 //TODO: cycle exact division
3039 dst = cycles(dst, inst->op == M68K_DIVS ? 158 : 140); 3220 dst = cycles(dst, inst->op == M68K_DIVS ? 158 : 140);
3040 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 3221 dst = set_flag(dst, 0, FLAG_C, opts);
3041 dst = push_r(dst, RDX); 3222 dst = push_r(dst, RDX);
3042 dst = push_r(dst, RAX); 3223 dst = push_r(dst, RAX);
3043 if (dst_op.mode == MODE_REG_DIRECT) { 3224 if (dst_op.mode == MODE_REG_DIRECT) {
3044 dst = mov_rr(dst, dst_op.base, RAX, SZ_D); 3225 dst = mov_rr(dst, dst_op.base, RAX, SZ_D);
3045 } else { 3226 } else {
3102 dst = mov_rrdisp8(dst, RAX, dst_op.base, dst_op.disp, SZ_W); 3283 dst = mov_rrdisp8(dst, RAX, dst_op.base, dst_op.disp, SZ_W);
3103 } 3284 }
3104 dst = cmp_ir(dst, 0, RAX, SZ_W); 3285 dst = cmp_ir(dst, 0, RAX, SZ_W);
3105 dst = pop_r(dst, RAX); 3286 dst = pop_r(dst, RAX);
3106 dst = pop_r(dst, RDX); 3287 dst = pop_r(dst, RDX);
3107 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 3288 dst = set_flag(dst, 0, FLAG_V, opts);
3108 dst = setcc_r(dst, CC_Z, FLAG_Z); 3289 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3109 dst = setcc_r(dst, CC_S, FLAG_N); 3290 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3110 end_off = dst+1; 3291 end_off = dst+1;
3111 dst = jmp(dst, dst+2); 3292 dst = jmp(dst, dst+2);
3112 *norm_off = dst - (norm_off + 1); 3293 *norm_off = dst - (norm_off + 1);
3113 if (inst->op == M68K_DIVS) { 3294 if (inst->op == M68K_DIVS) {
3114 *skip_sec_check = dst - (skip_sec_check+1); 3295 *skip_sec_check = dst - (skip_sec_check+1);
3115 } 3296 }
3116 dst = pop_r(dst, RAX); 3297 dst = pop_r(dst, RAX);
3117 dst = pop_r(dst, RDX); 3298 dst = pop_r(dst, RDX);
3118 dst = mov_ir(dst, 1, FLAG_V, SZ_B); 3299 dst = set_flag(dst, 1, FLAG_V, opts);
3119 *end_off = dst - (end_off + 1); 3300 *end_off = dst - (end_off + 1);
3120 break; 3301 break;
3121 } 3302 }
3122 case M68K_EOR: 3303 case M68K_EOR:
3123 dst = cycles(dst, BUS); 3304 dst = cycles(dst, BUS);
3134 dst = xor_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 3315 dst = xor_ir(dst, src_op.disp, dst_op.base, inst->extra.size);
3135 } else { 3316 } else {
3136 dst = xor_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3317 dst = xor_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3137 } 3318 }
3138 } 3319 }
3139 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 3320 dst = set_flag(dst, 0, FLAG_C, opts);
3140 dst = setcc_r(dst, CC_Z, FLAG_Z); 3321 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3141 dst = setcc_r(dst, CC_S, FLAG_N); 3322 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3142 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 3323 dst = set_flag(dst, 0, FLAG_V, opts);
3143 dst = m68k_save_result(inst, dst, opts); 3324 dst = m68k_save_result(inst, dst, opts);
3144 break; 3325 break;
3145 case M68K_EORI_CCR: 3326 case M68K_EORI_CCR:
3146 case M68K_EORI_SR: 3327 case M68K_EORI_SR:
3147 dst = cycles(dst, 20); 3328 dst = cycles(dst, 20);
3148 //TODO: If ANDI to SR, trap if not in supervisor mode 3329 //TODO: If ANDI to SR, trap if not in supervisor mode
3149 if (inst->src.params.immed & 0x1) { 3330 if (inst->src.params.immed & 0x1) {
3150 dst = xor_ir(dst, 1, FLAG_C, SZ_B); 3331 dst = xor_flag(dst, 1, FLAG_C, opts);
3151 } 3332 }
3152 if (inst->src.params.immed & 0x2) { 3333 if (inst->src.params.immed & 0x2) {
3153 dst = xor_ir(dst, 1, FLAG_V, SZ_B); 3334 dst = xor_flag(dst, 1, FLAG_V, opts);
3154 } 3335 }
3155 if (inst->src.params.immed & 0x4) { 3336 if (inst->src.params.immed & 0x4) {
3156 dst = xor_ir(dst, 1, FLAG_Z, SZ_B); 3337 dst = xor_flag(dst, 1, FLAG_Z, opts);
3157 } 3338 }
3158 if (inst->src.params.immed & 0x8) { 3339 if (inst->src.params.immed & 0x8) {
3159 dst = xor_ir(dst, 1, FLAG_N, SZ_B); 3340 dst = xor_flag(dst, 1, FLAG_N, opts);
3160 } 3341 }
3161 if (inst->src.params.immed & 0x10) { 3342 if (inst->src.params.immed & 0x10) {
3162 dst = xor_irdisp8(dst, 1, CONTEXT, 0, SZ_B); 3343 dst = xor_flag(dst, 1, FLAG_X, opts);
3163 } 3344 }
3164 if (inst->op == M68K_ORI_SR) { 3345 if (inst->op == M68K_ORI_SR) {
3165 dst = xor_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B); 3346 dst = xor_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B);
3166 if (inst->src.params.immed & 0x700) { 3347 if (inst->src.params.immed & 0x700) {
3167 dst = call(dst, opts->do_sync); 3348 dst = call(dst, opts->do_sync);
3208 break; 3389 break;
3209 case M68K_MOVE_CCR: 3390 case M68K_MOVE_CCR:
3210 case M68K_MOVE_SR: 3391 case M68K_MOVE_SR:
3211 //TODO: Privilege check for MOVE to SR 3392 //TODO: Privilege check for MOVE to SR
3212 if (src_op.mode == MODE_IMMED) { 3393 if (src_op.mode == MODE_IMMED) {
3213 dst = mov_ir(dst, src_op.disp & 0x1, FLAG_C, SZ_B); 3394 dst = set_flag(dst, src_op.disp & 0x1, FLAG_C, opts);
3214 dst = mov_ir(dst, (src_op.disp >> 1) & 0x1, FLAG_V, SZ_B); 3395 dst = set_flag(dst, (src_op.disp >> 1) & 0x1, FLAG_V, opts);
3215 dst = mov_ir(dst, (src_op.disp >> 2) & 0x1, FLAG_Z, SZ_B); 3396 dst = set_flag(dst, (src_op.disp >> 2) & 0x1, FLAG_Z, opts);
3216 dst = mov_ir(dst, (src_op.disp >> 3) & 0x1, FLAG_N, SZ_B); 3397 dst = set_flag(dst, (src_op.disp >> 3) & 0x1, FLAG_N, opts);
3217 dst = mov_irind(dst, (src_op.disp >> 4) & 0x1, CONTEXT, SZ_B); 3398 dst = set_flag(dst, (src_op.disp >> 4) & 0x1, FLAG_X, opts);
3218 if (inst->op == M68K_MOVE_SR) { 3399 if (inst->op == M68K_MOVE_SR) {
3219 dst = mov_irdisp8(dst, (src_op.disp >> 8), CONTEXT, offsetof(m68k_context, status), SZ_B); 3400 dst = mov_irdisp8(dst, (src_op.disp >> 8), CONTEXT, offsetof(m68k_context, status), SZ_B);
3220 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 3401 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
3221 //leave supervisor mode 3402 //leave supervisor mode
3222 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3403 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3295 } 3476 }
3296 dst = imul_rr(dst, SCRATCH1, dst_reg, SZ_D); 3477 dst = imul_rr(dst, SCRATCH1, dst_reg, SZ_D);
3297 if (dst_op.mode == MODE_REG_DISPLACE8) { 3478 if (dst_op.mode == MODE_REG_DISPLACE8) {
3298 dst = mov_rrdisp8(dst, dst_reg, dst_op.base, dst_op.disp, SZ_D); 3479 dst = mov_rrdisp8(dst, dst_reg, dst_op.base, dst_op.disp, SZ_D);
3299 } 3480 }
3300 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 3481 dst = set_flag(dst, 0, FLAG_V, opts);
3301 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 3482 dst = set_flag(dst, 0, FLAG_C, opts);
3302 dst = cmp_ir(dst, 0, dst_reg, SZ_D); 3483 dst = cmp_ir(dst, 0, dst_reg, SZ_D);
3303 dst = setcc_r(dst, CC_Z, FLAG_Z); 3484 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3304 dst = setcc_r(dst, CC_S, FLAG_N); 3485 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3305 break; 3486 break;
3306 //case M68K_NBCD: 3487 //case M68K_NBCD:
3307 case M68K_NEG: 3488 case M68K_NEG:
3308 dst = cycles(dst, BUS); 3489 dst = cycles(dst, BUS);
3309 if (dst_op.mode == MODE_REG_DIRECT) { 3490 if (dst_op.mode == MODE_REG_DIRECT) {
3310 dst = neg_r(dst, dst_op.base, inst->extra.size); 3491 dst = neg_r(dst, dst_op.base, inst->extra.size);
3311 } else { 3492 } else {
3312 dst = neg_rdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3493 dst = neg_rdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size);
3313 } 3494 }
3314 dst = setcc_r(dst, CC_C, FLAG_C); 3495 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3315 dst = setcc_r(dst, CC_Z, FLAG_Z); 3496 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3316 dst = setcc_r(dst, CC_S, FLAG_N); 3497 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3317 dst = setcc_r(dst, CC_O, FLAG_V); 3498 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
3318 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 3499 if (opts->flag_regs[FLAG_C] >= 0) {
3500 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts);
3501 } else {
3502 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
3503 }
3319 dst = m68k_save_result(inst, dst, opts); 3504 dst = m68k_save_result(inst, dst, opts);
3320 break; 3505 break;
3321 case M68K_NEGX: 3506 case M68K_NEGX: {
3322 dst = cycles(dst, BUS); 3507 dst = cycles(dst, BUS);
3323 if (dst_op.mode == MODE_REG_DIRECT) { 3508 if (dst_op.mode == MODE_REG_DIRECT) {
3324 if (dst_op.base == SCRATCH1) { 3509 if (dst_op.base == SCRATCH1) {
3325 dst = push_r(dst, SCRATCH2); 3510 dst = push_r(dst, SCRATCH2);
3326 dst = xor_rr(dst, SCRATCH2, SCRATCH2, inst->extra.size); 3511 dst = xor_rr(dst, SCRATCH2, SCRATCH2, inst->extra.size);
3327 dst = bt_irdisp8(dst, 0, CONTEXT, 0, SZ_B); 3512 dst = flag_to_carry(dst, FLAG_X, opts);
3328 dst = sbb_rr(dst, dst_op.base, SCRATCH2, inst->extra.size); 3513 dst = sbb_rr(dst, dst_op.base, SCRATCH2, inst->extra.size);
3329 dst = mov_rr(dst, SCRATCH2, dst_op.base, inst->extra.size); 3514 dst = mov_rr(dst, SCRATCH2, dst_op.base, inst->extra.size);
3330 dst = pop_r(dst, SCRATCH2); 3515 dst = pop_r(dst, SCRATCH2);
3331 } else { 3516 } else {
3332 dst = xor_rr(dst, SCRATCH1, SCRATCH1, inst->extra.size); 3517 dst = xor_rr(dst, SCRATCH1, SCRATCH1, inst->extra.size);
3333 dst = bt_irdisp8(dst, 0, CONTEXT, 0, SZ_B); 3518 dst = flag_to_carry(dst, FLAG_X, opts);
3334 dst = sbb_rr(dst, dst_op.base, SCRATCH1, inst->extra.size); 3519 dst = sbb_rr(dst, dst_op.base, SCRATCH1, inst->extra.size);
3335 dst = mov_rr(dst, SCRATCH1, dst_op.base, inst->extra.size); 3520 dst = mov_rr(dst, SCRATCH1, dst_op.base, inst->extra.size);
3336 } 3521 }
3337 } else { 3522 } else {
3338 dst = xor_rr(dst, SCRATCH1, SCRATCH1, inst->extra.size); 3523 dst = xor_rr(dst, SCRATCH1, SCRATCH1, inst->extra.size);
3339 dst = bt_irdisp8(dst, 0, CONTEXT, 0, SZ_B); 3524 dst = flag_to_carry(dst, FLAG_X, opts);
3340 dst = sbb_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, inst->extra.size); 3525 dst = sbb_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, inst->extra.size);
3341 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, inst->extra.size); 3526 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, inst->extra.size);
3342 } 3527 }
3343 dst = setcc_r(dst, CC_C, FLAG_C); 3528 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3344 dst = jcc(dst, CC_Z, dst+4); 3529 uint8_t *after_flag_set = dst+1;
3345 dst = mov_ir(dst, 0, FLAG_Z, SZ_B); 3530 dst = jcc(dst, CC_Z, dst+2);
3346 dst = setcc_r(dst, CC_S, FLAG_N); 3531 dst = set_flag(dst, 0, FLAG_Z, opts);
3347 dst = setcc_r(dst, CC_O, FLAG_V); 3532 *after_flag_set = dst - (after_flag_set+1);
3348 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 3533 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3534 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
3535 if (opts->flag_regs[FLAG_C] >= 0) {
3536 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts);
3537 } else {
3538 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
3539 }
3349 dst = m68k_save_result(inst, dst, opts); 3540 dst = m68k_save_result(inst, dst, opts);
3350 break; 3541 break;
3351 break; 3542 }
3352 case M68K_NOP: 3543 case M68K_NOP:
3353 dst = cycles(dst, BUS); 3544 dst = cycles(dst, BUS);
3354 break; 3545 break;
3355 case M68K_NOT: 3546 case M68K_NOT:
3356 if (dst_op.mode == MODE_REG_DIRECT) { 3547 if (dst_op.mode == MODE_REG_DIRECT) {
3359 } else { 3550 } else {
3360 dst = not_rdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3551 dst = not_rdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size);
3361 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size); 3552 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size);
3362 } 3553 }
3363 3554
3364 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 3555 dst = set_flag(dst, 0, FLAG_C, opts);
3365 dst = setcc_r(dst, CC_Z, FLAG_Z); 3556 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3366 dst = setcc_r(dst, CC_S, FLAG_N); 3557 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3367 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 3558 dst = set_flag(dst, 0, FLAG_V, opts);
3368 dst = m68k_save_result(inst, dst, opts); 3559 dst = m68k_save_result(inst, dst, opts);
3369 break; 3560 break;
3370 case M68K_OR: 3561 case M68K_OR:
3371 dst = cycles(dst, BUS); 3562 dst = cycles(dst, BUS);
3372 if (src_op.mode == MODE_REG_DIRECT) { 3563 if (src_op.mode == MODE_REG_DIRECT) {
3382 dst = or_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 3573 dst = or_ir(dst, src_op.disp, dst_op.base, inst->extra.size);
3383 } else { 3574 } else {
3384 dst = or_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3575 dst = or_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3385 } 3576 }
3386 } 3577 }
3387 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 3578 dst = set_flag(dst, 0, FLAG_C, opts);
3388 dst = setcc_r(dst, CC_Z, FLAG_Z); 3579 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3389 dst = setcc_r(dst, CC_S, FLAG_N); 3580 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3390 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 3581 dst = set_flag(dst, 0, FLAG_V, opts);
3391 dst = m68k_save_result(inst, dst, opts); 3582 dst = m68k_save_result(inst, dst, opts);
3392 break; 3583 break;
3393 case M68K_ORI_CCR: 3584 case M68K_ORI_CCR:
3394 case M68K_ORI_SR: 3585 case M68K_ORI_SR:
3395 dst = cycles(dst, 20); 3586 dst = cycles(dst, 20);
3396 //TODO: If ANDI to SR, trap if not in supervisor mode 3587 //TODO: If ANDI to SR, trap if not in supervisor mode
3397 if (inst->src.params.immed & 0x1) { 3588 if (inst->src.params.immed & 0x1) {
3398 dst = mov_ir(dst, 1, FLAG_C, SZ_B); 3589 dst = set_flag(dst, 1, FLAG_C, opts);
3399 } 3590 }
3400 if (inst->src.params.immed & 0x2) { 3591 if (inst->src.params.immed & 0x2) {
3401 dst = mov_ir(dst, 1, FLAG_V, SZ_B); 3592 dst = set_flag(dst, 1, FLAG_V, opts);
3402 } 3593 }
3403 if (inst->src.params.immed & 0x4) { 3594 if (inst->src.params.immed & 0x4) {
3404 dst = mov_ir(dst, 1, FLAG_Z, SZ_B); 3595 dst = set_flag(dst, 1, FLAG_Z, opts);
3405 } 3596 }
3406 if (inst->src.params.immed & 0x8) { 3597 if (inst->src.params.immed & 0x8) {
3407 dst = mov_ir(dst, 1, FLAG_N, SZ_B); 3598 dst = set_flag(dst, 1, FLAG_N, opts);
3408 } 3599 }
3409 if (inst->src.params.immed & 0x10) { 3600 if (inst->src.params.immed & 0x10) {
3410 dst = mov_irind(dst, 1, CONTEXT, SZ_B); 3601 dst = set_flag(dst, 1, FLAG_X, opts);
3411 } 3602 }
3412 if (inst->op == M68K_ORI_SR) { 3603 if (inst->op == M68K_ORI_SR) {
3413 dst = or_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B); 3604 dst = or_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B);
3414 if (inst->src.params.immed & 0x700) { 3605 if (inst->src.params.immed & 0x700) {
3415 dst = call(dst, opts->do_sync); 3606 dst = call(dst, opts->do_sync);
3421 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); 3612 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
3422 dst = call(dst, (uint8_t *)print_regs_exit); 3613 dst = call(dst, (uint8_t *)print_regs_exit);
3423 break; 3614 break;
3424 case M68K_ROL: 3615 case M68K_ROL:
3425 case M68K_ROR: 3616 case M68K_ROR:
3426 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 3617 dst = set_flag(dst, 0, FLAG_V, opts);
3427 if (inst->src.addr_mode == MODE_UNUSED) { 3618 if (inst->src.addr_mode == MODE_UNUSED) {
3428 dst = cycles(dst, BUS); 3619 dst = cycles(dst, BUS);
3429 //Memory rotate 3620 //Memory rotate
3430 if (inst->op == M68K_ROL) { 3621 if (inst->op == M68K_ROL) {
3431 dst = rol_ir(dst, 1, dst_op.base, inst->extra.size); 3622 dst = rol_ir(dst, 1, dst_op.base, inst->extra.size);
3432 } else { 3623 } else {
3433 dst = ror_ir(dst, 1, dst_op.base, inst->extra.size); 3624 dst = ror_ir(dst, 1, dst_op.base, inst->extra.size);
3434 } 3625 }
3435 dst = setcc_r(dst, CC_C, FLAG_C); 3626 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3436 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); 3627 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size);
3437 dst = setcc_r(dst, CC_Z, FLAG_Z); 3628 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3438 dst = setcc_r(dst, CC_S, FLAG_N); 3629 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3439 dst = m68k_save_result(inst, dst, opts); 3630 dst = m68k_save_result(inst, dst, opts);
3440 } else { 3631 } else {
3441 if (src_op.mode == MODE_IMMED) { 3632 if (src_op.mode == MODE_IMMED) {
3442 dst = cycles(dst, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + src_op.disp*2); 3633 dst = cycles(dst, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + src_op.disp*2);
3443 if (dst_op.mode == MODE_REG_DIRECT) { 3634 if (dst_op.mode == MODE_REG_DIRECT) {
3451 dst = rol_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3642 dst = rol_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3452 } else { 3643 } else {
3453 dst = ror_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3644 dst = ror_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3454 } 3645 }
3455 } 3646 }
3456 dst = setcc_r(dst, CC_C, FLAG_C); 3647 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3457 } else { 3648 } else {
3458 if (src_op.mode == MODE_REG_DIRECT) { 3649 if (src_op.mode == MODE_REG_DIRECT) {
3459 if (src_op.base != SCRATCH1) { 3650 if (src_op.base != SCRATCH1) {
3460 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_B); 3651 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_B);
3461 } 3652 }
3500 dst = rol_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3691 dst = rol_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size);
3501 } else { 3692 } else {
3502 dst = ror_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3693 dst = ror_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size);
3503 } 3694 }
3504 } 3695 }
3505 dst = setcc_r(dst, CC_C, FLAG_C); 3696 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3506 end_off = dst + 1; 3697 end_off = dst + 1;
3507 dst = jmp(dst, dst+2); 3698 dst = jmp(dst, dst+2);
3508 *zero_off = dst - (zero_off+1); 3699 *zero_off = dst - (zero_off+1);
3509 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 3700 dst = set_flag(dst, 0, FLAG_C, opts);
3510 *end_off = dst - (end_off+1); 3701 *end_off = dst - (end_off+1);
3511 } 3702 }
3512 if (dst_op.mode == MODE_REG_DIRECT) { 3703 if (dst_op.mode == MODE_REG_DIRECT) {
3513 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); 3704 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size);
3514 } else { 3705 } else {
3515 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size); 3706 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size);
3516 } 3707 }
3517 dst = setcc_r(dst, CC_Z, FLAG_Z); 3708 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3518 dst = setcc_r(dst, CC_S, FLAG_N); 3709 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3519 } 3710 }
3520 break; 3711 break;
3521 case M68K_ROXL: 3712 case M68K_ROXL:
3522 case M68K_ROXR: 3713 case M68K_ROXR:
3523 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 3714 dst = set_flag(dst, 0, FLAG_V, opts);
3524 if (inst->src.addr_mode == MODE_UNUSED) { 3715 if (inst->src.addr_mode == MODE_UNUSED) {
3525 dst = cycles(dst, BUS); 3716 dst = cycles(dst, BUS);
3526 //Memory rotate 3717 //Memory rotate
3527 dst = bt_irdisp8(dst, 0, CONTEXT, 0, SZ_B); 3718 dst = flag_to_carry(dst, FLAG_X, opts);
3528 if (inst->op == M68K_ROXL) { 3719 if (inst->op == M68K_ROXL) {
3529 dst = rcl_ir(dst, 1, dst_op.base, inst->extra.size); 3720 dst = rcl_ir(dst, 1, dst_op.base, inst->extra.size);
3530 } else { 3721 } else {
3531 dst = rcr_ir(dst, 1, dst_op.base, inst->extra.size); 3722 dst = rcr_ir(dst, 1, dst_op.base, inst->extra.size);
3532 } 3723 }
3533 dst = setcc_r(dst, CC_C, FLAG_C); 3724 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3725 if (opts->flag_regs[FLAG_C] < 0) {
3726 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
3727 }
3534 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); 3728 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size);
3535 dst = setcc_r(dst, CC_Z, FLAG_Z); 3729 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3536 dst = setcc_r(dst, CC_S, FLAG_N); 3730 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3537 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 3731 if (opts->flag_regs[FLAG_C] >= 0) {
3732 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts);
3733 }
3538 dst = m68k_save_result(inst, dst, opts); 3734 dst = m68k_save_result(inst, dst, opts);
3539 } else { 3735 } else {
3540 if (src_op.mode == MODE_IMMED) { 3736 if (src_op.mode == MODE_IMMED) {
3541 dst = cycles(dst, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + src_op.disp*2); 3737 dst = cycles(dst, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + src_op.disp*2);
3542 dst = bt_irdisp8(dst, 0, CONTEXT, 0, SZ_B); 3738 dst = flag_to_carry(dst, FLAG_X, opts);
3543 if (dst_op.mode == MODE_REG_DIRECT) { 3739 if (dst_op.mode == MODE_REG_DIRECT) {
3544 if (inst->op == M68K_ROXL) { 3740 if (inst->op == M68K_ROXL) {
3545 dst = rcl_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 3741 dst = rcl_ir(dst, src_op.disp, dst_op.base, inst->extra.size);
3546 } else { 3742 } else {
3547 dst = rcr_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 3743 dst = rcr_ir(dst, src_op.disp, dst_op.base, inst->extra.size);
3551 dst = rcl_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3747 dst = rcl_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3552 } else { 3748 } else {
3553 dst = rcr_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3749 dst = rcr_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3554 } 3750 }
3555 } 3751 }
3556 dst = setcc_r(dst, CC_C, FLAG_C); 3752 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3557 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 3753 if (opts->flag_regs[FLAG_C] >= 0) {
3754 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts);
3755 } else {
3756 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
3757 }
3558 } else { 3758 } else {
3559 if (src_op.mode == MODE_REG_DIRECT) { 3759 if (src_op.mode == MODE_REG_DIRECT) {
3560 if (src_op.base != SCRATCH1) { 3760 if (src_op.base != SCRATCH1) {
3561 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_B); 3761 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_B);
3562 } 3762 }
3569 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D); 3769 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D);
3570 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D); 3770 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D);
3571 dst = cmp_ir(dst, 32, SCRATCH1, SZ_B); 3771 dst = cmp_ir(dst, 32, SCRATCH1, SZ_B);
3572 norm_off = dst+1; 3772 norm_off = dst+1;
3573 dst = jcc(dst, CC_L, dst+2); 3773 dst = jcc(dst, CC_L, dst+2);
3574 dst = bt_irdisp8(dst, 0, CONTEXT, 0, SZ_B); 3774 dst = flag_to_carry(dst, FLAG_X, opts);
3575 if (dst_op.mode == MODE_REG_DIRECT) { 3775 if (dst_op.mode == MODE_REG_DIRECT) {
3576 if (inst->op == M68K_ROXL) { 3776 if (inst->op == M68K_ROXL) {
3577 dst = rcl_ir(dst, 31, dst_op.base, inst->extra.size); 3777 dst = rcl_ir(dst, 31, dst_op.base, inst->extra.size);
3578 dst = rcl_ir(dst, 1, dst_op.base, inst->extra.size); 3778 dst = rcl_ir(dst, 1, dst_op.base, inst->extra.size);
3579 } else { 3779 } else {
3587 } else { 3787 } else {
3588 dst = rcr_irdisp8(dst, 31, dst_op.base, dst_op.disp, inst->extra.size); 3788 dst = rcr_irdisp8(dst, 31, dst_op.base, dst_op.disp, inst->extra.size);
3589 dst = rcr_irdisp8(dst, 1, dst_op.base, dst_op.disp, inst->extra.size); 3789 dst = rcr_irdisp8(dst, 1, dst_op.base, dst_op.disp, inst->extra.size);
3590 } 3790 }
3591 } 3791 }
3592 dst = setcc_rind(dst, CC_C, CONTEXT); 3792 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
3593 dst = sub_ir(dst, 32, SCRATCH1, SZ_B); 3793 dst = sub_ir(dst, 32, SCRATCH1, SZ_B);
3594 *norm_off = dst - (norm_off+1); 3794 *norm_off = dst - (norm_off+1);
3595 dst = bt_irdisp8(dst, 0, CONTEXT, 0, SZ_B); 3795 dst = flag_to_carry(dst, FLAG_X, opts);
3596 if (dst_op.mode == MODE_REG_DIRECT) { 3796 if (dst_op.mode == MODE_REG_DIRECT) {
3597 if (inst->op == M68K_ROXL) { 3797 if (inst->op == M68K_ROXL) {
3598 dst = rcl_clr(dst, dst_op.base, inst->extra.size); 3798 dst = rcl_clr(dst, dst_op.base, inst->extra.size);
3599 } else { 3799 } else {
3600 dst = rcr_clr(dst, dst_op.base, inst->extra.size); 3800 dst = rcr_clr(dst, dst_op.base, inst->extra.size);
3604 dst = rcl_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3804 dst = rcl_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size);
3605 } else { 3805 } else {
3606 dst = rcr_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3806 dst = rcr_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size);
3607 } 3807 }
3608 } 3808 }
3609 dst = setcc_r(dst, CC_C, FLAG_C); 3809 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3610 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 3810 if (opts->flag_regs[FLAG_C] >= 0) {
3811 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts);
3812 } else {
3813 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
3814 }
3611 end_off = dst + 1; 3815 end_off = dst + 1;
3612 dst = jmp(dst, dst+2); 3816 dst = jmp(dst, dst+2);
3613 *zero_off = dst - (zero_off+1); 3817 *zero_off = dst - (zero_off+1);
3614 //Carry flag is set to X flag when count is 0, this is different from ROR/ROL 3818 //Carry flag is set to X flag when count is 0, this is different from ROR/ROL
3615 dst = mov_rindr(dst, CONTEXT, FLAG_C, SZ_B); 3819 dst = flag_to_flag(dst, FLAG_X, FLAG_C, opts);
3616 *end_off = dst - (end_off+1); 3820 *end_off = dst - (end_off+1);
3617 } 3821 }
3618 if (dst_op.mode == MODE_REG_DIRECT) { 3822 if (dst_op.mode == MODE_REG_DIRECT) {
3619 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); 3823 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size);
3620 } else { 3824 } else {
3621 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size); 3825 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size);
3622 } 3826 }
3623 dst = setcc_r(dst, CC_Z, FLAG_Z); 3827 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3624 dst = setcc_r(dst, CC_S, FLAG_N); 3828 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3625 } 3829 }
3626 break; 3830 break;
3627 case M68K_RTE: 3831 case M68K_RTE:
3628 //TODO: Trap if not in system mode 3832 //TODO: Trap if not in system mode
3629 //Read saved SR 3833 //Read saved SR
3659 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 3863 dst = add_ir(dst, 4, opts->aregs[7], SZ_D);
3660 //Get native address and jump to it 3864 //Get native address and jump to it
3661 dst = call(dst, opts->native_addr); 3865 dst = call(dst, opts->native_addr);
3662 dst = jmp_r(dst, SCRATCH1); 3866 dst = jmp_r(dst, SCRATCH1);
3663 break; 3867 break;
3664 case M68K_SBCD: 3868 case M68K_SBCD: {
3665 if (src_op.base != SCRATCH2) { 3869 if (src_op.base != SCRATCH2) {
3666 if (src_op.mode == MODE_REG_DIRECT) { 3870 if (src_op.mode == MODE_REG_DIRECT) {
3667 dst = mov_rr(dst, src_op.base, SCRATCH2, SZ_B); 3871 dst = mov_rr(dst, src_op.base, SCRATCH2, SZ_B);
3668 } else { 3872 } else {
3669 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_B); 3873 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_B);
3674 dst = mov_rr(dst, dst_op.base, SCRATCH1, SZ_B); 3878 dst = mov_rr(dst, dst_op.base, SCRATCH1, SZ_B);
3675 } else { 3879 } else {
3676 dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, SZ_B); 3880 dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, SZ_B);
3677 } 3881 }
3678 } 3882 }
3679 dst = bt_irdisp8(dst, 0, CONTEXT, 0, SZ_B); 3883 dst = flag_to_carry(dst, FLAG_X, opts);
3680 dst = jcc(dst, CC_NC, dst+5); 3884 dst = jcc(dst, CC_NC, dst+5);
3681 dst = sub_ir(dst, 1, SCRATCH1, SZ_B); 3885 dst = sub_ir(dst, 1, SCRATCH1, SZ_B);
3682 dst = call(dst, (uint8_t *)bcd_sub); 3886 dst = call(dst, (uint8_t *)bcd_sub);
3683 dst = mov_rr(dst, CH, FLAG_C, SZ_B); 3887 dst = reg_to_flag(dst, CH, FLAG_C, opts);
3684 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 3888 dst = reg_to_flag(dst, CH, FLAG_X, opts);
3685 dst = cmp_ir(dst, 0, SCRATCH1, SZ_B); 3889 dst = cmp_ir(dst, 0, SCRATCH1, SZ_B);
3686 dst = jcc(dst, CC_Z, dst+4); 3890 uint8_t *after_flag_set = dst+1;
3687 dst = mov_ir(dst, 0, FLAG_Z, SZ_B); 3891 dst = jcc(dst, CC_Z, dst+2);
3892 dst = set_flag(dst, 0, FLAG_Z, opts);
3893 *after_flag_set = dst - (after_flag_set+1);
3688 if (dst_op.base != SCRATCH1) { 3894 if (dst_op.base != SCRATCH1) {
3689 if (dst_op.mode == MODE_REG_DIRECT) { 3895 if (dst_op.mode == MODE_REG_DIRECT) {
3690 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_B); 3896 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_B);
3691 } else { 3897 } else {
3692 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_B); 3898 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_B);
3693 } 3899 }
3694 } 3900 }
3695 dst = m68k_save_result(inst, dst, opts); 3901 dst = m68k_save_result(inst, dst, opts);
3696 break; 3902 break;
3903 }
3697 case M68K_STOP: { 3904 case M68K_STOP: {
3698 //TODO: Trap if not in system mode 3905 //TODO: Trap if not in system mode
3699 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction 3906 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction
3700 //possibly even 12 since that's how long MOVE to SR takes 3907 //possibly even 12 since that's how long MOVE to SR takes
3701 dst = cycles(dst, BUS*2); 3908 dst = cycles(dst, BUS*2);
3702 dst = mov_ir(dst, src_op.disp & 0x1, FLAG_C, SZ_B); 3909 dst = set_flag(dst, src_op.disp & 0x1, FLAG_C, opts);
3703 dst = mov_ir(dst, (src_op.disp >> 1) & 0x1, FLAG_V, SZ_B); 3910 dst = set_flag(dst, (src_op.disp >> 1) & 0x1, FLAG_V, opts);
3704 dst = mov_ir(dst, (src_op.disp >> 2) & 0x1, FLAG_Z, SZ_B); 3911 dst = set_flag(dst, (src_op.disp >> 2) & 0x1, FLAG_Z, opts);
3705 dst = mov_ir(dst, (src_op.disp >> 3) & 0x1, FLAG_N, SZ_B); 3912 dst = set_flag(dst, (src_op.disp >> 3) & 0x1, FLAG_N, opts);
3706 dst = mov_irind(dst, (src_op.disp >> 4) & 0x1, CONTEXT, SZ_B); 3913 dst = set_flag(dst, (src_op.disp >> 4) & 0x1, FLAG_X, opts);
3707 dst = mov_irdisp8(dst, (src_op.disp >> 8), CONTEXT, offsetof(m68k_context, status), SZ_B); 3914 dst = mov_irdisp8(dst, (src_op.disp >> 8), CONTEXT, offsetof(m68k_context, status), SZ_B);
3708 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 3915 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
3709 //leave supervisor mode 3916 //leave supervisor mode
3710 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3917 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3711 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); 3918 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D);
3743 } else { 3950 } else {
3744 dst = sub_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size); 3951 dst = sub_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size);
3745 } 3952 }
3746 } 3953 }
3747 if (inst->dst.addr_mode != MODE_AREG) { 3954 if (inst->dst.addr_mode != MODE_AREG) {
3748 dst = setcc_r(dst, CC_C, FLAG_C); 3955 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3749 dst = setcc_r(dst, CC_Z, FLAG_Z); 3956 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3750 dst = setcc_r(dst, CC_S, FLAG_N); 3957 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3751 dst = setcc_r(dst, CC_O, FLAG_V); 3958 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
3752 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 3959 if (opts->flag_regs[FLAG_C] >= 0) {
3960 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts);
3961 } else {
3962 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
3963 }
3753 } 3964 }
3754 dst = m68k_save_result(inst, dst, opts); 3965 dst = m68k_save_result(inst, dst, opts);
3755 break; 3966 break;
3756 case M68K_SUBX: 3967 case M68K_SUBX: {
3757 dst = cycles(dst, BUS); 3968 dst = cycles(dst, BUS);
3758 dst = bt_irdisp8(dst, 0, CONTEXT, 0, SZ_B); 3969 dst = flag_to_carry(dst, FLAG_X, opts);
3759 if (src_op.mode == MODE_REG_DIRECT) { 3970 if (src_op.mode == MODE_REG_DIRECT) {
3760 if (dst_op.mode == MODE_REG_DIRECT) { 3971 if (dst_op.mode == MODE_REG_DIRECT) {
3761 dst = sbb_rr(dst, src_op.base, dst_op.base, inst->extra.size); 3972 dst = sbb_rr(dst, src_op.base, dst_op.base, inst->extra.size);
3762 } else { 3973 } else {
3763 dst = sbb_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); 3974 dst = sbb_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size);
3769 dst = sbb_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 3980 dst = sbb_ir(dst, src_op.disp, dst_op.base, inst->extra.size);
3770 } else { 3981 } else {
3771 dst = sbb_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3982 dst = sbb_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3772 } 3983 }
3773 } 3984 }
3774 dst = setcc_r(dst, CC_C, FLAG_C); 3985 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3775 dst = jcc(dst, CC_Z, dst+4); 3986 if (opts->flag_regs[FLAG_C] < 0) {
3776 dst = mov_ir(dst, 0, FLAG_Z, SZ_B); 3987 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
3777 dst = setcc_r(dst, CC_S, FLAG_N); 3988 }
3778 dst = setcc_r(dst, CC_O, FLAG_V); 3989 uint8_t *after_flag_set = dst+1;
3779 dst = mov_rrind(dst, FLAG_C, CONTEXT, SZ_B); 3990 dst = jcc(dst, CC_Z, dst+2);
3991 dst = set_flag(dst, 0, FLAG_Z, opts);
3992 *after_flag_set = dst - (after_flag_set+1);
3993 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3994 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
3995 if (opts->flag_regs[FLAG_C] >= 0) {
3996 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts);
3997 }
3780 dst = m68k_save_result(inst, dst, opts); 3998 dst = m68k_save_result(inst, dst, opts);
3781 break; 3999 break;
4000 }
3782 case M68K_SWAP: 4001 case M68K_SWAP:
3783 dst = cycles(dst, BUS); 4002 dst = cycles(dst, BUS);
3784 if (src_op.mode == MODE_REG_DIRECT) { 4003 if (src_op.mode == MODE_REG_DIRECT) {
3785 dst = rol_ir(dst, 16, src_op.base, SZ_D); 4004 dst = rol_ir(dst, 16, src_op.base, SZ_D);
3786 dst = cmp_ir(dst, 0, src_op.base, SZ_D); 4005 dst = cmp_ir(dst, 0, src_op.base, SZ_D);
3787 } else{ 4006 } else{
3788 dst = rol_irdisp8(dst, 16, src_op.base, src_op.disp, SZ_D); 4007 dst = rol_irdisp8(dst, 16, src_op.base, src_op.disp, SZ_D);
3789 dst = cmp_irdisp8(dst, 0, src_op.base, src_op.disp, SZ_D); 4008 dst = cmp_irdisp8(dst, 0, src_op.base, src_op.disp, SZ_D);
3790 } 4009 }
3791 4010
3792 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 4011 dst = set_flag(dst, 0, FLAG_C, opts);
3793 dst = setcc_r(dst, CC_Z, FLAG_Z); 4012 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3794 dst = setcc_r(dst, CC_S, FLAG_N); 4013 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3795 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 4014 dst = set_flag(dst, 0, FLAG_V, opts);
3796 break; 4015 break;
3797 //case M68K_TAS: 4016 //case M68K_TAS:
3798 case M68K_TRAP: 4017 case M68K_TRAP:
3799 dst = mov_ir(dst, src_op.disp + VECTOR_TRAP_0, SCRATCH2, SZ_D); 4018 dst = mov_ir(dst, src_op.disp + VECTOR_TRAP_0, SCRATCH2, SZ_D);
3800 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); 4019 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
3806 if (src_op.mode == MODE_REG_DIRECT) { 4025 if (src_op.mode == MODE_REG_DIRECT) {
3807 dst = cmp_ir(dst, 0, src_op.base, inst->extra.size); 4026 dst = cmp_ir(dst, 0, src_op.base, inst->extra.size);
3808 } else { //M68000 doesn't support immedate operand for tst, so this must be MODE_REG_DISPLACE8 4027 } else { //M68000 doesn't support immedate operand for tst, so this must be MODE_REG_DISPLACE8
3809 dst = cmp_irdisp8(dst, 0, src_op.base, src_op.disp, inst->extra.size); 4028 dst = cmp_irdisp8(dst, 0, src_op.base, src_op.disp, inst->extra.size);
3810 } 4029 }
3811 dst = mov_ir(dst, 0, FLAG_C, SZ_B); 4030 dst = set_flag(dst, 0, FLAG_C, opts);
3812 dst = setcc_r(dst, CC_Z, FLAG_Z); 4031 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts);
3813 dst = setcc_r(dst, CC_S, FLAG_N); 4032 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3814 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 4033 dst = set_flag(dst, 0, FLAG_V, opts);
3815 break; 4034 break;
3816 case M68K_UNLK: 4035 case M68K_UNLK:
3817 dst = cycles(dst, BUS); 4036 dst = cycles(dst, BUS);
3818 if (dst_op.mode == MODE_REG_DIRECT) { 4037 if (dst_op.mode == MODE_REG_DIRECT) {
3819 dst = mov_rr(dst, dst_op.base, opts->aregs[7], SZ_D); 4038 dst = mov_rr(dst, dst_op.base, opts->aregs[7], SZ_D);