comparison m68k_to_x86.c @ 541:a59ac6b4b5b5

Get rid of the native stack option the 68K core. Trying to make it work with code that messes with the stack is not worth the trouble.
author Michael Pavone <pavone@retrodev.com>
date Sat, 15 Feb 2014 22:35:18 -0800
parents 4ca826862174
children 5d57fd8b44f8
comparison
equal deleted inserted replaced
540:4ca826862174 541:a59ac6b4b5b5
29 char disasm_buf[1024]; 29 char disasm_buf[1024];
30 30
31 m68k_context * sync_components(m68k_context * context, uint32_t address); 31 m68k_context * sync_components(m68k_context * context, uint32_t address);
32 32
33 void handle_cycle_limit(); 33 void handle_cycle_limit();
34 void m68k_modified_ret_addr();
35 void m68k_native_addr(); 34 void m68k_native_addr();
36 void m68k_native_addr_and_sync(); 35 void m68k_native_addr_and_sync();
37 void m68k_invalid(); 36 void m68k_invalid();
38 void m68k_retrans_stub(); 37 void m68k_retrans_stub();
39 void set_sr(); 38 void set_sr();
1752 int32_t disp = inst->src.params.immed; 1751 int32_t disp = inst->src.params.immed;
1753 uint32_t after = inst->address + (inst->variant == VAR_BYTE ? 2 : 4); 1752 uint32_t after = inst->address + (inst->variant == VAR_BYTE ? 2 : 4);
1754 //TODO: Add cycles in the right place relative to pushing the return address on the stack 1753 //TODO: Add cycles in the right place relative to pushing the return address on the stack
1755 dst = cycles(dst, 10); 1754 dst = cycles(dst, 10);
1756 dst = mov_ir(dst, after, SCRATCH1, SZ_D); 1755 dst = mov_ir(dst, after, SCRATCH1, SZ_D);
1757 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1758 dst = push_r(dst, SCRATCH1);
1759 }
1760 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1756 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1761 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1757 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1762 dst = call(dst, opts->write_32_highfirst); 1758 dst = call(dst, opts->write_32_highfirst);
1763 uint8_t * dest_addr = get_native_address(opts->native_code_map, (inst->address+2) + disp); 1759 uint8_t * dest_addr = get_native_address(opts->native_code_map, (inst->address+2) + disp);
1764 if (!dest_addr) { 1760 if (!dest_addr) {
1765 opts->deferred = defer_address(opts->deferred, (inst->address+2) + disp, dst + 1); 1761 opts->deferred = defer_address(opts->deferred, (inst->address+2) + disp, dst + 1);
1766 //dummy address to be replaced later 1762 //dummy address to be replaced later
1767 dest_addr = dst + 256; 1763 dest_addr = dst + 256;
1768 } 1764 }
1769 if (opts->flags & OPT_NATIVE_CALL_STACK) { 1765 dst = jmp(dst, (char *)dest_addr);
1770 dst = call(dst, (char *)dest_addr);
1771 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1772 dst = pop_r(dst, SCRATCH1);
1773 } else {
1774 dst = jmp(dst, (char *)dest_addr);
1775 }
1776 return dst; 1766 return dst;
1777 } 1767 }
1778 1768
1779 uint8_t * translate_m68k_bcc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1769 uint8_t * translate_m68k_bcc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
1780 { 1770 {
2078 switch(inst->src.addr_mode) 2068 switch(inst->src.addr_mode)
2079 { 2069 {
2080 case MODE_AREG_INDIRECT: 2070 case MODE_AREG_INDIRECT:
2081 dst = cycles(dst, BUS*2); 2071 dst = cycles(dst, BUS*2);
2082 dst = mov_ir(dst, inst->address + 2, SCRATCH1, SZ_D); 2072 dst = mov_ir(dst, inst->address + 2, SCRATCH1, SZ_D);
2083 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2084 dst = push_r(dst, SCRATCH1);
2085 }
2086 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2073 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2087 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2074 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2088 dst = call(dst, opts->write_32_highfirst); 2075 dst = call(dst, opts->write_32_highfirst);
2089 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 2076 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2090 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 2077 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
2091 } else { 2078 } else {
2092 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 2079 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D);
2093 } 2080 }
2094 dst = call(dst, (uint8_t *)m68k_native_addr); 2081 dst = call(dst, (uint8_t *)m68k_native_addr);
2095 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2082 dst = jmp_r(dst, SCRATCH1);
2096 dst = call_r(dst, SCRATCH1);
2097 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
2098 dst = pop_r(dst, SCRATCH1);
2099 } else {
2100 dst = jmp_r(dst, SCRATCH1);
2101 }
2102 break; 2083 break;
2103 case MODE_AREG_DISPLACE: 2084 case MODE_AREG_DISPLACE:
2104 dst = cycles(dst, BUS*2); 2085 dst = cycles(dst, BUS*2);
2105 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D); 2086 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
2106 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2107 dst = push_r(dst, SCRATCH1);
2108 }
2109 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2087 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2110 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2088 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2111 dst = call(dst, opts->write_32_highfirst); 2089 dst = call(dst, opts->write_32_highfirst);
2112 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 2090 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2113 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 2091 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
2114 } else { 2092 } else {
2115 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 2093 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D);
2116 } 2094 }
2117 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 2095 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
2118 dst = call(dst, (uint8_t *)m68k_native_addr); 2096 dst = call(dst, (uint8_t *)m68k_native_addr);
2119 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2097 dst = jmp_r(dst, SCRATCH1);
2120 dst = call_r(dst, SCRATCH1);
2121 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
2122 dst = pop_r(dst, SCRATCH1);
2123 } else {
2124 dst = jmp_r(dst, SCRATCH1);
2125 }
2126 break; 2098 break;
2127 case MODE_AREG_INDEX_DISP8: 2099 case MODE_AREG_INDEX_DISP8:
2128 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct 2100 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
2129 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D); 2101 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
2130 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2131 dst = push_r(dst, SCRATCH1);
2132 }
2133 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2102 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2134 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2103 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2135 dst = call(dst, opts->write_32_highfirst); 2104 dst = call(dst, opts->write_32_highfirst);
2136 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 2105 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2137 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 2106 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
2171 } 2140 }
2172 if (inst->src.params.regs.displacement) { 2141 if (inst->src.params.regs.displacement) {
2173 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 2142 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
2174 } 2143 }
2175 dst = call(dst, (uint8_t *)m68k_native_addr); 2144 dst = call(dst, (uint8_t *)m68k_native_addr);
2176 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2145 dst = jmp_r(dst, SCRATCH1);
2177 dst = call_r(dst, SCRATCH1);
2178 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
2179 dst = pop_r(dst, SCRATCH1);
2180 } else {
2181 dst = jmp_r(dst, SCRATCH1);
2182 }
2183 break; 2146 break;
2184 case MODE_PC_DISPLACE: 2147 case MODE_PC_DISPLACE:
2185 //TODO: Add cycles in the right place relative to pushing the return address on the stack 2148 //TODO: Add cycles in the right place relative to pushing the return address on the stack
2186 dst = cycles(dst, 10); 2149 dst = cycles(dst, 10);
2187 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D); 2150 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
2188 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2189 dst = push_r(dst, SCRATCH1);
2190 }
2191 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2151 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2192 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2152 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2193 dst = call(dst, opts->write_32_highfirst); 2153 dst = call(dst, opts->write_32_highfirst);
2194 m68k_addr = inst->src.params.regs.displacement + inst->address + 2; 2154 m68k_addr = inst->src.params.regs.displacement + inst->address + 2;
2195 if ((m68k_addr & 0xFFFFFF) < 0x400000) { 2155 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2197 if (!dest_addr) { 2157 if (!dest_addr) {
2198 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); 2158 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1);
2199 //dummy address to be replaced later, make sure it generates a 4-byte displacement 2159 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2200 dest_addr = dst + 256; 2160 dest_addr = dst + 256;
2201 } 2161 }
2202 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2162 dst = jmp(dst, dest_addr);
2203 dst = call(dst, (char *)dest_addr);
2204 } else {
2205 dst = jmp(dst, dest_addr);
2206 }
2207 } else { 2163 } else {
2208 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); 2164 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D);
2209 dst = call(dst, (uint8_t *)m68k_native_addr); 2165 dst = call(dst, (uint8_t *)m68k_native_addr);
2210 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2166 dst = jmp_r(dst, SCRATCH1);
2211 dst = call_r(dst, SCRATCH1);
2212 } else {
2213 dst = jmp_r(dst, SCRATCH1);
2214 }
2215 }
2216 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2217 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
2218 dst = pop_r(dst, SCRATCH1);
2219 } 2167 }
2220 break; 2168 break;
2221 case MODE_PC_INDEX_DISP8: 2169 case MODE_PC_INDEX_DISP8:
2222 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct 2170 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
2223 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D); 2171 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
2224 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2225 dst = push_r(dst, SCRATCH1);
2226 }
2227 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2172 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2228 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2173 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2229 dst = call(dst, opts->write_32_highfirst); 2174 dst = call(dst, opts->write_32_highfirst);
2230 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); 2175 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
2231 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; 2176 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
2261 } 2206 }
2262 if (inst->src.params.regs.displacement) { 2207 if (inst->src.params.regs.displacement) {
2263 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 2208 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
2264 } 2209 }
2265 dst = call(dst, (uint8_t *)m68k_native_addr); 2210 dst = call(dst, (uint8_t *)m68k_native_addr);
2266 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2211 dst = jmp_r(dst, SCRATCH1);
2267 dst = call_r(dst, SCRATCH1);
2268 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
2269 dst = pop_r(dst, SCRATCH1);
2270 } else {
2271 dst = jmp_r(dst, SCRATCH1);
2272 }
2273 break; 2212 break;
2274 case MODE_ABSOLUTE: 2213 case MODE_ABSOLUTE:
2275 case MODE_ABSOLUTE_SHORT: 2214 case MODE_ABSOLUTE_SHORT:
2276 //TODO: Add cycles in the right place relative to pushing the return address on the stack 2215 //TODO: Add cycles in the right place relative to pushing the return address on the stack
2277 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10); 2216 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10);
2278 dst = mov_ir(dst, inst->address + (inst->src.addr_mode == MODE_ABSOLUTE ? 6 : 4), SCRATCH1, SZ_D); 2217 dst = mov_ir(dst, inst->address + (inst->src.addr_mode == MODE_ABSOLUTE ? 6 : 4), SCRATCH1, SZ_D);
2279 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2280 dst = push_r(dst, SCRATCH1);
2281 }
2282 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2218 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2283 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2219 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2284 dst = call(dst, opts->write_32_highfirst); 2220 dst = call(dst, opts->write_32_highfirst);
2285 m68k_addr = inst->src.params.immed; 2221 m68k_addr = inst->src.params.immed;
2286 if ((m68k_addr & 0xFFFFFF) < 0x400000) { 2222 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2288 if (!dest_addr) { 2224 if (!dest_addr) {
2289 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); 2225 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1);
2290 //dummy address to be replaced later, make sure it generates a 4-byte displacement 2226 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2291 dest_addr = dst + 256; 2227 dest_addr = dst + 256;
2292 } 2228 }
2293 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2229 dst = jmp(dst, dest_addr);
2294 dst = call(dst, (char *)dest_addr);
2295 } else {
2296 dst = jmp(dst, dest_addr);
2297 }
2298 } else { 2230 } else {
2299 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); 2231 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D);
2300 dst = call(dst, (uint8_t *)m68k_native_addr); 2232 dst = call(dst, (uint8_t *)m68k_native_addr);
2301 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2233 dst = jmp_r(dst, SCRATCH1);
2302 dst = call_r(dst, SCRATCH1);
2303 } else {
2304 dst = jmp_r(dst, SCRATCH1);
2305 }
2306 }
2307 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2308 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
2309 dst = pop_r(dst, SCRATCH1);
2310 } 2234 }
2311 break; 2235 break;
2312 default: 2236 default:
2313 m68k_disasm(inst, disasm_buf); 2237 m68k_disasm(inst, disasm_buf);
2314 printf("%s\naddress mode %d not yet supported (jsr)\n", disasm_buf, inst->src.addr_mode); 2238 printf("%s\naddress mode %d not yet supported (jsr)\n", disasm_buf, inst->src.addr_mode);
2321 { 2245 {
2322 //TODO: Add cycles 2246 //TODO: Add cycles
2323 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 2247 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
2324 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 2248 dst = add_ir(dst, 4, opts->aregs[7], SZ_D);
2325 dst = call(dst, opts->read_32); 2249 dst = call(dst, opts->read_32);
2326 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2250 dst = call(dst, (uint8_t *)m68k_native_addr);
2327 dst = cmp_rdisp8r(dst, RSP, 8, SCRATCH1, SZ_D); 2251 dst = jmp_r(dst, SCRATCH1);
2328 dst = jcc(dst, CC_NZ, dst+3);
2329 dst = retn(dst);
2330 dst = jmp(dst, (char *)m68k_modified_ret_addr);
2331 } else {
2332 dst = call(dst, (uint8_t *)m68k_native_addr);
2333 dst = jmp_r(dst, SCRATCH1);
2334 }
2335 return dst; 2252 return dst;
2336 } 2253 }
2337 2254
2338 uint8_t * translate_m68k_dbcc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 2255 uint8_t * translate_m68k_dbcc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
2339 { 2256 {