comparison m68k_to_x86.c @ 73:8da611e69b32

Implement a couple of supervisor instructions
author Mike Pavone <pavone@retrodev.com>
date Fri, 21 Dec 2012 16:04:41 -0800
parents f80fa1776507
children 6396dc91f61e
comparison
equal deleted inserted replaced
72:7935cd64d5c8 73:8da611e69b32
1221 dst = m68k_save_result(inst, dst, opts); 1221 dst = m68k_save_result(inst, dst, opts);
1222 } 1222 }
1223 return dst; 1223 return dst;
1224 } 1224 }
1225 1225
1226 #define BIT_SUPERVISOR 5
1227
1226 uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1228 uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
1227 { 1229 {
1228 uint8_t * end_off; 1230 uint8_t * end_off;
1229 map_native_address(opts->native_code_map, inst->address, dst); 1231 map_native_address(opts->native_code_map, inst->address, dst);
1230 if (inst->op == M68K_MOVE) { 1232 if (inst->op == M68K_MOVE) {
1304 dst = setcc_r(dst, CC_Z, FLAG_Z); 1306 dst = setcc_r(dst, CC_Z, FLAG_Z);
1305 dst = setcc_r(dst, CC_S, FLAG_N); 1307 dst = setcc_r(dst, CC_S, FLAG_N);
1306 dst = mov_ir(dst, 0, FLAG_V, SZ_B); 1308 dst = mov_ir(dst, 0, FLAG_V, SZ_B);
1307 dst = m68k_save_result(inst, dst, opts); 1309 dst = m68k_save_result(inst, dst, opts);
1308 break; 1310 break;
1309 //case M68K_ANDI_CCR: 1311 case M68K_ANDI_CCR:
1310 //case M68K_ANDI_SR: 1312 case M68K_ANDI_SR:
1311 // break; 1313 dst = cycles(dst, 20);
1314 //TODO: If ANDI to SR, trap if not in supervisor mode
1315 if (!(inst->src.params.immed & 0x1)) {
1316 dst = mov_ir(dst, 0, FLAG_C, SZ_B);
1317 }
1318 if (!(inst->src.params.immed & 0x2)) {
1319 dst = mov_ir(dst, 0, FLAG_V, SZ_B);
1320 }
1321 if (!(inst->src.params.immed & 0x4)) {
1322 dst = mov_ir(dst, 0, FLAG_Z, SZ_B);
1323 }
1324 if (!(inst->src.params.immed & 0x8)) {
1325 dst = mov_ir(dst, 0, FLAG_N, SZ_B);
1326 }
1327 if (!(inst->src.params.immed & 0x10)) {
1328 dst = mov_irind(dst, 0, CONTEXT, SZ_B);
1329 }
1330 if (inst->op == M68K_ANDI_SR) {
1331 dst = and_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B);
1332 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
1333 //leave supervisor mode
1334 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_B);
1335 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_B);
1336 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_B);
1337 }
1338 }
1339 break;
1312 case M68K_ASL: 1340 case M68K_ASL:
1313 case M68K_LSL: 1341 case M68K_LSL:
1314 dst = translate_shift(dst, inst, &src_op, &dst_op, opts, shl_ir, shl_irdisp8, shl_clr, shl_clrdisp8, shr_ir, shr_irdisp8); 1342 dst = translate_shift(dst, inst, &src_op, &dst_op, opts, shl_ir, shl_irdisp8, shl_clr, shl_clrdisp8, shr_ir, shr_irdisp8);
1315 break; 1343 break;
1316 case M68K_ASR: 1344 case M68K_ASR:
1434 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_D); 1462 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_D);
1435 dst = mov_rrdisp8(dst, SCRATCH2, src_op.base, src_op.disp, SZ_D); 1463 dst = mov_rrdisp8(dst, SCRATCH2, src_op.base, src_op.disp, SZ_D);
1436 } 1464 }
1437 } 1465 }
1438 break; 1466 break;
1439 case M68K_EXT: 1467 //case M68K_EXT:
1440 break; 1468 // break;
1441 case M68K_ILLEGAL: 1469 case M68K_ILLEGAL:
1442 dst = call(dst, (uint8_t *)m68k_save_context); 1470 dst = call(dst, (uint8_t *)m68k_save_context);
1443 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); 1471 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
1444 dst = call(dst, (uint8_t *)print_regs_exit); 1472 dst = call(dst, (uint8_t *)print_regs_exit);
1445 break; 1473 break;
1457 dst = mov_ir(dst, (src_op.disp >> 2) & 0x1, FLAG_Z, SZ_B); 1485 dst = mov_ir(dst, (src_op.disp >> 2) & 0x1, FLAG_Z, SZ_B);
1458 dst = mov_ir(dst, (src_op.disp >> 3) & 0x1, FLAG_N, SZ_B); 1486 dst = mov_ir(dst, (src_op.disp >> 3) & 0x1, FLAG_N, SZ_B);
1459 dst = mov_irind(dst, (src_op.disp >> 4) & 0x1, CONTEXT, SZ_B); 1487 dst = mov_irind(dst, (src_op.disp >> 4) & 0x1, CONTEXT, SZ_B);
1460 if (inst->op == M68K_MOVE_SR) { 1488 if (inst->op == M68K_MOVE_SR) {
1461 dst = mov_irdisp8(dst, (src_op.disp >> 8), CONTEXT, offsetof(m68k_context, status), SZ_B); 1489 dst = mov_irdisp8(dst, (src_op.disp >> 8), CONTEXT, offsetof(m68k_context, status), SZ_B);
1490 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
1491 //leave supervisor mode
1492 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
1493 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D);
1494 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
1495 }
1462 } 1496 }
1463 dst = cycles(dst, 12); 1497 dst = cycles(dst, 12);
1464 } else { 1498 } else {
1465 if (src_op.mode == MODE_REG_DIRECT) { 1499 if (src_op.mode == MODE_REG_DIRECT) {
1466 dst = mov_rr(dst, src_op.base, FLAG_C, SZ_B); 1500 dst = mov_rr(dst, src_op.base, FLAG_C, SZ_B);
1490 } 1524 }
1491 dst = shr_ir(dst, 8, SCRATCH2, SZ_B); 1525 dst = shr_ir(dst, 8, SCRATCH2, SZ_B);
1492 dst = mov_rrdisp8(dst, SCRATCH2, CONTEXT, offsetof(m68k_context, status), SZ_B); 1526 dst = mov_rrdisp8(dst, SCRATCH2, CONTEXT, offsetof(m68k_context, status), SZ_B);
1493 } 1527 }
1494 break; 1528 break;
1495 /*case M68K_MOVE_USP: 1529 case M68K_MOVE_USP:
1496 case M68K_MOVEP: 1530 dst = cycles(dst, BUS);
1531 //TODO: Trap if not in supervisor mode
1532 //dst = bt_irdisp8(dst, BIT_SUPERVISOR, CONTEXT, offsetof(m68k_context, status), SZ_B);
1533 if (inst->src.addr_mode == MODE_UNUSED) {
1534 if (dst_op.mode == MODE_REG_DIRECT) {
1535 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, dst_op.base, SZ_D);
1536 } else {
1537 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SCRATCH1, SZ_D);
1538 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_D);
1539 }
1540 } else {
1541 if (src_op.mode == MODE_REG_DIRECT) {
1542 dst = mov_rrdisp8(dst, src_op.base, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
1543 } else {
1544 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_D);
1545 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
1546 }
1547 }
1548 break;
1549 /*case M68K_MOVEP:
1497 case M68K_MULS: 1550 case M68K_MULS:
1498 case M68K_MULU: 1551 case M68K_MULU:
1499 case M68K_NBCD: 1552 case M68K_NBCD:
1500 case M68K_NEG: 1553 case M68K_NEG:
1501 case M68K_NEGX: 1554 case M68K_NEGX:
1502 break;*/ 1555 break;*/
1503 case M68K_NOP: 1556 case M68K_NOP:
1504 dst = cycles(dst, BUS); 1557 dst = cycles(dst, BUS);
1505 break; 1558 break;
1506 case M68K_NOT: 1559 //case M68K_NOT:
1507 break; 1560 // break;
1508 case M68K_OR: 1561 case M68K_OR:
1509 dst = cycles(dst, BUS); 1562 dst = cycles(dst, BUS);
1510 if (src_op.mode == MODE_REG_DIRECT) { 1563 if (src_op.mode == MODE_REG_DIRECT) {
1511 if (dst_op.mode == MODE_REG_DIRECT) { 1564 if (dst_op.mode == MODE_REG_DIRECT) {
1512 dst = or_rr(dst, src_op.base, dst_op.base, inst->extra.size); 1565 dst = or_rr(dst, src_op.base, dst_op.base, inst->extra.size);