Mercurial > repos > blastem
comparison m68k_to_x86.c @ 81:6d231dbe75ab
Add support for indexed modes as a source, some work on jmp and jsr with areg indirect mode
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 22 Dec 2012 21:37:25 -0800 |
parents | 463641032588 |
children | 6331ddec228f |
comparison
equal
deleted
inserted
replaced
80:7b1e16e981ef | 81:6d231dbe75ab |
---|---|
77 } | 77 } |
78 | 78 |
79 uint8_t * translate_m68k_src(m68kinst * inst, x86_ea * ea, uint8_t * out, x86_68k_options * opts) | 79 uint8_t * translate_m68k_src(m68kinst * inst, x86_ea * ea, uint8_t * out, x86_68k_options * opts) |
80 { | 80 { |
81 int8_t reg = native_reg(&(inst->src), opts); | 81 int8_t reg = native_reg(&(inst->src), opts); |
82 uint8_t sec_reg; | |
82 int32_t dec_amount,inc_amount; | 83 int32_t dec_amount,inc_amount; |
83 if (reg >= 0) { | 84 if (reg >= 0) { |
84 ea->mode = MODE_REG_DIRECT; | 85 ea->mode = MODE_REG_DIRECT; |
85 ea->base = reg; | 86 ea->base = reg; |
86 return out; | 87 return out; |
164 break; | 165 break; |
165 } | 166 } |
166 ea->mode = MODE_REG_DIRECT; | 167 ea->mode = MODE_REG_DIRECT; |
167 ea->base = SCRATCH1; | 168 ea->base = SCRATCH1; |
168 break; | 169 break; |
170 case MODE_AREG_INDEX_DISP8: | |
171 out = cycles(out, 6); | |
172 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | |
173 out = mov_rr(out, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); | |
174 } else { | |
175 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); | |
176 } | |
177 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; | |
178 if (inst->src.params.regs.sec & 1) { | |
179 if (inst->src.params.regs.sec & 0x10) { | |
180 if (opts->aregs[sec_reg] >= 0) { | |
181 out = add_rr(out, opts->aregs[sec_reg], SCRATCH1, SZ_D); | |
182 } else { | |
183 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
184 } | |
185 } else { | |
186 if (opts->dregs[sec_reg] >= 0) { | |
187 out = add_rr(out, opts->dregs[sec_reg], SCRATCH1, SZ_D); | |
188 } else { | |
189 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
190 } | |
191 } | |
192 } else { | |
193 if (inst->src.params.regs.sec & 0x10) { | |
194 if (opts->aregs[sec_reg] >= 0) { | |
195 out = movsx_rr(out, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
196 } else { | |
197 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
198 } | |
199 } else { | |
200 if (opts->dregs[sec_reg] >= 0) { | |
201 out = movsx_rr(out, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
202 } else { | |
203 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
204 } | |
205 } | |
206 out = add_rr(out, SCRATCH2, SCRATCH1, SZ_D); | |
207 } | |
208 if (inst->src.params.regs.displacement) { | |
209 out = add_ir(out, inst->src.params.regs.displacement, SCRATCH1, SZ_D); | |
210 } | |
211 break; | |
169 case MODE_PC_DISPLACE: | 212 case MODE_PC_DISPLACE: |
170 out = cycles(out, BUS); | 213 out = cycles(out, BUS); |
171 out = mov_ir(out, inst->src.params.regs.displacement + inst->address+2, SCRATCH1, SZ_D); | 214 out = mov_ir(out, inst->src.params.regs.displacement + inst->address+2, SCRATCH1, SZ_D); |
172 switch (inst->extra.size) | 215 switch (inst->extra.size) |
173 { | 216 { |
181 out = call(out, (char *)m68k_read_long_scratch1); | 224 out = call(out, (char *)m68k_read_long_scratch1); |
182 break; | 225 break; |
183 } | 226 } |
184 ea->mode = MODE_REG_DIRECT; | 227 ea->mode = MODE_REG_DIRECT; |
185 ea->base = SCRATCH1; | 228 ea->base = SCRATCH1; |
229 break; | |
230 case MODE_PC_INDEX_DISP8: | |
231 out = cycles(out, 6); | |
232 out = mov_ir(out, inst->address, SCRATCH1, SZ_D); | |
233 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; | |
234 if (inst->src.params.regs.sec & 1) { | |
235 if (inst->src.params.regs.sec & 0x10) { | |
236 if (opts->aregs[sec_reg] >= 0) { | |
237 out = add_rr(out, opts->aregs[sec_reg], SCRATCH1, SZ_D); | |
238 } else { | |
239 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
240 } | |
241 } else { | |
242 if (opts->dregs[sec_reg] >= 0) { | |
243 out = add_rr(out, opts->dregs[sec_reg], SCRATCH1, SZ_D); | |
244 } else { | |
245 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
246 } | |
247 } | |
248 } else { | |
249 if (inst->src.params.regs.sec & 0x10) { | |
250 if (opts->aregs[sec_reg] >= 0) { | |
251 out = movsx_rr(out, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
252 } else { | |
253 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
254 } | |
255 } else { | |
256 if (opts->dregs[sec_reg] >= 0) { | |
257 out = movsx_rr(out, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
258 } else { | |
259 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
260 } | |
261 } | |
262 out = add_rr(out, SCRATCH2, SCRATCH1, SZ_D); | |
263 } | |
264 if (inst->src.params.regs.displacement) { | |
265 out = add_ir(out, inst->src.params.regs.displacement, SCRATCH1, SZ_D); | |
266 } | |
186 break; | 267 break; |
187 case MODE_ABSOLUTE: | 268 case MODE_ABSOLUTE: |
188 case MODE_ABSOLUTE_SHORT: | 269 case MODE_ABSOLUTE_SHORT: |
189 if (inst->src.addr_mode == MODE_ABSOLUTE) { | 270 if (inst->src.addr_mode == MODE_ABSOLUTE) { |
190 out = cycles(out, BUS*2); | 271 out = cycles(out, BUS*2); |
1005 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); | 1086 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); |
1006 } else { | 1087 } else { |
1007 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); | 1088 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); |
1008 } | 1089 } |
1009 dst = call(dst, (uint8_t *)m68k_native_addr); | 1090 dst = call(dst, (uint8_t *)m68k_native_addr); |
1010 //TODO: Finish me | 1091 dst = jmp_r(dst, SCRATCH1); |
1011 printf("address mode %d not yet supported (jmp)\n", inst->src.addr_mode); | |
1012 break; | 1092 break; |
1013 case MODE_PC_DISPLACE: | 1093 case MODE_PC_DISPLACE: |
1014 dst = cycles(dst, 10); | 1094 dst = cycles(dst, 10); |
1015 dest_addr = get_native_address(opts->native_code_map, inst->src.params.regs.displacement + inst->address + 2); | 1095 dest_addr = get_native_address(opts->native_code_map, inst->src.params.regs.displacement + inst->address + 2); |
1016 if (!dest_addr) { | 1096 if (!dest_addr) { |
1043 uint32_t after; | 1123 uint32_t after; |
1044 switch(inst->src.addr_mode) | 1124 switch(inst->src.addr_mode) |
1045 { | 1125 { |
1046 case MODE_AREG_INDIRECT: | 1126 case MODE_AREG_INDIRECT: |
1047 dst = cycles(dst, BUS*2); | 1127 dst = cycles(dst, BUS*2); |
1128 dst = mov_ir(dst, inst->address + 8, SCRATCH1, SZ_D); | |
1129 dst = push_r(dst, SCRATCH1); | |
1130 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); | |
1131 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); | |
1132 dst = call(dst, (char *)m68k_write_long_highfirst); | |
1048 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | 1133 if (opts->aregs[inst->src.params.regs.pri] >= 0) { |
1049 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); | 1134 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); |
1050 } else { | 1135 } else { |
1051 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); | 1136 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); |
1052 } | 1137 } |
1053 dst = call(dst, (uint8_t *)m68k_native_addr); | 1138 dst = call(dst, (uint8_t *)m68k_native_addr); |
1054 //TODO: Finish me | 1139 dst = call_r(dst, SCRATCH1); |
1055 printf("address mode %d not yet supported (jsr)\n", inst->src.addr_mode); | 1140 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? |
1141 dst = pop_r(dst, SCRATCH1); | |
1056 break; | 1142 break; |
1057 case MODE_PC_DISPLACE: | 1143 case MODE_PC_DISPLACE: |
1058 //TODO: Add cycles in the right place relative to pushing the return address on the stack | 1144 //TODO: Add cycles in the right place relative to pushing the return address on the stack |
1059 dst = cycles(dst, 10); | 1145 dst = cycles(dst, 10); |
1060 dst = mov_ir(dst, inst->address + 8, SCRATCH1, SZ_D); | 1146 dst = mov_ir(dst, inst->address + 8, SCRATCH1, SZ_D); |