Mercurial > repos > blastem
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 { |