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);