comparison m68k_to_x86.c @ 110:a575808dd90b

Implement more address modes for jsr
author Mike Pavone <pavone@retrodev.com>
date Fri, 28 Dec 2012 15:16:36 -0800
parents 9705075fcf36
children e3594572fb98
comparison
equal deleted inserted replaced
109:004dd46e0a97 110:a575808dd90b
1381 return dst; 1381 return dst;
1382 } 1382 }
1383 1383
1384 uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1384 uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
1385 { 1385 {
1386 uint8_t * dest_addr; 1386 uint8_t * dest_addr, sec_reg;
1387 uint32_t after; 1387 uint32_t after;
1388 switch(inst->src.addr_mode) 1388 switch(inst->src.addr_mode)
1389 { 1389 {
1390 case MODE_AREG_INDIRECT: 1390 case MODE_AREG_INDIRECT:
1391 dst = cycles(dst, BUS*2); 1391 dst = cycles(dst, BUS*2);
1396 dst = call(dst, (char *)m68k_write_long_highfirst); 1396 dst = call(dst, (char *)m68k_write_long_highfirst);
1397 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1397 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1398 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1398 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
1399 } else { 1399 } else {
1400 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 1400 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D);
1401 }
1402 dst = call(dst, (uint8_t *)m68k_native_addr);
1403 dst = call_r(dst, SCRATCH1);
1404 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1405 dst = pop_r(dst, SCRATCH1);
1406 break;
1407 case MODE_AREG_INDEX_DISP8:
1408 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
1409 dst = mov_ir(dst, inst->address + 8, SCRATCH1, SZ_D);
1410 dst = push_r(dst, SCRATCH1);
1411 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1412 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1413 dst = call(dst, (char *)m68k_write_long_highfirst);
1414 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1415 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
1416 } else {
1417 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D);
1418 }
1419 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
1420 if (inst->src.params.regs.sec & 1) {
1421 if (inst->src.params.regs.sec & 0x10) {
1422 if (opts->aregs[sec_reg] >= 0) {
1423 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D);
1424 } else {
1425 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
1426 }
1427 } else {
1428 if (opts->dregs[sec_reg] >= 0) {
1429 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D);
1430 } else {
1431 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
1432 }
1433 }
1434 } else {
1435 if (inst->src.params.regs.sec & 0x10) {
1436 if (opts->aregs[sec_reg] >= 0) {
1437 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
1438 } else {
1439 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
1440 }
1441 } else {
1442 if (opts->dregs[sec_reg] >= 0) {
1443 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
1444 } else {
1445 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
1446 }
1447 }
1448 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
1449 }
1450 if (inst->src.params.regs.displacement) {
1451 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
1401 } 1452 }
1402 dst = call(dst, (uint8_t *)m68k_native_addr); 1453 dst = call(dst, (uint8_t *)m68k_native_addr);
1403 dst = call_r(dst, SCRATCH1); 1454 dst = call_r(dst, SCRATCH1);
1404 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? 1455 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1405 dst = pop_r(dst, SCRATCH1); 1456 dst = pop_r(dst, SCRATCH1);
1417 opts->deferred = defer_address(opts->deferred, inst->src.params.immed, dst + 1); 1468 opts->deferred = defer_address(opts->deferred, inst->src.params.immed, dst + 1);
1418 //dummy address to be replaced later, make sure it generates a 4-byte displacement 1469 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1419 dest_addr = dst + 5; 1470 dest_addr = dst + 5;
1420 } 1471 }
1421 dst = call(dst, (char *)dest_addr); 1472 dst = call(dst, (char *)dest_addr);
1473 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1474 dst = pop_r(dst, SCRATCH1);
1475 break;
1476 case MODE_PC_INDEX_DISP8:
1477 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
1478 dst = mov_ir(dst, inst->address + 8, SCRATCH1, SZ_D);
1479 dst = push_r(dst, SCRATCH1);
1480 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1481 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1482 dst = call(dst, (char *)m68k_write_long_highfirst);
1483 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
1484 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
1485 if (inst->src.params.regs.sec & 1) {
1486 if (inst->src.params.regs.sec & 0x10) {
1487 if (opts->aregs[sec_reg] >= 0) {
1488 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D);
1489 } else {
1490 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
1491 }
1492 } else {
1493 if (opts->dregs[sec_reg] >= 0) {
1494 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D);
1495 } else {
1496 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
1497 }
1498 }
1499 } else {
1500 if (inst->src.params.regs.sec & 0x10) {
1501 if (opts->aregs[sec_reg] >= 0) {
1502 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
1503 } else {
1504 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
1505 }
1506 } else {
1507 if (opts->dregs[sec_reg] >= 0) {
1508 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
1509 } else {
1510 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
1511 }
1512 }
1513 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
1514 }
1515 if (inst->src.params.regs.displacement) {
1516 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
1517 }
1518 dst = call(dst, (uint8_t *)m68k_native_addr);
1519 dst = call_r(dst, SCRATCH1);
1422 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? 1520 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1423 dst = pop_r(dst, SCRATCH1); 1521 dst = pop_r(dst, SCRATCH1);
1424 break; 1522 break;
1425 case MODE_ABSOLUTE: 1523 case MODE_ABSOLUTE:
1426 case MODE_ABSOLUTE_SHORT: 1524 case MODE_ABSOLUTE_SHORT: