Mercurial > repos > blastem
comparison m68k_to_x86.c @ 98:104e257fb93c
Allow indexed modes to be used as a destination
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 27 Dec 2012 21:54:54 -0800 |
parents | c7185fd840fc |
children | 8491de5d6c06 |
comparison
equal
deleted
inserted
replaced
97:c7185fd840fc | 98:104e257fb93c |
---|---|
347 return out; | 347 return out; |
348 } | 348 } |
349 | 349 |
350 uint8_t * translate_m68k_dst(m68kinst * inst, x86_ea * ea, uint8_t * out, x86_68k_options * opts, uint8_t fake_read) | 350 uint8_t * translate_m68k_dst(m68kinst * inst, x86_ea * ea, uint8_t * out, x86_68k_options * opts, uint8_t fake_read) |
351 { | 351 { |
352 int8_t reg = native_reg(&(inst->dst), opts); | 352 int8_t reg = native_reg(&(inst->dst), opts), sec_reg; |
353 int32_t dec_amount, inc_amount; | 353 int32_t dec_amount, inc_amount; |
354 if (reg >= 0) { | 354 if (reg >= 0) { |
355 ea->mode = MODE_REG_DIRECT; | 355 ea->mode = MODE_REG_DIRECT; |
356 ea->base = reg; | 356 ea->base = reg; |
357 return out; | 357 return out; |
438 out = pop_r(out, SCRATCH2); | 438 out = pop_r(out, SCRATCH2); |
439 } | 439 } |
440 ea->mode = MODE_REG_DIRECT; | 440 ea->mode = MODE_REG_DIRECT; |
441 ea->base = SCRATCH1; | 441 ea->base = SCRATCH1; |
442 break; | 442 break; |
443 case MODE_AREG_INDEX_DISP8: | |
444 out = cycles(out, fake_read ? (6 + inst->extra.size == OPSIZE_LONG ? 8 : 4) : 6); | |
445 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { | |
446 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], SCRATCH1, SZ_D); | |
447 } else { | |
448 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), SCRATCH1, SZ_D); | |
449 } | |
450 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; | |
451 if (inst->dst.params.regs.sec & 1) { | |
452 if (inst->dst.params.regs.sec & 0x10) { | |
453 if (opts->aregs[sec_reg] >= 0) { | |
454 out = add_rr(out, opts->aregs[sec_reg], SCRATCH1, SZ_D); | |
455 } else { | |
456 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
457 } | |
458 } else { | |
459 if (opts->dregs[sec_reg] >= 0) { | |
460 out = add_rr(out, opts->dregs[sec_reg], SCRATCH1, SZ_D); | |
461 } else { | |
462 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
463 } | |
464 } | |
465 } else { | |
466 if (inst->dst.params.regs.sec & 0x10) { | |
467 if (opts->aregs[sec_reg] >= 0) { | |
468 out = movsx_rr(out, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
469 } else { | |
470 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
471 } | |
472 } else { | |
473 if (opts->dregs[sec_reg] >= 0) { | |
474 out = movsx_rr(out, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
475 } else { | |
476 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
477 } | |
478 } | |
479 out = add_rr(out, SCRATCH2, SCRATCH1, SZ_D); | |
480 } | |
481 if (inst->dst.params.regs.displacement) { | |
482 out = add_ir(out, inst->dst.params.regs.displacement, SCRATCH1, SZ_D); | |
483 } | |
484 if (fake_read) { | |
485 out = mov_rr(out, SCRATCH1, SCRATCH2, SZ_D); | |
486 } else { | |
487 out = push_r(out, SCRATCH1); | |
488 switch (inst->extra.size) | |
489 { | |
490 case OPSIZE_BYTE: | |
491 out = call(out, (char *)m68k_read_byte_scratch1); | |
492 break; | |
493 case OPSIZE_WORD: | |
494 out = call(out, (char *)m68k_read_word_scratch1); | |
495 break; | |
496 case OPSIZE_LONG: | |
497 out = call(out, (char *)m68k_read_long_scratch1); | |
498 break; | |
499 } | |
500 out = pop_r(out, SCRATCH2); | |
501 } | |
502 ea->mode = MODE_REG_DIRECT; | |
503 ea->base = SCRATCH1; | |
443 case MODE_PC_DISPLACE: | 504 case MODE_PC_DISPLACE: |
444 out = cycles(out, fake_read ? BUS+(inst->extra.size == OPSIZE_LONG ? BUS*2 : BUS) : BUS); | 505 out = cycles(out, fake_read ? BUS+(inst->extra.size == OPSIZE_LONG ? BUS*2 : BUS) : BUS); |
445 out = mov_ir(out, inst->dst.params.regs.displacement + inst->address+2, fake_read ? SCRATCH2 : SCRATCH1, SZ_D); | 506 out = mov_ir(out, inst->dst.params.regs.displacement + inst->address+2, fake_read ? SCRATCH2 : SCRATCH1, SZ_D); |
446 if (!fake_read) { | 507 if (!fake_read) { |
508 out = push_r(out, SCRATCH1); | |
509 switch (inst->extra.size) | |
510 { | |
511 case OPSIZE_BYTE: | |
512 out = call(out, (char *)m68k_read_byte_scratch1); | |
513 break; | |
514 case OPSIZE_WORD: | |
515 out = call(out, (char *)m68k_read_word_scratch1); | |
516 break; | |
517 case OPSIZE_LONG: | |
518 out = call(out, (char *)m68k_read_long_scratch1); | |
519 break; | |
520 } | |
521 out = pop_r(out, SCRATCH2); | |
522 } | |
523 ea->mode = MODE_REG_DIRECT; | |
524 ea->base = SCRATCH1; | |
525 break; | |
526 case MODE_PC_INDEX_DISP8: | |
527 out = cycles(out, fake_read ? (6 + inst->extra.size == OPSIZE_LONG ? 8 : 4) : 6); | |
528 out = mov_ir(out, inst->address+2, SCRATCH1, SZ_D); | |
529 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; | |
530 if (inst->dst.params.regs.sec & 1) { | |
531 if (inst->dst.params.regs.sec & 0x10) { | |
532 if (opts->aregs[sec_reg] >= 0) { | |
533 out = add_rr(out, opts->aregs[sec_reg], SCRATCH1, SZ_D); | |
534 } else { | |
535 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
536 } | |
537 } else { | |
538 if (opts->dregs[sec_reg] >= 0) { | |
539 out = add_rr(out, opts->dregs[sec_reg], SCRATCH1, SZ_D); | |
540 } else { | |
541 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
542 } | |
543 } | |
544 } else { | |
545 if (inst->dst.params.regs.sec & 0x10) { | |
546 if (opts->aregs[sec_reg] >= 0) { | |
547 out = movsx_rr(out, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
548 } else { | |
549 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
550 } | |
551 } else { | |
552 if (opts->dregs[sec_reg] >= 0) { | |
553 out = movsx_rr(out, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
554 } else { | |
555 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
556 } | |
557 } | |
558 out = add_rr(out, SCRATCH2, SCRATCH1, SZ_D); | |
559 } | |
560 if (inst->dst.params.regs.displacement) { | |
561 out = add_ir(out, inst->dst.params.regs.displacement, SCRATCH1, SZ_D); | |
562 } | |
563 if (fake_read) { | |
564 out = mov_rr(out, SCRATCH1, SCRATCH2, SZ_D); | |
565 } else { | |
447 out = push_r(out, SCRATCH1); | 566 out = push_r(out, SCRATCH1); |
448 switch (inst->extra.size) | 567 switch (inst->extra.size) |
449 { | 568 { |
450 case OPSIZE_BYTE: | 569 case OPSIZE_BYTE: |
451 out = call(out, (char *)m68k_read_byte_scratch1); | 570 out = call(out, (char *)m68k_read_byte_scratch1); |