25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: cpu_sh_instr.c,v 1.49 2007/01/28 16:59:06 debug Exp $ |
* $Id: cpu_sh_instr.c,v 1.51 2007/03/08 19:04:09 debug Exp $ |
29 |
* |
* |
30 |
* SH instructions. |
* SH instructions. |
31 |
* |
* |
285 |
|
|
286 |
|
|
287 |
/* |
/* |
288 |
* mov_b_rm_predec_rn: mov.b reg,@-Rn |
* mov_b_rm_predec_rn: mov.b reg,@-Rn |
289 |
* mov_w_rm_predec_rn: mov.w reg,@-Rn |
* mov_w_rm_predec_rn: mov.w reg,@-Rn |
290 |
* mov_l_rm_predec_rn: mov.l reg,@-Rn |
* mov_l_rm_predec_rn: mov.l reg,@-Rn |
291 |
* stc_l_rm_predec_rn: mov.l reg,@-Rn, with MD status bit check |
* stc_l_rm_predec_rn_md: mov.l reg,@-Rn, with MD status bit check |
292 |
* |
* |
293 |
* arg[0] = ptr to rm (or other register) |
* arg[0] = ptr to rm (or other register) |
294 |
* arg[1] = ptr to rn |
* arg[1] = ptr to rn |
362 |
reg(ic->arg[1]) = addr; |
reg(ic->arg[1]) = addr; |
363 |
} |
} |
364 |
} |
} |
365 |
X(stc_l_rm_predec_rn) |
X(stc_l_rm_predec_rn_md) |
366 |
{ |
{ |
367 |
uint32_t addr = reg(ic->arg[1]) - sizeof(uint32_t); |
uint32_t addr = reg(ic->arg[1]) - sizeof(uint32_t); |
368 |
uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12]; |
uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12]; |
2632 |
|
|
2633 |
|
|
2634 |
/* |
/* |
2635 |
* prom_emul_dreamcast: |
* prom_emul: |
2636 |
*/ |
*/ |
2637 |
X(prom_emul_dreamcast) |
X(prom_emul) |
2638 |
{ |
{ |
2639 |
uint32_t old_pc; |
uint32_t old_pc; |
2640 |
SYNCH_PC; |
SYNCH_PC; |
2641 |
old_pc = cpu->pc; |
old_pc = cpu->pc; |
2642 |
|
|
2643 |
dreamcast_emul(cpu); |
switch (cpu->machine->machine_type) { |
2644 |
|
case MACHINE_DREAMCAST: |
2645 |
|
dreamcast_emul(cpu); |
2646 |
|
break; |
2647 |
|
case MACHINE_LANDISK: |
2648 |
|
sh_ipl_g_emul(cpu); |
2649 |
|
break; |
2650 |
|
default: |
2651 |
|
fatal("SH prom_emul: unimplemented machine type.\n"); |
2652 |
|
exit(1); |
2653 |
|
} |
2654 |
|
|
2655 |
if (!cpu->running) { |
if (!cpu->running) { |
2656 |
cpu->n_translated_instrs --; |
cpu->n_translated_instrs --; |
2901 |
ic->f = instr(copy_privileged_register); |
ic->f = instr(copy_privileged_register); |
2902 |
ic->arg[0] = (size_t)&cpu->cd.sh.r_bank[(lo8 >> 4) & 7]; |
ic->arg[0] = (size_t)&cpu->cd.sh.r_bank[(lo8 >> 4) & 7]; |
2903 |
} else if (iword == SH_INVALID_INSTR) { |
} else if (iword == SH_INVALID_INSTR) { |
2904 |
/* PROM emulation specifically for Dreamcast */ |
/* PROM emulation (GXemul specific) */ |
2905 |
ic->f = instr(prom_emul_dreamcast); |
ic->f = instr(prom_emul); |
2906 |
} else { |
} else { |
2907 |
switch (lo8) { |
switch (lo8) { |
2908 |
case 0x02: /* STC SR,Rn */ |
case 0x02: /* STC SR,Rn */ |
3112 |
ic->f = instr(shld); |
ic->f = instr(shld); |
3113 |
} else if ((lo8 & 0x8f) == 0x83) { |
} else if ((lo8 & 0x8f) == 0x83) { |
3114 |
/* STC.L Rm_BANK,@-Rn */ |
/* STC.L Rm_BANK,@-Rn */ |
3115 |
ic->f = instr(stc_l_rm_predec_rn); |
ic->f = instr(stc_l_rm_predec_rn_md); |
3116 |
ic->arg[0] = (size_t)&cpu->cd.sh.r_bank[ |
ic->arg[0] = (size_t)&cpu->cd.sh.r_bank[ |
3117 |
(lo8 >> 4) & 7]; /* m */ |
(lo8 >> 4) & 7]; /* m */ |
3118 |
} else if ((lo8 & 0x8f) == 0x87) { |
} else if ((lo8 & 0x8f) == 0x87) { |
3137 |
ic->arg[0] = (size_t)&cpu->cd.sh.mach; |
ic->arg[0] = (size_t)&cpu->cd.sh.mach; |
3138 |
break; |
break; |
3139 |
case 0x03: /* STC.L SR,@-Rn */ |
case 0x03: /* STC.L SR,@-Rn */ |
3140 |
ic->f = instr(stc_l_rm_predec_rn); |
ic->f = instr(stc_l_rm_predec_rn_md); |
3141 |
ic->arg[0] = (size_t)&cpu->cd.sh.sr; |
ic->arg[0] = (size_t)&cpu->cd.sh.sr; |
3142 |
break; |
break; |
3143 |
case 0x04: /* ROTL Rn */ |
case 0x04: /* ROTL Rn */ |
3182 |
ic->arg[0] = (size_t)&cpu->cd.sh.macl; |
ic->arg[0] = (size_t)&cpu->cd.sh.macl; |
3183 |
break; |
break; |
3184 |
case 0x13: /* STC.L GBR,@-Rn */ |
case 0x13: /* STC.L GBR,@-Rn */ |
3185 |
ic->f = instr(stc_l_rm_predec_rn); |
ic->f = instr(mov_l_rm_predec_rn); |
3186 |
ic->arg[0] = (size_t)&cpu->cd.sh.gbr; |
ic->arg[0] = (size_t)&cpu->cd.sh.gbr; |
3187 |
break; |
break; |
3188 |
case 0x15: /* CMP/PL Rn */ |
case 0x15: /* CMP/PL Rn */ |
3193 |
ic->arg[0] = (size_t)&cpu->cd.sh.macl; |
ic->arg[0] = (size_t)&cpu->cd.sh.macl; |
3194 |
break; |
break; |
3195 |
case 0x17: /* LDC.L @Rm+,GBR */ |
case 0x17: /* LDC.L @Rm+,GBR */ |
3196 |
ic->f = instr(mov_l_arg1_postinc_to_arg0_md); |
ic->f = instr(mov_l_arg1_postinc_to_arg0); |
3197 |
ic->arg[0] = (size_t)&cpu->cd.sh.gbr; |
ic->arg[0] = (size_t)&cpu->cd.sh.gbr; |
3198 |
break; |
break; |
3199 |
case 0x18: /* SHLL8 Rn */ |
case 0x18: /* SHLL8 Rn */ |
3222 |
ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */ |
ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */ |
3223 |
break; |
break; |
3224 |
case 0x23: /* STC.L VBR,@-Rn */ |
case 0x23: /* STC.L VBR,@-Rn */ |
3225 |
ic->f = instr(stc_l_rm_predec_rn); |
ic->f = instr(stc_l_rm_predec_rn_md); |
3226 |
ic->arg[0] = (size_t)&cpu->cd.sh.vbr; |
ic->arg[0] = (size_t)&cpu->cd.sh.vbr; |
3227 |
break; |
break; |
3228 |
case 0x24: /* ROTCL Rn */ |
case 0x24: /* ROTCL Rn */ |
3264 |
ic->arg[1] = (size_t)&cpu->cd.sh.vbr; |
ic->arg[1] = (size_t)&cpu->cd.sh.vbr; |
3265 |
break; |
break; |
3266 |
case 0x33: /* STC.L SSR,@-Rn */ |
case 0x33: /* STC.L SSR,@-Rn */ |
3267 |
ic->f = instr(stc_l_rm_predec_rn); |
ic->f = instr(stc_l_rm_predec_rn_md); |
3268 |
ic->arg[0] = (size_t)&cpu->cd.sh.ssr; |
ic->arg[0] = (size_t)&cpu->cd.sh.ssr; |
3269 |
break; |
break; |
3270 |
case 0x37: /* LDC.L @Rm+,SSR */ |
case 0x37: /* LDC.L @Rm+,SSR */ |
3277 |
ic->arg[1] = (size_t)&cpu->cd.sh.ssr; |
ic->arg[1] = (size_t)&cpu->cd.sh.ssr; |
3278 |
break; |
break; |
3279 |
case 0x43: /* STC.L SPC,@-Rn */ |
case 0x43: /* STC.L SPC,@-Rn */ |
3280 |
ic->f = instr(stc_l_rm_predec_rn); |
ic->f = instr(stc_l_rm_predec_rn_md); |
3281 |
ic->arg[0] = (size_t)&cpu->cd.sh.spc; |
ic->arg[0] = (size_t)&cpu->cd.sh.spc; |
3282 |
break; |
break; |
3283 |
case 0x47: /* LDC.L @Rm+,SPC */ |
case 0x47: /* LDC.L @Rm+,SPC */ |