1.1 --- a/src/sh4/sh4core.c Tue Jan 23 08:17:06 2007 +0000
1.2 +++ b/src/sh4/sh4core.c Tue Aug 28 08:46:14 2007 +0000
1.5 - * $Id: sh4core.c,v 1.40 2007-01-23 08:17:06 nkeynes Exp $
1.6 + * $Id: sh4core.c,v 1.41 2007-08-23 12:33:27 nkeynes Exp $
1.8 * SH4 emulation core, and parent module for all the SH4 peripheral
1.11 void sh4_stop( void );
1.12 void sh4_save_state( FILE *f );
1.13 int sh4_load_state( FILE *f );
1.14 -static void sh4_accept_interrupt( void );
1.15 +void sh4_accept_interrupt( void );
1.17 struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_reset,
1.18 NULL, sh4_run_slice, sh4_stop,
1.20 #define CHECKWALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_WRITE_ADDR_ERR )
1.21 #define CHECKWALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_WRITE_ADDR_ERR )
1.23 -#define CHECKFPUEN() if( !IS_FPU_ENABLED() ) return sh4_raise_slot_exception( EXC_FPDISABLE, EXC_SLOT_FPDISABLE )
1.24 +#define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPDISABLE, EXC_SLOT_FPDISABLE ); } }
1.25 #define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }
1.26 #define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)
1.29 RAISE( code, EXV_TLBMISS );
1.32 -static void sh4_accept_interrupt( void )
1.33 +void sh4_accept_interrupt( void )
1.35 uint32_t code = intc_accept_interrupt();
1.36 sh4r.ssr = sh4_read_sr();
1.37 @@ -433,39 +433,10 @@
1.45 #define R0 sh4r.r[0]
1.48 -#define RN(ir) sh4r.r[(ir&0x0F00)>>8]
1.49 -#define RN_BANK(ir) sh4r.r_bank[(ir&0x0070)>>4]
1.50 -#define RM(ir) sh4r.r[(ir&0x00F0)>>4]
1.51 -#define DISP4(ir) (ir&0x000F) /* 4-bit displacements are *NOT* sign-extended */
1.52 -#define DISP8(ir) (ir&0x00FF)
1.53 -#define PCDISP8(ir) SIGNEXT8(ir&0x00FF)
1.54 -#define IMM8(ir) SIGNEXT8(ir&0x00FF)
1.55 -#define UIMM8(ir) (ir&0x00FF) /* Unsigned immmediate */
1.56 -#define DISP12(ir) SIGNEXT12(ir&0x0FFF)
1.57 -#define FRNn(ir) ((ir&0x0F00)>>8)
1.58 -#define FRMn(ir) ((ir&0x00F0)>>4)
1.59 -#define DRNn(ir) ((ir&0x0E00)>>9)
1.60 -#define DRMn(ir) ((ir&0x00E0)>>5)
1.61 -#define FVN(ir) ((ir&0x0C00)>>8)
1.62 -#define FVM(ir) ((ir&0x0300)>>6)
1.63 -#define FRN(ir) FR(FRNn(ir))
1.64 -#define FRM(ir) FR(FRMn(ir))
1.65 -#define FRNi(ir) (*((uint32_t *)&FR(FRNn(ir))))
1.66 -#define FRMi(ir) (*((uint32_t *)&FR(FRMn(ir))))
1.67 -#define DRN(ir) DRb(DRNn(ir), ir&0x0100)
1.68 -#define DRM(ir) DRb(DRMn(ir),ir&0x0010)
1.69 -#define DRNi(ir) (*((uint64_t *)&DR(FRNn(ir))))
1.70 -#define DRMi(ir) (*((uint64_t *)&DR(FRMn(ir))))
1.71 -#define FPULf *((float *)&sh4r.fpul)
1.72 -#define FPULi (sh4r.fpul)
1.75 if( pc > 0xFFFFFF00 ) {
1.77 @@ -493,1176 +464,1891 @@
1.78 ir = sh4_icache[(pc&0xFFF)>>1];
1.82 - switch( (ir&0xF000)>>12 ) {
1.83 - case 0: /* 0000nnnnmmmmxxxx */
1.84 - switch( ir&0x000F ) {
1.86 - switch( (ir&0x00F0)>>4 ) {
1.87 - case 0: /* STC SR, Rn */
1.89 - RN(ir) = sh4_read_sr();
1.91 - case 1: /* STC GBR, Rn */
1.92 - RN(ir) = sh4r.gbr;
1.94 - case 2: /* STC VBR, Rn */
1.96 - RN(ir) = sh4r.vbr;
1.98 - case 3: /* STC SSR, Rn */
1.100 - RN(ir) = sh4r.ssr;
1.102 - case 4: /* STC SPC, Rn */
1.104 - RN(ir) = sh4r.spc;
1.106 - case 8: case 9: case 10: case 11: case 12: case 13:
1.107 - case 14: case 15:/* STC Rm_bank, Rn */
1.109 - RN(ir) = RN_BANK(ir);
1.111 - default: UNDEF(ir);
1.115 - switch( (ir&0x00F0)>>4 ) {
1.116 - case 0: /* BSRF Rn */
1.117 - CHECKSLOTILLEGAL();
1.118 - CHECKDEST( pc + 4 + RN(ir) );
1.119 - sh4r.in_delay_slot = 1;
1.120 - sh4r.pr = sh4r.pc + 4;
1.121 - sh4r.pc = sh4r.new_pc;
1.122 - sh4r.new_pc = pc + 4 + RN(ir);
1.123 - TRACE_CALL( pc, sh4r.new_pc );
1.124 + switch( (ir&0xF000) >> 12 ) {
1.126 + switch( ir&0xF ) {
1.128 + switch( (ir&0x80) >> 7 ) {
1.130 + switch( (ir&0x70) >> 4 ) {
1.132 + { /* STC SR, Rn */
1.133 + uint32_t Rn = ((ir>>8)&0xF);
1.135 + sh4r.r[Rn] = sh4_read_sr();
1.139 + { /* STC GBR, Rn */
1.140 + uint32_t Rn = ((ir>>8)&0xF);
1.142 + sh4r.r[Rn] = sh4r.gbr;
1.146 + { /* STC VBR, Rn */
1.147 + uint32_t Rn = ((ir>>8)&0xF);
1.149 + sh4r.r[Rn] = sh4r.vbr;
1.153 + { /* STC SSR, Rn */
1.154 + uint32_t Rn = ((ir>>8)&0xF);
1.156 + sh4r.r[Rn] = sh4r.ssr;
1.160 + { /* STC SPC, Rn */
1.161 + uint32_t Rn = ((ir>>8)&0xF);
1.163 + sh4r.r[Rn] = sh4r.spc;
1.172 + { /* STC Rm_BANK, Rn */
1.173 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1.175 + sh4r.r[Rn] = sh4r.r_bank[Rm_BANK];
1.181 + switch( (ir&0xF0) >> 4 ) {
1.184 + uint32_t Rn = ((ir>>8)&0xF);
1.185 + CHECKSLOTILLEGAL();
1.186 + CHECKDEST( pc + 4 + sh4r.r[Rn] );
1.187 + sh4r.in_delay_slot = 1;
1.188 + sh4r.pr = sh4r.pc + 4;
1.189 + sh4r.pc = sh4r.new_pc;
1.190 + sh4r.new_pc = pc + 4 + sh4r.r[Rn];
1.191 + TRACE_CALL( pc, sh4r.new_pc );
1.197 + uint32_t Rn = ((ir>>8)&0xF);
1.198 + CHECKSLOTILLEGAL();
1.199 + CHECKDEST( pc + 4 + sh4r.r[Rn] );
1.200 + sh4r.in_delay_slot = 1;
1.201 + sh4r.pc = sh4r.new_pc;
1.202 + sh4r.new_pc = pc + 4 + sh4r.r[Rn];
1.208 + uint32_t Rn = ((ir>>8)&0xF);
1.209 + tmp = sh4r.r[Rn];
1.210 + if( (tmp & 0xFC000000) == 0xE0000000 ) {
1.211 + /* Store queue operation */
1.212 + int queue = (tmp&0x20)>>2;
1.213 + int32_t *src = &sh4r.store_queue[queue];
1.214 + uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;
1.215 + uint32_t target = tmp&0x03FFFFE0 | hi;
1.216 + mem_copy_to_sh4( target, src, 32 );
1.222 + uint32_t Rn = ((ir>>8)&0xF);
1.227 + uint32_t Rn = ((ir>>8)&0xF);
1.231 + { /* OCBWB @Rn */
1.232 + uint32_t Rn = ((ir>>8)&0xF);
1.236 + { /* MOVCA.L R0, @Rn */
1.237 + uint32_t Rn = ((ir>>8)&0xF);
1.238 + tmp = sh4r.r[Rn];
1.239 + CHECKWALIGN32(tmp);
1.240 + MEM_WRITE_LONG( tmp, R0 );
1.249 + { /* MOV.B Rm, @(R0, Rn) */
1.250 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.251 + MEM_WRITE_BYTE( R0 + sh4r.r[Rn], sh4r.r[Rm] );
1.255 + { /* MOV.W Rm, @(R0, Rn) */
1.256 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.257 + CHECKWALIGN16( R0 + sh4r.r[Rn] );
1.258 + MEM_WRITE_WORD( R0 + sh4r.r[Rn], sh4r.r[Rm] );
1.262 + { /* MOV.L Rm, @(R0, Rn) */
1.263 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.264 + CHECKWALIGN32( R0 + sh4r.r[Rn] );
1.265 + MEM_WRITE_LONG( R0 + sh4r.r[Rn], sh4r.r[Rm] );
1.269 + { /* MUL.L Rm, Rn */
1.270 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.271 + sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
1.272 + (sh4r.r[Rm] * sh4r.r[Rn]);
1.276 + switch( (ir&0xFF0) >> 4 ) {
1.313 + switch( (ir&0xF0) >> 4 ) {
1.321 + sh4r.m = sh4r.q = sh4r.t = 0;
1.326 + uint32_t Rn = ((ir>>8)&0xF);
1.327 + sh4r.r[Rn] = sh4r.t;
1.336 + switch( (ir&0xF0) >> 4 ) {
1.338 + { /* STS MACH, Rn */
1.339 + uint32_t Rn = ((ir>>8)&0xF);
1.340 + sh4r.r[Rn] = (sh4r.mac>>32);
1.344 + { /* STS MACL, Rn */
1.345 + uint32_t Rn = ((ir>>8)&0xF);
1.346 + sh4r.r[Rn] = (uint32_t)sh4r.mac;
1.350 + { /* STS PR, Rn */
1.351 + uint32_t Rn = ((ir>>8)&0xF);
1.352 + sh4r.r[Rn] = sh4r.pr;
1.356 + { /* STC SGR, Rn */
1.357 + uint32_t Rn = ((ir>>8)&0xF);
1.359 + sh4r.r[Rn] = sh4r.sgr;
1.363 + { /* STS FPUL, Rn */
1.364 + uint32_t Rn = ((ir>>8)&0xF);
1.365 + sh4r.r[Rn] = sh4r.fpul;
1.369 + { /* STS FPSCR, Rn */
1.370 + uint32_t Rn = ((ir>>8)&0xF);
1.371 + sh4r.r[Rn] = sh4r.fpscr;
1.375 + { /* STC DBR, Rn */
1.376 + uint32_t Rn = ((ir>>8)&0xF);
1.377 + CHECKPRIV(); sh4r.r[Rn] = sh4r.dbr;
1.386 + switch( (ir&0xFF0) >> 4 ) {
1.389 + CHECKSLOTILLEGAL();
1.390 + CHECKDEST( sh4r.pr );
1.391 + sh4r.in_delay_slot = 1;
1.392 + sh4r.pc = sh4r.new_pc;
1.393 + sh4r.new_pc = sh4r.pr;
1.394 + TRACE_RETURN( pc, sh4r.new_pc );
1.400 + if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
1.401 + sh4r.sh4_state = SH4_STATE_STANDBY;
1.403 + sh4r.sh4_state = SH4_STATE_SLEEP;
1.405 + return FALSE; /* Halt CPU */
1.411 + CHECKDEST( sh4r.spc );
1.412 + CHECKSLOTILLEGAL();
1.413 + sh4r.in_delay_slot = 1;
1.414 + sh4r.pc = sh4r.new_pc;
1.415 + sh4r.new_pc = sh4r.spc;
1.416 + sh4_load_sr( sh4r.ssr );
1.426 + { /* MOV.B @(R0, Rm), Rn */
1.427 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.428 + sh4r.r[Rn] = MEM_READ_BYTE( R0 + sh4r.r[Rm] );
1.432 + { /* MOV.W @(R0, Rm), Rn */
1.433 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.434 + CHECKRALIGN16( R0 + sh4r.r[Rm] );
1.435 + sh4r.r[Rn] = MEM_READ_WORD( R0 + sh4r.r[Rm] );
1.439 + { /* MOV.L @(R0, Rm), Rn */
1.440 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.441 + CHECKRALIGN32( R0 + sh4r.r[Rm] );
1.442 + sh4r.r[Rn] = MEM_READ_LONG( R0 + sh4r.r[Rm] );
1.446 + { /* MAC.L @Rm+, @Rn+ */
1.447 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.448 + CHECKRALIGN32( sh4r.r[Rm] );
1.449 + CHECKRALIGN32( sh4r.r[Rn] );
1.450 + int64_t tmpl = SIGNEXT32(MEM_READ_LONG(sh4r.r[Rn]));
1.452 + tmpl = tmpl * SIGNEXT32(MEM_READ_LONG(sh4r.r[Rm])) + sh4r.mac;
1.455 + /* 48-bit Saturation. Yuch */
1.456 + if( tmpl < (int64_t)0xFFFF800000000000LL )
1.457 + tmpl = 0xFFFF800000000000LL;
1.458 + else if( tmpl > (int64_t)0x00007FFFFFFFFFFFLL )
1.459 + tmpl = 0x00007FFFFFFFFFFFLL;
1.470 + { /* MOV.L Rm, @(disp, Rn) */
1.471 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1.472 + tmp = sh4r.r[Rn] + disp;
1.473 + CHECKWALIGN32( tmp );
1.474 + MEM_WRITE_LONG( tmp, sh4r.r[Rm] );
1.478 + switch( ir&0xF ) {
1.480 + { /* MOV.B Rm, @Rn */
1.481 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.482 + MEM_WRITE_BYTE( sh4r.r[Rn], sh4r.r[Rm] );
1.486 + { /* MOV.W Rm, @Rn */
1.487 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.488 + CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn], sh4r.r[Rm] );
1.492 + { /* MOV.L Rm, @Rn */
1.493 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.494 + CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r[Rm] );
1.498 + { /* MOV.B Rm, @-Rn */
1.499 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.500 + sh4r.r[Rn] --; MEM_WRITE_BYTE( sh4r.r[Rn], sh4r.r[Rm] );
1.504 + { /* MOV.W Rm, @-Rn */
1.505 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.506 + sh4r.r[Rn] -= 2; CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn], sh4r.r[Rm] );
1.510 + { /* MOV.L Rm, @-Rn */
1.511 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.512 + sh4r.r[Rn] -= 4; CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r[Rm] );
1.516 + { /* DIV0S Rm, Rn */
1.517 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.518 + sh4r.q = sh4r.r[Rn]>>31;
1.519 + sh4r.m = sh4r.r[Rm]>>31;
1.520 + sh4r.t = sh4r.q ^ sh4r.m;
1.524 + { /* TST Rm, Rn */
1.525 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.526 + sh4r.t = (sh4r.r[Rn]&sh4r.r[Rm] ? 0 : 1);
1.530 + { /* AND Rm, Rn */
1.531 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.532 + sh4r.r[Rn] &= sh4r.r[Rm];
1.536 + { /* XOR Rm, Rn */
1.537 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.538 + sh4r.r[Rn] ^= sh4r.r[Rm];
1.542 + { /* OR Rm, Rn */
1.543 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.544 + sh4r.r[Rn] |= sh4r.r[Rm];
1.548 + { /* CMP/STR Rm, Rn */
1.549 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.550 + /* set T = 1 if any byte in RM & RN is the same */
1.551 + tmp = sh4r.r[Rm] ^ sh4r.r[Rn];
1.552 + sh4r.t = ((tmp&0x000000FF)==0 || (tmp&0x0000FF00)==0 ||
1.553 + (tmp&0x00FF0000)==0 || (tmp&0xFF000000)==0)?1:0;
1.557 + { /* XTRCT Rm, Rn */
1.558 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.559 + sh4r.r[Rn] = (sh4r.r[Rn]>>16) | (sh4r.r[Rm]<<16);
1.563 + { /* MULU.W Rm, Rn */
1.564 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.565 + sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
1.566 + (uint32_t)((sh4r.r[Rm]&0xFFFF) * (sh4r.r[Rn]&0xFFFF));
1.570 + { /* MULS.W Rm, Rn */
1.571 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.572 + sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
1.573 + (uint32_t)(SIGNEXT32(sh4r.r[Rm]&0xFFFF) * SIGNEXT32(sh4r.r[Rn]&0xFFFF));
1.582 + switch( ir&0xF ) {
1.584 + { /* CMP/EQ Rm, Rn */
1.585 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.586 + sh4r.t = ( sh4r.r[Rm] == sh4r.r[Rn] ? 1 : 0 );
1.590 + { /* CMP/HS Rm, Rn */
1.591 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.592 + sh4r.t = ( sh4r.r[Rn] >= sh4r.r[Rm] ? 1 : 0 );
1.596 + { /* CMP/GE Rm, Rn */
1.597 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.598 + sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= ((int32_t)sh4r.r[Rm]) ? 1 : 0 );
1.602 + { /* DIV1 Rm, Rn */
1.603 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.604 + /* This is just from the sh4p manual with some
1.605 + * simplifications (someone want to check it's correct? :)
1.606 + * Why they couldn't just provide a real DIV instruction...
1.608 + uint32_t tmp0, tmp1, tmp2, dir;
1.610 + dir = sh4r.q ^ sh4r.m;
1.611 + sh4r.q = (sh4r.r[Rn] >> 31);
1.612 + tmp2 = sh4r.r[Rm];
1.613 + sh4r.r[Rn] = (sh4r.r[Rn] << 1) | sh4r.t;
1.614 + tmp0 = sh4r.r[Rn];
1.616 + sh4r.r[Rn] += tmp2;
1.617 + tmp1 = (sh4r.r[Rn]<tmp0 ? 1 : 0 );
1.619 + sh4r.r[Rn] -= tmp2;
1.620 + tmp1 = (sh4r.r[Rn]>tmp0 ? 1 : 0 );
1.622 + sh4r.q ^= sh4r.m ^ tmp1;
1.623 + sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );
1.627 + { /* DMULU.L Rm, Rn */
1.628 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.629 + sh4r.mac = ((uint64_t)sh4r.r[Rm]) * ((uint64_t)sh4r.r[Rn]);
1.633 + { /* CMP/HI Rm, Rn */
1.634 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.635 + sh4r.t = ( sh4r.r[Rn] > sh4r.r[Rm] ? 1 : 0 );
1.639 + { /* CMP/GT Rm, Rn */
1.640 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.641 + sh4r.t = ( ((int32_t)sh4r.r[Rn]) > ((int32_t)sh4r.r[Rm]) ? 1 : 0 );
1.645 + { /* SUB Rm, Rn */
1.646 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.647 + sh4r.r[Rn] -= sh4r.r[Rm];
1.651 + { /* SUBC Rm, Rn */
1.652 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.653 + tmp = sh4r.r[Rn];
1.654 + sh4r.r[Rn] = sh4r.r[Rn] - sh4r.r[Rm] - sh4r.t;
1.655 + sh4r.t = (sh4r.r[Rn] > tmp || (sh4r.r[Rn] == tmp && sh4r.t == 1));
1.659 + UNIMP(ir); /* SUBV Rm, Rn */
1.662 + { /* ADD Rm, Rn */
1.663 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.664 + sh4r.r[Rn] += sh4r.r[Rm];
1.668 + { /* DMULS.L Rm, Rn */
1.669 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.670 + sh4r.mac = SIGNEXT32(sh4r.r[Rm]) * SIGNEXT32(sh4r.r[Rn]);
1.674 + { /* ADDC Rm, Rn */
1.675 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.676 + tmp = sh4r.r[Rn];
1.677 + sh4r.r[Rn] += sh4r.r[Rm] + sh4r.t;
1.678 + sh4r.t = ( sh4r.r[Rn] < tmp || (sh4r.r[Rn] == tmp && sh4r.t != 0) ? 1 : 0 );
1.682 + { /* ADDV Rm, Rn */
1.683 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.684 + tmp = sh4r.r[Rn] + sh4r.r[Rm];
1.685 + sh4r.t = ( (sh4r.r[Rn]>>31) == (sh4r.r[Rm]>>31) && ((sh4r.r[Rn]>>31) != (tmp>>31)) );
1.686 + sh4r.r[Rn] = tmp;
1.695 + switch( ir&0xF ) {
1.697 + switch( (ir&0xF0) >> 4 ) {
1.700 + uint32_t Rn = ((ir>>8)&0xF);
1.701 + sh4r.t = sh4r.r[Rn] >> 31; sh4r.r[Rn] <<= 1;
1.706 + uint32_t Rn = ((ir>>8)&0xF);
1.708 + sh4r.t = ( sh4r.r[Rn] == 0 ? 1 : 0 );
1.713 + uint32_t Rn = ((ir>>8)&0xF);
1.714 + sh4r.t = sh4r.r[Rn] >> 31;
1.715 + sh4r.r[Rn] <<= 1;
1.724 + switch( (ir&0xF0) >> 4 ) {
1.727 + uint32_t Rn = ((ir>>8)&0xF);
1.728 + sh4r.t = sh4r.r[Rn] & 0x00000001; sh4r.r[Rn] >>= 1;
1.732 + { /* CMP/PZ Rn */
1.733 + uint32_t Rn = ((ir>>8)&0xF);
1.734 + sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= 0 ? 1 : 0 );
1.739 + uint32_t Rn = ((ir>>8)&0xF);
1.740 + sh4r.t = sh4r.r[Rn] & 0x00000001;
1.741 + sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 1;
1.750 + switch( (ir&0xF0) >> 4 ) {
1.752 + { /* STS.L MACH, @-Rn */
1.753 + uint32_t Rn = ((ir>>8)&0xF);
1.755 + CHECKWALIGN32( sh4r.r[Rn] );
1.756 + MEM_WRITE_LONG( sh4r.r[Rn], (sh4r.mac>>32) );
1.760 + { /* STS.L MACL, @-Rn */
1.761 + uint32_t Rn = ((ir>>8)&0xF);
1.763 + CHECKWALIGN32( sh4r.r[Rn] );
1.764 + MEM_WRITE_LONG( sh4r.r[Rn], (uint32_t)sh4r.mac );
1.768 + { /* STS.L PR, @-Rn */
1.769 + uint32_t Rn = ((ir>>8)&0xF);
1.771 + CHECKWALIGN32( sh4r.r[Rn] );
1.772 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.pr );
1.776 + { /* STC.L SGR, @-Rn */
1.777 + uint32_t Rn = ((ir>>8)&0xF);
1.780 + CHECKWALIGN32( sh4r.r[Rn] );
1.781 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.sgr );
1.785 + { /* STS.L FPUL, @-Rn */
1.786 + uint32_t Rn = ((ir>>8)&0xF);
1.788 + CHECKWALIGN32( sh4r.r[Rn] );
1.789 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpul );
1.793 + { /* STS.L FPSCR, @-Rn */
1.794 + uint32_t Rn = ((ir>>8)&0xF);
1.796 + CHECKWALIGN32( sh4r.r[Rn] );
1.797 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpscr );
1.801 + { /* STC.L DBR, @-Rn */
1.802 + uint32_t Rn = ((ir>>8)&0xF);
1.805 + CHECKWALIGN32( sh4r.r[Rn] );
1.806 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.dbr );
1.815 + switch( (ir&0x80) >> 7 ) {
1.817 + switch( (ir&0x70) >> 4 ) {
1.819 + { /* STC.L SR, @-Rn */
1.820 + uint32_t Rn = ((ir>>8)&0xF);
1.823 + CHECKWALIGN32( sh4r.r[Rn] );
1.824 + MEM_WRITE_LONG( sh4r.r[Rn], sh4_read_sr() );
1.828 + { /* STC.L GBR, @-Rn */
1.829 + uint32_t Rn = ((ir>>8)&0xF);
1.831 + CHECKWALIGN32( sh4r.r[Rn] );
1.832 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.gbr );
1.836 + { /* STC.L VBR, @-Rn */
1.837 + uint32_t Rn = ((ir>>8)&0xF);
1.840 + CHECKWALIGN32( sh4r.r[Rn] );
1.841 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.vbr );
1.845 + { /* STC.L SSR, @-Rn */
1.846 + uint32_t Rn = ((ir>>8)&0xF);
1.849 + CHECKWALIGN32( sh4r.r[Rn] );
1.850 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.ssr );
1.854 + { /* STC.L SPC, @-Rn */
1.855 + uint32_t Rn = ((ir>>8)&0xF);
1.858 + CHECKWALIGN32( sh4r.r[Rn] );
1.859 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.spc );
1.868 + { /* STC.L Rm_BANK, @-Rn */
1.869 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1.872 + CHECKWALIGN32( sh4r.r[Rn] );
1.873 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r_bank[Rm_BANK] );
1.879 + switch( (ir&0xF0) >> 4 ) {
1.882 + uint32_t Rn = ((ir>>8)&0xF);
1.883 + sh4r.t = sh4r.r[Rn] >> 31;
1.884 + sh4r.r[Rn] <<= 1;
1.885 + sh4r.r[Rn] |= sh4r.t;
1.890 + uint32_t Rn = ((ir>>8)&0xF);
1.891 + tmp = sh4r.r[Rn] >> 31;
1.892 + sh4r.r[Rn] <<= 1;
1.893 + sh4r.r[Rn] |= sh4r.t;
1.903 + switch( (ir&0xF0) >> 4 ) {
1.906 + uint32_t Rn = ((ir>>8)&0xF);
1.907 + sh4r.t = sh4r.r[Rn] & 0x00000001;
1.908 + sh4r.r[Rn] >>= 1;
1.909 + sh4r.r[Rn] |= (sh4r.t << 31);
1.913 + { /* CMP/PL Rn */
1.914 + uint32_t Rn = ((ir>>8)&0xF);
1.915 + sh4r.t = ( ((int32_t)sh4r.r[Rn]) > 0 ? 1 : 0 );
1.920 + uint32_t Rn = ((ir>>8)&0xF);
1.921 + tmp = sh4r.r[Rn] & 0x00000001;
1.922 + sh4r.r[Rn] >>= 1;
1.923 + sh4r.r[Rn] |= (sh4r.t << 31 );
1.933 + switch( (ir&0xF0) >> 4 ) {
1.935 + { /* LDS.L @Rm+, MACH */
1.936 + uint32_t Rm = ((ir>>8)&0xF);
1.937 + CHECKRALIGN32( sh4r.r[Rm] );
1.938 + sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1.939 + (((uint64_t)MEM_READ_LONG(sh4r.r[Rm]))<<32);
1.944 + { /* LDS.L @Rm+, MACL */
1.945 + uint32_t Rm = ((ir>>8)&0xF);
1.946 + CHECKRALIGN32( sh4r.r[Rm] );
1.947 + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1.948 + (uint64_t)((uint32_t)MEM_READ_LONG(sh4r.r[Rm]));
1.953 + { /* LDS.L @Rm+, PR */
1.954 + uint32_t Rm = ((ir>>8)&0xF);
1.955 + CHECKRALIGN32( sh4r.r[Rm] );
1.956 + sh4r.pr = MEM_READ_LONG( sh4r.r[Rm] );
1.961 + { /* LDC.L @Rm+, SGR */
1.962 + uint32_t Rm = ((ir>>8)&0xF);
1.964 + CHECKRALIGN32( sh4r.r[Rm] );
1.965 + sh4r.sgr = MEM_READ_LONG(sh4r.r[Rm]);
1.970 + { /* LDS.L @Rm+, FPUL */
1.971 + uint32_t Rm = ((ir>>8)&0xF);
1.972 + CHECKRALIGN32( sh4r.r[Rm] );
1.973 + sh4r.fpul = MEM_READ_LONG(sh4r.r[Rm]);
1.978 + { /* LDS.L @Rm+, FPSCR */
1.979 + uint32_t Rm = ((ir>>8)&0xF);
1.980 + CHECKRALIGN32( sh4r.r[Rm] );
1.981 + sh4r.fpscr = MEM_READ_LONG(sh4r.r[Rm]);
1.986 + { /* LDC.L @Rm+, DBR */
1.987 + uint32_t Rm = ((ir>>8)&0xF);
1.989 + CHECKRALIGN32( sh4r.r[Rm] );
1.990 + sh4r.dbr = MEM_READ_LONG(sh4r.r[Rm]);
1.1000 + switch( (ir&0x80) >> 7 ) {
1.1002 + switch( (ir&0x70) >> 4 ) {
1.1004 + { /* LDC.L @Rm+, SR */
1.1005 + uint32_t Rm = ((ir>>8)&0xF);
1.1008 + CHECKWALIGN32( sh4r.r[Rm] );
1.1009 + sh4_load_sr( MEM_READ_LONG(sh4r.r[Rm]) );
1.1014 + { /* LDC.L @Rm+, GBR */
1.1015 + uint32_t Rm = ((ir>>8)&0xF);
1.1016 + CHECKRALIGN32( sh4r.r[Rm] );
1.1017 + sh4r.gbr = MEM_READ_LONG(sh4r.r[Rm]);
1.1022 + { /* LDC.L @Rm+, VBR */
1.1023 + uint32_t Rm = ((ir>>8)&0xF);
1.1025 + CHECKRALIGN32( sh4r.r[Rm] );
1.1026 + sh4r.vbr = MEM_READ_LONG(sh4r.r[Rm]);
1.1031 + { /* LDC.L @Rm+, SSR */
1.1032 + uint32_t Rm = ((ir>>8)&0xF);
1.1034 + CHECKRALIGN32( sh4r.r[Rm] );
1.1035 + sh4r.ssr = MEM_READ_LONG(sh4r.r[Rm]);
1.1040 + { /* LDC.L @Rm+, SPC */
1.1041 + uint32_t Rm = ((ir>>8)&0xF);
1.1043 + CHECKRALIGN32( sh4r.r[Rm] );
1.1044 + sh4r.spc = MEM_READ_LONG(sh4r.r[Rm]);
1.1054 + { /* LDC.L @Rm+, Rn_BANK */
1.1055 + uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1.1057 + CHECKRALIGN32( sh4r.r[Rm] );
1.1058 + sh4r.r_bank[Rn_BANK] = MEM_READ_LONG( sh4r.r[Rm] );
1.1065 + switch( (ir&0xF0) >> 4 ) {
1.1068 + uint32_t Rn = ((ir>>8)&0xF);
1.1074 + uint32_t Rn = ((ir>>8)&0xF);
1.1080 + uint32_t Rn = ((ir>>8)&0xF);
1.1090 + switch( (ir&0xF0) >> 4 ) {
1.1093 + uint32_t Rn = ((ir>>8)&0xF);
1.1099 + uint32_t Rn = ((ir>>8)&0xF);
1.1105 + uint32_t Rn = ((ir>>8)&0xF);
1.1115 + switch( (ir&0xF0) >> 4 ) {
1.1118 + uint32_t Rm = ((ir>>8)&0xF);
1.1119 + sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1.1120 + (((uint64_t)sh4r.r[Rm])<<32);
1.1125 + uint32_t Rm = ((ir>>8)&0xF);
1.1126 + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1.1127 + (uint64_t)((uint32_t)(sh4r.r[Rm]));
1.1132 + uint32_t Rm = ((ir>>8)&0xF);
1.1133 + sh4r.pr = sh4r.r[Rm];
1.1138 + uint32_t Rm = ((ir>>8)&0xF);
1.1140 + sh4r.sgr = sh4r.r[Rm];
1.1145 + uint32_t Rm = ((ir>>8)&0xF);
1.1146 + sh4r.fpul = sh4r.r[Rm];
1.1150 + { /* LDS Rm, FPSCR */
1.1151 + uint32_t Rm = ((ir>>8)&0xF);
1.1152 + sh4r.fpscr = sh4r.r[Rm];
1.1157 + uint32_t Rm = ((ir>>8)&0xF);
1.1159 + sh4r.dbr = sh4r.r[Rm];
1.1168 + switch( (ir&0xF0) >> 4 ) {
1.1171 + uint32_t Rn = ((ir>>8)&0xF);
1.1172 + CHECKDEST( sh4r.r[Rn] );
1.1174 + sh4r.in_delay_slot = 1;
1.1175 + sh4r.pc = sh4r.new_pc;
1.1176 + sh4r.new_pc = sh4r.r[Rn];
1.1178 + TRACE_CALL( pc, sh4r.new_pc );
1.1184 + uint32_t Rn = ((ir>>8)&0xF);
1.1185 + tmp = MEM_READ_BYTE( sh4r.r[Rn] );
1.1186 + sh4r.t = ( tmp == 0 ? 1 : 0 );
1.1187 + MEM_WRITE_BYTE( sh4r.r[Rn], tmp | 0x80 );
1.1192 + uint32_t Rn = ((ir>>8)&0xF);
1.1193 + CHECKDEST( sh4r.r[Rn] );
1.1195 + sh4r.in_delay_slot = 1;
1.1196 + sh4r.pc = sh4r.new_pc;
1.1197 + sh4r.new_pc = sh4r.r[Rn];
1.1208 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1210 + if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);
1.1211 + else if( (tmp & 0x1F) == 0 )
1.1212 + sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 31;
1.1214 + sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> (((~sh4r.r[Rm]) & 0x1F)+1);
1.1219 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1221 + if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);
1.1222 + else if( (tmp & 0x1F) == 0 ) sh4r.r[Rn] = 0;
1.1223 + else sh4r.r[Rn] >>= (((~tmp) & 0x1F)+1);
1.1227 + switch( (ir&0x80) >> 7 ) {
1.1229 + switch( (ir&0x70) >> 4 ) {
1.1232 + uint32_t Rm = ((ir>>8)&0xF);
1.1235 + sh4_load_sr( sh4r.r[Rm] );
1.1240 + uint32_t Rm = ((ir>>8)&0xF);
1.1241 + sh4r.gbr = sh4r.r[Rm];
1.1246 + uint32_t Rm = ((ir>>8)&0xF);
1.1248 + sh4r.vbr = sh4r.r[Rm];
1.1253 + uint32_t Rm = ((ir>>8)&0xF);
1.1255 + sh4r.ssr = sh4r.r[Rm];
1.1260 + uint32_t Rm = ((ir>>8)&0xF);
1.1262 + sh4r.spc = sh4r.r[Rm];
1.1271 + { /* LDC Rm, Rn_BANK */
1.1272 + uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1.1274 + sh4r.r_bank[Rn_BANK] = sh4r.r[Rm];
1.1280 + { /* MAC.W @Rm+, @Rn+ */
1.1281 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1282 + CHECKRALIGN16( sh4r.r[Rn] );
1.1283 + CHECKRALIGN16( sh4r.r[Rm] );
1.1284 + int32_t stmp = SIGNEXT16(MEM_READ_WORD(sh4r.r[Rn]));
1.1286 + stmp = stmp * SIGNEXT16(MEM_READ_WORD(sh4r.r[Rm]));
1.1289 + int64_t tmpl = (int64_t)((int32_t)sh4r.mac) + (int64_t)stmp;
1.1290 + if( tmpl > (int64_t)0x000000007FFFFFFFLL ) {
1.1291 + sh4r.mac = 0x000000017FFFFFFFLL;
1.1292 + } else if( tmpl < (int64_t)0xFFFFFFFF80000000LL ) {
1.1293 + sh4r.mac = 0x0000000180000000LL;
1.1295 + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1.1296 + ((uint32_t)(sh4r.mac + stmp));
1.1299 + sh4r.mac += SIGNEXT32(stmp);
1.1306 + { /* MOV.L @(disp, Rm), Rn */
1.1307 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1.1308 + tmp = sh4r.r[Rm] + disp;
1.1309 + CHECKRALIGN32( tmp );
1.1310 + sh4r.r[Rn] = MEM_READ_LONG( tmp );
1.1316 + { /* MOV.B @Rm, Rn */
1.1317 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1318 + sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] );
1.1322 + { /* MOV.W @Rm, Rn */
1.1323 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1324 + CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] );
1.1328 + { /* MOV.L @Rm, Rn */
1.1329 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1330 + CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] );
1.1335 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1336 + sh4r.r[Rn] = sh4r.r[Rm];
1.1340 + { /* MOV.B @Rm+, Rn */
1.1341 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1342 + sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] ); sh4r.r[Rm] ++;
1.1346 + { /* MOV.W @Rm+, Rn */
1.1347 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1348 + CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] ); sh4r.r[Rm] += 2;
1.1352 + { /* MOV.L @Rm+, Rn */
1.1353 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1354 + CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] ); sh4r.r[Rm] += 4;
1.1359 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1360 + sh4r.r[Rn] = ~sh4r.r[Rm];
1.1364 + { /* SWAP.B Rm, Rn */
1.1365 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1366 + sh4r.r[Rn] = (sh4r.r[Rm]&0xFFFF0000) | ((sh4r.r[Rm]&0x0000FF00)>>8) | ((sh4r.r[Rm]&0x000000FF)<<8);
1.1370 + { /* SWAP.W Rm, Rn */
1.1371 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1372 + sh4r.r[Rn] = (sh4r.r[Rm]>>16) | (sh4r.r[Rm]<<16);
1.1377 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1378 + tmp = 0 - sh4r.r[Rm];
1.1379 + sh4r.r[Rn] = tmp - sh4r.t;
1.1380 + sh4r.t = ( 0<tmp || tmp<sh4r.r[Rn] ? 1 : 0 );
1.1385 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1386 + sh4r.r[Rn] = 0 - sh4r.r[Rm];
1.1390 + { /* EXTU.B Rm, Rn */
1.1391 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1392 + sh4r.r[Rn] = sh4r.r[Rm]&0x000000FF;
1.1396 + { /* EXTU.W Rm, Rn */
1.1397 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1398 + sh4r.r[Rn] = sh4r.r[Rm]&0x0000FFFF;
1.1402 + { /* EXTS.B Rm, Rn */
1.1403 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1404 + sh4r.r[Rn] = SIGNEXT8( sh4r.r[Rm]&0x000000FF );
1.1408 + { /* EXTS.W Rm, Rn */
1.1409 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1410 + sh4r.r[Rn] = SIGNEXT16( sh4r.r[Rm]&0x0000FFFF );
1.1417 + uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1.1422 + switch( (ir&0xF00) >> 8 ) {
1.1424 + { /* MOV.B R0, @(disp, Rn) */
1.1425 + uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1.1426 + MEM_WRITE_BYTE( sh4r.r[Rn] + disp, R0 );
1.1430 + { /* MOV.W R0, @(disp, Rn) */
1.1431 + uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1.1432 + tmp = sh4r.r[Rn] + disp;
1.1433 + CHECKWALIGN16( tmp );
1.1434 + MEM_WRITE_WORD( tmp, R0 );
1.1438 + { /* MOV.B @(disp, Rm), R0 */
1.1439 + uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1.1440 + R0 = MEM_READ_BYTE( sh4r.r[Rm] + disp );
1.1444 + { /* MOV.W @(disp, Rm), R0 */
1.1445 + uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1.1446 + tmp = sh4r.r[Rm] + disp;
1.1447 + CHECKRALIGN16( tmp );
1.1448 + R0 = MEM_READ_WORD( tmp );
1.1452 + { /* CMP/EQ #imm, R0 */
1.1453 + int32_t imm = SIGNEXT8(ir&0xFF);
1.1454 + sh4r.t = ( R0 == imm ? 1 : 0 );
1.1459 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1.1462 + CHECKDEST( sh4r.pc + disp + 4 )
1.1464 + sh4r.new_pc = sh4r.pc + 2;
1.1466 - case 2: /* BRAF Rn */
1.1468 - CHECKDEST( pc + 4 + RN(ir) );
1.1474 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1.1477 + CHECKDEST( sh4r.pc + disp + 4 )
1.1479 + sh4r.new_pc = sh4r.pc + 2;
1.1486 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1.1489 + CHECKDEST( sh4r.pc + disp + 4 )
1.1490 sh4r.in_delay_slot = 1;
1.1492 - sh4r.new_pc = pc + 4 + RN(ir);
1.1493 + sh4r.new_pc = pc + disp + 4;
1.1494 + sh4r.in_delay_slot = 1;
1.1496 - case 8: /* PREF [Rn] */
1.1498 - if( (tmp & 0xFC000000) == 0xE0000000 ) {
1.1499 - /* Store queue operation */
1.1500 - int queue = (tmp&0x20)>>2;
1.1501 - int32_t *src = &sh4r.store_queue[queue];
1.1502 - uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;
1.1503 - uint32_t target = tmp&0x03FFFFE0 | hi;
1.1504 - mem_copy_to_sh4( target, src, 32 );
1.1507 - case 9: /* OCBI [Rn] */
1.1508 - case 10:/* OCBP [Rn] */
1.1509 - case 11:/* OCBWB [Rn] */
1.1512 - case 12:/* MOVCA.L R0, [Rn] */
1.1515 - MEM_WRITE_LONG( tmp, R0 );
1.1520 - case 4: /* MOV.B Rm, [R0 + Rn] */
1.1521 - MEM_WRITE_BYTE( R0 + RN(ir), RM(ir) );
1.1523 - case 5: /* MOV.W Rm, [R0 + Rn] */
1.1524 - CHECKWALIGN16( R0 + RN(ir) );
1.1525 - MEM_WRITE_WORD( R0 + RN(ir), RM(ir) );
1.1527 - case 6: /* MOV.L Rm, [R0 + Rn] */
1.1528 - CHECKWALIGN32( R0 + RN(ir) );
1.1529 - MEM_WRITE_LONG( R0 + RN(ir), RM(ir) );
1.1531 - case 7: /* MUL.L Rm, Rn */
1.1532 - sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
1.1536 - switch( (ir&0x0FF0)>>4 ) {
1.1558 - if( (ir&0x00F0) == 0x20 ) /* MOVT Rn */
1.1560 - else if( ir == 0x0019 ) /* DIV0U */
1.1561 - sh4r.m = sh4r.q = sh4r.t = 0;
1.1562 - else if( ir == 0x0009 )
1.1567 - switch( (ir&0x00F0) >> 4 ) {
1.1568 - case 0: /* STS MACH, Rn */
1.1569 - RN(ir) = sh4r.mac >> 32;
1.1571 - case 1: /* STS MACL, Rn */
1.1572 - RN(ir) = (uint32_t)sh4r.mac;
1.1574 - case 2: /* STS PR, Rn */
1.1577 - case 3: /* STC SGR, Rn */
1.1581 - case 5:/* STS FPUL, Rn */
1.1584 - case 6: /* STS FPSCR, Rn */
1.1587 - case 15:/* STC DBR, Rn */
1.1595 - switch( (ir&0x0FF0)>>4 ) {
1.1598 - CHECKDEST( sh4r.pr );
1.1604 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1.1607 + CHECKDEST( sh4r.pc + disp + 4 )
1.1608 sh4r.in_delay_slot = 1;
1.1610 - sh4r.new_pc = sh4r.pr;
1.1611 - TRACE_RETURN( pc, sh4r.new_pc );
1.1612 + sh4r.new_pc = pc + disp + 4;
1.1615 - if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
1.1616 - sh4r.sh4_state = SH4_STATE_STANDBY;
1.1618 - sh4r.sh4_state = SH4_STATE_SLEEP;
1.1620 - return FALSE; /* Halt CPU */
1.1623 - CHECKDEST( sh4r.spc );
1.1625 - sh4r.in_delay_slot = 1;
1.1626 - sh4r.pc = sh4r.new_pc;
1.1627 - sh4r.new_pc = sh4r.spc;
1.1628 - sh4_load_sr( sh4r.ssr );
1.1633 - case 12:/* MOV.B [R0+R%d], R%d */
1.1634 - RN(ir) = MEM_READ_BYTE( R0 + RM(ir) );
1.1636 - case 13:/* MOV.W [R0+R%d], R%d */
1.1637 - CHECKRALIGN16( R0 + RM(ir) );
1.1638 - RN(ir) = MEM_READ_WORD( R0 + RM(ir) );
1.1640 - case 14:/* MOV.L [R0+R%d], R%d */
1.1641 - CHECKRALIGN32( R0 + RM(ir) );
1.1642 - RN(ir) = MEM_READ_LONG( R0 + RM(ir) );
1.1644 - case 15:/* MAC.L [Rm++], [Rn++] */
1.1645 - CHECKRALIGN32( RM(ir) );
1.1646 - CHECKRALIGN32( RN(ir) );
1.1647 - tmpl = ( SIGNEXT32(MEM_READ_LONG(RM(ir))) *
1.1648 - SIGNEXT32(MEM_READ_LONG(RN(ir))) );
1.1650 - /* 48-bit Saturation. Yuch */
1.1651 - tmpl += SIGNEXT48(sh4r.mac);
1.1652 - if( tmpl < 0xFFFF800000000000LL )
1.1653 - tmpl = 0xFFFF800000000000LL;
1.1654 - else if( tmpl > 0x00007FFFFFFFFFFFLL )
1.1655 - tmpl = 0x00007FFFFFFFFFFFLL;
1.1656 - sh4r.mac = (sh4r.mac&0xFFFF000000000000LL) |
1.1657 - (tmpl&0x0000FFFFFFFFFFFFLL);
1.1658 - } else sh4r.mac = tmpl;
1.1667 - case 1: /* 0001nnnnmmmmdddd */
1.1668 - /* MOV.L Rm, [Rn + disp4*4] */
1.1669 - tmp = RN(ir) + (DISP4(ir)<<2);
1.1670 - CHECKWALIGN32( tmp );
1.1671 - MEM_WRITE_LONG( tmp, RM(ir) );
1.1673 - case 2: /* 0010nnnnmmmmxxxx */
1.1674 - switch( ir&0x000F ) {
1.1675 - case 0: /* MOV.B Rm, [Rn] */
1.1676 - MEM_WRITE_BYTE( RN(ir), RM(ir) );
1.1678 - case 1: /* MOV.W Rm, [Rn] */
1.1679 - CHECKWALIGN16( RN(ir) );
1.1680 - MEM_WRITE_WORD( RN(ir), RM(ir) );
1.1682 - case 2: /* MOV.L Rm, [Rn] */
1.1683 - CHECKWALIGN32( RN(ir) );
1.1684 - MEM_WRITE_LONG( RN(ir), RM(ir) );
1.1688 - case 4: /* MOV.B Rm, [--Rn] */
1.1690 - MEM_WRITE_BYTE( RN(ir), RM(ir) );
1.1692 - case 5: /* MOV.W Rm, [--Rn] */
1.1694 - CHECKWALIGN16( RN(ir) );
1.1695 - MEM_WRITE_WORD( RN(ir), RM(ir) );
1.1697 - case 6: /* MOV.L Rm, [--Rn] */
1.1699 - CHECKWALIGN32( RN(ir) );
1.1700 - MEM_WRITE_LONG( RN(ir), RM(ir) );
1.1702 - case 7: /* DIV0S Rm, Rn */
1.1705 - sh4r.t = sh4r.q ^ sh4r.m;
1.1707 - case 8: /* TST Rm, Rn */
1.1708 - sh4r.t = (RN(ir)&RM(ir) ? 0 : 1);
1.1710 - case 9: /* AND Rm, Rn */
1.1713 - case 10:/* XOR Rm, Rn */
1.1716 - case 11:/* OR Rm, Rn */
1.1719 - case 12:/* CMP/STR Rm, Rn */
1.1720 - /* set T = 1 if any byte in RM & RN is the same */
1.1721 - tmp = RM(ir) ^ RN(ir);
1.1722 - sh4r.t = ((tmp&0x000000FF)==0 || (tmp&0x0000FF00)==0 ||
1.1723 - (tmp&0x00FF0000)==0 || (tmp&0xFF000000)==0)?1:0;
1.1725 - case 13:/* XTRCT Rm, Rn */
1.1726 - RN(ir) = (RN(ir)>>16) | (RM(ir)<<16);
1.1728 - case 14:/* MULU.W Rm, Rn */
1.1729 - sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
1.1730 - (uint32_t)((RM(ir)&0xFFFF) * (RN(ir)&0xFFFF));
1.1732 - case 15:/* MULS.W Rm, Rn */
1.1733 - sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
1.1734 - (uint32_t)(SIGNEXT32(RM(ir)&0xFFFF) * SIGNEXT32(RN(ir)&0xFFFF));
1.1738 - case 3: /* 0011nnnnmmmmxxxx */
1.1739 - switch( ir&0x000F ) {
1.1740 - case 0: /* CMP/EQ Rm, Rn */
1.1741 - sh4r.t = ( RM(ir) == RN(ir) ? 1 : 0 );
1.1743 - case 2: /* CMP/HS Rm, Rn */
1.1744 - sh4r.t = ( RN(ir) >= RM(ir) ? 1 : 0 );
1.1746 - case 3: /* CMP/GE Rm, Rn */
1.1747 - sh4r.t = ( ((int32_t)RN(ir)) >= ((int32_t)RM(ir)) ? 1 : 0 );
1.1749 - case 4: { /* DIV1 Rm, Rn */
1.1750 - /* This is just from the sh4p manual with some
1.1751 - * simplifications (someone want to check it's correct? :)
1.1752 - * Why they couldn't just provide a real DIV instruction...
1.1753 - * Please oh please let the translator batch these things
1.1754 - * up into a single DIV... */
1.1755 - uint32_t tmp0, tmp1, tmp2, dir;
1.1765 + { /* MOV.W @(disp, PC), Rn */
1.1766 + uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
1.1769 + sh4r.r[Rn] = MEM_READ_WORD( tmp );
1.1774 + int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1.1776 + CHECKDEST( sh4r.pc + disp + 4 );
1.1777 + sh4r.in_delay_slot = 1;
1.1778 + sh4r.pc = sh4r.new_pc;
1.1779 + sh4r.new_pc = pc + 4 + disp;
1.1785 + int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1.1786 + CHECKDEST( sh4r.pc + disp + 4 );
1.1788 + sh4r.in_delay_slot = 1;
1.1790 + sh4r.pc = sh4r.new_pc;
1.1791 + sh4r.new_pc = pc + 4 + disp;
1.1792 + TRACE_CALL( pc, sh4r.new_pc );
1.1797 + switch( (ir&0xF00) >> 8 ) {
1.1799 + { /* MOV.B R0, @(disp, GBR) */
1.1800 + uint32_t disp = (ir&0xFF);
1.1801 + MEM_WRITE_BYTE( sh4r.gbr + disp, R0 );
1.1805 + { /* MOV.W R0, @(disp, GBR) */
1.1806 + uint32_t disp = (ir&0xFF)<<1;
1.1807 + tmp = sh4r.gbr + disp;
1.1808 + CHECKWALIGN16( tmp );
1.1809 + MEM_WRITE_WORD( tmp, R0 );
1.1813 + { /* MOV.L R0, @(disp, GBR) */
1.1814 + uint32_t disp = (ir&0xFF)<<2;
1.1815 + tmp = sh4r.gbr + disp;
1.1816 + CHECKWALIGN32( tmp );
1.1817 + MEM_WRITE_LONG( tmp, R0 );
1.1822 + uint32_t imm = (ir&0xFF);
1.1824 + MMIO_WRITE( MMU, TRA, imm<<2 );
1.1826 + sh4_raise_exception( EXC_TRAP );
1.1830 + { /* MOV.B @(disp, GBR), R0 */
1.1831 + uint32_t disp = (ir&0xFF);
1.1832 + R0 = MEM_READ_BYTE( sh4r.gbr + disp );
1.1836 + { /* MOV.W @(disp, GBR), R0 */
1.1837 + uint32_t disp = (ir&0xFF)<<1;
1.1838 + tmp = sh4r.gbr + disp;
1.1839 + CHECKRALIGN16( tmp );
1.1840 + R0 = MEM_READ_WORD( tmp );
1.1844 + { /* MOV.L @(disp, GBR), R0 */
1.1845 + uint32_t disp = (ir&0xFF)<<2;
1.1846 + tmp = sh4r.gbr + disp;
1.1847 + CHECKRALIGN32( tmp );
1.1848 + R0 = MEM_READ_LONG( tmp );
1.1852 + { /* MOVA @(disp, PC), R0 */
1.1853 + uint32_t disp = (ir&0xFF)<<2;
1.1855 + R0 = (pc&0xFFFFFFFC) + disp + 4;
1.1860 + uint32_t imm = (ir&0xFF);
1.1861 + sh4r.t = (R0 & imm ? 0 : 1);
1.1866 + uint32_t imm = (ir&0xFF);
1.1872 + uint32_t imm = (ir&0xFF);
1.1878 + uint32_t imm = (ir&0xFF);
1.1883 + { /* TST.B #imm, @(R0, GBR) */
1.1884 + uint32_t imm = (ir&0xFF);
1.1885 + sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & imm ? 0 : 1 );
1.1889 + { /* AND.B #imm, @(R0, GBR) */
1.1890 + uint32_t imm = (ir&0xFF);
1.1891 + MEM_WRITE_BYTE( R0 + sh4r.gbr, imm & MEM_READ_BYTE(R0 + sh4r.gbr) );
1.1895 + { /* XOR.B #imm, @(R0, GBR) */
1.1896 + uint32_t imm = (ir&0xFF);
1.1897 + MEM_WRITE_BYTE( R0 + sh4r.gbr, imm ^ MEM_READ_BYTE(R0 + sh4r.gbr) );
1.1901 + { /* OR.B #imm, @(R0, GBR) */
1.1902 + uint32_t imm = (ir&0xFF);
1.1903 + MEM_WRITE_BYTE( R0 + sh4r.gbr, imm | MEM_READ_BYTE(R0 + sh4r.gbr) );
1.1909 + { /* MOV.L @(disp, PC), Rn */
1.1910 + uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
1.1912 + tmp = (pc&0xFFFFFFFC) + disp + 4;
1.1913 + sh4r.r[Rn] = MEM_READ_LONG( tmp );
1.1918 + uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1.1925 + { /* FADD FRm, FRn */
1.1926 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1928 + if( IS_FPU_DOUBLEPREC() ) {
1.1936 + { /* FSUB FRm, FRn */
1.1937 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1939 + if( IS_FPU_DOUBLEPREC() ) {
1.1947 + { /* FMUL FRm, FRn */
1.1948 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1950 + if( IS_FPU_DOUBLEPREC() ) {
1.1958 + { /* FDIV FRm, FRn */
1.1959 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1961 + if( IS_FPU_DOUBLEPREC() ) {
1.1969 + { /* FCMP/EQ FRm, FRn */
1.1970 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1972 + if( IS_FPU_DOUBLEPREC() ) {
1.1973 + sh4r.t = ( DR(FRn) == DR(FRm) ? 1 : 0 );
1.1975 + sh4r.t = ( FR(FRn) == FR(FRm) ? 1 : 0 );
1.1980 + { /* FCMP/GT FRm, FRn */
1.1981 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1983 + if( IS_FPU_DOUBLEPREC() ) {
1.1984 + sh4r.t = ( DR(FRn) > DR(FRm) ? 1 : 0 );
1.1986 + sh4r.t = ( FR(FRn) > FR(FRm) ? 1 : 0 );
1.1991 + { /* FMOV @(R0, Rm), FRn */
1.1992 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1993 + MEM_FP_READ( sh4r.r[Rm] + R0, FRn );
1.1997 + { /* FMOV FRm, @(R0, Rn) */
1.1998 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1999 + MEM_FP_WRITE( sh4r.r[Rn] + R0, FRm );
1.2003 + { /* FMOV @Rm, FRn */
1.2004 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.2005 + MEM_FP_READ( sh4r.r[Rm], FRn );
1.2009 + { /* FMOV @Rm+, FRn */
1.2010 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.2011 + MEM_FP_READ( sh4r.r[Rm], FRn ); sh4r.r[Rm] += FP_WIDTH;
1.2015 + { /* FMOV FRm, @Rn */
1.2016 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.2017 + MEM_FP_WRITE( sh4r.r[Rn], FRm );
1.2021 + { /* FMOV FRm, @-Rn */
1.2022 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.2023 + sh4r.r[Rn] -= FP_WIDTH; MEM_FP_WRITE( sh4r.r[Rn], FRm );
1.2027 + { /* FMOV FRm, FRn */
1.2028 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.2029 + if( IS_FPU_DOUBLESIZE() )
1.2036 + switch( (ir&0xF0) >> 4 ) {
1.2038 + { /* FSTS FPUL, FRn */
1.2039 + uint32_t FRn = ((ir>>8)&0xF);
1.2040 + CHECKFPUEN(); FR(FRn) = FPULf;
1.2044 + { /* FLDS FRm, FPUL */
1.2045 + uint32_t FRm = ((ir>>8)&0xF);
1.2046 + CHECKFPUEN(); FPULf = FR(FRm);
1.2050 + { /* FLOAT FPUL, FRn */
1.2051 + uint32_t FRn = ((ir>>8)&0xF);
1.2053 + if( IS_FPU_DOUBLEPREC() )
1.2054 + DR(FRn) = (float)FPULi;
1.2056 + FR(FRn) = (float)FPULi;
1.2060 + { /* FTRC FRm, FPUL */
1.2061 + uint32_t FRm = ((ir>>8)&0xF);
1.2063 + if( IS_FPU_DOUBLEPREC() ) {
1.2065 + if( dtmp >= MAX_INTF )
1.2067 + else if( dtmp <= MIN_INTF )
1.2070 + FPULi = (int32_t)dtmp;
1.2073 + if( ftmp >= MAX_INTF )
1.2075 + else if( ftmp <= MIN_INTF )
1.2078 + FPULi = (int32_t)ftmp;
1.2084 + uint32_t FRn = ((ir>>8)&0xF);
1.2086 + if( IS_FPU_DOUBLEPREC() ) {
1.2095 + uint32_t FRn = ((ir>>8)&0xF);
1.2097 + if( IS_FPU_DOUBLEPREC() ) {
1.2098 + DR(FRn) = fabs(DR(FRn));
1.2100 + FR(FRn) = fabsf(FR(FRn));
1.2106 + uint32_t FRn = ((ir>>8)&0xF);
1.2108 + if( IS_FPU_DOUBLEPREC() ) {
1.2109 + DR(FRn) = sqrt(DR(FRn));
1.2111 + FR(FRn) = sqrtf(FR(FRn));
1.2117 + uint32_t FRn = ((ir>>8)&0xF);
1.2119 + if( !IS_FPU_DOUBLEPREC() ) {
1.2120 + FR(FRn) = 1.0/sqrtf(FR(FRn));
1.2126 + uint32_t FRn = ((ir>>8)&0xF);
1.2128 + if( IS_FPU_DOUBLEPREC() ) {
1.2137 + uint32_t FRn = ((ir>>8)&0xF);
1.2139 + if( IS_FPU_DOUBLEPREC() ) {
1.2147 + { /* FCNVSD FPUL, FRn */
1.2148 + uint32_t FRn = ((ir>>8)&0xF);
1.2150 + if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
1.2151 + DR(FRn) = (double)FPULf;
1.2156 + { /* FCNVDS FRm, FPUL */
1.2157 + uint32_t FRm = ((ir>>8)&0xF);
1.2159 + if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
1.2160 + FPULf = (float)DR(FRm);
1.2165 + { /* FIPR FVm, FVn */
1.2166 + uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
1.2168 + if( !IS_FPU_DOUBLEPREC() ) {
1.2171 + FR(tmp2+3) = FR(tmp)*FR(tmp2) +
1.2172 + FR(tmp+1)*FR(tmp2+1) +
1.2173 + FR(tmp+2)*FR(tmp2+2) +
1.2174 + FR(tmp+3)*FR(tmp2+3);
1.2179 + switch( (ir&0x100) >> 8 ) {
1.2181 + { /* FSCA FPUL, FRn */
1.2182 + uint32_t FRn = ((ir>>9)&0x7)<<1;
1.2184 + if( !IS_FPU_DOUBLEPREC() ) {
1.2185 + float angle = (((float)(FPULi&0xFFFF))/65536.0) * 2 * M_PI;
1.2186 + FR(FRn) = sinf(angle);
1.2187 + FR((FRn)+1) = cosf(angle);
1.2192 + switch( (ir&0x200) >> 9 ) {
1.2194 + { /* FTRV XMTRX, FVn */
1.2195 + uint32_t FVn = ((ir>>10)&0x3);
1.2197 + if( !IS_FPU_DOUBLEPREC() ) {
1.2199 + float fv[4] = { FR(tmp), FR(tmp+1), FR(tmp+2), FR(tmp+3) };
1.2200 + FR(tmp) = XF(0) * fv[0] + XF(4)*fv[1] +
1.2201 + XF(8)*fv[2] + XF(12)*fv[3];
1.2202 + FR(tmp+1) = XF(1) * fv[0] + XF(5)*fv[1] +
1.2203 + XF(9)*fv[2] + XF(13)*fv[3];
1.2204 + FR(tmp+2) = XF(2) * fv[0] + XF(6)*fv[1] +
1.2205 + XF(10)*fv[2] + XF(14)*fv[3];
1.2206 + FR(tmp+3) = XF(3) * fv[0] + XF(7)*fv[1] +
1.2207 + XF(11)*fv[2] + XF(15)*fv[3];
1.2212 + switch( (ir&0xC00) >> 10 ) {
1.2215 + CHECKFPUEN(); sh4r.fpscr ^= FPSCR_SZ;
1.2220 + CHECKFPUEN(); sh4r.fpscr ^= FPSCR_FR;
1.2243 + { /* FMAC FR0, FRm, FRn */
1.2244 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.2246 + if( IS_FPU_DOUBLEPREC() ) {
1.2247 + DR(FRn) += DR(FRm)*DR(0);
1.2249 + FR(FRn) += FR(FRm)*FR(0);
1.2260 - dir = sh4r.q ^ sh4r.m;
1.2261 - sh4r.q = (RN(ir) >> 31);
1.2263 - RN(ir) = (RN(ir) << 1) | sh4r.t;
1.2267 - tmp1 = (RN(ir)<tmp0 ? 1 : 0 );
1.2270 - tmp1 = (RN(ir)>tmp0 ? 1 : 0 );
1.2272 - sh4r.q ^= sh4r.m ^ tmp1;
1.2273 - sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );
1.2275 - case 5: /* DMULU.L Rm, Rn */
1.2276 - sh4r.mac = ((uint64_t)RM(ir)) * ((uint64_t)RN(ir));
1.2278 - case 6: /* CMP/HI Rm, Rn */
1.2279 - sh4r.t = ( RN(ir) > RM(ir) ? 1 : 0 );
1.2281 - case 7: /* CMP/GT Rm, Rn */
1.2282 - sh4r.t = ( ((int32_t)RN(ir)) > ((int32_t)RM(ir)) ? 1 : 0 );
1.2284 - case 8: /* SUB Rm, Rn */
1.2287 - case 10:/* SUBC Rm, Rn */
1.2289 - RN(ir) = RN(ir) - RM(ir) - sh4r.t;
1.2290 - sh4r.t = (RN(ir) > tmp || (RN(ir) == tmp && sh4r.t == 1));
1.2292 - case 11:/* SUBV Rm, Rn */
1.2295 - case 12:/* ADD Rm, Rn */
1.2298 - case 13:/* DMULS.L Rm, Rn */
1.2299 - sh4r.mac = SIGNEXT32(RM(ir)) * SIGNEXT32(RN(ir));
1.2301 - case 14:/* ADDC Rm, Rn */
1.2303 - RN(ir) += RM(ir) + sh4r.t;
1.2304 - sh4r.t = ( RN(ir) < tmp || (RN(ir) == tmp && sh4r.t != 0) ? 1 : 0 );
1.2306 - case 15:/* ADDV Rm, Rn */
1.2307 - tmp = RN(ir) + RM(ir);
1.2308 - sh4r.t = ( (RN(ir)>>31) == (RM(ir)>>31) && ((RN(ir)>>31) != (tmp>>31)) );
1.2314 - case 4: /* 0100nnnnxxxxxxxx */
1.2315 - switch( ir&0x00FF ) {
1.2316 - case 0x00: /* SHLL Rn */
1.2317 - sh4r.t = RN(ir) >> 31;
1.2320 - case 0x01: /* SHLR Rn */
1.2321 - sh4r.t = RN(ir) & 0x00000001;
1.2324 - case 0x02: /* STS.L MACH, [--Rn] */
1.2326 - CHECKWALIGN32( RN(ir) );
1.2327 - MEM_WRITE_LONG( RN(ir), (sh4r.mac>>32) );
1.2329 - case 0x03: /* STC.L SR, [--Rn] */
1.2332 - CHECKWALIGN32( RN(ir) );
1.2333 - MEM_WRITE_LONG( RN(ir), sh4_read_sr() );
1.2335 - case 0x04: /* ROTL Rn */
1.2336 - sh4r.t = RN(ir) >> 31;
1.2340 - case 0x05: /* ROTR Rn */
1.2341 - sh4r.t = RN(ir) & 0x00000001;
1.2343 - RN(ir) |= (sh4r.t << 31);
1.2345 - case 0x06: /* LDS.L [Rn++], MACH */
1.2346 - CHECKRALIGN32( RN(ir) );
1.2347 - sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1.2348 - (((uint64_t)MEM_READ_LONG(RN(ir)))<<32);
1.2351 - case 0x07: /* LDC.L [Rn++], SR */
1.2354 - CHECKWALIGN32( RN(ir) );
1.2355 - sh4_load_sr( MEM_READ_LONG(RN(ir)) );
1.2358 - case 0x08: /* SHLL2 Rn */
1.2361 - case 0x09: /* SHLR2 Rn */
1.2364 - case 0x0A: /* LDS Rn, MACH */
1.2365 - sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1.2366 - (((uint64_t)RN(ir))<<32);
1.2368 - case 0x0B: /* JSR [Rn] */
1.2371 - sh4r.in_delay_slot = 1;
1.2372 - sh4r.pc = sh4r.new_pc;
1.2373 - sh4r.new_pc = RN(ir);
1.2375 - TRACE_CALL( pc, sh4r.new_pc );
1.2377 - case 0x0E: /* LDC Rn, SR */
1.2380 - sh4_load_sr( RN(ir) );
1.2382 - case 0x10: /* DT Rn */
1.2384 - sh4r.t = ( RN(ir) == 0 ? 1 : 0 );
1.2386 - case 0x11: /* CMP/PZ Rn */
1.2387 - sh4r.t = ( ((int32_t)RN(ir)) >= 0 ? 1 : 0 );
1.2389 - case 0x12: /* STS.L MACL, [--Rn] */
1.2391 - CHECKWALIGN32( RN(ir) );
1.2392 - MEM_WRITE_LONG( RN(ir), (uint32_t)sh4r.mac );
1.2394 - case 0x13: /* STC.L GBR, [--Rn] */
1.2396 - CHECKWALIGN32( RN(ir) );
1.2397 - MEM_WRITE_LONG( RN(ir), sh4r.gbr );
1.2399 - case 0x15: /* CMP/PL Rn */
1.2400 - sh4r.t = ( ((int32_t)RN(ir)) > 0 ? 1 : 0 );
1.2402 - case 0x16: /* LDS.L [Rn++], MACL */
1.2403 - CHECKRALIGN32( RN(ir) );
1.2404 - sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1.2405 - (uint64_t)((uint32_t)MEM_READ_LONG(RN(ir)));
1.2408 - case 0x17: /* LDC.L [Rn++], GBR */
1.2409 - CHECKRALIGN32( RN(ir) );
1.2410 - sh4r.gbr = MEM_READ_LONG(RN(ir));
1.2413 - case 0x18: /* SHLL8 Rn */
1.2416 - case 0x19: /* SHLR8 Rn */
1.2419 - case 0x1A: /* LDS Rn, MACL */
1.2420 - sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1.2421 - (uint64_t)((uint32_t)(RN(ir)));
1.2423 - case 0x1B: /* TAS.B [Rn] */
1.2424 - tmp = MEM_READ_BYTE( RN(ir) );
1.2425 - sh4r.t = ( tmp == 0 ? 1 : 0 );
1.2426 - MEM_WRITE_BYTE( RN(ir), tmp | 0x80 );
1.2428 - case 0x1E: /* LDC Rn, GBR */
1.2431 - case 0x20: /* SHAL Rn */
1.2432 - sh4r.t = RN(ir) >> 31;
1.2435 - case 0x21: /* SHAR Rn */
1.2436 - sh4r.t = RN(ir) & 0x00000001;
1.2437 - RN(ir) = ((int32_t)RN(ir)) >> 1;
1.2439 - case 0x22: /* STS.L PR, [--Rn] */
1.2441 - CHECKWALIGN32( RN(ir) );
1.2442 - MEM_WRITE_LONG( RN(ir), sh4r.pr );
1.2444 - case 0x23: /* STC.L VBR, [--Rn] */
1.2447 - CHECKWALIGN32( RN(ir) );
1.2448 - MEM_WRITE_LONG( RN(ir), sh4r.vbr );
1.2450 - case 0x24: /* ROTCL Rn */
1.2456 - case 0x25: /* ROTCR Rn */
1.2457 - tmp = RN(ir) & 0x00000001;
1.2459 - RN(ir) |= (sh4r.t << 31 );
1.2462 - case 0x26: /* LDS.L [Rn++], PR */
1.2463 - CHECKRALIGN32( RN(ir) );
1.2464 - sh4r.pr = MEM_READ_LONG( RN(ir) );
1.2467 - case 0x27: /* LDC.L [Rn++], VBR */
1.2469 - CHECKRALIGN32( RN(ir) );
1.2470 - sh4r.vbr = MEM_READ_LONG(RN(ir));
1.2473 - case 0x28: /* SHLL16 Rn */
1.2476 - case 0x29: /* SHLR16 Rn */
1.2479 - case 0x2A: /* LDS Rn, PR */
1.2482 - case 0x2B: /* JMP [Rn] */
1.2485 - sh4r.in_delay_slot = 1;
1.2486 - sh4r.pc = sh4r.new_pc;
1.2487 - sh4r.new_pc = RN(ir);
1.2489 - case 0x2E: /* LDC Rn, VBR */
1.2493 - case 0x32: /* STC.L SGR, [--Rn] */
1.2496 - CHECKWALIGN32( RN(ir) );
1.2497 - MEM_WRITE_LONG( RN(ir), sh4r.sgr );
1.2499 - case 0x33: /* STC.L SSR, [--Rn] */
1.2502 - CHECKWALIGN32( RN(ir) );
1.2503 - MEM_WRITE_LONG( RN(ir), sh4r.ssr );
1.2505 - case 0x37: /* LDC.L [Rn++], SSR */
1.2507 - CHECKRALIGN32( RN(ir) );
1.2508 - sh4r.ssr = MEM_READ_LONG(RN(ir));
1.2511 - case 0x3E: /* LDC Rn, SSR */
1.2515 - case 0x43: /* STC.L SPC, [--Rn] */
1.2518 - CHECKWALIGN32( RN(ir) );
1.2519 - MEM_WRITE_LONG( RN(ir), sh4r.spc );
1.2521 - case 0x47: /* LDC.L [Rn++], SPC */
1.2523 - CHECKRALIGN32( RN(ir) );
1.2524 - sh4r.spc = MEM_READ_LONG(RN(ir));
1.2527 - case 0x4E: /* LDC Rn, SPC */
1.2531 - case 0x52: /* STS.L FPUL, [--Rn] */
1.2533 - CHECKWALIGN32( RN(ir) );
1.2534 - MEM_WRITE_LONG( RN(ir), sh4r.fpul );
1.2536 - case 0x56: /* LDS.L [Rn++], FPUL */
1.2537 - CHECKRALIGN32( RN(ir) );
1.2538 - sh4r.fpul = MEM_READ_LONG(RN(ir));
1.2541 - case 0x5A: /* LDS Rn, FPUL */
1.2544 - case 0x62: /* STS.L FPSCR, [--Rn] */
1.2546 - CHECKWALIGN32( RN(ir) );
1.2547 - MEM_WRITE_LONG( RN(ir), sh4r.fpscr );
1.2549 - case 0x66: /* LDS.L [Rn++], FPSCR */
1.2550 - CHECKRALIGN32( RN(ir) );
1.2551 - sh4r.fpscr = MEM_READ_LONG(RN(ir));
1.2554 - case 0x6A: /* LDS Rn, FPSCR */
1.2557 - case 0xF2: /* STC.L DBR, [--Rn] */
1.2560 - CHECKWALIGN32( RN(ir) );
1.2561 - MEM_WRITE_LONG( RN(ir), sh4r.dbr );
1.2563 - case 0xF6: /* LDC.L [Rn++], DBR */
1.2565 - CHECKRALIGN32( RN(ir) );
1.2566 - sh4r.dbr = MEM_READ_LONG(RN(ir));
1.2569 - case 0xFA: /* LDC Rn, DBR */
1.2573 - case 0x83: case 0x93: case 0xA3: case 0xB3: case 0xC3:
1.2574 - case 0xD3: case 0xE3: case 0xF3: /* STC.L Rn_BANK, [--Rn] */
1.2577 - CHECKWALIGN32( RN(ir) );
1.2578 - MEM_WRITE_LONG( RN(ir), RN_BANK(ir) );
1.2580 - case 0x87: case 0x97: case 0xA7: case 0xB7: case 0xC7:
1.2581 - case 0xD7: case 0xE7: case 0xF7: /* LDC.L [Rn++], Rn_BANK */
1.2583 - CHECKRALIGN32( RN(ir) );
1.2584 - RN_BANK(ir) = MEM_READ_LONG( RN(ir) );
1.2587 - case 0x8E: case 0x9E: case 0xAE: case 0xBE: case 0xCE:
1.2588 - case 0xDE: case 0xEE: case 0xFE: /* LDC Rm, Rn_BANK */
1.2590 - RN_BANK(ir) = RM(ir);
1.2593 - if( (ir&0x000F) == 0x0F ) {
1.2594 - /* MAC.W [Rm++], [Rn++] */
1.2595 - CHECKRALIGN16( RN(ir) );
1.2596 - CHECKRALIGN16( RM(ir) );
1.2597 - tmp = SIGNEXT16(MEM_READ_WORD(RM(ir))) *
1.2598 - SIGNEXT16(MEM_READ_WORD(RN(ir)));
1.2602 - } else sh4r.mac += SIGNEXT32(tmp);
1.2605 - } else if( (ir&0x000F) == 0x0C ) {
1.2608 - if( (tmp & 0x80000000) == 0 ) RN(ir) <<= (tmp&0x1f);
1.2609 - else if( (tmp & 0x1F) == 0 )
1.2610 - RN(ir) = ((int32_t)RN(ir)) >> 31;
1.2612 - RN(ir) = ((int32_t)RN(ir)) >> (((~RM(ir)) & 0x1F)+1);
1.2613 - } else if( (ir&0x000F) == 0x0D ) {
1.2616 - if( (tmp & 0x80000000) == 0 ) RN(ir) <<= (tmp&0x1f);
1.2617 - else if( (tmp & 0x1F) == 0 ) RN(ir) = 0;
1.2618 - else RN(ir) >>= (((~tmp) & 0x1F)+1);
1.2622 - case 5: /* 0101nnnnmmmmdddd */
1.2623 - /* MOV.L [Rm + disp4*4], Rn */
1.2624 - tmp = RM(ir) + (DISP4(ir)<<2);
1.2625 - CHECKRALIGN32( tmp );
1.2626 - RN(ir) = MEM_READ_LONG( tmp );
1.2628 - case 6: /* 0110xxxxxxxxxxxx */
1.2629 - switch( ir&0x000f ) {
1.2630 - case 0: /* MOV.B [Rm], Rn */
1.2631 - RN(ir) = MEM_READ_BYTE( RM(ir) );
1.2633 - case 1: /* MOV.W [Rm], Rn */
1.2634 - CHECKRALIGN16( RM(ir) );
1.2635 - RN(ir) = MEM_READ_WORD( RM(ir) );
1.2637 - case 2: /* MOV.L [Rm], Rn */
1.2638 - CHECKRALIGN32( RM(ir) );
1.2639 - RN(ir) = MEM_READ_LONG( RM(ir) );
1.2641 - case 3: /* MOV Rm, Rn */
1.2644 - case 4: /* MOV.B [Rm++], Rn */
1.2645 - RN(ir) = MEM_READ_BYTE( RM(ir) );
1.2648 - case 5: /* MOV.W [Rm++], Rn */
1.2649 - CHECKRALIGN16( RM(ir) );
1.2650 - RN(ir) = MEM_READ_WORD( RM(ir) );
1.2653 - case 6: /* MOV.L [Rm++], Rn */
1.2654 - CHECKRALIGN32( RM(ir) );
1.2655 - RN(ir) = MEM_READ_LONG( RM(ir) );
1.2658 - case 7: /* NOT Rm, Rn */
1.2661 - case 8: /* SWAP.B Rm, Rn */
1.2662 - RN(ir) = (RM(ir)&0xFFFF0000) | ((RM(ir)&0x0000FF00)>>8) |
1.2663 - ((RM(ir)&0x000000FF)<<8);
1.2665 - case 9: /* SWAP.W Rm, Rn */
1.2666 - RN(ir) = (RM(ir)>>16) | (RM(ir)<<16);
1.2668 - case 10:/* NEGC Rm, Rn */
1.2670 - RN(ir) = tmp - sh4r.t;
1.2671 - sh4r.t = ( 0<tmp || tmp<RN(ir) ? 1 : 0 );
1.2673 - case 11:/* NEG Rm, Rn */
1.2676 - case 12:/* EXTU.B Rm, Rn */
1.2677 - RN(ir) = RM(ir)&0x000000FF;
1.2679 - case 13:/* EXTU.W Rm, Rn */
1.2680 - RN(ir) = RM(ir)&0x0000FFFF;
1.2682 - case 14:/* EXTS.B Rm, Rn */
1.2683 - RN(ir) = SIGNEXT8( RM(ir)&0x000000FF );
1.2685 - case 15:/* EXTS.W Rm, Rn */
1.2686 - RN(ir) = SIGNEXT16( RM(ir)&0x0000FFFF );
1.2690 - case 7: /* 0111nnnniiiiiiii */
1.2694 - case 8: /* 1000xxxxxxxxxxxx */
1.2695 - switch( (ir&0x0F00) >> 8 ) {
1.2696 - case 0: /* MOV.B R0, [Rm + disp4] */
1.2697 - MEM_WRITE_BYTE( RM(ir) + DISP4(ir), R0 );
1.2699 - case 1: /* MOV.W R0, [Rm + disp4*2] */
1.2700 - tmp = RM(ir) + (DISP4(ir)<<1);
1.2701 - CHECKWALIGN16( tmp );
1.2702 - MEM_WRITE_WORD( tmp, R0 );
1.2704 - case 4: /* MOV.B [Rm + disp4], R0 */
1.2705 - R0 = MEM_READ_BYTE( RM(ir) + DISP4(ir) );
1.2707 - case 5: /* MOV.W [Rm + disp4*2], R0 */
1.2708 - tmp = RM(ir) + (DISP4(ir)<<1);
1.2709 - CHECKRALIGN16( tmp );
1.2710 - R0 = MEM_READ_WORD( tmp );
1.2712 - case 8: /* CMP/EQ imm, R0 */
1.2713 - sh4r.t = ( R0 == IMM8(ir) ? 1 : 0 );
1.2715 - case 9: /* BT disp8 */
1.2718 - CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
1.2719 - sh4r.pc += (PCDISP8(ir)<<1) + 4;
1.2720 - sh4r.new_pc = sh4r.pc + 2;
1.2724 - case 11:/* BF disp8 */
1.2727 - CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
1.2728 - sh4r.pc += (PCDISP8(ir)<<1) + 4;
1.2729 - sh4r.new_pc = sh4r.pc + 2;
1.2733 - case 13:/* BT/S disp8 */
1.2736 - CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
1.2737 - sh4r.in_delay_slot = 1;
1.2738 - sh4r.pc = sh4r.new_pc;
1.2739 - sh4r.new_pc = pc + (PCDISP8(ir)<<1) + 4;
1.2740 - sh4r.in_delay_slot = 1;
1.2744 - case 15:/* BF/S disp8 */
1.2747 - CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
1.2748 - sh4r.in_delay_slot = 1;
1.2749 - sh4r.pc = sh4r.new_pc;
1.2750 - sh4r.new_pc = pc + (PCDISP8(ir)<<1) + 4;
1.2757 - case 9: /* 1001xxxxxxxxxxxx */
1.2758 - /* MOV.W [disp8*2 + pc + 4], Rn */
1.2760 - tmp = pc + 4 + (DISP8(ir)<<1);
1.2761 - RN(ir) = MEM_READ_WORD( tmp );
1.2763 - case 10:/* 1010dddddddddddd */
1.2766 - CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 );
1.2767 - sh4r.in_delay_slot = 1;
1.2768 - sh4r.pc = sh4r.new_pc;
1.2769 - sh4r.new_pc = pc + 4 + (DISP12(ir)<<1);
1.2771 - case 11:/* 1011dddddddddddd */
1.2773 - CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 );
1.2775 - sh4r.in_delay_slot = 1;
1.2777 - sh4r.pc = sh4r.new_pc;
1.2778 - sh4r.new_pc = pc + 4 + (DISP12(ir)<<1);
1.2779 - TRACE_CALL( pc, sh4r.new_pc );
1.2781 - case 12:/* 1100xxxxdddddddd */
1.2782 - switch( (ir&0x0F00)>>8 ) {
1.2783 - case 0: /* MOV.B R0, [GBR + disp8] */
1.2784 - MEM_WRITE_BYTE( sh4r.gbr + DISP8(ir), R0 );
1.2786 - case 1: /* MOV.W R0, [GBR + disp8*2] */
1.2787 - tmp = sh4r.gbr + (DISP8(ir)<<1);
1.2788 - CHECKWALIGN16( tmp );
1.2789 - MEM_WRITE_WORD( tmp, R0 );
1.2791 - case 2: /*MOV.L R0, [GBR + disp8*4] */
1.2792 - tmp = sh4r.gbr + (DISP8(ir)<<2);
1.2793 - CHECKWALIGN32( tmp );
1.2794 - MEM_WRITE_LONG( tmp, R0 );
1.2796 - case 3: /* TRAPA imm8 */
1.2798 - MMIO_WRITE( MMU, TRA, UIMM8(ir)<<2 );
1.2800 - sh4_raise_exception( EXC_TRAP );
1.2802 - case 4: /* MOV.B [GBR + disp8], R0 */
1.2803 - R0 = MEM_READ_BYTE( sh4r.gbr + DISP8(ir) );
1.2805 - case 5: /* MOV.W [GBR + disp8*2], R0 */
1.2806 - tmp = sh4r.gbr + (DISP8(ir)<<1);
1.2807 - CHECKRALIGN16( tmp );
1.2808 - R0 = MEM_READ_WORD( tmp );
1.2810 - case 6: /* MOV.L [GBR + disp8*4], R0 */
1.2811 - tmp = sh4r.gbr + (DISP8(ir)<<2);
1.2812 - CHECKRALIGN32( tmp );
1.2813 - R0 = MEM_READ_LONG( tmp );
1.2815 - case 7: /* MOVA disp8 + pc&~3 + 4, R0 */
1.2817 - R0 = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;
1.2819 - case 8: /* TST imm8, R0 */
1.2820 - sh4r.t = (R0 & UIMM8(ir) ? 0 : 1);
1.2822 - case 9: /* AND imm8, R0 */
1.2825 - case 10:/* XOR imm8, R0 */
1.2828 - case 11:/* OR imm8, R0 */
1.2831 - case 12:/* TST.B imm8, [R0+GBR] */
1.2832 - sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & UIMM8(ir) ? 0 : 1 );
1.2834 - case 13:/* AND.B imm8, [R0+GBR] */
1.2835 - MEM_WRITE_BYTE( R0 + sh4r.gbr,
1.2836 - UIMM8(ir) & MEM_READ_BYTE(R0 + sh4r.gbr) );
1.2838 - case 14:/* XOR.B imm8, [R0+GBR] */
1.2839 - MEM_WRITE_BYTE( R0 + sh4r.gbr,
1.2840 - UIMM8(ir) ^ MEM_READ_BYTE(R0 + sh4r.gbr) );
1.2842 - case 15:/* OR.B imm8, [R0+GBR] */
1.2843 - MEM_WRITE_BYTE( R0 + sh4r.gbr,
1.2844 - UIMM8(ir) | MEM_READ_BYTE(R0 + sh4r.gbr) );
1.2848 - case 13:/* 1101nnnndddddddd */
1.2849 - /* MOV.L [disp8*4 + pc&~3 + 4], Rn */
1.2851 - tmp = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;
1.2852 - RN(ir) = MEM_READ_LONG( tmp );
1.2854 - case 14:/* 1110nnnniiiiiiii */
1.2858 - case 15:/* 1111xxxxxxxxxxxx */
1.2860 - if( IS_FPU_DOUBLEPREC() ) {
1.2861 - switch( ir&0x000F ) {
1.2862 - case 0: /* FADD FRm, FRn */
1.2865 - case 1: /* FSUB FRm, FRn */
1.2868 - case 2: /* FMUL FRm, FRn */
1.2869 - DRN(ir) = DRN(ir) * DRM(ir);
1.2871 - case 3: /* FDIV FRm, FRn */
1.2872 - DRN(ir) = DRN(ir) / DRM(ir);
1.2874 - case 4: /* FCMP/EQ FRm, FRn */
1.2875 - sh4r.t = ( DRN(ir) == DRM(ir) ? 1 : 0 );
1.2877 - case 5: /* FCMP/GT FRm, FRn */
1.2878 - sh4r.t = ( DRN(ir) > DRM(ir) ? 1 : 0 );
1.2880 - case 6: /* FMOV.S [Rm+R0], FRn */
1.2881 - MEM_FP_READ( RM(ir) + R0, FRNn(ir) );
1.2883 - case 7: /* FMOV.S FRm, [Rn+R0] */
1.2884 - MEM_FP_WRITE( RN(ir) + R0, FRMn(ir) );
1.2886 - case 8: /* FMOV.S [Rm], FRn */
1.2887 - MEM_FP_READ( RM(ir), FRNn(ir) );
1.2889 - case 9: /* FMOV.S [Rm++], FRn */
1.2890 - MEM_FP_READ( RM(ir), FRNn(ir) );
1.2893 - case 10:/* FMOV.S FRm, [Rn] */
1.2894 - MEM_FP_WRITE( RN(ir), FRMn(ir) );
1.2896 - case 11:/* FMOV.S FRm, [--Rn] */
1.2898 - MEM_FP_WRITE( RN(ir), FRMn(ir) );
1.2900 - case 12:/* FMOV FRm, FRn */
1.2901 - if( IS_FPU_DOUBLESIZE() )
1.2907 - switch( (ir&0x00F0) >> 4 ) {
1.2908 - case 0: /* FSTS FPUL, FRn */
1.2911 - case 1: /* FLDS FRn,FPUL */
1.2914 - case 2: /* FLOAT FPUL, FRn */
1.2915 - DRN(ir) = (float)FPULi;
1.2917 - case 3: /* FTRC FRn, FPUL */
1.2919 - if( dtmp >= MAX_INTF )
1.2921 - else if( dtmp <= MIN_INTF )
1.2924 - FPULi = (int32_t)dtmp;
1.2926 - case 4: /* FNEG FRn */
1.2929 - case 5: /* FABS FRn */
1.2930 - DRN(ir) = fabs(DRN(ir));
1.2932 - case 6: /* FSQRT FRn */
1.2933 - DRN(ir) = sqrt(DRN(ir));
1.2935 - case 7: /* FSRRA FRn */
1.2936 - /* NO-OP when PR=1 */
1.2938 - case 8: /* FLDI0 FRn */
1.2941 - case 9: /* FLDI1 FRn */
1.2944 - case 10: /* FCNVSD FPUL, DRn */
1.2945 - if( ! IS_FPU_DOUBLESIZE() )
1.2946 - DRN(ir) = (double)FPULf;
1.2948 - case 11: /* FCNVDS DRn, FPUL */
1.2949 - if( ! IS_FPU_DOUBLESIZE() )
1.2950 - FPULf = (float)DRN(ir);
1.2952 - case 14:/* FIPR FVm, FVn */
1.2953 - /* NO-OP when PR=1 */
1.2956 - if( (ir&0x0300) == 0x0100 ) { /* FTRV XMTRX,FVn */
1.2957 - /* NO-OP when PR=1 */
1.2960 - else if( (ir&0x0100) == 0 ) { /* FSCA FPUL, DRn */
1.2961 - /* NO-OP when PR=1 */
1.2964 - else if( ir == 0xFBFD ) {
1.2966 - sh4r.fpscr ^= FPSCR_FR;
1.2969 - else if( ir == 0xF3FD ) {
1.2971 - sh4r.fpscr ^= FPSCR_SZ;
1.2977 - case 14:/* FMAC FR0, FRm, FRn */
1.2978 - DRN(ir) += DRM(ir)*DR0;
1.2982 - } else { /* Single precision */
1.2983 - switch( ir&0x000F ) {
1.2984 - case 0: /* FADD FRm, FRn */
1.2987 - case 1: /* FSUB FRm, FRn */
1.2990 - case 2: /* FMUL FRm, FRn */
1.2991 - FRN(ir) = FRN(ir) * FRM(ir);
1.2993 - case 3: /* FDIV FRm, FRn */
1.2994 - FRN(ir) = FRN(ir) / FRM(ir);
1.2996 - case 4: /* FCMP/EQ FRm, FRn */
1.2997 - sh4r.t = ( FRN(ir) == FRM(ir) ? 1 : 0 );
1.2999 - case 5: /* FCMP/GT FRm, FRn */
1.3000 - sh4r.t = ( FRN(ir) > FRM(ir) ? 1 : 0 );
1.3002 - case 6: /* FMOV.S [Rm+R0], FRn */
1.3003 - MEM_FP_READ( RM(ir) + R0, FRNn(ir) );
1.3005 - case 7: /* FMOV.S FRm, [Rn+R0] */
1.3006 - MEM_FP_WRITE( RN(ir) + R0, FRMn(ir) );
1.3008 - case 8: /* FMOV.S [Rm], FRn */
1.3009 - MEM_FP_READ( RM(ir), FRNn(ir) );
1.3011 - case 9: /* FMOV.S [Rm++], FRn */
1.3012 - MEM_FP_READ( RM(ir), FRNn(ir) );
1.3015 - case 10:/* FMOV.S FRm, [Rn] */
1.3016 - MEM_FP_WRITE( RN(ir), FRMn(ir) );
1.3018 - case 11:/* FMOV.S FRm, [--Rn] */
1.3020 - MEM_FP_WRITE( RN(ir), FRMn(ir) );
1.3022 - case 12:/* FMOV FRm, FRn */
1.3023 - if( IS_FPU_DOUBLESIZE() )
1.3029 - switch( (ir&0x00F0) >> 4 ) {
1.3030 - case 0: /* FSTS FPUL, FRn */
1.3033 - case 1: /* FLDS FRn,FPUL */
1.3036 - case 2: /* FLOAT FPUL, FRn */
1.3037 - FRN(ir) = (float)FPULi;
1.3039 - case 3: /* FTRC FRn, FPUL */
1.3041 - if( ftmp >= MAX_INTF )
1.3043 - else if( ftmp <= MIN_INTF )
1.3046 - FPULi = (int32_t)ftmp;
1.3048 - case 4: /* FNEG FRn */
1.3051 - case 5: /* FABS FRn */
1.3052 - FRN(ir) = fabsf(FRN(ir));
1.3054 - case 6: /* FSQRT FRn */
1.3055 - FRN(ir) = sqrtf(FRN(ir));
1.3057 - case 7: /* FSRRA FRn */
1.3058 - FRN(ir) = 1.0/sqrtf(FRN(ir));
1.3060 - case 8: /* FLDI0 FRn */
1.3063 - case 9: /* FLDI1 FRn */
1.3066 - case 10: /* FCNVSD FPUL, DRn */
1.3068 - case 11: /* FCNVDS DRn, FPUL */
1.3070 - case 14:/* FIPR FVm, FVn */
1.3071 - /* FIXME: This is not going to be entirely accurate
1.3072 - * as the SH4 instruction is less precise. Also
1.3073 - * need to check for 0s and infinities.
1.3078 - FR(tmp2+3) = FR(tmp)*FR(tmp2) +
1.3079 - FR(tmp+1)*FR(tmp2+1) +
1.3080 - FR(tmp+2)*FR(tmp2+2) +
1.3081 - FR(tmp+3)*FR(tmp2+3);
1.3085 - if( (ir&0x0300) == 0x0100 ) { /* FTRV XMTRX,FVn */
1.3087 - float fv[4] = { FR(tmp), FR(tmp+1), FR(tmp+2), FR(tmp+3) };
1.3088 - FR(tmp) = XF(0) * fv[0] + XF(4)*fv[1] +
1.3089 - XF(8)*fv[2] + XF(12)*fv[3];
1.3090 - FR(tmp+1) = XF(1) * fv[0] + XF(5)*fv[1] +
1.3091 - XF(9)*fv[2] + XF(13)*fv[3];
1.3092 - FR(tmp+2) = XF(2) * fv[0] + XF(6)*fv[1] +
1.3093 - XF(10)*fv[2] + XF(14)*fv[3];
1.3094 - FR(tmp+3) = XF(3) * fv[0] + XF(7)*fv[1] +
1.3095 - XF(11)*fv[2] + XF(15)*fv[3];
1.3098 - else if( (ir&0x0100) == 0 ) { /* FSCA FPUL, DRn */
1.3099 - float angle = (((float)(short)(FPULi>>16)) +
1.3100 - (((float)(FPULi&0xFFFF))/65536.0)) *
1.3103 - FR(reg) = sinf(angle);
1.3104 - FR(reg+1) = cosf(angle);
1.3107 - else if( ir == 0xFBFD ) {
1.3109 - sh4r.fpscr ^= FPSCR_FR;
1.3112 - else if( ir == 0xF3FD ) {
1.3114 - sh4r.fpscr ^= FPSCR_SZ;
1.3120 - case 14:/* FMAC FR0, FRm, FRn */
1.3121 - FRN(ir) += FRM(ir)*FR0;
1.3130 sh4r.in_delay_slot = 0;