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