comparison m68k_to_x86.c @ 132:0969d8363a20

Support more address modes for jmp
author Mike Pavone <pavone@retrodev.com>
date Sun, 30 Dec 2012 07:52:44 -0800
parents 691e4b147cea
children c4d10c2aaee2
comparison
equal deleted inserted replaced
131:8fc8e46be691 132:0969d8363a20
1518 return dst; 1518 return dst;
1519 } 1519 }
1520 1520
1521 uint8_t * translate_m68k_jmp(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1521 uint8_t * translate_m68k_jmp(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
1522 { 1522 {
1523 uint8_t * dest_addr; 1523 uint8_t * dest_addr, sec_reg;
1524 uint32_t m68k_addr; 1524 uint32_t m68k_addr;
1525 switch(inst->src.addr_mode) 1525 switch(inst->src.addr_mode)
1526 { 1526 {
1527 case MODE_AREG_INDIRECT: 1527 case MODE_AREG_INDIRECT:
1528 dst = cycles(dst, BUS*2); 1528 dst = cycles(dst, BUS*2);
1529 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1529 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1530 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1530 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
1531 } else { 1531 } else {
1532 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 1532 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D);
1533 }
1534 dst = call(dst, (uint8_t *)m68k_native_addr);
1535 dst = jmp_r(dst, SCRATCH1);
1536 break;
1537 case MODE_AREG_INDEX_DISP8:
1538 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
1539 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1540 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
1541 } else {
1542 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D);
1543 }
1544 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
1545 if (inst->src.params.regs.sec & 1) {
1546 if (inst->src.params.regs.sec & 0x10) {
1547 if (opts->aregs[sec_reg] >= 0) {
1548 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D);
1549 } else {
1550 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
1551 }
1552 } else {
1553 if (opts->dregs[sec_reg] >= 0) {
1554 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D);
1555 } else {
1556 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
1557 }
1558 }
1559 } else {
1560 if (inst->src.params.regs.sec & 0x10) {
1561 if (opts->aregs[sec_reg] >= 0) {
1562 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
1563 } else {
1564 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
1565 }
1566 } else {
1567 if (opts->dregs[sec_reg] >= 0) {
1568 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
1569 } else {
1570 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
1571 }
1572 }
1573 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
1574 }
1575 if (inst->src.params.regs.displacement) {
1576 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
1533 } 1577 }
1534 dst = call(dst, (uint8_t *)m68k_native_addr); 1578 dst = call(dst, (uint8_t *)m68k_native_addr);
1535 dst = jmp_r(dst, SCRATCH1); 1579 dst = jmp_r(dst, SCRATCH1);
1536 break; 1580 break;
1537 case MODE_PC_DISPLACE: 1581 case MODE_PC_DISPLACE:
1548 } else { 1592 } else {
1549 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); 1593 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D);
1550 dst = call(dst, (uint8_t *)m68k_native_addr); 1594 dst = call(dst, (uint8_t *)m68k_native_addr);
1551 dst = jmp_r(dst, SCRATCH1); 1595 dst = jmp_r(dst, SCRATCH1);
1552 } 1596 }
1597 break;
1598 case MODE_PC_INDEX_DISP8:
1599 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
1600 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
1601 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
1602 if (inst->src.params.regs.sec & 1) {
1603 if (inst->src.params.regs.sec & 0x10) {
1604 if (opts->aregs[sec_reg] >= 0) {
1605 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D);
1606 } else {
1607 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
1608 }
1609 } else {
1610 if (opts->dregs[sec_reg] >= 0) {
1611 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D);
1612 } else {
1613 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
1614 }
1615 }
1616 } else {
1617 if (inst->src.params.regs.sec & 0x10) {
1618 if (opts->aregs[sec_reg] >= 0) {
1619 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
1620 } else {
1621 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
1622 }
1623 } else {
1624 if (opts->dregs[sec_reg] >= 0) {
1625 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
1626 } else {
1627 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
1628 }
1629 }
1630 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
1631 }
1632 if (inst->src.params.regs.displacement) {
1633 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
1634 }
1635 dst = call(dst, (uint8_t *)m68k_native_addr);
1636 dst = jmp_r(dst, SCRATCH1);
1553 break; 1637 break;
1554 case MODE_ABSOLUTE: 1638 case MODE_ABSOLUTE:
1555 case MODE_ABSOLUTE_SHORT: 1639 case MODE_ABSOLUTE_SHORT:
1556 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10); 1640 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10);
1557 m68k_addr = inst->src.params.immed; 1641 m68k_addr = inst->src.params.immed;