Mercurial > repos > blastem
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); |