comparison m68k_core_x86.c @ 686:8cb61671777b

Fix indentation that presumably got messed up in a merge
author Michael Pavone <pavone@retrodev.com>
date Thu, 08 Jan 2015 09:36:54 -0800
parents 7ed1dbb48f61
children a61d33ccea7d
comparison
equal deleted inserted replaced
685:943b9323bf60 686:8cb61671777b
214 214
215 void dreg_to_native_sx(m68k_options *opts, uint8_t reg, uint8_t native_reg) 215 void dreg_to_native_sx(m68k_options *opts, uint8_t reg, uint8_t native_reg)
216 { 216 {
217 if (opts->dregs[reg] >= 0) { 217 if (opts->dregs[reg] >= 0) {
218 movsx_rr(&opts->gen.code, opts->dregs[reg], native_reg, SZ_W, SZ_D); 218 movsx_rr(&opts->gen.code, opts->dregs[reg], native_reg, SZ_W, SZ_D);
219 } else { 219 } else {
220 movsx_rdispr(&opts->gen.code, opts->gen.context_reg, dreg_offset(reg), native_reg, SZ_W, SZ_D); 220 movsx_rdispr(&opts->gen.code, opts->gen.context_reg, dreg_offset(reg), native_reg, SZ_W, SZ_D);
221 } 221 }
222 } 222 }
223 223
224 void native_to_areg(m68k_options *opts, uint8_t native_reg, uint8_t reg) 224 void native_to_areg(m68k_options *opts, uint8_t native_reg, uint8_t reg)
225 { 225 {
226 if (opts->aregs[reg] >= 0) { 226 if (opts->aregs[reg] >= 0) {
227 mov_rr(&opts->gen.code, native_reg, opts->aregs[reg], SZ_D); 227 mov_rr(&opts->gen.code, native_reg, opts->aregs[reg], SZ_D);
228 } else { 228 } else {
229 mov_rrdisp(&opts->gen.code, native_reg, opts->gen.context_reg, areg_offset(reg), SZ_D); 229 mov_rrdisp(&opts->gen.code, native_reg, opts->gen.context_reg, areg_offset(reg), SZ_D);
230 } 230 }
231 } 231 }
232 232
233 void native_to_dreg(m68k_options *opts, uint8_t native_reg, uint8_t reg) 233 void native_to_dreg(m68k_options *opts, uint8_t native_reg, uint8_t reg)
234 { 234 {
235 if (opts->dregs[reg] >= 0) { 235 if (opts->dregs[reg] >= 0) {
236 mov_rr(&opts->gen.code, native_reg, opts->dregs[reg], SZ_D); 236 mov_rr(&opts->gen.code, native_reg, opts->dregs[reg], SZ_D);
237 } else { 237 } else {
238 mov_rrdisp(&opts->gen.code, native_reg, opts->gen.context_reg, dreg_offset(reg), SZ_D); 238 mov_rrdisp(&opts->gen.code, native_reg, opts->gen.context_reg, dreg_offset(reg), SZ_D);
239 } 239 }
240 } 240 }
241 241
242 void ldi_areg(m68k_options *opts, int32_t value, uint8_t reg) 242 void ldi_areg(m68k_options *opts, int32_t value, uint8_t reg)
243 { 243 {
244 if (opts->aregs[reg] >= 0) { 244 if (opts->aregs[reg] >= 0) {
245 mov_ir(&opts->gen.code, value, opts->aregs[reg], SZ_D); 245 mov_ir(&opts->gen.code, value, opts->aregs[reg], SZ_D);
246 } else { 246 } else {
247 mov_irdisp(&opts->gen.code, value, opts->gen.context_reg, areg_offset(reg), SZ_D); 247 mov_irdisp(&opts->gen.code, value, opts->gen.context_reg, areg_offset(reg), SZ_D);
248 } 248 }
249 } 249 }
250 250
251 void ldi_native(m68k_options *opts, int32_t value, uint8_t reg) 251 void ldi_native(m68k_options *opts, int32_t value, uint8_t reg)
252 { 252 {
253 mov_ir(&opts->gen.code, value, reg, SZ_D); 253 mov_ir(&opts->gen.code, value, reg, SZ_D);
254 } 254 }
255 255
256 void addi_native(m68k_options *opts, int32_t value, uint8_t reg) 256 void addi_native(m68k_options *opts, int32_t value, uint8_t reg)
257 { 257 {
258 add_ir(&opts->gen.code, value, reg, SZ_D); 258 add_ir(&opts->gen.code, value, reg, SZ_D);
259 } 259 }
260 260
261 void subi_native(m68k_options *opts, int32_t value, uint8_t reg) 261 void subi_native(m68k_options *opts, int32_t value, uint8_t reg)
262 { 262 {
263 sub_ir(&opts->gen.code, value, reg, SZ_D); 263 sub_ir(&opts->gen.code, value, reg, SZ_D);
264 } 264 }
265 265
266 void push_native(m68k_options *opts, uint8_t reg) 266 void push_native(m68k_options *opts, uint8_t reg)
267 { 267 {
268 push_r(&opts->gen.code, reg); 268 push_r(&opts->gen.code, reg);
269 } 269 }
270 270
271 void pop_native(m68k_options *opts, uint8_t reg) 271 void pop_native(m68k_options *opts, uint8_t reg)
272 { 272 {
273 pop_r(&opts->gen.code, reg); 273 pop_r(&opts->gen.code, reg);
274 } 274 }
275 275
276 void sign_extend16_native(m68k_options *opts, uint8_t reg) 276 void sign_extend16_native(m68k_options *opts, uint8_t reg)
277 { 277 {
278 movsx_rr(&opts->gen.code, reg, reg, SZ_W, SZ_D); 278 movsx_rr(&opts->gen.code, reg, reg, SZ_W, SZ_D);
279 } 279 }
280 280
281 void addi_areg(m68k_options *opts, int32_t val, uint8_t reg) 281 void addi_areg(m68k_options *opts, int32_t val, uint8_t reg)
282 { 282 {
283 if (opts->aregs[reg] >= 0) { 283 if (opts->aregs[reg] >= 0) {
284 add_ir(&opts->gen.code, val, opts->aregs[reg], SZ_D); 284 add_ir(&opts->gen.code, val, opts->aregs[reg], SZ_D);
285 } else { 285 } else {
286 add_irdisp(&opts->gen.code, val, opts->gen.context_reg, areg_offset(reg), SZ_D); 286 add_irdisp(&opts->gen.code, val, opts->gen.context_reg, areg_offset(reg), SZ_D);
287 } 287 }
288 } 288 }
289 289
290 void subi_areg(m68k_options *opts, int32_t val, uint8_t reg) 290 void subi_areg(m68k_options *opts, int32_t val, uint8_t reg)
291 { 291 {
292 if (opts->aregs[reg] >= 0) { 292 if (opts->aregs[reg] >= 0) {
293 sub_ir(&opts->gen.code, val, opts->aregs[reg], SZ_D); 293 sub_ir(&opts->gen.code, val, opts->aregs[reg], SZ_D);
294 } else { 294 } else {
295 sub_irdisp(&opts->gen.code, val, opts->gen.context_reg, areg_offset(reg), SZ_D); 295 sub_irdisp(&opts->gen.code, val, opts->gen.context_reg, areg_offset(reg), SZ_D);
296 } 296 }
297 } 297 }
298 298
299 void add_areg_native(m68k_options *opts, uint8_t reg, uint8_t native_reg) 299 void add_areg_native(m68k_options *opts, uint8_t reg, uint8_t native_reg)
300 { 300 {
301 if (opts->aregs[reg] >= 0) { 301 if (opts->aregs[reg] >= 0) {
302 add_rr(&opts->gen.code, opts->aregs[reg], native_reg, SZ_D); 302 add_rr(&opts->gen.code, opts->aregs[reg], native_reg, SZ_D);
303 } else { 303 } else {
304 add_rdispr(&opts->gen.code, opts->gen.context_reg, areg_offset(reg), native_reg, SZ_D); 304 add_rdispr(&opts->gen.code, opts->gen.context_reg, areg_offset(reg), native_reg, SZ_D);
305 } 305 }
306 } 306 }
307 307
308 void add_dreg_native(m68k_options *opts, uint8_t reg, uint8_t native_reg) 308 void add_dreg_native(m68k_options *opts, uint8_t reg, uint8_t native_reg)
309 { 309 {
310 if (opts->dregs[reg] >= 0) { 310 if (opts->dregs[reg] >= 0) {
311 add_rr(&opts->gen.code, opts->dregs[reg], native_reg, SZ_D); 311 add_rr(&opts->gen.code, opts->dregs[reg], native_reg, SZ_D);
312 } else { 312 } else {
313 add_rdispr(&opts->gen.code, opts->gen.context_reg, dreg_offset(reg), native_reg, SZ_D); 313 add_rdispr(&opts->gen.code, opts->gen.context_reg, dreg_offset(reg), native_reg, SZ_D);
314 } 314 }
315 } 315 }
316 316
317 void calc_areg_displace(m68k_options *opts, m68k_op_info *op, uint8_t native_reg) 317 void calc_areg_displace(m68k_options *opts, m68k_op_info *op, uint8_t native_reg)
318 { 318 {
319 areg_to_native(opts, op->params.regs.pri, native_reg); 319 areg_to_native(opts, op->params.regs.pri, native_reg);
320 add_ir(&opts->gen.code, op->params.regs.displacement, native_reg, SZ_D); 320 add_ir(&opts->gen.code, op->params.regs.displacement, native_reg, SZ_D);
321 } 321 }
322 322
323 void calc_index_disp8(m68k_options *opts, m68k_op_info *op, uint8_t native_reg) 323 void calc_index_disp8(m68k_options *opts, m68k_op_info *op, uint8_t native_reg)
324 { 324 {
325 uint8_t sec_reg = (op->params.regs.sec >> 1) & 0x7; 325 uint8_t sec_reg = (op->params.regs.sec >> 1) & 0x7;
326 if (op->params.regs.sec & 1) { 326 if (op->params.regs.sec & 1) {
327 if (op->params.regs.sec & 0x10) { 327 if (op->params.regs.sec & 0x10) {
328 add_areg_native(opts, sec_reg, native_reg); 328 add_areg_native(opts, sec_reg, native_reg);
329 } else { 329 } else {
330 add_dreg_native(opts, sec_reg, native_reg); 330 add_dreg_native(opts, sec_reg, native_reg);
331 } 331 }
332 } else { 332 } else {
333 uint8_t other_reg = native_reg == opts->gen.scratch1 ? opts->gen.scratch2 : opts->gen.scratch1; 333 uint8_t other_reg = native_reg == opts->gen.scratch1 ? opts->gen.scratch2 : opts->gen.scratch1;
334 if (op->params.regs.sec & 0x10) { 334 if (op->params.regs.sec & 0x10) {
335 areg_to_native_sx(opts, sec_reg, other_reg); 335 areg_to_native_sx(opts, sec_reg, other_reg);
336 } else { 336 } else {
337 dreg_to_native_sx(opts, sec_reg, other_reg); 337 dreg_to_native_sx(opts, sec_reg, other_reg);
338 } 338 }
339 add_rr(&opts->gen.code, other_reg, native_reg, SZ_D); 339 add_rr(&opts->gen.code, other_reg, native_reg, SZ_D);
340 } 340 }
341 if (op->params.regs.displacement) { 341 if (op->params.regs.displacement) {
342 add_ir(&opts->gen.code, op->params.regs.displacement, native_reg, SZ_D); 342 add_ir(&opts->gen.code, op->params.regs.displacement, native_reg, SZ_D);
343 } 343 }
344 } 344 }
345 345
346 void calc_areg_index_disp8(m68k_options *opts, m68k_op_info *op, uint8_t native_reg) 346 void calc_areg_index_disp8(m68k_options *opts, m68k_op_info *op, uint8_t native_reg)
347 { 347 {
348 areg_to_native(opts, op->params.regs.pri, native_reg); 348 areg_to_native(opts, op->params.regs.pri, native_reg);
349 calc_index_disp8(opts, op, native_reg); 349 calc_index_disp8(opts, op, native_reg);
350 } 350 }
351 351
352 void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8_t dst) 352 void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8_t dst)
360 ea->mode = MODE_REG_DIRECT; 360 ea->mode = MODE_REG_DIRECT;
361 if (!dst && inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) { 361 if (!dst && inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) {
362 movsx_rr(code, reg, opts->gen.scratch1, SZ_W, SZ_D); 362 movsx_rr(code, reg, opts->gen.scratch1, SZ_W, SZ_D);
363 ea->base = opts->gen.scratch1; 363 ea->base = opts->gen.scratch1;
364 } else { 364 } else {
365 ea->base = reg; 365 ea->base = reg;
366 } 366 }
367 return; 367 return;
368 } 368 }
369 switch (op->addr_mode) 369 switch (op->addr_mode)
370 { 370 {
371 case MODE_REG: 371 case MODE_REG:
373 //We only get one memory parameter, so if the dst operand is a register in memory, 373 //We only get one memory parameter, so if the dst operand is a register in memory,
374 //we need to copy this to a temp register first if we're translating the src operand 374 //we need to copy this to a temp register first if we're translating the src operand
375 if (dst || native_reg(&(inst->dst), opts) >= 0 || inst->dst.addr_mode == MODE_UNUSED || !(inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG) 375 if (dst || native_reg(&(inst->dst), opts) >= 0 || inst->dst.addr_mode == MODE_UNUSED || !(inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG)
376 || inst->op == M68K_EXG) { 376 || inst->op == M68K_EXG) {
377 377
378 ea->mode = MODE_REG_DISPLACE8; 378 ea->mode = MODE_REG_DISPLACE8;
379 ea->base = opts->gen.context_reg; 379 ea->base = opts->gen.context_reg;
380 ea->disp = reg_offset(op); 380 ea->disp = reg_offset(op);
381 } else { 381 } else {
382 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) { 382 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) {
383 movsx_rdispr(code, opts->gen.context_reg, reg_offset(op), opts->gen.scratch1, SZ_W, SZ_D); 383 movsx_rdispr(code, opts->gen.context_reg, reg_offset(op), opts->gen.scratch1, SZ_W, SZ_D);
403 case MODE_AREG_POSTINC: 403 case MODE_AREG_POSTINC:
404 areg_to_native(opts, op->params.regs.pri, opts->gen.scratch1); 404 areg_to_native(opts, op->params.regs.pri, opts->gen.scratch1);
405 m68k_read_size(opts, inst->extra.size); 405 m68k_read_size(opts, inst->extra.size);
406 406
407 if (dst) { 407 if (dst) {
408 if (inst->src.addr_mode == MODE_AREG_PREDEC) { 408 if (inst->src.addr_mode == MODE_AREG_PREDEC) {
409 //restore src operand to opts->gen.scratch2 409 //restore src operand to opts->gen.scratch2
410 pop_r(code, opts->gen.scratch2); 410 pop_r(code, opts->gen.scratch2);
411 } else { 411 } else {
412 //save reg value in opts->gen.scratch2 so we can use it to save the result in memory later 412 //save reg value in opts->gen.scratch2 so we can use it to save the result in memory later
413 areg_to_native(opts, op->params.regs.pri, opts->gen.scratch2); 413 areg_to_native(opts, op->params.regs.pri, opts->gen.scratch2);
414 } 414 }
415 } 415 }
416 416
428 push_r(code, opts->gen.scratch1); 428 push_r(code, opts->gen.scratch1);
429 } 429 }
430 m68k_read_size(opts, inst->extra.size); 430 m68k_read_size(opts, inst->extra.size);
431 if (dst) { 431 if (dst) {
432 pop_r(code, opts->gen.scratch2); 432 pop_r(code, opts->gen.scratch2);
433 } 433 }
434 434
435 ea->mode = MODE_REG_DIRECT; 435 ea->mode = MODE_REG_DIRECT;
436 ea->base = opts->gen.scratch1; 436 ea->base = opts->gen.scratch1;
437 break; 437 break;
438 case MODE_AREG_INDEX_DISP8: 438 case MODE_AREG_INDEX_DISP8:
442 push_r(code, opts->gen.scratch1); 442 push_r(code, opts->gen.scratch1);
443 } 443 }
444 m68k_read_size(opts, inst->extra.size); 444 m68k_read_size(opts, inst->extra.size);
445 if (dst) { 445 if (dst) {
446 pop_r(code, opts->gen.scratch2); 446 pop_r(code, opts->gen.scratch2);
447 } 447 }
448 448
449 ea->mode = MODE_REG_DIRECT; 449 ea->mode = MODE_REG_DIRECT;
450 ea->base = opts->gen.scratch1; 450 ea->base = opts->gen.scratch1;
451 break; 451 break;
452 case MODE_PC_DISPLACE: 452 case MODE_PC_DISPLACE:
453 cycles(&opts->gen, BUS); 453 cycles(&opts->gen, BUS);
454 mov_ir(code, op->params.regs.displacement + inst->address+2, opts->gen.scratch1, SZ_D); 454 mov_ir(code, op->params.regs.displacement + inst->address+2, opts->gen.scratch1, SZ_D);
455 if (dst) { 455 if (dst) {
456 push_r(code, opts->gen.scratch1); 456 push_r(code, opts->gen.scratch1);
457 } 457 }
458 m68k_read_size(opts, inst->extra.size); 458 m68k_read_size(opts, inst->extra.size);
459 if (dst) { 459 if (dst) {
460 pop_r(code, opts->gen.scratch2); 460 pop_r(code, opts->gen.scratch2);
461 } 461 }
462 462
467 cycles(&opts->gen, 6); 467 cycles(&opts->gen, 6);
468 mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D); 468 mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D);
469 calc_index_disp8(opts, op, opts->gen.scratch1); 469 calc_index_disp8(opts, op, opts->gen.scratch1);
470 if (dst) { 470 if (dst) {
471 push_r(code, opts->gen.scratch1); 471 push_r(code, opts->gen.scratch1);
472 } 472 }
473 m68k_read_size(opts, inst->extra.size); 473 m68k_read_size(opts, inst->extra.size);
474 if (dst) { 474 if (dst) {
475 pop_r(code, opts->gen.scratch2); 475 pop_r(code, opts->gen.scratch2);
476 } 476 }
477 477
478 ea->mode = MODE_REG_DIRECT; 478 ea->mode = MODE_REG_DIRECT;
479 ea->base = opts->gen.scratch1; 479 ea->base = opts->gen.scratch1;
480 break; 480 break;
481 case MODE_ABSOLUTE: 481 case MODE_ABSOLUTE:
482 case MODE_ABSOLUTE_SHORT: 482 case MODE_ABSOLUTE_SHORT:
483 cycles(&opts->gen, op->addr_mode == MODE_ABSOLUTE ? BUS*2 : BUS); 483 cycles(&opts->gen, op->addr_mode == MODE_ABSOLUTE ? BUS*2 : BUS);
484 mov_ir(code, op->params.immed, opts->gen.scratch1, SZ_D); 484 mov_ir(code, op->params.immed, opts->gen.scratch1, SZ_D);
485 if (dst) { 485 if (dst) {
486 push_r(code, opts->gen.scratch1); 486 push_r(code, opts->gen.scratch1);
487 } 487 }
488 m68k_read_size(opts, inst->extra.size); 488 m68k_read_size(opts, inst->extra.size);
489 if (dst) { 489 if (dst) {
490 pop_r(code, opts->gen.scratch2); 490 pop_r(code, opts->gen.scratch2);
491 } 491 }
492 492
706 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) { 706 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) {
707 m68k_write_size(opts, inst->extra.size); 707 m68k_write_size(opts, inst->extra.size);
708 if (inst->dst.addr_mode == MODE_AREG_POSTINC) { 708 if (inst->dst.addr_mode == MODE_AREG_POSTINC) {
709 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); 709 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1));
710 addi_areg(opts, inc_amount, inst->dst.params.regs.pri); 710 addi_areg(opts, inc_amount, inst->dst.params.regs.pri);
711 } 711 }
712 } 712 }
713 713
714 //add cycles for prefetch 714 //add cycles for prefetch
715 cycles(&opts->gen, BUS); 715 cycles(&opts->gen, BUS);
716 } 716 }
717 717
756 //M68K EXT only operates on registers so no need for a call to save result here 756 //M68K EXT only operates on registers so no need for a call to save result here
757 } 757 }
758 758
759 uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc) 759 uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc)
760 { 760 {
761 uint8_t cond = CC_NZ; 761 uint8_t cond = CC_NZ;
762 switch (cc) 762 switch (cc)
763 { 763 {
764 case COND_HIGH: 764 case COND_HIGH:
765 cond = CC_Z; 765 cond = CC_Z;
766 case COND_LOW_SAME: 766 case COND_LOW_SAME:
767 flag_to_reg(opts, FLAG_Z, opts->gen.scratch1); 767 flag_to_reg(opts, FLAG_Z, opts->gen.scratch1);
768 or_flag_to_reg(opts, FLAG_C, opts->gen.scratch1); 768 or_flag_to_reg(opts, FLAG_C, opts->gen.scratch1);
769 break; 769 break;
770 case COND_CARRY_CLR: 770 case COND_CARRY_CLR:
771 cond = CC_Z; 771 cond = CC_Z;
772 case COND_CARRY_SET: 772 case COND_CARRY_SET:
773 check_flag(opts, FLAG_C); 773 check_flag(opts, FLAG_C);
774 break; 774 break;
775 case COND_NOT_EQ: 775 case COND_NOT_EQ:
776 cond = CC_Z; 776 cond = CC_Z;
777 case COND_EQ: 777 case COND_EQ:
778 check_flag(opts, FLAG_Z); 778 check_flag(opts, FLAG_Z);
779 break; 779 break;
780 case COND_OVERF_CLR: 780 case COND_OVERF_CLR:
781 cond = CC_Z; 781 cond = CC_Z;
782 case COND_OVERF_SET: 782 case COND_OVERF_SET:
783 check_flag(opts, FLAG_V); 783 check_flag(opts, FLAG_V);
784 break; 784 break;
785 case COND_PLUS: 785 case COND_PLUS:
786 cond = CC_Z; 786 cond = CC_Z;
787 case COND_MINUS: 787 case COND_MINUS:
788 check_flag(opts, FLAG_N); 788 check_flag(opts, FLAG_N);
789 break; 789 break;
790 case COND_GREATER_EQ: 790 case COND_GREATER_EQ:
791 cond = CC_Z; 791 cond = CC_Z;
792 case COND_LESS: 792 case COND_LESS:
793 cmp_flags(opts, FLAG_N, FLAG_V); 793 cmp_flags(opts, FLAG_N, FLAG_V);
794 break; 794 break;
795 case COND_GREATER: 795 case COND_GREATER:
796 cond = CC_Z; 796 cond = CC_Z;
797 case COND_LESS_EQ: 797 case COND_LESS_EQ:
798 flag_to_reg(opts, FLAG_V, opts->gen.scratch1); 798 flag_to_reg(opts, FLAG_V, opts->gen.scratch1);
799 xor_flag_to_reg(opts, FLAG_N, opts->gen.scratch1); 799 xor_flag_to_reg(opts, FLAG_N, opts->gen.scratch1);
800 or_flag_to_reg(opts, FLAG_Z, opts->gen.scratch1); 800 or_flag_to_reg(opts, FLAG_Z, opts->gen.scratch1);
801 break; 801 break;
802 } 802 }
803 return cond; 803 return cond;
804 } 804 }
805 805
806 void translate_m68k_bcc(m68k_options * opts, m68kinst * inst) 806 void translate_m68k_bcc(m68k_options * opts, m68kinst * inst)
807 { 807 {
1208 case M68K_ROR: ror_irdisp(code, val, dst, disp, size); break; 1208 case M68K_ROR: ror_irdisp(code, val, dst, disp, size); break;
1209 case M68K_ROXL: rcl_irdisp(code, val, dst, disp, size); break; 1209 case M68K_ROXL: rcl_irdisp(code, val, dst, disp, size); break;
1210 case M68K_ROXR: rcr_irdisp(code, val, dst, disp, size); break; 1210 case M68K_ROXR: rcr_irdisp(code, val, dst, disp, size); break;
1211 case M68K_SUB: sub_irdisp(code, val, dst, disp, size); break; 1211 case M68K_SUB: sub_irdisp(code, val, dst, disp, size); break;
1212 case M68K_SUBX: sbb_irdisp(code, val, dst, disp, size); break; 1212 case M68K_SUBX: sbb_irdisp(code, val, dst, disp, size); break;
1213 } 1213 }
1214 } 1214 }
1215 1215
1216 void op_rr(code_info *code, m68kinst *inst, uint8_t src, uint8_t dst, uint8_t size) 1216 void op_rr(code_info *code, m68kinst *inst, uint8_t src, uint8_t dst, uint8_t size)
1217 { 1217 {
1218 switch (inst->op) 1218 switch (inst->op)
1219 { 1219 {
1228 case M68K_EOR: xor_rr(code, src, dst, size); break; 1228 case M68K_EOR: xor_rr(code, src, dst, size); break;
1229 case M68K_OR: or_rr(code, src, dst, size); break; 1229 case M68K_OR: or_rr(code, src, dst, size); break;
1230 case M68K_SUB: sub_rr(code, src, dst, size); break; 1230 case M68K_SUB: sub_rr(code, src, dst, size); break;
1231 case M68K_SUBX: sbb_rr(code, src, dst, size); break; 1231 case M68K_SUBX: sbb_rr(code, src, dst, size); break;
1232 } 1232 }
1233 } 1233 }
1234 1234
1235 void op_rrdisp(code_info *code, m68kinst *inst, uint8_t src, uint8_t dst, int32_t disp, uint8_t size) 1235 void op_rrdisp(code_info *code, m68kinst *inst, uint8_t src, uint8_t dst, int32_t disp, uint8_t size)
1236 { 1236 {
1237 switch(inst->op) 1237 switch(inst->op)
1238 { 1238 {
1246 case M68K_CMP: cmp_rrdisp(code, src, dst, disp, size); break; 1246 case M68K_CMP: cmp_rrdisp(code, src, dst, disp, size); break;
1247 case M68K_EOR: xor_rrdisp(code, src, dst, disp, size); break; 1247 case M68K_EOR: xor_rrdisp(code, src, dst, disp, size); break;
1248 case M68K_OR: or_rrdisp(code, src, dst, disp, size); break; 1248 case M68K_OR: or_rrdisp(code, src, dst, disp, size); break;
1249 case M68K_SUB: sub_rrdisp(code, src, dst, disp, size); break; 1249 case M68K_SUB: sub_rrdisp(code, src, dst, disp, size); break;
1250 case M68K_SUBX: sbb_rrdisp(code, src, dst, disp, size); break; 1250 case M68K_SUBX: sbb_rrdisp(code, src, dst, disp, size); break;
1251 } 1251 }
1252 } 1252 }
1253 1253
1254 void op_rdispr(code_info *code, m68kinst *inst, uint8_t src, int32_t disp, uint8_t dst, uint8_t size) 1254 void op_rdispr(code_info *code, m68kinst *inst, uint8_t src, int32_t disp, uint8_t dst, uint8_t size)
1255 { 1255 {
1256 switch (inst->op) 1256 switch (inst->op)
1257 { 1257 {
1261 case M68K_CMP: cmp_rdispr(code, src, disp, dst, size); break; 1261 case M68K_CMP: cmp_rdispr(code, src, disp, dst, size); break;
1262 case M68K_EOR: xor_rdispr(code, src, disp, dst, size); break; 1262 case M68K_EOR: xor_rdispr(code, src, disp, dst, size); break;
1263 case M68K_OR: or_rdispr(code, src, disp, dst, size); break; 1263 case M68K_OR: or_rdispr(code, src, disp, dst, size); break;
1264 case M68K_SUB: sub_rdispr(code, src, disp, dst, size); break; 1264 case M68K_SUB: sub_rdispr(code, src, disp, dst, size); break;
1265 case M68K_SUBX: sbb_rdispr(code, src, disp, dst, size); break; 1265 case M68K_SUBX: sbb_rdispr(code, src, disp, dst, size); break;
1266 } 1266 }
1267 } 1267 }
1268 1268
1269 void translate_m68k_arith(m68k_options *opts, m68kinst * inst, uint32_t flag_mask, host_ea *src_op, host_ea *dst_op) 1269 void translate_m68k_arith(m68k_options *opts, m68kinst * inst, uint32_t flag_mask, host_ea *src_op, host_ea *dst_op)
1270 { 1270 {
1271 code_info *code = &opts->gen.code; 1271 code_info *code = &opts->gen.code;
1272 cycles(&opts->gen, BUS); 1272 cycles(&opts->gen, BUS);
1273 if (inst->op == M68K_ADDX || inst->op == M68K_SUBX) { 1273 if (inst->op == M68K_ADDX || inst->op == M68K_SUBX) {
1274 flag_to_carry(opts, FLAG_X); 1274 flag_to_carry(opts, FLAG_X);
1275 } 1275 }
1276 uint8_t size = inst->dst.addr_mode == MODE_AREG ? OPSIZE_LONG : inst->extra.size; 1276 uint8_t size = inst->dst.addr_mode == MODE_AREG ? OPSIZE_LONG : inst->extra.size;
1277 if (src_op->mode == MODE_REG_DIRECT) { 1277 if (src_op->mode == MODE_REG_DIRECT) {
1278 if (dst_op->mode == MODE_REG_DIRECT) { 1278 if (dst_op->mode == MODE_REG_DIRECT) {
1279 op_rr(code, inst, src_op->base, dst_op->base, size); 1279 op_rr(code, inst, src_op->base, dst_op->base, size);
1280 } else { 1280 } else {
1281 op_rrdisp(code, inst, src_op->base, dst_op->base, dst_op->disp, size); 1281 op_rrdisp(code, inst, src_op->base, dst_op->base, dst_op->disp, size);
1282 } 1282 }
1283 } else if (src_op->mode == MODE_REG_DISPLACE8) { 1283 } else if (src_op->mode == MODE_REG_DISPLACE8) {
1284 op_rdispr(code, inst, src_op->base, src_op->disp, dst_op->base, size); 1284 op_rdispr(code, inst, src_op->base, src_op->disp, dst_op->base, size);
1285 } else { 1285 } else {
1286 if (dst_op->mode == MODE_REG_DIRECT) { 1286 if (dst_op->mode == MODE_REG_DIRECT) {
1287 op_ir(code, inst, src_op->disp, dst_op->base, size); 1287 op_ir(code, inst, src_op->disp, dst_op->base, size);
1288 } else { 1288 } else {
1289 op_irdisp(code, inst, src_op->disp, dst_op->base, dst_op->disp, size); 1289 op_irdisp(code, inst, src_op->disp, dst_op->base, dst_op->disp, size);
1290 } 1290 }
1291 } 1291 }
1292 if (inst->dst.addr_mode != MODE_AREG || inst->op == M68K_CMP) { 1292 if (inst->dst.addr_mode != MODE_AREG || inst->op == M68K_CMP) {
1293 update_flags(opts, flag_mask); 1293 update_flags(opts, flag_mask);
1294 if (inst->op == M68K_ADDX || inst->op == M68K_SUBX) { 1294 if (inst->op == M68K_ADDX || inst->op == M68K_SUBX) {
1295 check_alloc_code(code, 2*MAX_INST_LEN); 1295 check_alloc_code(code, 2*MAX_INST_LEN);
1296 code_ptr after_flag_set = code->cur + 1; 1296 code_ptr after_flag_set = code->cur + 1;
1297 jcc(code, CC_Z, code->cur + 2); 1297 jcc(code, CC_Z, code->cur + 2);
1298 set_flag(opts, 0, FLAG_Z); 1298 set_flag(opts, 0, FLAG_Z);
1299 *after_flag_set = code->cur - (after_flag_set+1); 1299 *after_flag_set = code->cur - (after_flag_set+1);
1300 } 1300 }
1301 } 1301 }
1302 if (inst->op != M68K_CMP) { 1302 if (inst->op != M68K_CMP) {
1303 m68k_save_result(inst, opts); 1303 m68k_save_result(inst, opts);
1304 } 1304 }
1305 } 1305 }
1306 1306
1313 if (inst->dst.addr_mode == MODE_AREG_POSTINC) { 1313 if (inst->dst.addr_mode == MODE_AREG_POSTINC) {
1314 push_r(code, opts->gen.scratch1); 1314 push_r(code, opts->gen.scratch1);
1315 translate_m68k_op(inst, &dst_op, opts, 1); 1315 translate_m68k_op(inst, &dst_op, opts, 1);
1316 pop_r(code, opts->gen.scratch2); 1316 pop_r(code, opts->gen.scratch2);
1317 src_op.base = opts->gen.scratch2; 1317 src_op.base = opts->gen.scratch2;
1318 } else { 1318 } else {
1319 translate_m68k_op(inst, &dst_op, opts, 1); 1319 translate_m68k_op(inst, &dst_op, opts, 1);
1320 if (inst->dst.addr_mode == MODE_AREG && size == OPSIZE_WORD) { 1320 if (inst->dst.addr_mode == MODE_AREG && size == OPSIZE_WORD) {
1321 size = OPSIZE_LONG; 1321 size = OPSIZE_LONG;
1322 } 1322 }
1323 } 1323 }
1324 translate_m68k_arith(opts, inst, N|Z|V|C, &src_op, &dst_op); 1324 translate_m68k_arith(opts, inst, N|Z|V|C, &src_op, &dst_op);
1325 } 1325 }
1326 1326
1327 void op_r(code_info *code, m68kinst *inst, uint8_t dst, uint8_t size) 1327 void op_r(code_info *code, m68kinst *inst, uint8_t dst, uint8_t size)
1358 { 1358 {
1359 code_info *code = &opts->gen.code; 1359 code_info *code = &opts->gen.code;
1360 cycles(&opts->gen, BUS); 1360 cycles(&opts->gen, BUS);
1361 if (dst_op->mode == MODE_REG_DIRECT) { 1361 if (dst_op->mode == MODE_REG_DIRECT) {
1362 op_r(code, inst, dst_op->base, inst->extra.size); 1362 op_r(code, inst, dst_op->base, inst->extra.size);
1363 } else { 1363 } else {
1364 op_rdisp(code, inst, dst_op->base, dst_op->disp, inst->extra.size); 1364 op_rdisp(code, inst, dst_op->base, dst_op->disp, inst->extra.size);
1365 } 1365 }
1366 update_flags(opts, flag_mask); 1366 update_flags(opts, flag_mask);
1367 m68k_save_result(inst, opts); 1367 m68k_save_result(inst, opts);
1368 } 1368 }
1369 1369
1370 void translate_m68k_invalid(m68k_options *opts, m68kinst *inst) 1370 void translate_m68k_invalid(m68k_options *opts, m68kinst *inst)
1371 { 1371 {
1372 code_info *code = &opts->gen.code; 1372 code_info *code = &opts->gen.code;
1373 if (inst->src.params.immed == 0x7100) { 1373 if (inst->src.params.immed == 0x7100) {
1389 } 1389 }
1390 } 1390 }
1391 if (dst_op->base != opts->gen.scratch1) { 1391 if (dst_op->base != opts->gen.scratch1) {
1392 if (dst_op->mode == MODE_REG_DIRECT) { 1392 if (dst_op->mode == MODE_REG_DIRECT) {
1393 mov_rr(code, dst_op->base, opts->gen.scratch1, SZ_B); 1393 mov_rr(code, dst_op->base, opts->gen.scratch1, SZ_B);
1394 } else { 1394 } else {
1395 mov_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch1, SZ_B); 1395 mov_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch1, SZ_B);
1396 } 1396 }
1397 } 1397 }
1398 uint8_t other_reg; 1398 uint8_t other_reg;
1399 //WARNING: This may need adjustment if register assignments change 1399 //WARNING: This may need adjustment if register assignments change
1400 if (opts->gen.scratch2 > RBX) { 1400 if (opts->gen.scratch2 > RBX) {
1401 other_reg = RAX; 1401 other_reg = RAX;
1402 xchg_rr(code, opts->gen.scratch2, RAX, SZ_D); 1402 xchg_rr(code, opts->gen.scratch2, RAX, SZ_D);
1403 } else { 1403 } else {
1404 other_reg = opts->gen.scratch2; 1404 other_reg = opts->gen.scratch2;
1405 } 1405 }
1406 mov_rr(code, opts->gen.scratch1, opts->gen.scratch1 + (AH-RAX), SZ_B); 1406 mov_rr(code, opts->gen.scratch1, opts->gen.scratch1 + (AH-RAX), SZ_B);
1407 mov_rr(code, other_reg, other_reg + (AH-RAX), SZ_B); 1407 mov_rr(code, other_reg, other_reg + (AH-RAX), SZ_B);
1408 and_ir(code, 0xF0, opts->gen.scratch1, SZ_B); 1408 and_ir(code, 0xF0, opts->gen.scratch1, SZ_B);
1411 and_ir(code, 0xF, other_reg + (AH-RAX), SZ_B); 1411 and_ir(code, 0xF, other_reg + (AH-RAX), SZ_B);
1412 //do op on low nibble 1412 //do op on low nibble
1413 flag_to_carry(opts, FLAG_X); 1413 flag_to_carry(opts, FLAG_X);
1414 if (inst->op == M68K_ABCD) { 1414 if (inst->op == M68K_ABCD) {
1415 adc_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B); 1415 adc_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B);
1416 } else { 1416 } else {
1417 sbb_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B); 1417 sbb_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B);
1418 } 1418 }
1419 cmp_ir(code, 0xA, opts->gen.scratch1 + (AH-RAX), SZ_B); 1419 cmp_ir(code, 0xA, opts->gen.scratch1 + (AH-RAX), SZ_B);
1420 code_ptr no_adjust = code->cur+1; 1420 code_ptr no_adjust = code->cur+1;
1421 //add correction factor if necessary 1421 //add correction factor if necessary
1422 jcc(code, CC_B, no_adjust); 1422 jcc(code, CC_B, no_adjust);
1423 if (inst->op == M68K_ABCD) { 1423 if (inst->op == M68K_ABCD) {
1424 add_ir(code, 6, opts->gen.scratch1 + (AH-RAX), SZ_B); 1424 add_ir(code, 6, opts->gen.scratch1 + (AH-RAX), SZ_B);
1425 } else { 1425 } else {
1426 sub_ir(code, 6, opts->gen.scratch1 + (AH-RAX), SZ_B); 1426 sub_ir(code, 6, opts->gen.scratch1 + (AH-RAX), SZ_B);
1427 } 1427 }
1428 *no_adjust = code->cur - (no_adjust+1); 1428 *no_adjust = code->cur - (no_adjust+1);
1429 //add low nibble result to one of the high nibble operands 1429 //add low nibble result to one of the high nibble operands
1430 add_rr(code, opts->gen.scratch1 + (AH-RAX), opts->gen.scratch1, SZ_B); 1430 add_rr(code, opts->gen.scratch1 + (AH-RAX), opts->gen.scratch1, SZ_B);
1431 if (inst->op == M68K_ABCD) { 1431 if (inst->op == M68K_ABCD) {
1432 add_rr(code, other_reg, opts->gen.scratch1, SZ_B); 1432 add_rr(code, other_reg, opts->gen.scratch1, SZ_B);
1433 } else { 1433 } else {
1434 sub_rr(code, other_reg, opts->gen.scratch1, SZ_B); 1434 sub_rr(code, other_reg, opts->gen.scratch1, SZ_B);
1435 } 1435 }
1436 if (opts->gen.scratch2 > RBX) { 1436 if (opts->gen.scratch2 > RBX) {
1437 mov_rr(code, opts->gen.scratch2, RAX, SZ_D); 1437 mov_rr(code, opts->gen.scratch2, RAX, SZ_D);
1438 } 1438 }
1439 set_flag(opts, 0, FLAG_C); 1439 set_flag(opts, 0, FLAG_C);
1440 set_flag(opts, 0, FLAG_V); 1440 set_flag(opts, 0, FLAG_V);
1441 code_ptr def_adjust = code->cur+1; 1441 code_ptr def_adjust = code->cur+1;
1442 jcc(code, CC_C, def_adjust); 1442 jcc(code, CC_C, def_adjust);
1443 cmp_ir(code, 0xA0, opts->gen.scratch1, SZ_B); 1443 cmp_ir(code, 0xA0, opts->gen.scratch1, SZ_B);
1447 set_flag(opts, 1, FLAG_C); 1447 set_flag(opts, 1, FLAG_C);
1448 if (inst->op == M68K_ABCD) { 1448 if (inst->op == M68K_ABCD) {
1449 add_ir(code, 0x60, opts->gen.scratch1, SZ_B); 1449 add_ir(code, 0x60, opts->gen.scratch1, SZ_B);
1450 } else { 1450 } else {
1451 sub_ir(code, 0x60, opts->gen.scratch1, SZ_B); 1451 sub_ir(code, 0x60, opts->gen.scratch1, SZ_B);
1452 } 1452 }
1453 //V flag is set based on the result of the addition of the 1453 //V flag is set based on the result of the addition of the
1454 //result and the correction factor 1454 //result and the correction factor
1455 set_flag_cond(opts, CC_O, FLAG_V); 1455 set_flag_cond(opts, CC_O, FLAG_V);
1456 *no_adjust = code->cur - (no_adjust+1); 1456 *no_adjust = code->cur - (no_adjust+1);
1457 flag_to_flag(opts, FLAG_C, FLAG_X); 1457 flag_to_flag(opts, FLAG_C, FLAG_X);
1464 if (dst_op->mode == MODE_REG_DIRECT) { 1464 if (dst_op->mode == MODE_REG_DIRECT) {
1465 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_B); 1465 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_B);
1466 } else { 1466 } else {
1467 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_B); 1467 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_B);
1468 } 1468 }
1469 } 1469 }
1470 m68k_save_result(inst, opts); 1470 m68k_save_result(inst, opts);
1471 } 1471 }
1472 1472
1473 void translate_m68k_sl(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 1473 void translate_m68k_sl(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
1474 { 1474 {
1475 translate_shift(opts, inst, src_op, dst_op, shl_ir, shl_irdisp, shl_clr, shl_clrdisp, shr_ir, shr_irdisp); 1475 translate_shift(opts, inst, src_op, dst_op, shl_ir, shl_irdisp, shl_clr, shl_clrdisp, shr_ir, shr_irdisp);
1476 } 1476 }
1477 1477
1478 void translate_m68k_asr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 1478 void translate_m68k_asr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
1479 { 1479 {
1480 translate_shift(opts, inst, src_op, dst_op, sar_ir, sar_irdisp, sar_clr, sar_clrdisp, NULL, NULL); 1480 translate_shift(opts, inst, src_op, dst_op, sar_ir, sar_irdisp, sar_clr, sar_clrdisp, NULL, NULL);
1481 } 1481 }
1482 1482
1483 void translate_m68k_lsr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 1483 void translate_m68k_lsr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
1484 { 1484 {
1485 translate_shift(opts, inst, src_op, dst_op, shr_ir, shr_irdisp, shr_clr, shr_clrdisp, shl_ir, shl_irdisp); 1485 translate_shift(opts, inst, src_op, dst_op, shr_ir, shr_irdisp, shr_clr, shr_clrdisp, shl_ir, shl_irdisp);
1486 } 1486 }
1488 void translate_m68k_bit(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 1488 void translate_m68k_bit(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
1489 { 1489 {
1490 code_info *code = &opts->gen.code; 1490 code_info *code = &opts->gen.code;
1491 cycles(&opts->gen, inst->extra.size == OPSIZE_BYTE ? 4 : ( 1491 cycles(&opts->gen, inst->extra.size == OPSIZE_BYTE ? 4 : (
1492 inst->op == M68K_BTST ? 6 : (inst->op == M68K_BCLR ? 10 : 8)) 1492 inst->op == M68K_BTST ? 6 : (inst->op == M68K_BCLR ? 10 : 8))
1493 ); 1493 );
1494 if (src_op->mode == MODE_IMMED) { 1494 if (src_op->mode == MODE_IMMED) {
1495 if (inst->extra.size == OPSIZE_BYTE) { 1495 if (inst->extra.size == OPSIZE_BYTE) {
1496 src_op->disp &= 0x7; 1496 src_op->disp &= 0x7;
1497 } 1497 }
1498 if (dst_op->mode == MODE_REG_DIRECT) { 1498 if (dst_op->mode == MODE_REG_DIRECT) {
1499 op_ir(code, inst, src_op->disp, dst_op->base, inst->extra.size); 1499 op_ir(code, inst, src_op->disp, dst_op->base, inst->extra.size);
1500 } else { 1500 } else {
1501 op_irdisp(code, inst, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size); 1501 op_irdisp(code, inst, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size);
1502 } 1502 }
1503 } else { 1503 } else {
1504 if (src_op->mode == MODE_REG_DISPLACE8 || (inst->dst.addr_mode != MODE_REG && src_op->base != opts->gen.scratch1 && src_op->base != opts->gen.scratch2)) { 1504 if (src_op->mode == MODE_REG_DISPLACE8 || (inst->dst.addr_mode != MODE_REG && src_op->base != opts->gen.scratch1 && src_op->base != opts->gen.scratch2)) {
1505 if (dst_op->base == opts->gen.scratch1) { 1505 if (dst_op->base == opts->gen.scratch1) {
1506 push_r(code, opts->gen.scratch2); 1506 push_r(code, opts->gen.scratch2);
1507 if (src_op->mode == MODE_REG_DIRECT) { 1507 if (src_op->mode == MODE_REG_DIRECT) {
1508 mov_rr(code, src_op->base, opts->gen.scratch2, SZ_B); 1508 mov_rr(code, src_op->base, opts->gen.scratch2, SZ_B);
1522 uint8_t size = inst->extra.size; 1522 uint8_t size = inst->extra.size;
1523 if (dst_op->mode == MODE_REG_DISPLACE8) { 1523 if (dst_op->mode == MODE_REG_DISPLACE8) {
1524 if (src_op->base != opts->gen.scratch1 && src_op->base != opts->gen.scratch2) { 1524 if (src_op->base != opts->gen.scratch1 && src_op->base != opts->gen.scratch2) {
1525 if (src_op->mode == MODE_REG_DIRECT) { 1525 if (src_op->mode == MODE_REG_DIRECT) {
1526 mov_rr(code, src_op->base, opts->gen.scratch1, SZ_D); 1526 mov_rr(code, src_op->base, opts->gen.scratch1, SZ_D);
1527 } else { 1527 } else {
1528 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_D); 1528 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_D);
1529 src_op->mode = MODE_REG_DIRECT; 1529 src_op->mode = MODE_REG_DIRECT;
1530 } 1530 }
1531 src_op->base = opts->gen.scratch1; 1531 src_op->base = opts->gen.scratch1;
1532 } 1532 }
1533 //b### with register destination is modulo 32 1533 //b### with register destination is modulo 32
1534 //x86 with a memory destination isn't modulo anything 1534 //x86 with a memory destination isn't modulo anything
1535 //so use an and here to force the value to be modulo 32 1535 //so use an and here to force the value to be modulo 32
1536 and_ir(code, 31, opts->gen.scratch1, SZ_D); 1536 and_ir(code, 31, opts->gen.scratch1, SZ_D);
1537 } else if(inst->dst.addr_mode != MODE_REG) { 1537 } else if(inst->dst.addr_mode != MODE_REG) {
1538 //b### with memory destination is modulo 8 1538 //b### with memory destination is modulo 8
1539 //x86-64 doesn't support 8-bit bit operations 1539 //x86-64 doesn't support 8-bit bit operations
1540 //so we fake it by forcing the bit number to be modulo 8 1540 //so we fake it by forcing the bit number to be modulo 8
1541 and_ir(code, 7, src_op->base, SZ_D); 1541 and_ir(code, 7, src_op->base, SZ_D);
1542 size = SZ_D; 1542 size = SZ_D;
1543 } 1543 }
1544 if (dst_op->mode == MODE_REG_DIRECT) { 1544 if (dst_op->mode == MODE_REG_DIRECT) {
1545 op_rr(code, inst, src_op->base, dst_op->base, size); 1545 op_rr(code, inst, src_op->base, dst_op->base, size);
1546 } else { 1546 } else {
1547 op_rrdisp(code, inst, src_op->base, dst_op->base, dst_op->disp, size); 1547 op_rrdisp(code, inst, src_op->base, dst_op->base, dst_op->disp, size);
1548 } 1548 }
1549 if (src_op->base == opts->gen.scratch2) { 1549 if (src_op->base == opts->gen.scratch2) {
1550 pop_r(code, opts->gen.scratch2); 1550 pop_r(code, opts->gen.scratch2);
1551 } 1551 }
1552 } 1552 }
1553 //x86 sets the carry flag to the value of the bit tested 1553 //x86 sets the carry flag to the value of the bit tested
1554 //68K sets the zero flag to the complement of the bit tested 1554 //68K sets the zero flag to the complement of the bit tested
1555 set_flag_cond(opts, CC_NC, FLAG_Z); 1555 set_flag_cond(opts, CC_NC, FLAG_Z);
1556 if (inst->op != M68K_BTST) { 1556 if (inst->op != M68K_BTST) {
1557 m68k_save_result(inst, opts); 1557 m68k_save_result(inst, opts);
1558 } 1558 }
1559 } 1559 }
1560 1560
1561 void translate_m68k_chk(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 1561 void translate_m68k_chk(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
1562 { 1562 {
1563 code_info *code = &opts->gen.code; 1563 code_info *code = &opts->gen.code;
1564 cycles(&opts->gen, 6); 1564 cycles(&opts->gen, 6);
1565 if (dst_op->mode == MODE_REG_DIRECT) { 1565 if (dst_op->mode == MODE_REG_DIRECT) {
1566 cmp_ir(code, 0, dst_op->base, inst->extra.size); 1566 cmp_ir(code, 0, dst_op->base, inst->extra.size);
1567 } else { 1567 } else {
1568 cmp_irdisp(code, 0, dst_op->base, dst_op->disp, inst->extra.size); 1568 cmp_irdisp(code, 0, dst_op->base, dst_op->disp, inst->extra.size);
1569 } 1569 }
1570 uint32_t isize; 1570 uint32_t isize;
1571 switch(inst->src.addr_mode) 1571 switch(inst->src.addr_mode)
1572 { 1572 {
1573 case MODE_AREG_DISPLACE: 1573 case MODE_AREG_DISPLACE:
1574 case MODE_AREG_INDEX_DISP8: 1574 case MODE_AREG_INDEX_DISP8:
1575 case MODE_ABSOLUTE_SHORT: 1575 case MODE_ABSOLUTE_SHORT:
1576 case MODE_PC_INDEX_DISP8: 1576 case MODE_PC_INDEX_DISP8:
1577 case MODE_PC_DISPLACE: 1577 case MODE_PC_DISPLACE:
1578 case MODE_IMMEDIATE: 1578 case MODE_IMMEDIATE:
1579 isize = 4; 1579 isize = 4;
1580 break; 1580 break;
1581 case MODE_ABSOLUTE: 1581 case MODE_ABSOLUTE:
1582 isize = 6; 1582 isize = 6;
1583 break; 1583 break;
1584 default: 1584 default:
1585 isize = 2; 1585 isize = 2;
1586 } 1586 }
1587 //make sure we won't start a new chunk in the middle of these branches 1587 //make sure we won't start a new chunk in the middle of these branches
1588 check_alloc_code(code, MAX_INST_LEN * 11); 1588 check_alloc_code(code, MAX_INST_LEN * 11);
1589 code_ptr passed = code->cur + 1; 1589 code_ptr passed = code->cur + 1;
1590 jcc(code, CC_GE, code->cur + 2); 1590 jcc(code, CC_GE, code->cur + 2);
1591 set_flag(opts, 1, FLAG_N); 1591 set_flag(opts, 1, FLAG_N);
1596 if (dst_op->mode == MODE_REG_DIRECT) { 1596 if (dst_op->mode == MODE_REG_DIRECT) {
1597 if (src_op->mode == MODE_REG_DIRECT) { 1597 if (src_op->mode == MODE_REG_DIRECT) {
1598 cmp_rr(code, src_op->base, dst_op->base, inst->extra.size); 1598 cmp_rr(code, src_op->base, dst_op->base, inst->extra.size);
1599 } else if(src_op->mode == MODE_REG_DISPLACE8) { 1599 } else if(src_op->mode == MODE_REG_DISPLACE8) {
1600 cmp_rdispr(code, src_op->base, src_op->disp, dst_op->base, inst->extra.size); 1600 cmp_rdispr(code, src_op->base, src_op->disp, dst_op->base, inst->extra.size);
1601 } else { 1601 } else {
1602 cmp_ir(code, src_op->disp, dst_op->base, inst->extra.size); 1602 cmp_ir(code, src_op->disp, dst_op->base, inst->extra.size);
1603 } 1603 }
1604 } else if(dst_op->mode == MODE_REG_DISPLACE8) { 1604 } else if(dst_op->mode == MODE_REG_DISPLACE8) {
1605 if (src_op->mode == MODE_REG_DIRECT) { 1605 if (src_op->mode == MODE_REG_DIRECT) {
1606 cmp_rrdisp(code, src_op->base, dst_op->base, dst_op->disp, inst->extra.size); 1606 cmp_rrdisp(code, src_op->base, dst_op->base, dst_op->disp, inst->extra.size);
1607 } else { 1607 } else {
1608 cmp_irdisp(code, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size); 1608 cmp_irdisp(code, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size);
1609 } 1609 }
1610 } 1610 }
1611 passed = code->cur + 1; 1611 passed = code->cur + 1;
1612 jcc(code, CC_LE, code->cur + 2); 1612 jcc(code, CC_LE, code->cur + 2);
1613 set_flag(opts, 0, FLAG_N); 1613 set_flag(opts, 0, FLAG_N);
1614 mov_ir(code, VECTOR_CHK, opts->gen.scratch2, SZ_D); 1614 mov_ir(code, VECTOR_CHK, opts->gen.scratch2, SZ_D);
1615 mov_ir(code, inst->address+isize, opts->gen.scratch1, SZ_D); 1615 mov_ir(code, inst->address+isize, opts->gen.scratch1, SZ_D);
1616 jmp(code, opts->trap); 1616 jmp(code, opts->trap);
1617 *passed = code->cur - (passed+1); 1617 *passed = code->cur - (passed+1);
1618 cycles(&opts->gen, 4); 1618 cycles(&opts->gen, 4);
1619 } 1619 }
1620 1620
1621 void translate_m68k_div(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 1621 void translate_m68k_div(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
1622 { 1622 {
1623 code_info *code = &opts->gen.code; 1623 code_info *code = &opts->gen.code;
1624 check_alloc_code(code, MAX_NATIVE_SIZE); 1624 check_alloc_code(code, MAX_NATIVE_SIZE);
1625 //TODO: cycle exact division 1625 //TODO: cycle exact division
1626 cycles(&opts->gen, inst->op == M68K_DIVS ? 158 : 140); 1626 cycles(&opts->gen, inst->op == M68K_DIVS ? 158 : 140);
1627 set_flag(opts, 0, FLAG_C); 1627 set_flag(opts, 0, FLAG_C);
1628 push_r(code, RDX); 1628 push_r(code, RDX);
1629 push_r(code, RAX); 1629 push_r(code, RAX);
1630 if (dst_op->mode == MODE_REG_DIRECT) { 1630 if (dst_op->mode == MODE_REG_DIRECT) {
1631 mov_rr(code, dst_op->base, RAX, SZ_D); 1631 mov_rr(code, dst_op->base, RAX, SZ_D);
1632 } else { 1632 } else {
1633 mov_rdispr(code, dst_op->base, dst_op->disp, RAX, SZ_D); 1633 mov_rdispr(code, dst_op->base, dst_op->disp, RAX, SZ_D);
1634 } 1634 }
1635 if (src_op->mode == MODE_IMMED) { 1635 if (src_op->mode == MODE_IMMED) {
1636 mov_ir(code, (src_op->disp & 0x8000) && inst->op == M68K_DIVS ? src_op->disp | 0xFFFF0000 : src_op->disp, opts->gen.scratch2, SZ_D); 1636 mov_ir(code, (src_op->disp & 0x8000) && inst->op == M68K_DIVS ? src_op->disp | 0xFFFF0000 : src_op->disp, opts->gen.scratch2, SZ_D);
1637 } else if (src_op->mode == MODE_REG_DIRECT) { 1637 } else if (src_op->mode == MODE_REG_DIRECT) {
1638 if (inst->op == M68K_DIVS) { 1638 if (inst->op == M68K_DIVS) {
1639 movsx_rr(code, src_op->base, opts->gen.scratch2, SZ_W, SZ_D); 1639 movsx_rr(code, src_op->base, opts->gen.scratch2, SZ_W, SZ_D);
1640 } else { 1640 } else {
1641 movzx_rr(code, src_op->base, opts->gen.scratch2, SZ_W, SZ_D); 1641 movzx_rr(code, src_op->base, opts->gen.scratch2, SZ_W, SZ_D);
1642 } 1642 }
1643 } else if (src_op->mode == MODE_REG_DISPLACE8) { 1643 } else if (src_op->mode == MODE_REG_DISPLACE8) {
1644 if (inst->op == M68K_DIVS) { 1644 if (inst->op == M68K_DIVS) {
1645 movsx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch2, SZ_W, SZ_D); 1645 movsx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch2, SZ_W, SZ_D);
1646 } else { 1646 } else {
1647 movzx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch2, SZ_W, SZ_D); 1647 movzx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch2, SZ_W, SZ_D);
1648 } 1648 }
1649 } 1649 }
1650 uint32_t isize = 2; 1650 uint32_t isize = 2;
1651 switch(inst->src.addr_mode) 1651 switch(inst->src.addr_mode)
1652 { 1652 {
1653 case MODE_AREG_DISPLACE: 1653 case MODE_AREG_DISPLACE:
1654 case MODE_AREG_INDEX_DISP8: 1654 case MODE_AREG_INDEX_DISP8:
1669 pop_r(code, RDX); 1669 pop_r(code, RDX);
1670 mov_ir(code, VECTOR_INT_DIV_ZERO, opts->gen.scratch2, SZ_D); 1670 mov_ir(code, VECTOR_INT_DIV_ZERO, opts->gen.scratch2, SZ_D);
1671 mov_ir(code, inst->address+isize, opts->gen.scratch1, SZ_D); 1671 mov_ir(code, inst->address+isize, opts->gen.scratch1, SZ_D);
1672 jmp(code, opts->trap); 1672 jmp(code, opts->trap);
1673 *not_zero = code->cur - (not_zero+1); 1673 *not_zero = code->cur - (not_zero+1);
1674 if (inst->op == M68K_DIVS) { 1674 if (inst->op == M68K_DIVS) {
1675 cdq(code); 1675 cdq(code);
1676 } else { 1676 } else {
1677 xor_rr(code, RDX, RDX, SZ_D); 1677 xor_rr(code, RDX, RDX, SZ_D);
1678 } 1678 }
1679 if (inst->op == M68K_DIVS) { 1679 if (inst->op == M68K_DIVS) {
1680 idiv_r(code, opts->gen.scratch2, SZ_D); 1680 idiv_r(code, opts->gen.scratch2, SZ_D);
1681 } else { 1681 } else {
1682 div_r(code, opts->gen.scratch2, SZ_D); 1682 div_r(code, opts->gen.scratch2, SZ_D);
1683 } 1683 }
1684 code_ptr skip_sec_check, norm_off; 1684 code_ptr skip_sec_check, norm_off;
1685 if (inst->op == M68K_DIVS) { 1685 if (inst->op == M68K_DIVS) {
1686 cmp_ir(code, 0x8000, RAX, SZ_D); 1686 cmp_ir(code, 0x8000, RAX, SZ_D);
1687 skip_sec_check = code->cur + 1; 1687 skip_sec_check = code->cur + 1;
1688 jcc(code, CC_GE, code->cur + 2); 1688 jcc(code, CC_GE, code->cur + 2);
1689 cmp_ir(code, -0x8000, RAX, SZ_D); 1689 cmp_ir(code, -0x8000, RAX, SZ_D);
1690 norm_off = code->cur + 1; 1690 norm_off = code->cur + 1;
1691 jcc(code, CC_L, code->cur + 2); 1691 jcc(code, CC_L, code->cur + 2);
1692 } else { 1692 } else {
1693 cmp_ir(code, 0x10000, RAX, SZ_D); 1693 cmp_ir(code, 0x10000, RAX, SZ_D);
1694 norm_off = code->cur + 1; 1694 norm_off = code->cur + 1;
1695 jcc(code, CC_NC, code->cur + 2); 1695 jcc(code, CC_NC, code->cur + 2);
1696 } 1696 }
1697 if (dst_op->mode == MODE_REG_DIRECT) { 1697 if (dst_op->mode == MODE_REG_DIRECT) {
1698 mov_rr(code, RDX, dst_op->base, SZ_W); 1698 mov_rr(code, RDX, dst_op->base, SZ_W);
1699 shl_ir(code, 16, dst_op->base, SZ_D); 1699 shl_ir(code, 16, dst_op->base, SZ_D);
1700 mov_rr(code, RAX, dst_op->base, SZ_W); 1700 mov_rr(code, RAX, dst_op->base, SZ_W);
1701 } else { 1701 } else {
1702 mov_rrdisp(code, RDX, dst_op->base, dst_op->disp, SZ_W); 1702 mov_rrdisp(code, RDX, dst_op->base, dst_op->disp, SZ_W);
1703 shl_irdisp(code, 16, dst_op->base, dst_op->disp, SZ_D); 1703 shl_irdisp(code, 16, dst_op->base, dst_op->disp, SZ_D);
1704 mov_rrdisp(code, RAX, dst_op->base, dst_op->disp, SZ_W); 1704 mov_rrdisp(code, RAX, dst_op->base, dst_op->disp, SZ_W);
1705 } 1705 }
1706 cmp_ir(code, 0, RAX, SZ_W); 1706 cmp_ir(code, 0, RAX, SZ_W);
1707 pop_r(code, RAX); 1707 pop_r(code, RAX);
1708 pop_r(code, RDX); 1708 pop_r(code, RDX);
1709 update_flags(opts, V0|Z|N); 1709 update_flags(opts, V0|Z|N);
1710 code_ptr end_off = code->cur + 1; 1710 code_ptr end_off = code->cur + 1;
1711 jmp(code, code->cur + 2); 1711 jmp(code, code->cur + 2);
1712 *norm_off = code->cur - (norm_off + 1); 1712 *norm_off = code->cur - (norm_off + 1);
1713 if (inst->op == M68K_DIVS) { 1713 if (inst->op == M68K_DIVS) {
1714 *skip_sec_check = code->cur - (skip_sec_check+1); 1714 *skip_sec_check = code->cur - (skip_sec_check+1);
1715 } 1715 }
1716 pop_r(code, RAX); 1716 pop_r(code, RAX);
1717 pop_r(code, RDX); 1717 pop_r(code, RDX);
1718 set_flag(opts, 1, FLAG_V); 1718 set_flag(opts, 1, FLAG_V);
1719 *end_off = code->cur - (end_off + 1); 1719 *end_off = code->cur - (end_off + 1);
1720 } 1720 }
1721 1721
1722 void translate_m68k_exg(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 1722 void translate_m68k_exg(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
1723 { 1723 {
1724 code_info *code = &opts->gen.code; 1724 code_info *code = &opts->gen.code;
1725 cycles(&opts->gen, 6); 1725 cycles(&opts->gen, 6);
1726 if (dst_op->mode == MODE_REG_DIRECT) { 1726 if (dst_op->mode == MODE_REG_DIRECT) {
1727 mov_rr(code, dst_op->base, opts->gen.scratch2, SZ_D); 1727 mov_rr(code, dst_op->base, opts->gen.scratch2, SZ_D);
1728 if (src_op->mode == MODE_REG_DIRECT) { 1728 if (src_op->mode == MODE_REG_DIRECT) {
1729 mov_rr(code, src_op->base, dst_op->base, SZ_D); 1729 mov_rr(code, src_op->base, dst_op->base, SZ_D);
1730 mov_rr(code, opts->gen.scratch2, src_op->base, SZ_D); 1730 mov_rr(code, opts->gen.scratch2, src_op->base, SZ_D);
1731 } else { 1731 } else {
1732 mov_rdispr(code, src_op->base, src_op->disp, dst_op->base, SZ_D); 1732 mov_rdispr(code, src_op->base, src_op->disp, dst_op->base, SZ_D);
1733 mov_rrdisp(code, opts->gen.scratch2, src_op->base, src_op->disp, SZ_D); 1733 mov_rrdisp(code, opts->gen.scratch2, src_op->base, src_op->disp, SZ_D);
1734 } 1734 }
1735 } else { 1735 } else {
1736 mov_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch2, SZ_D); 1736 mov_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch2, SZ_D);
1737 if (src_op->mode == MODE_REG_DIRECT) { 1737 if (src_op->mode == MODE_REG_DIRECT) {
1738 mov_rrdisp(code, src_op->base, dst_op->base, dst_op->disp, SZ_D); 1738 mov_rrdisp(code, src_op->base, dst_op->base, dst_op->disp, SZ_D);
1739 mov_rr(code, opts->gen.scratch2, src_op->base, SZ_D); 1739 mov_rr(code, opts->gen.scratch2, src_op->base, SZ_D);
1740 } else { 1740 } else {
1741 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_D); 1741 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_D);
1742 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_D); 1742 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_D);
1743 mov_rrdisp(code, opts->gen.scratch2, src_op->base, src_op->disp, SZ_D); 1743 mov_rrdisp(code, opts->gen.scratch2, src_op->base, src_op->disp, SZ_D);
1744 } 1744 }
1745 } 1745 }
1746 } 1746 }
1747 1747
1748 void translate_m68k_mul(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 1748 void translate_m68k_mul(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
1749 { 1749 {
1750 code_info *code = &opts->gen.code; 1750 code_info *code = &opts->gen.code;
1751 cycles(&opts->gen, 70); //TODO: Calculate the actual value based on the value of the <ea> parameter 1751 cycles(&opts->gen, 70); //TODO: Calculate the actual value based on the value of the <ea> parameter
1752 if (src_op->mode == MODE_IMMED) { 1752 if (src_op->mode == MODE_IMMED) {
1753 mov_ir(code, inst->op == M68K_MULU ? (src_op->disp & 0xFFFF) : ((src_op->disp & 0x8000) ? src_op->disp | 0xFFFF0000 : src_op->disp), opts->gen.scratch1, SZ_D); 1753 mov_ir(code, inst->op == M68K_MULU ? (src_op->disp & 0xFFFF) : ((src_op->disp & 0x8000) ? src_op->disp | 0xFFFF0000 : src_op->disp), opts->gen.scratch1, SZ_D);
1754 } else if (src_op->mode == MODE_REG_DIRECT) { 1754 } else if (src_op->mode == MODE_REG_DIRECT) {
1755 if (inst->op == M68K_MULS) { 1755 if (inst->op == M68K_MULS) {
1756 movsx_rr(code, src_op->base, opts->gen.scratch1, SZ_W, SZ_D); 1756 movsx_rr(code, src_op->base, opts->gen.scratch1, SZ_W, SZ_D);
1757 } else { 1757 } else {
1758 movzx_rr(code, src_op->base, opts->gen.scratch1, SZ_W, SZ_D); 1758 movzx_rr(code, src_op->base, opts->gen.scratch1, SZ_W, SZ_D);
1759 } 1759 }
1760 } else { 1760 } else {
1761 if (inst->op == M68K_MULS) { 1761 if (inst->op == M68K_MULS) {
1762 movsx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_W, SZ_D); 1762 movsx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_W, SZ_D);
1763 } else { 1763 } else {
1764 movzx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_W, SZ_D); 1764 movzx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_W, SZ_D);
1765 } 1765 }
1766 } 1766 }
1767 uint8_t dst_reg; 1767 uint8_t dst_reg;
1768 if (dst_op->mode == MODE_REG_DIRECT) { 1768 if (dst_op->mode == MODE_REG_DIRECT) {
1769 dst_reg = dst_op->base; 1769 dst_reg = dst_op->base;
1770 if (inst->op == M68K_MULS) { 1770 if (inst->op == M68K_MULS) {
1771 movsx_rr(code, dst_reg, dst_reg, SZ_W, SZ_D); 1771 movsx_rr(code, dst_reg, dst_reg, SZ_W, SZ_D);
1772 } else { 1772 } else {
1773 movzx_rr(code, dst_reg, dst_reg, SZ_W, SZ_D); 1773 movzx_rr(code, dst_reg, dst_reg, SZ_W, SZ_D);
1774 } 1774 }
1775 } else { 1775 } else {
1776 dst_reg = opts->gen.scratch2; 1776 dst_reg = opts->gen.scratch2;
1777 if (inst->op == M68K_MULS) { 1777 if (inst->op == M68K_MULS) {
1778 movsx_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch2, SZ_W, SZ_D); 1778 movsx_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch2, SZ_W, SZ_D);
1779 } else { 1779 } else {
1780 movzx_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch2, SZ_W, SZ_D); 1780 movzx_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch2, SZ_W, SZ_D);
1781 } 1781 }
1782 } 1782 }
1783 imul_rr(code, opts->gen.scratch1, dst_reg, SZ_D); 1783 imul_rr(code, opts->gen.scratch1, dst_reg, SZ_D);
1784 if (dst_op->mode == MODE_REG_DISPLACE8) { 1784 if (dst_op->mode == MODE_REG_DISPLACE8) {
1785 mov_rrdisp(code, dst_reg, dst_op->base, dst_op->disp, SZ_D); 1785 mov_rrdisp(code, dst_reg, dst_op->base, dst_op->disp, SZ_D);
1786 } 1786 }
1787 cmp_ir(code, 0, dst_reg, SZ_D); 1787 cmp_ir(code, 0, dst_reg, SZ_D);
1788 update_flags(opts, N|Z|V0|C0); 1788 update_flags(opts, N|Z|V0|C0);
1789 } 1789 }
1790 1790
1791 void translate_m68k_negx(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 1791 void translate_m68k_negx(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
1792 { 1792 {
1793 code_info *code = &opts->gen.code; 1793 code_info *code = &opts->gen.code;
1794 cycles(&opts->gen, BUS); 1794 cycles(&opts->gen, BUS);
1804 xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, inst->extra.size); 1804 xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, inst->extra.size);
1805 flag_to_carry(opts, FLAG_X); 1805 flag_to_carry(opts, FLAG_X);
1806 sbb_rr(code, dst_op->base, opts->gen.scratch1, inst->extra.size); 1806 sbb_rr(code, dst_op->base, opts->gen.scratch1, inst->extra.size);
1807 mov_rr(code, opts->gen.scratch1, dst_op->base, inst->extra.size); 1807 mov_rr(code, opts->gen.scratch1, dst_op->base, inst->extra.size);
1808 } 1808 }
1809 } else { 1809 } else {
1810 xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, inst->extra.size); 1810 xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, inst->extra.size);
1811 flag_to_carry(opts, FLAG_X); 1811 flag_to_carry(opts, FLAG_X);
1812 sbb_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch1, inst->extra.size); 1812 sbb_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch1, inst->extra.size);
1813 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, inst->extra.size); 1813 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, inst->extra.size);
1814 } 1814 }
1815 set_flag_cond(opts, CC_C, FLAG_C); 1815 set_flag_cond(opts, CC_C, FLAG_C);
1816 code_ptr after_flag_set = code->cur + 1; 1816 code_ptr after_flag_set = code->cur + 1;
1817 jcc(code, CC_Z, code->cur + 2); 1817 jcc(code, CC_Z, code->cur + 2);
1818 set_flag(opts, 0, FLAG_Z); 1818 set_flag(opts, 0, FLAG_Z);
1819 *after_flag_set = code->cur - (after_flag_set+1); 1819 *after_flag_set = code->cur - (after_flag_set+1);
1820 set_flag_cond(opts, CC_S, FLAG_N); 1820 set_flag_cond(opts, CC_S, FLAG_N);
1821 set_flag_cond(opts, CC_O, FLAG_V); 1821 set_flag_cond(opts, CC_O, FLAG_V);
1822 if (opts->flag_regs[FLAG_C] >= 0) { 1822 if (opts->flag_regs[FLAG_C] >= 0) {
1823 flag_to_flag(opts, FLAG_C, FLAG_X); 1823 flag_to_flag(opts, FLAG_C, FLAG_X);
1824 } else { 1824 } else {
1825 set_flag_cond(opts, CC_C, FLAG_X); 1825 set_flag_cond(opts, CC_C, FLAG_X);
1826 } 1826 }
1827 m68k_save_result(inst, opts); 1827 m68k_save_result(inst, opts);
1828 } 1828 }
1829 1829
1830 void translate_m68k_rot(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 1830 void translate_m68k_rot(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
1831 { 1831 {
1832 code_info *code = &opts->gen.code; 1832 code_info *code = &opts->gen.code;
1833 int32_t init_flags = C|V0; 1833 int32_t init_flags = C|V0;
1834 if (inst->src.addr_mode == MODE_UNUSED) { 1834 if (inst->src.addr_mode == MODE_UNUSED) {
1835 cycles(&opts->gen, BUS); 1835 cycles(&opts->gen, BUS);
1836 //Memory rotate 1836 //Memory rotate
1837 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) { 1837 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) {
1838 flag_to_carry(opts, FLAG_X); 1838 flag_to_carry(opts, FLAG_X);
1839 init_flags |= X; 1839 init_flags |= X;
1840 } 1840 }
1841 op_ir(code, inst, 1, dst_op->base, inst->extra.size); 1841 op_ir(code, inst, 1, dst_op->base, inst->extra.size);
1842 update_flags(opts, init_flags); 1842 update_flags(opts, init_flags);
1843 cmp_ir(code, 0, dst_op->base, inst->extra.size); 1843 cmp_ir(code, 0, dst_op->base, inst->extra.size);
1844 update_flags(opts, Z|N); 1844 update_flags(opts, Z|N);
1845 m68k_save_result(inst, opts); 1845 m68k_save_result(inst, opts);
1846 } else { 1846 } else {
1847 if (src_op->mode == MODE_IMMED) { 1847 if (src_op->mode == MODE_IMMED) {
1848 cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + src_op->disp*2); 1848 cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + src_op->disp*2);
1849 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) { 1849 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) {
1850 flag_to_carry(opts, FLAG_X); 1850 flag_to_carry(opts, FLAG_X);
1851 init_flags |= X; 1851 init_flags |= X;
1852 } 1852 }
1853 if (dst_op->mode == MODE_REG_DIRECT) { 1853 if (dst_op->mode == MODE_REG_DIRECT) {
1854 op_ir(code, inst, src_op->disp, dst_op->base, inst->extra.size); 1854 op_ir(code, inst, src_op->disp, dst_op->base, inst->extra.size);
1855 } else { 1855 } else {
1856 op_irdisp(code, inst, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size); 1856 op_irdisp(code, inst, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size);
1857 } 1857 }
1858 update_flags(opts, init_flags); 1858 update_flags(opts, init_flags);
1859 } else { 1859 } else {
1860 if (src_op->mode == MODE_REG_DIRECT) { 1860 if (src_op->mode == MODE_REG_DIRECT) {
1861 if (src_op->base != opts->gen.scratch1) { 1861 if (src_op->base != opts->gen.scratch1) {
1862 mov_rr(code, src_op->base, opts->gen.scratch1, SZ_B); 1862 mov_rr(code, src_op->base, opts->gen.scratch1, SZ_B);
1863 } 1863 }
1864 } else { 1864 } else {
1865 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_B); 1865 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_B);
1866 } 1866 }
1867 and_ir(code, 63, opts->gen.scratch1, SZ_D); 1867 and_ir(code, 63, opts->gen.scratch1, SZ_D);
1868 code_ptr zero_off = code->cur + 1; 1868 code_ptr zero_off = code->cur + 1;
1869 jcc(code, CC_Z, code->cur + 2); 1869 jcc(code, CC_Z, code->cur + 2);
1870 //add 2 cycles for every bit shifted 1870 //add 2 cycles for every bit shifted
1871 mov_ir(code, 2 * opts->gen.clock_divider, opts->gen.scratch2, SZ_D); 1871 mov_ir(code, 2 * opts->gen.clock_divider, opts->gen.scratch2, SZ_D);
1875 code_ptr norm_off = code->cur + 1; 1875 code_ptr norm_off = code->cur + 1;
1876 jcc(code, CC_L, code->cur + 2); 1876 jcc(code, CC_L, code->cur + 2);
1877 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) { 1877 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) {
1878 flag_to_carry(opts, FLAG_X); 1878 flag_to_carry(opts, FLAG_X);
1879 init_flags |= X; 1879 init_flags |= X;
1880 } else { 1880 } else {
1881 sub_ir(code, 32, opts->gen.scratch1, SZ_B); 1881 sub_ir(code, 32, opts->gen.scratch1, SZ_B);
1882 } 1882 }
1883 if (dst_op->mode == MODE_REG_DIRECT) { 1883 if (dst_op->mode == MODE_REG_DIRECT) {
1884 op_ir(code, inst, 31, dst_op->base, inst->extra.size); 1884 op_ir(code, inst, 31, dst_op->base, inst->extra.size);
1885 op_ir(code, inst, 1, dst_op->base, inst->extra.size); 1885 op_ir(code, inst, 1, dst_op->base, inst->extra.size);
1886 } else { 1886 } else {
1887 op_irdisp(code, inst, 31, dst_op->base, dst_op->disp, inst->extra.size); 1887 op_irdisp(code, inst, 31, dst_op->base, dst_op->disp, inst->extra.size);
1888 op_irdisp(code, inst, 1, dst_op->base, dst_op->disp, inst->extra.size); 1888 op_irdisp(code, inst, 1, dst_op->base, dst_op->disp, inst->extra.size);
1889 } 1889 }
1890 1890
1891 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) { 1891 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) {
1892 set_flag_cond(opts, CC_C, FLAG_X); 1892 set_flag_cond(opts, CC_C, FLAG_X);
1893 sub_ir(code, 32, opts->gen.scratch1, SZ_B); 1893 sub_ir(code, 32, opts->gen.scratch1, SZ_B);
1894 *norm_off = code->cur - (norm_off+1); 1894 *norm_off = code->cur - (norm_off+1);
1895 flag_to_carry(opts, FLAG_X); 1895 flag_to_carry(opts, FLAG_X);
1896 } else { 1896 } else {
1897 *norm_off = code->cur - (norm_off+1); 1897 *norm_off = code->cur - (norm_off+1);
1898 } 1898 }
1899 if (dst_op->mode == MODE_REG_DIRECT) { 1899 if (dst_op->mode == MODE_REG_DIRECT) {
1900 op_r(code, inst, dst_op->base, inst->extra.size); 1900 op_r(code, inst, dst_op->base, inst->extra.size);
1901 } else { 1901 } else {
1902 op_rdisp(code, inst, dst_op->base, dst_op->disp, inst->extra.size); 1902 op_rdisp(code, inst, dst_op->base, dst_op->disp, inst->extra.size);
1903 } 1903 }
1904 update_flags(opts, init_flags); 1904 update_flags(opts, init_flags);
1905 code_ptr end_off = code->cur + 1; 1905 code_ptr end_off = code->cur + 1;
1906 jmp(code, code->cur + 2); 1906 jmp(code, code->cur + 2);
1907 *zero_off = code->cur - (zero_off+1); 1907 *zero_off = code->cur - (zero_off+1);
1908 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) { 1908 if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) {
1909 //Carry flag is set to X flag when count is 0, this is different from ROR/ROL 1909 //Carry flag is set to X flag when count is 0, this is different from ROR/ROL
1910 flag_to_flag(opts, FLAG_X, FLAG_C); 1910 flag_to_flag(opts, FLAG_X, FLAG_C);
1911 } else { 1911 } else {
1912 set_flag(opts, 0, FLAG_C); 1912 set_flag(opts, 0, FLAG_C);
1913 } 1913 }
1914 *end_off = code->cur - (end_off+1); 1914 *end_off = code->cur - (end_off+1);
1915 } 1915 }
1916 if (dst_op->mode == MODE_REG_DIRECT) { 1916 if (dst_op->mode == MODE_REG_DIRECT) {
1917 cmp_ir(code, 0, dst_op->base, inst->extra.size); 1917 cmp_ir(code, 0, dst_op->base, inst->extra.size);
1918 } else { 1918 } else {
1919 cmp_irdisp(code, 0, dst_op->base, dst_op->disp, inst->extra.size); 1919 cmp_irdisp(code, 0, dst_op->base, dst_op->disp, inst->extra.size);
1920 } 1920 }
1921 update_flags(opts, Z|N); 1921 update_flags(opts, Z|N);
1922 } 1922 }
1923 } 1923 }
1924 1924
1925 void translate_m68k_illegal(m68k_options *opts, m68kinst *inst) 1925 void translate_m68k_illegal(m68k_options *opts, m68kinst *inst)
1926 { 1926 {
1927 code_info *code = &opts->gen.code; 1927 code_info *code = &opts->gen.code;
1928 call(code, opts->gen.save_context); 1928 call(code, opts->gen.save_context);
1929 call_args(code, (code_ptr)print_regs_exit, 1, opts->gen.context_reg); 1929 call_args(code, (code_ptr)print_regs_exit, 1, opts->gen.context_reg);
1930 } 1930 }
1931 1931
1932 #define BIT_SUPERVISOR 5 1932 #define BIT_SUPERVISOR 5
1933 1933
1934 void translate_m68k_andi_ori_ccr_sr(m68k_options *opts, m68kinst *inst) 1934 void translate_m68k_andi_ori_ccr_sr(m68k_options *opts, m68kinst *inst)
1935 { 1935 {
1941 for (int i = 0; i < 5; i++) 1941 for (int i = 0; i < 5; i++)
1942 { 1942 {
1943 if ((base_flag == X0) ^ (inst->src.params.immed & 1 << i) > 0) 1943 if ((base_flag == X0) ^ (inst->src.params.immed & 1 << i) > 0)
1944 { 1944 {
1945 flag_mask |= base_flag << ((4 - i) * 3); 1945 flag_mask |= base_flag << ((4 - i) * 3);
1946 } 1946 }
1947 } 1947 }
1948 update_flags(opts, flag_mask); 1948 update_flags(opts, flag_mask);
1949 if (inst->op == M68K_ANDI_SR || inst->op == M68K_ORI_SR) { 1949 if (inst->op == M68K_ANDI_SR || inst->op == M68K_ORI_SR) {
1950 if (inst->op == M68K_ANDI_SR) { 1950 if (inst->op == M68K_ANDI_SR) {
1951 and_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 1951 and_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
1952 } else { 1952 } else {
1953 or_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 1953 or_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
1954 } 1954 }
1955 if (inst->op == M68K_ANDI_SR && !(inst->src.params.immed & (1 << (BIT_SUPERVISOR + 8)))) { 1955 if (inst->op == M68K_ANDI_SR && !(inst->src.params.immed & (1 << (BIT_SUPERVISOR + 8)))) {
1956 //leave supervisor mode 1956 //leave supervisor mode
1957 swap_ssp_usp(opts); 1957 swap_ssp_usp(opts);
1958 } 1958 }
1959 if ((inst->op == M68K_ANDI_SR && (inst->src.params.immed & 0x700) != 0x700) 1959 if ((inst->op == M68K_ANDI_SR && (inst->src.params.immed & 0x700) != 0x700)
1960 || (inst->op == M68K_ORI_SR && inst->src.params.immed & 0x700)) { 1960 || (inst->op == M68K_ORI_SR && inst->src.params.immed & 0x700)) {
1961 call(code, opts->do_sync); 1961 call(code, opts->do_sync);
1962 } 1962 }
1963 } 1963 }
1964 } 1964 }
1965 1965
1966 void translate_m68k_eori_ccr_sr(m68k_options *opts, m68kinst *inst) 1966 void translate_m68k_eori_ccr_sr(m68k_options *opts, m68kinst *inst)
1967 { 1967 {
1968 code_info *code = &opts->gen.code; 1968 code_info *code = &opts->gen.code;
1969 cycles(&opts->gen, 20); 1969 cycles(&opts->gen, 20);
1970 //TODO: If ANDI to SR, trap if not in supervisor mode 1970 //TODO: If ANDI to SR, trap if not in supervisor mode
1971 if (inst->src.params.immed & 0x1) { 1971 if (inst->src.params.immed & 0x1) {
1972 xor_flag(opts, 1, FLAG_C); 1972 xor_flag(opts, 1, FLAG_C);
1973 } 1973 }
1974 if (inst->src.params.immed & 0x2) { 1974 if (inst->src.params.immed & 0x2) {
1975 xor_flag(opts, 1, FLAG_V); 1975 xor_flag(opts, 1, FLAG_V);
1976 } 1976 }
1977 if (inst->src.params.immed & 0x4) { 1977 if (inst->src.params.immed & 0x4) {
1978 xor_flag(opts, 1, FLAG_Z); 1978 xor_flag(opts, 1, FLAG_Z);
1979 } 1979 }
1980 if (inst->src.params.immed & 0x8) { 1980 if (inst->src.params.immed & 0x8) {
1981 xor_flag(opts, 1, FLAG_N); 1981 xor_flag(opts, 1, FLAG_N);
1982 } 1982 }
1983 if (inst->src.params.immed & 0x10) { 1983 if (inst->src.params.immed & 0x10) {
1984 xor_flag(opts, 1, FLAG_X); 1984 xor_flag(opts, 1, FLAG_X);
1985 } 1985 }
1986 if (inst->op == M68K_ORI_SR) { 1986 if (inst->op == M68K_ORI_SR) {
1987 xor_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 1987 xor_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
1988 if (inst->src.params.immed & 0x700) { 1988 if (inst->src.params.immed & 0x700) {
1989 call(code, opts->do_sync); 1989 call(code, opts->do_sync);
1990 } 1990 }
1991 } 1991 }
1992 } 1992 }
1993 1993
1994 void set_all_flags(m68k_options *opts, uint8_t flags) 1994 void set_all_flags(m68k_options *opts, uint8_t flags)
1995 { 1995 {
1996 uint32_t flag_mask = flags & 0x10 ? X1 : X0; 1996 uint32_t flag_mask = flags & 0x10 ? X1 : X0;
1997 flag_mask |= flags & 0x8 ? N1 : N0; 1997 flag_mask |= flags & 0x8 ? N1 : N0;
1998 flag_mask |= flags & 0x4 ? Z1 : Z0; 1998 flag_mask |= flags & 0x4 ? Z1 : Z0;
1999 flag_mask |= flags & 0x2 ? V1 : V0; 1999 flag_mask |= flags & 0x2 ? V1 : V0;
2000 flag_mask |= flags & 0x1 ? C1 : C0; 2000 flag_mask |= flags & 0x1 ? C1 : C0;
2001 update_flags(opts, flag_mask); 2001 update_flags(opts, flag_mask);
2002 } 2002 }
2003 2003
2004 void translate_m68k_move_ccr_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 2004 void translate_m68k_move_ccr_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
2005 { 2005 {
2006 code_info *code = &opts->gen.code; 2006 code_info *code = &opts->gen.code;
2007 //TODO: Privilege check for MOVE to SR 2007 //TODO: Privilege check for MOVE to SR
2010 if (inst->op == M68K_MOVE_SR) { 2010 if (inst->op == M68K_MOVE_SR) {
2011 mov_irdisp(code, (src_op->disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 2011 mov_irdisp(code, (src_op->disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
2012 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 2012 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
2013 //leave supervisor mode 2013 //leave supervisor mode
2014 swap_ssp_usp(opts); 2014 swap_ssp_usp(opts);
2015 } 2015 }
2016 call(code, opts->do_sync); 2016 call(code, opts->do_sync);
2017 } 2017 }
2018 cycles(&opts->gen, 12); 2018 cycles(&opts->gen, 12);
2019 } else { 2019 } else {
2020 if (src_op->base != opts->gen.scratch1) { 2020 if (src_op->base != opts->gen.scratch1) {
2021 if (src_op->mode == MODE_REG_DIRECT) { 2021 if (src_op->mode == MODE_REG_DIRECT) {
2022 mov_rr(code, src_op->base, opts->gen.scratch1, SZ_W); 2022 mov_rr(code, src_op->base, opts->gen.scratch1, SZ_W);
2023 } else { 2023 } else {
2024 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_W); 2024 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_W);
2025 } 2025 }
2026 } 2026 }
2027 call(code, inst->op == M68K_MOVE_SR ? opts->set_sr : opts->set_ccr); 2027 call(code, inst->op == M68K_MOVE_SR ? opts->set_sr : opts->set_ccr);
2028 cycles(&opts->gen, 12); 2028 cycles(&opts->gen, 12);
2029 } 2029 }
2030 } 2030 }
2031 2031
2032 void translate_m68k_stop(m68k_options *opts, m68kinst *inst) 2032 void translate_m68k_stop(m68k_options *opts, m68kinst *inst)
2033 { 2033 {
2034 //TODO: Trap if not in system mode 2034 //TODO: Trap if not in system mode
2035 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction 2035 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction
2036 //possibly even 12 since that's how long MOVE to SR takes 2036 //possibly even 12 since that's how long MOVE to SR takes
2037 //On further thought prefetch + the fact that this stops the CPU may make 2037 //On further thought prefetch + the fact that this stops the CPU may make
2038 //Motorola's accounting make sense here 2038 //Motorola's accounting make sense here
2039 code_info *code = &opts->gen.code; 2039 code_info *code = &opts->gen.code;
2040 cycles(&opts->gen, BUS*2); 2040 cycles(&opts->gen, BUS*2);
2041 set_all_flags(opts, inst->src.params.immed); 2041 set_all_flags(opts, inst->src.params.immed);
2042 mov_irdisp(code, (inst->src.params.immed >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 2042 mov_irdisp(code, (inst->src.params.immed >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
2043 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 2043 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
2044 //leave supervisor mode 2044 //leave supervisor mode
2045 swap_ssp_usp(opts); 2045 swap_ssp_usp(opts);
2046 } 2046 }
2047 code_ptr loop_top = code->cur; 2047 code_ptr loop_top = code->cur;
2048 call(code, opts->do_sync); 2048 call(code, opts->do_sync);
2049 cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D); 2049 cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D);
2050 code_ptr normal_cycle_up = code->cur + 1; 2050 code_ptr normal_cycle_up = code->cur + 1;
2051 jcc(code, CC_A, code->cur + 2); 2051 jcc(code, CC_A, code->cur + 2);
2055 *normal_cycle_up = code->cur - (normal_cycle_up + 1); 2055 *normal_cycle_up = code->cur - (normal_cycle_up + 1);
2056 mov_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D); 2056 mov_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D);
2057 *after_cycle_up = code->cur - (after_cycle_up+1); 2057 *after_cycle_up = code->cur - (after_cycle_up+1);
2058 cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), opts->gen.cycles, SZ_D); 2058 cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), opts->gen.cycles, SZ_D);
2059 jcc(code, CC_C, loop_top); 2059 jcc(code, CC_C, loop_top);
2060 } 2060 }
2061 2061
2062 void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 2062 void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
2063 { 2063 {
2064 code_info *code = &opts->gen.code; 2064 code_info *code = &opts->gen.code;
2065 //TODO: Trap if not in system mode 2065 //TODO: Trap if not in system mode
2066 call(code, opts->get_sr); 2066 call(code, opts->get_sr);
2067 if (dst_op->mode == MODE_REG_DIRECT) { 2067 if (dst_op->mode == MODE_REG_DIRECT) {
2068 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_W); 2068 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_W);
2069 } else { 2069 } else {
2070 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_W); 2070 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_W);
2071 } 2071 }
2072 m68k_save_result(inst, opts); 2072 m68k_save_result(inst, opts);
2073 } 2073 }
2074 2074
2075 void translate_m68k_reset(m68k_options *opts, m68kinst *inst) 2075 void translate_m68k_reset(m68k_options *opts, m68kinst *inst)
2076 { 2076 {
2112 void nop_fill_or_jmp_next(code_info *code, code_ptr old_end, code_ptr next_inst) 2112 void nop_fill_or_jmp_next(code_info *code, code_ptr old_end, code_ptr next_inst)
2113 { 2113 {
2114 if (next_inst == old_end && next_inst - code->cur < 2) { 2114 if (next_inst == old_end && next_inst - code->cur < 2) {
2115 while (code->cur < old_end) { 2115 while (code->cur < old_end) {
2116 *(code->cur++) = 0x90; //NOP 2116 *(code->cur++) = 0x90; //NOP
2117 } 2117 }
2118 } else { 2118 } else {
2119 jmp(code, next_inst); 2119 jmp(code, next_inst);
2120 } 2120 }
2121 } 2121 }
2122 2122
2123 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) 2123 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context)
2139 call_args(code,(code_ptr)m68k_retranslate_inst, 2, options->gen.scratch2, options->gen.context_reg); 2139 call_args(code,(code_ptr)m68k_retranslate_inst, 2, options->gen.scratch2, options->gen.context_reg);
2140 pop_r(code, options->gen.context_reg); 2140 pop_r(code, options->gen.context_reg);
2141 mov_rr(code, RAX, options->gen.scratch1, SZ_PTR); 2141 mov_rr(code, RAX, options->gen.scratch1, SZ_PTR);
2142 call(code, options->gen.load_context); 2142 call(code, options->gen.load_context);
2143 jmp_r(code, options->gen.scratch1); 2143 jmp_r(code, options->gen.scratch1);
2144 } 2144 }
2145 jmp(&orig, options->retrans_stub); 2145 jmp(&orig, options->retrans_stub);
2146 } 2146 }
2147 return context; 2147 return context;
2148 } 2148 }
2149 2149