25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: cpu_ppc.c,v 1.61 2005/04/01 16:44:36 debug Exp $ |
* $Id: cpu_ppc.c,v 1.62 2005/04/18 23:00:56 debug Exp $ |
29 |
* |
* |
30 |
* PowerPC/POWER CPU emulation. |
* PowerPC/POWER CPU emulation. |
31 |
*/ |
*/ |
1038 |
case PPC_31_SYNC: |
case PPC_31_SYNC: |
1039 |
debug("%s", power? "dcs" : "sync"); |
debug("%s", power? "dcs" : "sync"); |
1040 |
break; |
break; |
1041 |
|
case PPC_31_LSWI: |
1042 |
case PPC_31_STSWI: |
case PPC_31_STSWI: |
1043 |
rs = (iword >> 21) & 31; |
rs = (iword >> 21) & 31; /* lwsi uses rt */ |
1044 |
ra = (iword >> 16) & 31; |
ra = (iword >> 16) & 31; |
1045 |
nb = (iword >> 11) & 31; |
nb = (iword >> 11) & 31; |
1046 |
debug("%s\tr%i,r%i,%i", power? "stsi" : "stswi", |
switch (xo) { |
1047 |
rs, ra, nb); |
case PPC_31_LSWI: |
1048 |
|
mnem = power? "lsi" : "lswi"; break; |
1049 |
|
case PPC_31_STSWI: |
1050 |
|
mnem = power? "stsi" : "stswi"; break; |
1051 |
|
} |
1052 |
|
debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb); |
1053 |
if (running) |
if (running) |
1054 |
goto disasm_ret_nonewline; |
goto disasm_ret_nonewline; |
1055 |
break; |
break; |
2467 |
/* TODO: actually sync */ |
/* TODO: actually sync */ |
2468 |
break; |
break; |
2469 |
|
|
2470 |
|
case PPC_31_LSWI: |
2471 |
case PPC_31_STSWI: |
case PPC_31_STSWI: |
2472 |
rs = (iword >> 21) & 31; |
rs = (iword >> 21) & 31; |
2473 |
ra = (iword >> 16) & 31; |
ra = (iword >> 16) & 31; |
2479 |
else |
else |
2480 |
addr = cpu->cd.ppc.gpr[ra]; |
addr = cpu->cd.ppc.gpr[ra]; |
2481 |
|
|
2482 |
|
load = 0; |
2483 |
|
if (xo == PPC_31_LSWI) |
2484 |
|
load = 1; |
2485 |
|
|
2486 |
if (cpu->machine->instruction_trace) { |
if (cpu->machine->instruction_trace) { |
2487 |
if (cpu->cd.ppc.bits == 32) |
if (cpu->cd.ppc.bits == 32) |
2488 |
debug("\t[0x%08llx", (long long)addr); |
debug("\t[0x%08llx", (long long)addr); |
2491 |
} |
} |
2492 |
|
|
2493 |
i = 24; |
i = 24; |
2494 |
r = 0; /* There can be multiple errors */ |
r = 0; /* Error count. */ |
2495 |
while (nb > 0) { |
while (nb-- > 0) { |
2496 |
tmp_data[0] = cpu->cd.ppc.gpr[rs] >> i; |
if (load) { |
2497 |
if (cpu->memory_rw(cpu, cpu->mem, addr, |
/* (Actually rt should be used.) */ |
2498 |
tmp_data, 1, MEM_WRITE, CACHE_DATA) |
if (cpu->memory_rw(cpu, cpu->mem, addr, |
2499 |
!= MEMORY_ACCESS_OK) |
tmp_data, 1, MEM_READ, CACHE_DATA) |
2500 |
r++; |
!= MEMORY_ACCESS_OK) { |
2501 |
nb--; addr++; i-=8; |
r++; |
2502 |
|
break; |
2503 |
|
} |
2504 |
|
if (i == 24) |
2505 |
|
cpu->cd.ppc.gpr[rs] = 0; |
2506 |
|
cpu->cd.ppc.gpr[rs] |= |
2507 |
|
(tmp_data[0] << i); |
2508 |
|
} else { |
2509 |
|
tmp_data[0] = cpu->cd.ppc.gpr[rs] >> i; |
2510 |
|
if (cpu->memory_rw(cpu, cpu->mem, addr, |
2511 |
|
tmp_data, 1, MEM_WRITE, CACHE_DATA) |
2512 |
|
!= MEMORY_ACCESS_OK) { |
2513 |
|
r++; |
2514 |
|
break; |
2515 |
|
} |
2516 |
|
} |
2517 |
|
addr++; i-=8; |
2518 |
if (i < 0) { |
if (i < 0) { |
2519 |
i = 24; |
i = 24; |
2520 |
rs = (rs + 1) % 32; |
rs = (rs + 1) % 32; |
2530 |
|
|
2531 |
if (r > 0) { |
if (r > 0) { |
2532 |
/* TODO: exception */ |
/* TODO: exception */ |
2533 |
|
fatal("TODO: exception.\n"); |
2534 |
return 0; |
return 0; |
2535 |
} |
} |
2536 |
break; |
break; |