25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: cpu_ppc_instr.c,v 1.59 2006/02/09 22:40:27 debug Exp $ |
* $Id: cpu_ppc_instr.c,v 1.70 2006/04/14 19:58:21 debug Exp $ |
29 |
* |
* |
30 |
* POWER/PowerPC instructions. |
* POWER/PowerPC instructions. |
31 |
* |
* |
987 |
X(fctiwz) |
X(fctiwz) |
988 |
{ |
{ |
989 |
struct ieee_float_value frb; |
struct ieee_float_value frb; |
990 |
int32_t res = 0; |
uint32_t res = 0; |
991 |
|
|
992 |
CHECK_FOR_FPU_EXCEPTION; |
CHECK_FOR_FPU_EXCEPTION; |
993 |
|
|
1411 |
|
|
1412 |
|
|
1413 |
/* |
/* |
1414 |
|
* rldicl: |
1415 |
|
* |
1416 |
|
* arg[0] = copy of the instruction word |
1417 |
|
*/ |
1418 |
|
X(rldicl) |
1419 |
|
{ |
1420 |
|
int rs = (ic->arg[0] >> 21) & 31; |
1421 |
|
int ra = (ic->arg[0] >> 16) & 31; |
1422 |
|
int sh = ((ic->arg[0] >> 11) & 31) | ((ic->arg[0] & 2) << 4); |
1423 |
|
int mb = ((ic->arg[0] >> 6) & 31) | (ic->arg[0] & 0x20); |
1424 |
|
int rc = ic->arg[0] & 1; |
1425 |
|
uint64_t tmp = cpu->cd.ppc.gpr[rs], tmp2; |
1426 |
|
/* TODO: Fix this, its performance is awful: */ |
1427 |
|
while (sh-- != 0) { |
1428 |
|
int b = (tmp >> 63) & 1; |
1429 |
|
tmp = (tmp << 1) | b; |
1430 |
|
} |
1431 |
|
tmp2 = 0; |
1432 |
|
while (mb <= 63) { |
1433 |
|
tmp |= ((uint64_t)1 << (63-mb)); |
1434 |
|
mb ++; |
1435 |
|
} |
1436 |
|
cpu->cd.ppc.gpr[ra] = tmp & tmp2; |
1437 |
|
if (rc) |
1438 |
|
update_cr0(cpu, cpu->cd.ppc.gpr[ra]); |
1439 |
|
} |
1440 |
|
|
1441 |
|
|
1442 |
|
/* |
1443 |
* rldicr: |
* rldicr: |
1444 |
* |
* |
1445 |
* arg[0] = copy of the instruction word |
* arg[0] = copy of the instruction word |
1466 |
|
|
1467 |
|
|
1468 |
/* |
/* |
1469 |
|
* rldimi: |
1470 |
|
* |
1471 |
|
* arg[0] = copy of the instruction word |
1472 |
|
*/ |
1473 |
|
X(rldimi) |
1474 |
|
{ |
1475 |
|
uint32_t iw = ic->arg[0]; |
1476 |
|
int rs = (iw >> 21) & 31, ra = (iw >> 16) & 31; |
1477 |
|
int sh = ((iw >> 11) & 31) | ((iw & 2) << 4); |
1478 |
|
int mb = ((iw >> 6) & 31) | (iw & 0x20); |
1479 |
|
int rc = ic->arg[0] & 1; |
1480 |
|
int m; |
1481 |
|
uint64_t tmp, s = cpu->cd.ppc.gpr[rs]; |
1482 |
|
/* TODO: Fix this, its performance is awful: */ |
1483 |
|
while (sh-- != 0) { |
1484 |
|
int b = (s >> 63) & 1; |
1485 |
|
s = (s << 1) | b; |
1486 |
|
} |
1487 |
|
m = mb; tmp = 0; |
1488 |
|
do { |
1489 |
|
tmp |= ((uint64_t)1 << (63-m)); |
1490 |
|
m ++; |
1491 |
|
} while (m != 63 - sh); |
1492 |
|
cpu->cd.ppc.gpr[ra] &= ~tmp; |
1493 |
|
cpu->cd.ppc.gpr[ra] |= (tmp & s); |
1494 |
|
if (rc) |
1495 |
|
update_cr0(cpu, cpu->cd.ppc.gpr[ra]); |
1496 |
|
} |
1497 |
|
|
1498 |
|
|
1499 |
|
/* |
1500 |
* rlwnm: |
* rlwnm: |
1501 |
* |
* |
1502 |
* arg[0] = ptr to ra |
* arg[0] = ptr to ra |
1733 |
|
|
1734 |
|
|
1735 |
/* |
/* |
1736 |
* rfi: Return from Interrupt |
* rfi[d]: Return from Interrupt |
1737 |
*/ |
*/ |
1738 |
X(rfi) |
X(rfi) |
1739 |
{ |
{ |
1747 |
cpu->pc = cpu->cd.ppc.spr[SPR_SRR0]; |
cpu->pc = cpu->cd.ppc.spr[SPR_SRR0]; |
1748 |
quick_pc_to_pointers(cpu); |
quick_pc_to_pointers(cpu); |
1749 |
} |
} |
1750 |
|
X(rfid) |
1751 |
|
{ |
1752 |
|
uint64_t tmp, mask = 0x800000000000ff73ULL; |
1753 |
|
|
1754 |
|
reg_access_msr(cpu, &tmp, 0, 0); |
1755 |
|
tmp &= ~mask; |
1756 |
|
tmp |= (cpu->cd.ppc.spr[SPR_SRR1] & mask); |
1757 |
|
reg_access_msr(cpu, &tmp, 1, 0); |
1758 |
|
|
1759 |
|
cpu->pc = cpu->cd.ppc.spr[SPR_SRR0]; |
1760 |
|
if (!(tmp & PPC_MSR_SF)) |
1761 |
|
cpu->pc = (uint32_t)cpu->pc; |
1762 |
|
quick_pc_to_pointers(cpu); |
1763 |
|
} |
1764 |
|
|
1765 |
|
|
1766 |
/* |
/* |
1789 |
* mtmsr: Move To MSR |
* mtmsr: Move To MSR |
1790 |
* |
* |
1791 |
* arg[0] = pointer to source register |
* arg[0] = pointer to source register |
1792 |
|
* arg[1] = page offset of the next instruction |
1793 |
|
* arg[2] = 0 for 32-bit (mtmsr), 1 for 64-bit (mtmsrd) |
1794 |
*/ |
*/ |
1795 |
X(mtmsr) |
X(mtmsr) |
1796 |
{ |
{ |
1797 |
MODE_uint_t old_pc; |
MODE_uint_t old_pc; |
1798 |
|
uint64_t x = reg(ic->arg[0]); |
1799 |
|
|
1800 |
/* TODO: check permission! */ |
/* TODO: check permission! */ |
1801 |
|
|
1803 |
cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1]; |
cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1]; |
1804 |
old_pc = cpu->pc; |
old_pc = cpu->pc; |
1805 |
|
|
1806 |
reg_access_msr(cpu, (uint64_t*)ic->arg[0], 1, 1); |
if (!ic->arg[2]) { |
1807 |
|
uint64_t y; |
1808 |
|
reg_access_msr(cpu, &y, 0, 0); |
1809 |
|
x = (y & 0xffffffff00000000ULL) | (x & 0xffffffffULL); |
1810 |
|
} |
1811 |
|
|
1812 |
|
reg_access_msr(cpu, &x, 1, 1); |
1813 |
|
|
1814 |
/* |
/* |
1815 |
* Super-ugly hack: If the pc wasn't changed (i.e. if there was no |
* Super-ugly hack: If the pc wasn't changed (i.e. if there was no |
2031 |
DOT2(extsh) |
DOT2(extsh) |
2032 |
X(extsw) { |
X(extsw) { |
2033 |
#ifdef MODE32 |
#ifdef MODE32 |
2034 |
fatal("TODO: extsw: invalid instruction\n"); exit(1); |
fatal("TODO: extsw: invalid instruction\n"); |
2035 |
#else |
#else |
2036 |
reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]); |
reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]); |
2037 |
#endif |
#endif |
2040 |
X(slw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) |
X(slw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) |
2041 |
<< (reg(ic->arg[1]) & 31); } |
<< (reg(ic->arg[1]) & 31); } |
2042 |
DOT2(slw) |
DOT2(slw) |
2043 |
|
X(sld) {int sa = reg(ic->arg[1]) & 127; |
2044 |
|
if (sa >= 64) reg(ic->arg[2]) = 0; |
2045 |
|
else reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) << (sa & 63); } |
2046 |
|
DOT2(sld) |
2047 |
X(sraw) |
X(sraw) |
2048 |
{ |
{ |
2049 |
uint32_t tmp = reg(ic->arg[0]); |
uint32_t tmp = reg(ic->arg[0]); |
2082 |
DOT2(orc) |
DOT2(orc) |
2083 |
X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); } |
X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); } |
2084 |
DOT2(xor) |
DOT2(xor) |
2085 |
|
X(eqv) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) ^ reg(ic->arg[1])); } |
2086 |
|
DOT2(eqv) |
2087 |
|
|
2088 |
|
|
2089 |
/* |
/* |
2477 |
*/ |
*/ |
2478 |
X(tlbia) |
X(tlbia) |
2479 |
{ |
{ |
2480 |
printf("[ tlbia ]\n"); |
fatal("[ tlbia ]\n"); |
2481 |
cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL); |
cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL); |
2482 |
} |
} |
2483 |
|
|
2487 |
*/ |
*/ |
2488 |
X(tlbie) |
X(tlbie) |
2489 |
{ |
{ |
2490 |
|
/* fatal("[ tlbie ]\n"); */ |
2491 |
cpu->invalidate_translation_caches(cpu, reg(ic->arg[0]), |
cpu->invalidate_translation_caches(cpu, reg(ic->arg[0]), |
2492 |
INVALIDATE_VADDR); |
INVALIDATE_VADDR); |
2493 |
} |
} |
2516 |
X(user_syscall) |
X(user_syscall) |
2517 |
{ |
{ |
2518 |
useremul_syscall(cpu, ic->arg[0]); |
useremul_syscall(cpu, ic->arg[0]); |
2519 |
|
|
2520 |
|
if (!cpu->running) { |
2521 |
|
cpu->running_translated = 0; |
2522 |
|
cpu->n_translated_instrs --; |
2523 |
|
cpu->cd.ppc.next_ic = ¬hing_call; |
2524 |
|
} |
2525 |
} |
} |
2526 |
|
|
2527 |
|
|
2599 |
/* |
/* |
2600 |
* ppc_instr_to_be_translated(): |
* ppc_instr_to_be_translated(): |
2601 |
* |
* |
2602 |
* Translate an instruction word into an ppc_instr_call. ic is filled in with |
* Translate an instruction word into a ppc_instr_call. ic is filled in with |
2603 |
* valid data for the translated instruction, or a "nothing" instruction if |
* valid data for the translated instruction, or a "nothing" instruction if |
2604 |
* there was a translation failure. The newly translated instruction is then |
* there was a translation failure. The newly translated instruction is then |
2605 |
* executed. |
* executed. |
2610 |
uint32_t iword, mask; |
uint32_t iword, mask; |
2611 |
unsigned char *page; |
unsigned char *page; |
2612 |
unsigned char ib[4]; |
unsigned char ib[4]; |
|
#ifdef DYNTRANS_BACKEND |
|
|
int simple = 0; |
|
|
#endif |
|
2613 |
int main_opcode, rt, rs, ra, rb, rc, aa_bit, l_bit, lk_bit, spr, sh, |
int main_opcode, rt, rs, ra, rb, rc, aa_bit, l_bit, lk_bit, spr, sh, |
2614 |
xo, imm, load, size, update, zero, bf, bo, bi, bh, oe_bit, n64=0, |
xo, imm, load, size, update, zero, bf, bo, bi, bh, oe_bit, n64=0, |
2615 |
bfa, fp, byterev, nb, mb, me; |
bfa, fp, byterev, nb, mb, me; |
2626 |
addr &= ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1); |
addr &= ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1); |
2627 |
|
|
2628 |
/* Read the instruction word from memory: */ |
/* Read the instruction word from memory: */ |
2629 |
page = cpu->cd.ppc.host_load[addr >> 12]; |
#ifdef MODE32 |
2630 |
|
page = cpu->cd.ppc.host_load[((uint32_t)addr) >> 12]; |
2631 |
|
#else |
2632 |
|
{ |
2633 |
|
const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1; |
2634 |
|
const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1; |
2635 |
|
const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1; |
2636 |
|
uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1; |
2637 |
|
uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2; |
2638 |
|
uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N- |
2639 |
|
DYNTRANS_L3N)) & mask3; |
2640 |
|
struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.ppc.l1_64[x1]; |
2641 |
|
struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2]; |
2642 |
|
page = l3->host_load[x3]; |
2643 |
|
} |
2644 |
|
#endif |
2645 |
|
|
2646 |
if (page != NULL) { |
if (page != NULL) { |
2647 |
/* fatal("TRANSLATION HIT!\n"); */ |
/* fatal("TRANSLATION HIT!\n"); */ |
2797 |
case PPC_HI6_LHAU: |
case PPC_HI6_LHAU: |
2798 |
case PPC_HI6_LWZ: |
case PPC_HI6_LWZ: |
2799 |
case PPC_HI6_LWZU: |
case PPC_HI6_LWZU: |
2800 |
|
case PPC_HI6_LD: |
2801 |
case PPC_HI6_LFD: |
case PPC_HI6_LFD: |
2802 |
case PPC_HI6_LFS: |
case PPC_HI6_LFS: |
2803 |
case PPC_HI6_STB: |
case PPC_HI6_STB: |
2806 |
case PPC_HI6_STHU: |
case PPC_HI6_STHU: |
2807 |
case PPC_HI6_STW: |
case PPC_HI6_STW: |
2808 |
case PPC_HI6_STWU: |
case PPC_HI6_STWU: |
2809 |
|
case PPC_HI6_STD: |
2810 |
case PPC_HI6_STFD: |
case PPC_HI6_STFD: |
2811 |
case PPC_HI6_STFS: |
case PPC_HI6_STFS: |
2812 |
rs = (iword >> 21) & 31; |
rs = (iword >> 21) & 31; |
2823 |
case PPC_HI6_LHZU: load=1; size=1; update=1; break; |
case PPC_HI6_LHZU: load=1; size=1; update=1; break; |
2824 |
case PPC_HI6_LWZ: load=1; size=2; break; |
case PPC_HI6_LWZ: load=1; size=2; break; |
2825 |
case PPC_HI6_LWZU: load=1; size=2; update=1; break; |
case PPC_HI6_LWZU: load=1; size=2; update=1; break; |
2826 |
|
case PPC_HI6_LD: load=1; size=3; break; |
2827 |
case PPC_HI6_LFD: load=1; size=3; fp=1;ic->f=instr(lfd);break; |
case PPC_HI6_LFD: load=1; size=3; fp=1;ic->f=instr(lfd);break; |
2828 |
case PPC_HI6_LFS: load=1; size=2; fp=1;ic->f=instr(lfs);break; |
case PPC_HI6_LFS: load=1; size=2; fp=1;ic->f=instr(lfs);break; |
2829 |
case PPC_HI6_STB: break; |
case PPC_HI6_STB: break; |
2832 |
case PPC_HI6_STHU: size=1; update=1; break; |
case PPC_HI6_STHU: size=1; update=1; break; |
2833 |
case PPC_HI6_STW: size=2; break; |
case PPC_HI6_STW: size=2; break; |
2834 |
case PPC_HI6_STWU: size=2; update=1; break; |
case PPC_HI6_STWU: size=2; update=1; break; |
2835 |
|
case PPC_HI6_STD: size=3; break; |
2836 |
case PPC_HI6_STFD: size=3; fp=1; ic->f = instr(stfd); break; |
case PPC_HI6_STFD: size=3; fp=1; ic->f = instr(stfd); break; |
2837 |
case PPC_HI6_STFS: size=2; fp=1; ic->f = instr(stfs); break; |
case PPC_HI6_STFS: size=2; fp=1; ic->f = instr(stfs); break; |
2838 |
} |
} |
3002 |
ic->f = instr(rfi); |
ic->f = instr(rfi); |
3003 |
break; |
break; |
3004 |
|
|
3005 |
|
case PPC_19_RFID: |
3006 |
|
ic->f = instr(rfid); |
3007 |
|
break; |
3008 |
|
|
3009 |
case PPC_19_MCRF: |
case PPC_19_MCRF: |
3010 |
bf = (iword >> 23) & 7; |
bf = (iword >> 23) & 7; |
3011 |
bfa = (iword >> 18) & 7; |
bfa = (iword >> 18) & 7; |
3095 |
xo = (iword >> 2) & 7; |
xo = (iword >> 2) & 7; |
3096 |
switch (xo) { |
switch (xo) { |
3097 |
|
|
3098 |
|
case PPC_30_RLDICL: |
3099 |
case PPC_30_RLDICR: |
case PPC_30_RLDICR: |
3100 |
ic->f = instr(rldicr); |
case PPC_30_RLDIMI: |
3101 |
|
switch (xo) { |
3102 |
|
case PPC_30_RLDICL: ic->f = instr(rldicl); break; |
3103 |
|
case PPC_30_RLDICR: ic->f = instr(rldicr); break; |
3104 |
|
case PPC_30_RLDIMI: ic->f = instr(rldimi); break; |
3105 |
|
} |
3106 |
ic->arg[0] = iword; |
ic->arg[0] = iword; |
3107 |
if (cpu->cd.ppc.bits == 32) { |
if (cpu->cd.ppc.bits == 32) { |
3108 |
fatal("TODO: rldicr in 32-bit mode?\n"); |
fatal("TODO: rld* in 32-bit mode?\n"); |
3109 |
goto bad; |
goto bad; |
3110 |
} |
} |
3111 |
break; |
break; |
3199 |
break; |
break; |
3200 |
|
|
3201 |
case PPC_31_MTMSR: |
case PPC_31_MTMSR: |
3202 |
|
case PPC_31_MTMSRD: |
3203 |
rs = (iword >> 21) & 31; |
rs = (iword >> 21) & 31; |
3204 |
l_bit = (iword >> 16) & 1; |
l_bit = (iword >> 16) & 1; |
3205 |
if (l_bit) { |
if (l_bit) { |
3208 |
} |
} |
3209 |
ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]); |
ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]); |
3210 |
ic->arg[1] = (addr & 0xfff) + 4; |
ic->arg[1] = (addr & 0xfff) + 4; |
3211 |
|
ic->arg[2] = xo == PPC_31_MTMSRD; |
3212 |
ic->f = instr(mtmsr); |
ic->f = instr(mtmsr); |
3213 |
break; |
break; |
3214 |
|
|
3274 |
break; |
break; |
3275 |
|
|
3276 |
case PPC_31_SYNC: |
case PPC_31_SYNC: |
3277 |
|
case PPC_31_DSSALL: |
3278 |
case PPC_31_EIEIO: |
case PPC_31_EIEIO: |
3279 |
case PPC_31_DCBST: |
case PPC_31_DCBST: |
3280 |
case PPC_31_DCBTST: |
case PPC_31_DCBTST: |
3483 |
case PPC_31_EXTSH: |
case PPC_31_EXTSH: |
3484 |
case PPC_31_EXTSW: |
case PPC_31_EXTSW: |
3485 |
case PPC_31_SLW: |
case PPC_31_SLW: |
3486 |
|
case PPC_31_SLD: |
3487 |
case PPC_31_SRAW: |
case PPC_31_SRAW: |
3488 |
case PPC_31_SRW: |
case PPC_31_SRW: |
3489 |
case PPC_31_AND: |
case PPC_31_AND: |
3493 |
case PPC_31_OR: |
case PPC_31_OR: |
3494 |
case PPC_31_ORC: |
case PPC_31_ORC: |
3495 |
case PPC_31_XOR: |
case PPC_31_XOR: |
3496 |
|
case PPC_31_EQV: |
3497 |
rs = (iword >> 21) & 31; |
rs = (iword >> 21) & 31; |
3498 |
ra = (iword >> 16) & 31; |
ra = (iword >> 16) & 31; |
3499 |
rb = (iword >> 11) & 31; |
rb = (iword >> 11) & 31; |
3508 |
rc_f = instr(extsw_dot); break; |
rc_f = instr(extsw_dot); break; |
3509 |
case PPC_31_SLW: ic->f = instr(slw); |
case PPC_31_SLW: ic->f = instr(slw); |
3510 |
rc_f = instr(slw_dot); break; |
rc_f = instr(slw_dot); break; |
3511 |
|
case PPC_31_SLD: ic->f = instr(sld); |
3512 |
|
rc_f = instr(sld_dot); break; |
3513 |
case PPC_31_SRAW: ic->f = instr(sraw); |
case PPC_31_SRAW: ic->f = instr(sraw); |
3514 |
rc_f = instr(sraw_dot); break; |
rc_f = instr(sraw_dot); break; |
3515 |
case PPC_31_SRW: ic->f = instr(srw); |
case PPC_31_SRW: ic->f = instr(srw); |
3529 |
rc_f = instr(orc_dot); break; |
rc_f = instr(orc_dot); break; |
3530 |
case PPC_31_XOR: ic->f = instr(xor); |
case PPC_31_XOR: ic->f = instr(xor); |
3531 |
rc_f = instr(xor_dot); break; |
rc_f = instr(xor_dot); break; |
3532 |
|
case PPC_31_EQV: ic->f = instr(eqv); |
3533 |
|
rc_f = instr(eqv_dot); break; |
3534 |
} |
} |
3535 |
ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]); |
ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]); |
3536 |
ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]); |
ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]); |
3623 |
} |
} |
3624 |
break; |
break; |
3625 |
|
|
|
case 359: |
|
|
fatal("[ TODO: 359 ]\n"); |
|
|
ic->f = instr(nop); |
|
|
break; |
|
3626 |
case PPC_31_LVX: |
case PPC_31_LVX: |
3627 |
fatal("[ TODO: lvx ]\n"); |
case PPC_31_LVXL: |
|
ic->f = instr(nop); |
|
|
break; |
|
3628 |
case PPC_31_STVX: |
case PPC_31_STVX: |
|
fatal("[ TODO: stvx ]\n"); |
|
|
ic->f = instr(nop); |
|
|
break; |
|
3629 |
case PPC_31_STVXL: |
case PPC_31_STVXL: |
3630 |
fatal("[ TODO: stvxl ]\n"); |
fatal("[ TODO: altivec load/store ]\n"); |
3631 |
ic->f = instr(nop); |
load = 0; |
3632 |
|
switch (xo) { |
3633 |
|
case PPC_31_LVX: |
3634 |
|
case PPC_31_LVXL: |
3635 |
|
load = 1; break; |
3636 |
|
} |
3637 |
|
rs = (iword >> 21) & 31; |
3638 |
|
ra = (iword >> 16) & 31; |
3639 |
|
rb = (iword >> 11) & 31; |
3640 |
|
ic->arg[0] = (size_t)(&cpu->cd.ppc.vr_hi[rs]); |
3641 |
|
if (ra == 0) |
3642 |
|
ic->arg[1] = (size_t)(&cpu->cd.ppc.zero); |
3643 |
|
else |
3644 |
|
ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]); |
3645 |
|
ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]); |
3646 |
|
ic->f = |
3647 |
|
#ifdef MODE32 |
3648 |
|
ppc32_loadstore_indexed |
3649 |
|
#else |
3650 |
|
ppc_loadstore_indexed |
3651 |
|
#endif |
3652 |
|
[3 + 4 * load]; |
3653 |
break; |
break; |
3654 |
|
|
3655 |
default:goto bad; |
default:goto bad; |