Search
lxdream.org :: lxdream/src/sh4/sh4core.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4core.c
changeset 359:c588dce7ebde
prev312:2c34bdc36cbd
next367:9c52dcbad3fb
author nkeynes
date Tue Aug 28 08:46:14 2007 +0000 (16 years ago)
permissions -rw-r--r--
last change Translator WIP: fill out and correct another batch of instructions
file annotate diff log raw
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.3 @@ -1,5 +1,5 @@
1.4 /**
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.7 *
1.8 * SH4 emulation core, and parent module for all the SH4 peripheral
1.9 * modules.
1.10 @@ -58,7 +58,7 @@
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.16
1.17 struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_reset,
1.18 NULL, sh4_run_slice, sh4_stop,
1.19 @@ -327,7 +327,7 @@
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.22
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.27
1.28 @@ -415,7 +415,7 @@
1.29 RAISE( code, EXV_TLBMISS );
1.30 }
1.31
1.32 -static void sh4_accept_interrupt( void )
1.33 +void sh4_accept_interrupt( void )
1.34 {
1.35 uint32_t code = intc_accept_interrupt();
1.36 sh4r.ssr = sh4_read_sr();
1.37 @@ -433,39 +433,10 @@
1.38 uint32_t pc;
1.39 unsigned short ir;
1.40 uint32_t tmp;
1.41 - uint64_t tmpl;
1.42 float ftmp;
1.43 double dtmp;
1.44
1.45 #define R0 sh4r.r[0]
1.46 -#define FR0 FR(0)
1.47 -#define DR0 DR(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.73 -
1.74 pc = sh4r.pc;
1.75 if( pc > 0xFFFFFF00 ) {
1.76 /* SYSCALL Magic */
1.77 @@ -493,1176 +464,1891 @@
1.78 ir = sh4_icache[(pc&0xFFF)>>1];
1.79 }
1.80 }
1.81 -
1.82 - switch( (ir&0xF000)>>12 ) {
1.83 - case 0: /* 0000nnnnmmmmxxxx */
1.84 - switch( ir&0x000F ) {
1.85 - case 2:
1.86 - switch( (ir&0x00F0)>>4 ) {
1.87 - case 0: /* STC SR, Rn */
1.88 - CHECKPRIV();
1.89 - RN(ir) = sh4_read_sr();
1.90 - break;
1.91 - case 1: /* STC GBR, Rn */
1.92 - RN(ir) = sh4r.gbr;
1.93 - break;
1.94 - case 2: /* STC VBR, Rn */
1.95 - CHECKPRIV();
1.96 - RN(ir) = sh4r.vbr;
1.97 - break;
1.98 - case 3: /* STC SSR, Rn */
1.99 - CHECKPRIV();
1.100 - RN(ir) = sh4r.ssr;
1.101 - break;
1.102 - case 4: /* STC SPC, Rn */
1.103 - CHECKPRIV();
1.104 - RN(ir) = sh4r.spc;
1.105 - break;
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.108 - CHECKPRIV();
1.109 - RN(ir) = RN_BANK(ir);
1.110 - break;
1.111 - default: UNDEF(ir);
1.112 - }
1.113 - break;
1.114 - case 3:
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.125 + case 0x0:
1.126 + switch( ir&0xF ) {
1.127 + case 0x2:
1.128 + switch( (ir&0x80) >> 7 ) {
1.129 + case 0x0:
1.130 + switch( (ir&0x70) >> 4 ) {
1.131 + case 0x0:
1.132 + { /* STC SR, Rn */
1.133 + uint32_t Rn = ((ir>>8)&0xF);
1.134 + CHECKPRIV();
1.135 + sh4r.r[Rn] = sh4_read_sr();
1.136 + }
1.137 + break;
1.138 + case 0x1:
1.139 + { /* STC GBR, Rn */
1.140 + uint32_t Rn = ((ir>>8)&0xF);
1.141 + CHECKPRIV();
1.142 + sh4r.r[Rn] = sh4r.gbr;
1.143 + }
1.144 + break;
1.145 + case 0x2:
1.146 + { /* STC VBR, Rn */
1.147 + uint32_t Rn = ((ir>>8)&0xF);
1.148 + CHECKPRIV();
1.149 + sh4r.r[Rn] = sh4r.vbr;
1.150 + }
1.151 + break;
1.152 + case 0x3:
1.153 + { /* STC SSR, Rn */
1.154 + uint32_t Rn = ((ir>>8)&0xF);
1.155 + CHECKPRIV();
1.156 + sh4r.r[Rn] = sh4r.ssr;
1.157 + }
1.158 + break;
1.159 + case 0x4:
1.160 + { /* STC SPC, Rn */
1.161 + uint32_t Rn = ((ir>>8)&0xF);
1.162 + CHECKPRIV();
1.163 + sh4r.r[Rn] = sh4r.spc;
1.164 + }
1.165 + break;
1.166 + default:
1.167 + UNDEF();
1.168 + break;
1.169 + }
1.170 + break;
1.171 + case 0x1:
1.172 + { /* STC Rm_BANK, Rn */
1.173 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1.174 + CHECKPRIV();
1.175 + sh4r.r[Rn] = sh4r.r_bank[Rm_BANK];
1.176 + }
1.177 + break;
1.178 + }
1.179 + break;
1.180 + case 0x3:
1.181 + switch( (ir&0xF0) >> 4 ) {
1.182 + case 0x0:
1.183 + { /* BSRF Rn */
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.192 + return TRUE;
1.193 + }
1.194 + break;
1.195 + case 0x2:
1.196 + { /* BRAF Rn */
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.203 + return TRUE;
1.204 + }
1.205 + break;
1.206 + case 0x8:
1.207 + { /* PREF @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.217 + }
1.218 + }
1.219 + break;
1.220 + case 0x9:
1.221 + { /* OCBI @Rn */
1.222 + uint32_t Rn = ((ir>>8)&0xF);
1.223 + }
1.224 + break;
1.225 + case 0xA:
1.226 + { /* OCBP @Rn */
1.227 + uint32_t Rn = ((ir>>8)&0xF);
1.228 + }
1.229 + break;
1.230 + case 0xB:
1.231 + { /* OCBWB @Rn */
1.232 + uint32_t Rn = ((ir>>8)&0xF);
1.233 + }
1.234 + break;
1.235 + case 0xC:
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.241 + }
1.242 + break;
1.243 + default:
1.244 + UNDEF();
1.245 + break;
1.246 + }
1.247 + break;
1.248 + case 0x4:
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.252 + }
1.253 + break;
1.254 + case 0x5:
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.259 + }
1.260 + break;
1.261 + case 0x6:
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.266 + }
1.267 + break;
1.268 + case 0x7:
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.273 + }
1.274 + break;
1.275 + case 0x8:
1.276 + switch( (ir&0xFF0) >> 4 ) {
1.277 + case 0x0:
1.278 + { /* CLRT */
1.279 + sh4r.t = 0;
1.280 + }
1.281 + break;
1.282 + case 0x1:
1.283 + { /* SETT */
1.284 + sh4r.t = 1;
1.285 + }
1.286 + break;
1.287 + case 0x2:
1.288 + { /* CLRMAC */
1.289 + sh4r.mac = 0;
1.290 + }
1.291 + break;
1.292 + case 0x3:
1.293 + { /* LDTLB */
1.294 + /* TODO */
1.295 + }
1.296 + break;
1.297 + case 0x4:
1.298 + { /* CLRS */
1.299 + sh4r.s = 0;
1.300 + }
1.301 + break;
1.302 + case 0x5:
1.303 + { /* SETS */
1.304 + sh4r.s = 1;
1.305 + }
1.306 + break;
1.307 + default:
1.308 + UNDEF();
1.309 + break;
1.310 + }
1.311 + break;
1.312 + case 0x9:
1.313 + switch( (ir&0xF0) >> 4 ) {
1.314 + case 0x0:
1.315 + { /* NOP */
1.316 + /* NOP */
1.317 + }
1.318 + break;
1.319 + case 0x1:
1.320 + { /* DIV0U */
1.321 + sh4r.m = sh4r.q = sh4r.t = 0;
1.322 + }
1.323 + break;
1.324 + case 0x2:
1.325 + { /* MOVT Rn */
1.326 + uint32_t Rn = ((ir>>8)&0xF);
1.327 + sh4r.r[Rn] = sh4r.t;
1.328 + }
1.329 + break;
1.330 + default:
1.331 + UNDEF();
1.332 + break;
1.333 + }
1.334 + break;
1.335 + case 0xA:
1.336 + switch( (ir&0xF0) >> 4 ) {
1.337 + case 0x0:
1.338 + { /* STS MACH, Rn */
1.339 + uint32_t Rn = ((ir>>8)&0xF);
1.340 + sh4r.r[Rn] = (sh4r.mac>>32);
1.341 + }
1.342 + break;
1.343 + case 0x1:
1.344 + { /* STS MACL, Rn */
1.345 + uint32_t Rn = ((ir>>8)&0xF);
1.346 + sh4r.r[Rn] = (uint32_t)sh4r.mac;
1.347 + }
1.348 + break;
1.349 + case 0x2:
1.350 + { /* STS PR, Rn */
1.351 + uint32_t Rn = ((ir>>8)&0xF);
1.352 + sh4r.r[Rn] = sh4r.pr;
1.353 + }
1.354 + break;
1.355 + case 0x3:
1.356 + { /* STC SGR, Rn */
1.357 + uint32_t Rn = ((ir>>8)&0xF);
1.358 + CHECKPRIV();
1.359 + sh4r.r[Rn] = sh4r.sgr;
1.360 + }
1.361 + break;
1.362 + case 0x5:
1.363 + { /* STS FPUL, Rn */
1.364 + uint32_t Rn = ((ir>>8)&0xF);
1.365 + sh4r.r[Rn] = sh4r.fpul;
1.366 + }
1.367 + break;
1.368 + case 0x6:
1.369 + { /* STS FPSCR, Rn */
1.370 + uint32_t Rn = ((ir>>8)&0xF);
1.371 + sh4r.r[Rn] = sh4r.fpscr;
1.372 + }
1.373 + break;
1.374 + case 0xF:
1.375 + { /* STC DBR, Rn */
1.376 + uint32_t Rn = ((ir>>8)&0xF);
1.377 + CHECKPRIV(); sh4r.r[Rn] = sh4r.dbr;
1.378 + }
1.379 + break;
1.380 + default:
1.381 + UNDEF();
1.382 + break;
1.383 + }
1.384 + break;
1.385 + case 0xB:
1.386 + switch( (ir&0xFF0) >> 4 ) {
1.387 + case 0x0:
1.388 + { /* RTS */
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.395 + return TRUE;
1.396 + }
1.397 + break;
1.398 + case 0x1:
1.399 + { /* SLEEP */
1.400 + if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
1.401 + sh4r.sh4_state = SH4_STATE_STANDBY;
1.402 + } else {
1.403 + sh4r.sh4_state = SH4_STATE_SLEEP;
1.404 + }
1.405 + return FALSE; /* Halt CPU */
1.406 + }
1.407 + break;
1.408 + case 0x2:
1.409 + { /* RTE */
1.410 + CHECKPRIV();
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.417 + return TRUE;
1.418 + }
1.419 + break;
1.420 + default:
1.421 + UNDEF();
1.422 + break;
1.423 + }
1.424 + break;
1.425 + case 0xC:
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.429 + }
1.430 + break;
1.431 + case 0xD:
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.436 + }
1.437 + break;
1.438 + case 0xE:
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.443 + }
1.444 + break;
1.445 + case 0xF:
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.451 + sh4r.r[Rn] += 4;
1.452 + tmpl = tmpl * SIGNEXT32(MEM_READ_LONG(sh4r.r[Rm])) + sh4r.mac;
1.453 + sh4r.r[Rm] += 4;
1.454 + if( sh4r.s ) {
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.460 + }
1.461 + sh4r.mac = tmpl;
1.462 + }
1.463 + break;
1.464 + default:
1.465 + UNDEF();
1.466 + break;
1.467 + }
1.468 + break;
1.469 + case 0x1:
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.475 + }
1.476 + break;
1.477 + case 0x2:
1.478 + switch( ir&0xF ) {
1.479 + case 0x0:
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.483 + }
1.484 + break;
1.485 + case 0x1:
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.489 + }
1.490 + break;
1.491 + case 0x2:
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.495 + }
1.496 + break;
1.497 + case 0x4:
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.501 + }
1.502 + break;
1.503 + case 0x5:
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.507 + }
1.508 + break;
1.509 + case 0x6:
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.513 + }
1.514 + break;
1.515 + case 0x7:
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.521 + }
1.522 + break;
1.523 + case 0x8:
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.527 + }
1.528 + break;
1.529 + case 0x9:
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.533 + }
1.534 + break;
1.535 + case 0xA:
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.539 + }
1.540 + break;
1.541 + case 0xB:
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.545 + }
1.546 + break;
1.547 + case 0xC:
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.554 + }
1.555 + break;
1.556 + case 0xD:
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.560 + }
1.561 + break;
1.562 + case 0xE:
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.567 + }
1.568 + break;
1.569 + case 0xF:
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.574 + }
1.575 + break;
1.576 + default:
1.577 + UNDEF();
1.578 + break;
1.579 + }
1.580 + break;
1.581 + case 0x3:
1.582 + switch( ir&0xF ) {
1.583 + case 0x0:
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.587 + }
1.588 + break;
1.589 + case 0x2:
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.593 + }
1.594 + break;
1.595 + case 0x3:
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.599 + }
1.600 + break;
1.601 + case 0x4:
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.607 + */
1.608 + uint32_t tmp0, tmp1, tmp2, dir;
1.609 +
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.615 + if( dir ) {
1.616 + sh4r.r[Rn] += tmp2;
1.617 + tmp1 = (sh4r.r[Rn]<tmp0 ? 1 : 0 );
1.618 + } else {
1.619 + sh4r.r[Rn] -= tmp2;
1.620 + tmp1 = (sh4r.r[Rn]>tmp0 ? 1 : 0 );
1.621 + }
1.622 + sh4r.q ^= sh4r.m ^ tmp1;
1.623 + sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );
1.624 + }
1.625 + break;
1.626 + case 0x5:
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.630 + }
1.631 + break;
1.632 + case 0x6:
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.636 + }
1.637 + break;
1.638 + case 0x7:
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.642 + }
1.643 + break;
1.644 + case 0x8:
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.648 + }
1.649 + break;
1.650 + case 0xA:
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.656 + }
1.657 + break;
1.658 + case 0xB:
1.659 + UNIMP(ir); /* SUBV Rm, Rn */
1.660 + break;
1.661 + case 0xC:
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.665 + }
1.666 + break;
1.667 + case 0xD:
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.671 + }
1.672 + break;
1.673 + case 0xE:
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.679 + }
1.680 + break;
1.681 + case 0xF:
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.687 + }
1.688 + break;
1.689 + default:
1.690 + UNDEF();
1.691 + break;
1.692 + }
1.693 + break;
1.694 + case 0x4:
1.695 + switch( ir&0xF ) {
1.696 + case 0x0:
1.697 + switch( (ir&0xF0) >> 4 ) {
1.698 + case 0x0:
1.699 + { /* SHLL Rn */
1.700 + uint32_t Rn = ((ir>>8)&0xF);
1.701 + sh4r.t = sh4r.r[Rn] >> 31; sh4r.r[Rn] <<= 1;
1.702 + }
1.703 + break;
1.704 + case 0x1:
1.705 + { /* DT Rn */
1.706 + uint32_t Rn = ((ir>>8)&0xF);
1.707 + sh4r.r[Rn] --;
1.708 + sh4r.t = ( sh4r.r[Rn] == 0 ? 1 : 0 );
1.709 + }
1.710 + break;
1.711 + case 0x2:
1.712 + { /* SHAL Rn */
1.713 + uint32_t Rn = ((ir>>8)&0xF);
1.714 + sh4r.t = sh4r.r[Rn] >> 31;
1.715 + sh4r.r[Rn] <<= 1;
1.716 + }
1.717 + break;
1.718 + default:
1.719 + UNDEF();
1.720 + break;
1.721 + }
1.722 + break;
1.723 + case 0x1:
1.724 + switch( (ir&0xF0) >> 4 ) {
1.725 + case 0x0:
1.726 + { /* SHLR Rn */
1.727 + uint32_t Rn = ((ir>>8)&0xF);
1.728 + sh4r.t = sh4r.r[Rn] & 0x00000001; sh4r.r[Rn] >>= 1;
1.729 + }
1.730 + break;
1.731 + case 0x1:
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.735 + }
1.736 + break;
1.737 + case 0x2:
1.738 + { /* SHAR Rn */
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.742 + }
1.743 + break;
1.744 + default:
1.745 + UNDEF();
1.746 + break;
1.747 + }
1.748 + break;
1.749 + case 0x2:
1.750 + switch( (ir&0xF0) >> 4 ) {
1.751 + case 0x0:
1.752 + { /* STS.L MACH, @-Rn */
1.753 + uint32_t Rn = ((ir>>8)&0xF);
1.754 + sh4r.r[Rn] -= 4;
1.755 + CHECKWALIGN32( sh4r.r[Rn] );
1.756 + MEM_WRITE_LONG( sh4r.r[Rn], (sh4r.mac>>32) );
1.757 + }
1.758 + break;
1.759 + case 0x1:
1.760 + { /* STS.L MACL, @-Rn */
1.761 + uint32_t Rn = ((ir>>8)&0xF);
1.762 + sh4r.r[Rn] -= 4;
1.763 + CHECKWALIGN32( sh4r.r[Rn] );
1.764 + MEM_WRITE_LONG( sh4r.r[Rn], (uint32_t)sh4r.mac );
1.765 + }
1.766 + break;
1.767 + case 0x2:
1.768 + { /* STS.L PR, @-Rn */
1.769 + uint32_t Rn = ((ir>>8)&0xF);
1.770 + sh4r.r[Rn] -= 4;
1.771 + CHECKWALIGN32( sh4r.r[Rn] );
1.772 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.pr );
1.773 + }
1.774 + break;
1.775 + case 0x3:
1.776 + { /* STC.L SGR, @-Rn */
1.777 + uint32_t Rn = ((ir>>8)&0xF);
1.778 + CHECKPRIV();
1.779 + sh4r.r[Rn] -= 4;
1.780 + CHECKWALIGN32( sh4r.r[Rn] );
1.781 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.sgr );
1.782 + }
1.783 + break;
1.784 + case 0x5:
1.785 + { /* STS.L FPUL, @-Rn */
1.786 + uint32_t Rn = ((ir>>8)&0xF);
1.787 + sh4r.r[Rn] -= 4;
1.788 + CHECKWALIGN32( sh4r.r[Rn] );
1.789 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpul );
1.790 + }
1.791 + break;
1.792 + case 0x6:
1.793 + { /* STS.L FPSCR, @-Rn */
1.794 + uint32_t Rn = ((ir>>8)&0xF);
1.795 + sh4r.r[Rn] -= 4;
1.796 + CHECKWALIGN32( sh4r.r[Rn] );
1.797 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpscr );
1.798 + }
1.799 + break;
1.800 + case 0xF:
1.801 + { /* STC.L DBR, @-Rn */
1.802 + uint32_t Rn = ((ir>>8)&0xF);
1.803 + CHECKPRIV();
1.804 + sh4r.r[Rn] -= 4;
1.805 + CHECKWALIGN32( sh4r.r[Rn] );
1.806 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.dbr );
1.807 + }
1.808 + break;
1.809 + default:
1.810 + UNDEF();
1.811 + break;
1.812 + }
1.813 + break;
1.814 + case 0x3:
1.815 + switch( (ir&0x80) >> 7 ) {
1.816 + case 0x0:
1.817 + switch( (ir&0x70) >> 4 ) {
1.818 + case 0x0:
1.819 + { /* STC.L SR, @-Rn */
1.820 + uint32_t Rn = ((ir>>8)&0xF);
1.821 + CHECKPRIV();
1.822 + sh4r.r[Rn] -= 4;
1.823 + CHECKWALIGN32( sh4r.r[Rn] );
1.824 + MEM_WRITE_LONG( sh4r.r[Rn], sh4_read_sr() );
1.825 + }
1.826 + break;
1.827 + case 0x1:
1.828 + { /* STC.L GBR, @-Rn */
1.829 + uint32_t Rn = ((ir>>8)&0xF);
1.830 + sh4r.r[Rn] -= 4;
1.831 + CHECKWALIGN32( sh4r.r[Rn] );
1.832 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.gbr );
1.833 + }
1.834 + break;
1.835 + case 0x2:
1.836 + { /* STC.L VBR, @-Rn */
1.837 + uint32_t Rn = ((ir>>8)&0xF);
1.838 + CHECKPRIV();
1.839 + sh4r.r[Rn] -= 4;
1.840 + CHECKWALIGN32( sh4r.r[Rn] );
1.841 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.vbr );
1.842 + }
1.843 + break;
1.844 + case 0x3:
1.845 + { /* STC.L SSR, @-Rn */
1.846 + uint32_t Rn = ((ir>>8)&0xF);
1.847 + CHECKPRIV();
1.848 + sh4r.r[Rn] -= 4;
1.849 + CHECKWALIGN32( sh4r.r[Rn] );
1.850 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.ssr );
1.851 + }
1.852 + break;
1.853 + case 0x4:
1.854 + { /* STC.L SPC, @-Rn */
1.855 + uint32_t Rn = ((ir>>8)&0xF);
1.856 + CHECKPRIV();
1.857 + sh4r.r[Rn] -= 4;
1.858 + CHECKWALIGN32( sh4r.r[Rn] );
1.859 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.spc );
1.860 + }
1.861 + break;
1.862 + default:
1.863 + UNDEF();
1.864 + break;
1.865 + }
1.866 + break;
1.867 + case 0x1:
1.868 + { /* STC.L Rm_BANK, @-Rn */
1.869 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1.870 + CHECKPRIV();
1.871 + sh4r.r[Rn] -= 4;
1.872 + CHECKWALIGN32( sh4r.r[Rn] );
1.873 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r_bank[Rm_BANK] );
1.874 + }
1.875 + break;
1.876 + }
1.877 + break;
1.878 + case 0x4:
1.879 + switch( (ir&0xF0) >> 4 ) {
1.880 + case 0x0:
1.881 + { /* ROTL Rn */
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.886 + }
1.887 + break;
1.888 + case 0x2:
1.889 + { /* ROTCL Rn */
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.894 + sh4r.t = tmp;
1.895 + }
1.896 + break;
1.897 + default:
1.898 + UNDEF();
1.899 + break;
1.900 + }
1.901 + break;
1.902 + case 0x5:
1.903 + switch( (ir&0xF0) >> 4 ) {
1.904 + case 0x0:
1.905 + { /* ROTR Rn */
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.910 + }
1.911 + break;
1.912 + case 0x1:
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.916 + }
1.917 + break;
1.918 + case 0x2:
1.919 + { /* ROTCR Rn */
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.924 + sh4r.t = tmp;
1.925 + }
1.926 + break;
1.927 + default:
1.928 + UNDEF();
1.929 + break;
1.930 + }
1.931 + break;
1.932 + case 0x6:
1.933 + switch( (ir&0xF0) >> 4 ) {
1.934 + case 0x0:
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.940 + sh4r.r[Rm] += 4;
1.941 + }
1.942 + break;
1.943 + case 0x1:
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.949 + sh4r.r[Rm] += 4;
1.950 + }
1.951 + break;
1.952 + case 0x2:
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.957 + sh4r.r[Rm] += 4;
1.958 + }
1.959 + break;
1.960 + case 0x3:
1.961 + { /* LDC.L @Rm+, SGR */
1.962 + uint32_t Rm = ((ir>>8)&0xF);
1.963 + CHECKPRIV();
1.964 + CHECKRALIGN32( sh4r.r[Rm] );
1.965 + sh4r.sgr = MEM_READ_LONG(sh4r.r[Rm]);
1.966 + sh4r.r[Rm] +=4;
1.967 + }
1.968 + break;
1.969 + case 0x5:
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.974 + sh4r.r[Rm] +=4;
1.975 + }
1.976 + break;
1.977 + case 0x6:
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.982 + sh4r.r[Rm] +=4;
1.983 + }
1.984 + break;
1.985 + case 0xF:
1.986 + { /* LDC.L @Rm+, DBR */
1.987 + uint32_t Rm = ((ir>>8)&0xF);
1.988 + CHECKPRIV();
1.989 + CHECKRALIGN32( sh4r.r[Rm] );
1.990 + sh4r.dbr = MEM_READ_LONG(sh4r.r[Rm]);
1.991 + sh4r.r[Rm] +=4;
1.992 + }
1.993 + break;
1.994 + default:
1.995 + UNDEF();
1.996 + break;
1.997 + }
1.998 + break;
1.999 + case 0x7:
1.1000 + switch( (ir&0x80) >> 7 ) {
1.1001 + case 0x0:
1.1002 + switch( (ir&0x70) >> 4 ) {
1.1003 + case 0x0:
1.1004 + { /* LDC.L @Rm+, SR */
1.1005 + uint32_t Rm = ((ir>>8)&0xF);
1.1006 + CHECKSLOTILLEGAL();
1.1007 + CHECKPRIV();
1.1008 + CHECKWALIGN32( sh4r.r[Rm] );
1.1009 + sh4_load_sr( MEM_READ_LONG(sh4r.r[Rm]) );
1.1010 + sh4r.r[Rm] +=4;
1.1011 + }
1.1012 + break;
1.1013 + case 0x1:
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.1018 + sh4r.r[Rm] +=4;
1.1019 + }
1.1020 + break;
1.1021 + case 0x2:
1.1022 + { /* LDC.L @Rm+, VBR */
1.1023 + uint32_t Rm = ((ir>>8)&0xF);
1.1024 + CHECKPRIV();
1.1025 + CHECKRALIGN32( sh4r.r[Rm] );
1.1026 + sh4r.vbr = MEM_READ_LONG(sh4r.r[Rm]);
1.1027 + sh4r.r[Rm] +=4;
1.1028 + }
1.1029 + break;
1.1030 + case 0x3:
1.1031 + { /* LDC.L @Rm+, SSR */
1.1032 + uint32_t Rm = ((ir>>8)&0xF);
1.1033 + CHECKPRIV();
1.1034 + CHECKRALIGN32( sh4r.r[Rm] );
1.1035 + sh4r.ssr = MEM_READ_LONG(sh4r.r[Rm]);
1.1036 + sh4r.r[Rm] +=4;
1.1037 + }
1.1038 + break;
1.1039 + case 0x4:
1.1040 + { /* LDC.L @Rm+, SPC */
1.1041 + uint32_t Rm = ((ir>>8)&0xF);
1.1042 + CHECKPRIV();
1.1043 + CHECKRALIGN32( sh4r.r[Rm] );
1.1044 + sh4r.spc = MEM_READ_LONG(sh4r.r[Rm]);
1.1045 + sh4r.r[Rm] +=4;
1.1046 + }
1.1047 + break;
1.1048 + default:
1.1049 + UNDEF();
1.1050 + break;
1.1051 + }
1.1052 + break;
1.1053 + case 0x1:
1.1054 + { /* LDC.L @Rm+, Rn_BANK */
1.1055 + uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1.1056 + CHECKPRIV();
1.1057 + CHECKRALIGN32( sh4r.r[Rm] );
1.1058 + sh4r.r_bank[Rn_BANK] = MEM_READ_LONG( sh4r.r[Rm] );
1.1059 + sh4r.r[Rm] += 4;
1.1060 + }
1.1061 + break;
1.1062 + }
1.1063 + break;
1.1064 + case 0x8:
1.1065 + switch( (ir&0xF0) >> 4 ) {
1.1066 + case 0x0:
1.1067 + { /* SHLL2 Rn */
1.1068 + uint32_t Rn = ((ir>>8)&0xF);
1.1069 + sh4r.r[Rn] <<= 2;
1.1070 + }
1.1071 + break;
1.1072 + case 0x1:
1.1073 + { /* SHLL8 Rn */
1.1074 + uint32_t Rn = ((ir>>8)&0xF);
1.1075 + sh4r.r[Rn] <<= 8;
1.1076 + }
1.1077 + break;
1.1078 + case 0x2:
1.1079 + { /* SHLL16 Rn */
1.1080 + uint32_t Rn = ((ir>>8)&0xF);
1.1081 + sh4r.r[Rn] <<= 16;
1.1082 + }
1.1083 + break;
1.1084 + default:
1.1085 + UNDEF();
1.1086 + break;
1.1087 + }
1.1088 + break;
1.1089 + case 0x9:
1.1090 + switch( (ir&0xF0) >> 4 ) {
1.1091 + case 0x0:
1.1092 + { /* SHLR2 Rn */
1.1093 + uint32_t Rn = ((ir>>8)&0xF);
1.1094 + sh4r.r[Rn] >>= 2;
1.1095 + }
1.1096 + break;
1.1097 + case 0x1:
1.1098 + { /* SHLR8 Rn */
1.1099 + uint32_t Rn = ((ir>>8)&0xF);
1.1100 + sh4r.r[Rn] >>= 8;
1.1101 + }
1.1102 + break;
1.1103 + case 0x2:
1.1104 + { /* SHLR16 Rn */
1.1105 + uint32_t Rn = ((ir>>8)&0xF);
1.1106 + sh4r.r[Rn] >>= 16;
1.1107 + }
1.1108 + break;
1.1109 + default:
1.1110 + UNDEF();
1.1111 + break;
1.1112 + }
1.1113 + break;
1.1114 + case 0xA:
1.1115 + switch( (ir&0xF0) >> 4 ) {
1.1116 + case 0x0:
1.1117 + { /* LDS Rm, MACH */
1.1118 + uint32_t Rm = ((ir>>8)&0xF);
1.1119 + sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1.1120 + (((uint64_t)sh4r.r[Rm])<<32);
1.1121 + }
1.1122 + break;
1.1123 + case 0x1:
1.1124 + { /* LDS Rm, MACL */
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.1128 + }
1.1129 + break;
1.1130 + case 0x2:
1.1131 + { /* LDS Rm, PR */
1.1132 + uint32_t Rm = ((ir>>8)&0xF);
1.1133 + sh4r.pr = sh4r.r[Rm];
1.1134 + }
1.1135 + break;
1.1136 + case 0x3:
1.1137 + { /* LDC Rm, SGR */
1.1138 + uint32_t Rm = ((ir>>8)&0xF);
1.1139 + CHECKPRIV();
1.1140 + sh4r.sgr = sh4r.r[Rm];
1.1141 + }
1.1142 + break;
1.1143 + case 0x5:
1.1144 + { /* LDS Rm, FPUL */
1.1145 + uint32_t Rm = ((ir>>8)&0xF);
1.1146 + sh4r.fpul = sh4r.r[Rm];
1.1147 + }
1.1148 + break;
1.1149 + case 0x6:
1.1150 + { /* LDS Rm, FPSCR */
1.1151 + uint32_t Rm = ((ir>>8)&0xF);
1.1152 + sh4r.fpscr = sh4r.r[Rm];
1.1153 + }
1.1154 + break;
1.1155 + case 0xF:
1.1156 + { /* LDC Rm, DBR */
1.1157 + uint32_t Rm = ((ir>>8)&0xF);
1.1158 + CHECKPRIV();
1.1159 + sh4r.dbr = sh4r.r[Rm];
1.1160 + }
1.1161 + break;
1.1162 + default:
1.1163 + UNDEF();
1.1164 + break;
1.1165 + }
1.1166 + break;
1.1167 + case 0xB:
1.1168 + switch( (ir&0xF0) >> 4 ) {
1.1169 + case 0x0:
1.1170 + { /* JSR @Rn */
1.1171 + uint32_t Rn = ((ir>>8)&0xF);
1.1172 + CHECKDEST( sh4r.r[Rn] );
1.1173 + CHECKSLOTILLEGAL();
1.1174 + sh4r.in_delay_slot = 1;
1.1175 + sh4r.pc = sh4r.new_pc;
1.1176 + sh4r.new_pc = sh4r.r[Rn];
1.1177 + sh4r.pr = pc + 4;
1.1178 + TRACE_CALL( pc, sh4r.new_pc );
1.1179 + return TRUE;
1.1180 + }
1.1181 + break;
1.1182 + case 0x1:
1.1183 + { /* TAS.B @Rn */
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.1188 + }
1.1189 + break;
1.1190 + case 0x2:
1.1191 + { /* JMP @Rn */
1.1192 + uint32_t Rn = ((ir>>8)&0xF);
1.1193 + CHECKDEST( sh4r.r[Rn] );
1.1194 + CHECKSLOTILLEGAL();
1.1195 + sh4r.in_delay_slot = 1;
1.1196 + sh4r.pc = sh4r.new_pc;
1.1197 + sh4r.new_pc = sh4r.r[Rn];
1.1198 + return TRUE;
1.1199 + }
1.1200 + break;
1.1201 + default:
1.1202 + UNDEF();
1.1203 + break;
1.1204 + }
1.1205 + break;
1.1206 + case 0xC:
1.1207 + { /* SHAD Rm, Rn */
1.1208 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1209 + tmp = sh4r.r[Rm];
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.1213 + else
1.1214 + sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> (((~sh4r.r[Rm]) & 0x1F)+1);
1.1215 + }
1.1216 + break;
1.1217 + case 0xD:
1.1218 + { /* SHLD Rm, Rn */
1.1219 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1220 + tmp = sh4r.r[Rm];
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.1224 + }
1.1225 + break;
1.1226 + case 0xE:
1.1227 + switch( (ir&0x80) >> 7 ) {
1.1228 + case 0x0:
1.1229 + switch( (ir&0x70) >> 4 ) {
1.1230 + case 0x0:
1.1231 + { /* LDC Rm, SR */
1.1232 + uint32_t Rm = ((ir>>8)&0xF);
1.1233 + CHECKSLOTILLEGAL();
1.1234 + CHECKPRIV();
1.1235 + sh4_load_sr( sh4r.r[Rm] );
1.1236 + }
1.1237 + break;
1.1238 + case 0x1:
1.1239 + { /* LDC Rm, GBR */
1.1240 + uint32_t Rm = ((ir>>8)&0xF);
1.1241 + sh4r.gbr = sh4r.r[Rm];
1.1242 + }
1.1243 + break;
1.1244 + case 0x2:
1.1245 + { /* LDC Rm, VBR */
1.1246 + uint32_t Rm = ((ir>>8)&0xF);
1.1247 + CHECKPRIV();
1.1248 + sh4r.vbr = sh4r.r[Rm];
1.1249 + }
1.1250 + break;
1.1251 + case 0x3:
1.1252 + { /* LDC Rm, SSR */
1.1253 + uint32_t Rm = ((ir>>8)&0xF);
1.1254 + CHECKPRIV();
1.1255 + sh4r.ssr = sh4r.r[Rm];
1.1256 + }
1.1257 + break;
1.1258 + case 0x4:
1.1259 + { /* LDC Rm, SPC */
1.1260 + uint32_t Rm = ((ir>>8)&0xF);
1.1261 + CHECKPRIV();
1.1262 + sh4r.spc = sh4r.r[Rm];
1.1263 + }
1.1264 + break;
1.1265 + default:
1.1266 + UNDEF();
1.1267 + break;
1.1268 + }
1.1269 + break;
1.1270 + case 0x1:
1.1271 + { /* LDC Rm, Rn_BANK */
1.1272 + uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1.1273 + CHECKPRIV();
1.1274 + sh4r.r_bank[Rn_BANK] = sh4r.r[Rm];
1.1275 + }
1.1276 + break;
1.1277 + }
1.1278 + break;
1.1279 + case 0xF:
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.1285 + sh4r.r[Rn] += 2;
1.1286 + stmp = stmp * SIGNEXT16(MEM_READ_WORD(sh4r.r[Rm]));
1.1287 + sh4r.r[Rm] += 2;
1.1288 + if( sh4r.s ) {
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.1294 + } else {
1.1295 + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1.1296 + ((uint32_t)(sh4r.mac + stmp));
1.1297 + }
1.1298 + } else {
1.1299 + sh4r.mac += SIGNEXT32(stmp);
1.1300 + }
1.1301 + }
1.1302 + break;
1.1303 + }
1.1304 + break;
1.1305 + case 0x5:
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.1311 + }
1.1312 + break;
1.1313 + case 0x6:
1.1314 + switch( ir&0xF ) {
1.1315 + case 0x0:
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.1319 + }
1.1320 + break;
1.1321 + case 0x1:
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.1325 + }
1.1326 + break;
1.1327 + case 0x2:
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.1331 + }
1.1332 + break;
1.1333 + case 0x3:
1.1334 + { /* MOV Rm, Rn */
1.1335 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1336 + sh4r.r[Rn] = sh4r.r[Rm];
1.1337 + }
1.1338 + break;
1.1339 + case 0x4:
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.1343 + }
1.1344 + break;
1.1345 + case 0x5:
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.1349 + }
1.1350 + break;
1.1351 + case 0x6:
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.1355 + }
1.1356 + break;
1.1357 + case 0x7:
1.1358 + { /* NOT Rm, Rn */
1.1359 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1360 + sh4r.r[Rn] = ~sh4r.r[Rm];
1.1361 + }
1.1362 + break;
1.1363 + case 0x8:
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.1367 + }
1.1368 + break;
1.1369 + case 0x9:
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.1373 + }
1.1374 + break;
1.1375 + case 0xA:
1.1376 + { /* NEGC Rm, Rn */
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.1381 + }
1.1382 + break;
1.1383 + case 0xB:
1.1384 + { /* NEG Rm, Rn */
1.1385 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1386 + sh4r.r[Rn] = 0 - sh4r.r[Rm];
1.1387 + }
1.1388 + break;
1.1389 + case 0xC:
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.1393 + }
1.1394 + break;
1.1395 + case 0xD:
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.1399 + }
1.1400 + break;
1.1401 + case 0xE:
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.1405 + }
1.1406 + break;
1.1407 + case 0xF:
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.1411 + }
1.1412 + break;
1.1413 + }
1.1414 + break;
1.1415 + case 0x7:
1.1416 + { /* ADD #imm, Rn */
1.1417 + uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1.1418 + sh4r.r[Rn] += imm;
1.1419 + }
1.1420 + break;
1.1421 + case 0x8:
1.1422 + switch( (ir&0xF00) >> 8 ) {
1.1423 + case 0x0:
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.1427 + }
1.1428 + break;
1.1429 + case 0x1:
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.1435 + }
1.1436 + break;
1.1437 + case 0x4:
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.1441 + }
1.1442 + break;
1.1443 + case 0x5:
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.1449 + }
1.1450 + break;
1.1451 + case 0x8:
1.1452 + { /* CMP/EQ #imm, R0 */
1.1453 + int32_t imm = SIGNEXT8(ir&0xFF);
1.1454 + sh4r.t = ( R0 == imm ? 1 : 0 );
1.1455 + }
1.1456 + break;
1.1457 + case 0x9:
1.1458 + { /* BT disp */
1.1459 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1.1460 + CHECKSLOTILLEGAL();
1.1461 + if( sh4r.t ) {
1.1462 + CHECKDEST( sh4r.pc + disp + 4 )
1.1463 + sh4r.pc += disp + 4;
1.1464 + sh4r.new_pc = sh4r.pc + 2;
1.1465 return TRUE;
1.1466 - case 2: /* BRAF Rn */
1.1467 - CHECKSLOTILLEGAL();
1.1468 - CHECKDEST( pc + 4 + RN(ir) );
1.1469 + }
1.1470 + }
1.1471 + break;
1.1472 + case 0xB:
1.1473 + { /* BF disp */
1.1474 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1.1475 + CHECKSLOTILLEGAL();
1.1476 + if( !sh4r.t ) {
1.1477 + CHECKDEST( sh4r.pc + disp + 4 )
1.1478 + sh4r.pc += disp + 4;
1.1479 + sh4r.new_pc = sh4r.pc + 2;
1.1480 + return TRUE;
1.1481 + }
1.1482 + }
1.1483 + break;
1.1484 + case 0xD:
1.1485 + { /* BT/S disp */
1.1486 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1.1487 + CHECKSLOTILLEGAL();
1.1488 + if( sh4r.t ) {
1.1489 + CHECKDEST( sh4r.pc + disp + 4 )
1.1490 sh4r.in_delay_slot = 1;
1.1491 sh4r.pc = sh4r.new_pc;
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.1495 return TRUE;
1.1496 - case 8: /* PREF [Rn] */
1.1497 - tmp = RN(ir);
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.1505 - }
1.1506 - break;
1.1507 - case 9: /* OCBI [Rn] */
1.1508 - case 10:/* OCBP [Rn] */
1.1509 - case 11:/* OCBWB [Rn] */
1.1510 - /* anything? */
1.1511 - break;
1.1512 - case 12:/* MOVCA.L R0, [Rn] */
1.1513 - tmp = RN(ir);
1.1514 - CHECKWALIGN32(tmp);
1.1515 - MEM_WRITE_LONG( tmp, R0 );
1.1516 - break;
1.1517 - default: UNDEF(ir);
1.1518 - }
1.1519 - break;
1.1520 - case 4: /* MOV.B Rm, [R0 + Rn] */
1.1521 - MEM_WRITE_BYTE( R0 + RN(ir), RM(ir) );
1.1522 - break;
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.1526 - break;
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.1530 - break;
1.1531 - case 7: /* MUL.L Rm, Rn */
1.1532 - sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
1.1533 - (RM(ir) * RN(ir));
1.1534 - break;
1.1535 - case 8:
1.1536 - switch( (ir&0x0FF0)>>4 ) {
1.1537 - case 0: /* CLRT */
1.1538 - sh4r.t = 0;
1.1539 - break;
1.1540 - case 1: /* SETT */
1.1541 - sh4r.t = 1;
1.1542 - break;
1.1543 - case 2: /* CLRMAC */
1.1544 - sh4r.mac = 0;
1.1545 - break;
1.1546 - case 3: /* LDTLB */
1.1547 - break;
1.1548 - case 4: /* CLRS */
1.1549 - sh4r.s = 0;
1.1550 - break;
1.1551 - case 5: /* SETS */
1.1552 - sh4r.s = 1;
1.1553 - break;
1.1554 - default: UNDEF(ir);
1.1555 - }
1.1556 - break;
1.1557 - case 9:
1.1558 - if( (ir&0x00F0) == 0x20 ) /* MOVT Rn */
1.1559 - RN(ir) = sh4r.t;
1.1560 - else if( ir == 0x0019 ) /* DIV0U */
1.1561 - sh4r.m = sh4r.q = sh4r.t = 0;
1.1562 - else if( ir == 0x0009 )
1.1563 - /* NOP */;
1.1564 - else UNDEF(ir);
1.1565 - break;
1.1566 - case 10:
1.1567 - switch( (ir&0x00F0) >> 4 ) {
1.1568 - case 0: /* STS MACH, Rn */
1.1569 - RN(ir) = sh4r.mac >> 32;
1.1570 - break;
1.1571 - case 1: /* STS MACL, Rn */
1.1572 - RN(ir) = (uint32_t)sh4r.mac;
1.1573 - break;
1.1574 - case 2: /* STS PR, Rn */
1.1575 - RN(ir) = sh4r.pr;
1.1576 - break;
1.1577 - case 3: /* STC SGR, Rn */
1.1578 - CHECKPRIV();
1.1579 - RN(ir) = sh4r.sgr;
1.1580 - break;
1.1581 - case 5:/* STS FPUL, Rn */
1.1582 - RN(ir) = sh4r.fpul;
1.1583 - break;
1.1584 - case 6: /* STS FPSCR, Rn */
1.1585 - RN(ir) = sh4r.fpscr;
1.1586 - break;
1.1587 - case 15:/* STC DBR, Rn */
1.1588 - CHECKPRIV();
1.1589 - RN(ir) = sh4r.dbr;
1.1590 - break;
1.1591 - default: UNDEF(ir);
1.1592 - }
1.1593 - break;
1.1594 - case 11:
1.1595 - switch( (ir&0x0FF0)>>4 ) {
1.1596 - case 0: /* RTS */
1.1597 - CHECKSLOTILLEGAL();
1.1598 - CHECKDEST( sh4r.pr );
1.1599 + }
1.1600 + }
1.1601 + break;
1.1602 + case 0xF:
1.1603 + { /* BF/S disp */
1.1604 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1.1605 + CHECKSLOTILLEGAL();
1.1606 + if( !sh4r.t ) {
1.1607 + CHECKDEST( sh4r.pc + disp + 4 )
1.1608 sh4r.in_delay_slot = 1;
1.1609 sh4r.pc = sh4r.new_pc;
1.1610 - sh4r.new_pc = sh4r.pr;
1.1611 - TRACE_RETURN( pc, sh4r.new_pc );
1.1612 + sh4r.new_pc = pc + disp + 4;
1.1613 return TRUE;
1.1614 - case 1: /* SLEEP */
1.1615 - if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
1.1616 - sh4r.sh4_state = SH4_STATE_STANDBY;
1.1617 - } else {
1.1618 - sh4r.sh4_state = SH4_STATE_SLEEP;
1.1619 - }
1.1620 - return FALSE; /* Halt CPU */
1.1621 - case 2: /* RTE */
1.1622 - CHECKPRIV();
1.1623 - CHECKDEST( sh4r.spc );
1.1624 - CHECKSLOTILLEGAL();
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.1629 - return TRUE;
1.1630 - default:UNDEF(ir);
1.1631 - }
1.1632 - break;
1.1633 - case 12:/* MOV.B [R0+R%d], R%d */
1.1634 - RN(ir) = MEM_READ_BYTE( R0 + RM(ir) );
1.1635 - break;
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.1639 - break;
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.1643 - break;
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.1649 - if( sh4r.s ) {
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.1659 -
1.1660 - RM(ir) += 4;
1.1661 - RN(ir) += 4;
1.1662 -
1.1663 - break;
1.1664 - default: UNDEF(ir);
1.1665 - }
1.1666 - break;
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.1672 - break;
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.1677 - break;
1.1678 - case 1: /* MOV.W Rm, [Rn] */
1.1679 - CHECKWALIGN16( RN(ir) );
1.1680 - MEM_WRITE_WORD( RN(ir), RM(ir) );
1.1681 - break;
1.1682 - case 2: /* MOV.L Rm, [Rn] */
1.1683 - CHECKWALIGN32( RN(ir) );
1.1684 - MEM_WRITE_LONG( RN(ir), RM(ir) );
1.1685 - break;
1.1686 - case 3: UNDEF(ir);
1.1687 - break;
1.1688 - case 4: /* MOV.B Rm, [--Rn] */
1.1689 - RN(ir) --;
1.1690 - MEM_WRITE_BYTE( RN(ir), RM(ir) );
1.1691 - break;
1.1692 - case 5: /* MOV.W Rm, [--Rn] */
1.1693 - RN(ir) -= 2;
1.1694 - CHECKWALIGN16( RN(ir) );
1.1695 - MEM_WRITE_WORD( RN(ir), RM(ir) );
1.1696 - break;
1.1697 - case 6: /* MOV.L Rm, [--Rn] */
1.1698 - RN(ir) -= 4;
1.1699 - CHECKWALIGN32( RN(ir) );
1.1700 - MEM_WRITE_LONG( RN(ir), RM(ir) );
1.1701 - break;
1.1702 - case 7: /* DIV0S Rm, Rn */
1.1703 - sh4r.q = RN(ir)>>31;
1.1704 - sh4r.m = RM(ir)>>31;
1.1705 - sh4r.t = sh4r.q ^ sh4r.m;
1.1706 - break;
1.1707 - case 8: /* TST Rm, Rn */
1.1708 - sh4r.t = (RN(ir)&RM(ir) ? 0 : 1);
1.1709 - break;
1.1710 - case 9: /* AND Rm, Rn */
1.1711 - RN(ir) &= RM(ir);
1.1712 - break;
1.1713 - case 10:/* XOR Rm, Rn */
1.1714 - RN(ir) ^= RM(ir);
1.1715 - break;
1.1716 - case 11:/* OR Rm, Rn */
1.1717 - RN(ir) |= RM(ir);
1.1718 - break;
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.1724 - break;
1.1725 - case 13:/* XTRCT Rm, Rn */
1.1726 - RN(ir) = (RN(ir)>>16) | (RM(ir)<<16);
1.1727 - break;
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.1731 - break;
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.1735 - break;
1.1736 - }
1.1737 - break;
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.1742 - break;
1.1743 - case 2: /* CMP/HS Rm, Rn */
1.1744 - sh4r.t = ( RN(ir) >= RM(ir) ? 1 : 0 );
1.1745 - break;
1.1746 - case 3: /* CMP/GE Rm, Rn */
1.1747 - sh4r.t = ( ((int32_t)RN(ir)) >= ((int32_t)RM(ir)) ? 1 : 0 );
1.1748 - break;
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.1756 + }
1.1757 + }
1.1758 + break;
1.1759 + default:
1.1760 + UNDEF();
1.1761 + break;
1.1762 + }
1.1763 + break;
1.1764 + case 0x9:
1.1765 + { /* MOV.W @(disp, PC), Rn */
1.1766 + uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
1.1767 + CHECKSLOTILLEGAL();
1.1768 + tmp = pc + 4 + disp;
1.1769 + sh4r.r[Rn] = MEM_READ_WORD( tmp );
1.1770 + }
1.1771 + break;
1.1772 + case 0xA:
1.1773 + { /* BRA disp */
1.1774 + int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1.1775 + CHECKSLOTILLEGAL();
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.1780 + return TRUE;
1.1781 + }
1.1782 + break;
1.1783 + case 0xB:
1.1784 + { /* BSR disp */
1.1785 + int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1.1786 + CHECKDEST( sh4r.pc + disp + 4 );
1.1787 + CHECKSLOTILLEGAL();
1.1788 + sh4r.in_delay_slot = 1;
1.1789 + sh4r.pr = pc + 4;
1.1790 + sh4r.pc = sh4r.new_pc;
1.1791 + sh4r.new_pc = pc + 4 + disp;
1.1792 + TRACE_CALL( pc, sh4r.new_pc );
1.1793 + return TRUE;
1.1794 + }
1.1795 + break;
1.1796 + case 0xC:
1.1797 + switch( (ir&0xF00) >> 8 ) {
1.1798 + case 0x0:
1.1799 + { /* MOV.B R0, @(disp, GBR) */
1.1800 + uint32_t disp = (ir&0xFF);
1.1801 + MEM_WRITE_BYTE( sh4r.gbr + disp, R0 );
1.1802 + }
1.1803 + break;
1.1804 + case 0x1:
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.1810 + }
1.1811 + break;
1.1812 + case 0x2:
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.1818 + }
1.1819 + break;
1.1820 + case 0x3:
1.1821 + { /* TRAPA #imm */
1.1822 + uint32_t imm = (ir&0xFF);
1.1823 + CHECKSLOTILLEGAL();
1.1824 + MMIO_WRITE( MMU, TRA, imm<<2 );
1.1825 + sh4r.pc += 2;
1.1826 + sh4_raise_exception( EXC_TRAP );
1.1827 + }
1.1828 + break;
1.1829 + case 0x4:
1.1830 + { /* MOV.B @(disp, GBR), R0 */
1.1831 + uint32_t disp = (ir&0xFF);
1.1832 + R0 = MEM_READ_BYTE( sh4r.gbr + disp );
1.1833 + }
1.1834 + break;
1.1835 + case 0x5:
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.1841 + }
1.1842 + break;
1.1843 + case 0x6:
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.1849 + }
1.1850 + break;
1.1851 + case 0x7:
1.1852 + { /* MOVA @(disp, PC), R0 */
1.1853 + uint32_t disp = (ir&0xFF)<<2;
1.1854 + CHECKSLOTILLEGAL();
1.1855 + R0 = (pc&0xFFFFFFFC) + disp + 4;
1.1856 + }
1.1857 + break;
1.1858 + case 0x8:
1.1859 + { /* TST #imm, R0 */
1.1860 + uint32_t imm = (ir&0xFF);
1.1861 + sh4r.t = (R0 & imm ? 0 : 1);
1.1862 + }
1.1863 + break;
1.1864 + case 0x9:
1.1865 + { /* AND #imm, R0 */
1.1866 + uint32_t imm = (ir&0xFF);
1.1867 + R0 &= imm;
1.1868 + }
1.1869 + break;
1.1870 + case 0xA:
1.1871 + { /* XOR #imm, R0 */
1.1872 + uint32_t imm = (ir&0xFF);
1.1873 + R0 ^= imm;
1.1874 + }
1.1875 + break;
1.1876 + case 0xB:
1.1877 + { /* OR #imm, R0 */
1.1878 + uint32_t imm = (ir&0xFF);
1.1879 + R0 |= imm;
1.1880 + }
1.1881 + break;
1.1882 + case 0xC:
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.1886 + }
1.1887 + break;
1.1888 + case 0xD:
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.1892 + }
1.1893 + break;
1.1894 + case 0xE:
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.1898 + }
1.1899 + break;
1.1900 + case 0xF:
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.1904 + }
1.1905 + break;
1.1906 + }
1.1907 + break;
1.1908 + case 0xD:
1.1909 + { /* MOV.L @(disp, PC), Rn */
1.1910 + uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
1.1911 + CHECKSLOTILLEGAL();
1.1912 + tmp = (pc&0xFFFFFFFC) + disp + 4;
1.1913 + sh4r.r[Rn] = MEM_READ_LONG( tmp );
1.1914 + }
1.1915 + break;
1.1916 + case 0xE:
1.1917 + { /* MOV #imm, Rn */
1.1918 + uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1.1919 + sh4r.r[Rn] = imm;
1.1920 + }
1.1921 + break;
1.1922 + case 0xF:
1.1923 + switch( ir&0xF ) {
1.1924 + case 0x0:
1.1925 + { /* FADD FRm, FRn */
1.1926 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1927 + CHECKFPUEN();
1.1928 + if( IS_FPU_DOUBLEPREC() ) {
1.1929 + DR(FRn) += DR(FRm);
1.1930 + } else {
1.1931 + FR(FRn) += FR(FRm);
1.1932 + }
1.1933 + }
1.1934 + break;
1.1935 + case 0x1:
1.1936 + { /* FSUB FRm, FRn */
1.1937 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1938 + CHECKFPUEN();
1.1939 + if( IS_FPU_DOUBLEPREC() ) {
1.1940 + DR(FRn) -= DR(FRm);
1.1941 + } else {
1.1942 + FR(FRn) -= FR(FRm);
1.1943 + }
1.1944 + }
1.1945 + break;
1.1946 + case 0x2:
1.1947 + { /* FMUL FRm, FRn */
1.1948 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1949 + CHECKFPUEN();
1.1950 + if( IS_FPU_DOUBLEPREC() ) {
1.1951 + DR(FRn) *= DR(FRm);
1.1952 + } else {
1.1953 + FR(FRn) *= FR(FRm);
1.1954 + }
1.1955 + }
1.1956 + break;
1.1957 + case 0x3:
1.1958 + { /* FDIV FRm, FRn */
1.1959 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1960 + CHECKFPUEN();
1.1961 + if( IS_FPU_DOUBLEPREC() ) {
1.1962 + DR(FRn) /= DR(FRm);
1.1963 + } else {
1.1964 + FR(FRn) /= FR(FRm);
1.1965 + }
1.1966 + }
1.1967 + break;
1.1968 + case 0x4:
1.1969 + { /* FCMP/EQ FRm, FRn */
1.1970 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1971 + CHECKFPUEN();
1.1972 + if( IS_FPU_DOUBLEPREC() ) {
1.1973 + sh4r.t = ( DR(FRn) == DR(FRm) ? 1 : 0 );
1.1974 + } else {
1.1975 + sh4r.t = ( FR(FRn) == FR(FRm) ? 1 : 0 );
1.1976 + }
1.1977 + }
1.1978 + break;
1.1979 + case 0x5:
1.1980 + { /* FCMP/GT FRm, FRn */
1.1981 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1982 + CHECKFPUEN();
1.1983 + if( IS_FPU_DOUBLEPREC() ) {
1.1984 + sh4r.t = ( DR(FRn) > DR(FRm) ? 1 : 0 );
1.1985 + } else {
1.1986 + sh4r.t = ( FR(FRn) > FR(FRm) ? 1 : 0 );
1.1987 + }
1.1988 + }
1.1989 + break;
1.1990 + case 0x6:
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.1994 + }
1.1995 + break;
1.1996 + case 0x7:
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.2000 + }
1.2001 + break;
1.2002 + case 0x8:
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.2006 + }
1.2007 + break;
1.2008 + case 0x9:
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.2012 + }
1.2013 + break;
1.2014 + case 0xA:
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.2018 + }
1.2019 + break;
1.2020 + case 0xB:
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.2024 + }
1.2025 + break;
1.2026 + case 0xC:
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.2030 + DR(FRn) = DR(FRm);
1.2031 + else
1.2032 + FR(FRn) = FR(FRm);
1.2033 + }
1.2034 + break;
1.2035 + case 0xD:
1.2036 + switch( (ir&0xF0) >> 4 ) {
1.2037 + case 0x0:
1.2038 + { /* FSTS FPUL, FRn */
1.2039 + uint32_t FRn = ((ir>>8)&0xF);
1.2040 + CHECKFPUEN(); FR(FRn) = FPULf;
1.2041 + }
1.2042 + break;
1.2043 + case 0x1:
1.2044 + { /* FLDS FRm, FPUL */
1.2045 + uint32_t FRm = ((ir>>8)&0xF);
1.2046 + CHECKFPUEN(); FPULf = FR(FRm);
1.2047 + }
1.2048 + break;
1.2049 + case 0x2:
1.2050 + { /* FLOAT FPUL, FRn */
1.2051 + uint32_t FRn = ((ir>>8)&0xF);
1.2052 + CHECKFPUEN();
1.2053 + if( IS_FPU_DOUBLEPREC() )
1.2054 + DR(FRn) = (float)FPULi;
1.2055 + else
1.2056 + FR(FRn) = (float)FPULi;
1.2057 + }
1.2058 + break;
1.2059 + case 0x3:
1.2060 + { /* FTRC FRm, FPUL */
1.2061 + uint32_t FRm = ((ir>>8)&0xF);
1.2062 + CHECKFPUEN();
1.2063 + if( IS_FPU_DOUBLEPREC() ) {
1.2064 + dtmp = DR(FRm);
1.2065 + if( dtmp >= MAX_INTF )
1.2066 + FPULi = MAX_INT;
1.2067 + else if( dtmp <= MIN_INTF )
1.2068 + FPULi = MIN_INT;
1.2069 + else
1.2070 + FPULi = (int32_t)dtmp;
1.2071 + } else {
1.2072 + ftmp = FR(FRm);
1.2073 + if( ftmp >= MAX_INTF )
1.2074 + FPULi = MAX_INT;
1.2075 + else if( ftmp <= MIN_INTF )
1.2076 + FPULi = MIN_INT;
1.2077 + else
1.2078 + FPULi = (int32_t)ftmp;
1.2079 + }
1.2080 + }
1.2081 + break;
1.2082 + case 0x4:
1.2083 + { /* FNEG FRn */
1.2084 + uint32_t FRn = ((ir>>8)&0xF);
1.2085 + CHECKFPUEN();
1.2086 + if( IS_FPU_DOUBLEPREC() ) {
1.2087 + DR(FRn) = -DR(FRn);
1.2088 + } else {
1.2089 + FR(FRn) = -FR(FRn);
1.2090 + }
1.2091 + }
1.2092 + break;
1.2093 + case 0x5:
1.2094 + { /* FABS FRn */
1.2095 + uint32_t FRn = ((ir>>8)&0xF);
1.2096 + CHECKFPUEN();
1.2097 + if( IS_FPU_DOUBLEPREC() ) {
1.2098 + DR(FRn) = fabs(DR(FRn));
1.2099 + } else {
1.2100 + FR(FRn) = fabsf(FR(FRn));
1.2101 + }
1.2102 + }
1.2103 + break;
1.2104 + case 0x6:
1.2105 + { /* FSQRT FRn */
1.2106 + uint32_t FRn = ((ir>>8)&0xF);
1.2107 + CHECKFPUEN();
1.2108 + if( IS_FPU_DOUBLEPREC() ) {
1.2109 + DR(FRn) = sqrt(DR(FRn));
1.2110 + } else {
1.2111 + FR(FRn) = sqrtf(FR(FRn));
1.2112 + }
1.2113 + }
1.2114 + break;
1.2115 + case 0x7:
1.2116 + { /* FSRRA FRn */
1.2117 + uint32_t FRn = ((ir>>8)&0xF);
1.2118 + CHECKFPUEN();
1.2119 + if( !IS_FPU_DOUBLEPREC() ) {
1.2120 + FR(FRn) = 1.0/sqrtf(FR(FRn));
1.2121 + }
1.2122 + }
1.2123 + break;
1.2124 + case 0x8:
1.2125 + { /* FLDI0 FRn */
1.2126 + uint32_t FRn = ((ir>>8)&0xF);
1.2127 + CHECKFPUEN();
1.2128 + if( IS_FPU_DOUBLEPREC() ) {
1.2129 + DR(FRn) = 0.0;
1.2130 + } else {
1.2131 + FR(FRn) = 0.0;
1.2132 + }
1.2133 + }
1.2134 + break;
1.2135 + case 0x9:
1.2136 + { /* FLDI1 FRn */
1.2137 + uint32_t FRn = ((ir>>8)&0xF);
1.2138 + CHECKFPUEN();
1.2139 + if( IS_FPU_DOUBLEPREC() ) {
1.2140 + DR(FRn) = 1.0;
1.2141 + } else {
1.2142 + FR(FRn) = 1.0;
1.2143 + }
1.2144 + }
1.2145 + break;
1.2146 + case 0xA:
1.2147 + { /* FCNVSD FPUL, FRn */
1.2148 + uint32_t FRn = ((ir>>8)&0xF);
1.2149 + CHECKFPUEN();
1.2150 + if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
1.2151 + DR(FRn) = (double)FPULf;
1.2152 + }
1.2153 + }
1.2154 + break;
1.2155 + case 0xB:
1.2156 + { /* FCNVDS FRm, FPUL */
1.2157 + uint32_t FRm = ((ir>>8)&0xF);
1.2158 + CHECKFPUEN();
1.2159 + if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
1.2160 + FPULf = (float)DR(FRm);
1.2161 + }
1.2162 + }
1.2163 + break;
1.2164 + case 0xE:
1.2165 + { /* FIPR FVm, FVn */
1.2166 + uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
1.2167 + CHECKFPUEN();
1.2168 + if( !IS_FPU_DOUBLEPREC() ) {
1.2169 + int tmp2 = FVn<<2;
1.2170 + tmp = FVm<<2;
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.2175 + }
1.2176 + }
1.2177 + break;
1.2178 + case 0xF:
1.2179 + switch( (ir&0x100) >> 8 ) {
1.2180 + case 0x0:
1.2181 + { /* FSCA FPUL, FRn */
1.2182 + uint32_t FRn = ((ir>>9)&0x7)<<1;
1.2183 + CHECKFPUEN();
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.2188 + }
1.2189 + }
1.2190 + break;
1.2191 + case 0x1:
1.2192 + switch( (ir&0x200) >> 9 ) {
1.2193 + case 0x0:
1.2194 + { /* FTRV XMTRX, FVn */
1.2195 + uint32_t FVn = ((ir>>10)&0x3);
1.2196 + CHECKFPUEN();
1.2197 + if( !IS_FPU_DOUBLEPREC() ) {
1.2198 + tmp = FVn<<2;
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.2208 + }
1.2209 + }
1.2210 + break;
1.2211 + case 0x1:
1.2212 + switch( (ir&0xC00) >> 10 ) {
1.2213 + case 0x0:
1.2214 + { /* FSCHG */
1.2215 + CHECKFPUEN(); sh4r.fpscr ^= FPSCR_SZ;
1.2216 + }
1.2217 + break;
1.2218 + case 0x2:
1.2219 + { /* FRCHG */
1.2220 + CHECKFPUEN(); sh4r.fpscr ^= FPSCR_FR;
1.2221 + }
1.2222 + break;
1.2223 + case 0x3:
1.2224 + { /* UNDEF */
1.2225 + UNDEF(ir);
1.2226 + }
1.2227 + break;
1.2228 + default:
1.2229 + UNDEF();
1.2230 + break;
1.2231 + }
1.2232 + break;
1.2233 + }
1.2234 + break;
1.2235 + }
1.2236 + break;
1.2237 + default:
1.2238 + UNDEF();
1.2239 + break;
1.2240 + }
1.2241 + break;
1.2242 + case 0xE:
1.2243 + { /* FMAC FR0, FRm, FRn */
1.2244 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.2245 + CHECKFPUEN();
1.2246 + if( IS_FPU_DOUBLEPREC() ) {
1.2247 + DR(FRn) += DR(FRm)*DR(0);
1.2248 + } else {
1.2249 + FR(FRn) += FR(FRm)*FR(0);
1.2250 + }
1.2251 + }
1.2252 + break;
1.2253 + default:
1.2254 + UNDEF();
1.2255 + break;
1.2256 + }
1.2257 + break;
1.2258 + }
1.2259
1.2260 - dir = sh4r.q ^ sh4r.m;
1.2261 - sh4r.q = (RN(ir) >> 31);
1.2262 - tmp2 = RM(ir);
1.2263 - RN(ir) = (RN(ir) << 1) | sh4r.t;
1.2264 - tmp0 = RN(ir);
1.2265 - if( dir ) {
1.2266 - RN(ir) += tmp2;
1.2267 - tmp1 = (RN(ir)<tmp0 ? 1 : 0 );
1.2268 - } else {
1.2269 - RN(ir) -= tmp2;
1.2270 - tmp1 = (RN(ir)>tmp0 ? 1 : 0 );
1.2271 - }
1.2272 - sh4r.q ^= sh4r.m ^ tmp1;
1.2273 - sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );
1.2274 - break; }
1.2275 - case 5: /* DMULU.L Rm, Rn */
1.2276 - sh4r.mac = ((uint64_t)RM(ir)) * ((uint64_t)RN(ir));
1.2277 - break;
1.2278 - case 6: /* CMP/HI Rm, Rn */
1.2279 - sh4r.t = ( RN(ir) > RM(ir) ? 1 : 0 );
1.2280 - break;
1.2281 - case 7: /* CMP/GT Rm, Rn */
1.2282 - sh4r.t = ( ((int32_t)RN(ir)) > ((int32_t)RM(ir)) ? 1 : 0 );
1.2283 - break;
1.2284 - case 8: /* SUB Rm, Rn */
1.2285 - RN(ir) -= RM(ir);
1.2286 - break;
1.2287 - case 10:/* SUBC Rm, Rn */
1.2288 - tmp = RN(ir);
1.2289 - RN(ir) = RN(ir) - RM(ir) - sh4r.t;
1.2290 - sh4r.t = (RN(ir) > tmp || (RN(ir) == tmp && sh4r.t == 1));
1.2291 - break;
1.2292 - case 11:/* SUBV Rm, Rn */
1.2293 - UNIMP(ir);
1.2294 - break;
1.2295 - case 12:/* ADD Rm, Rn */
1.2296 - RN(ir) += RM(ir);
1.2297 - break;
1.2298 - case 13:/* DMULS.L Rm, Rn */
1.2299 - sh4r.mac = SIGNEXT32(RM(ir)) * SIGNEXT32(RN(ir));
1.2300 - break;
1.2301 - case 14:/* ADDC Rm, Rn */
1.2302 - tmp = RN(ir);
1.2303 - RN(ir) += RM(ir) + sh4r.t;
1.2304 - sh4r.t = ( RN(ir) < tmp || (RN(ir) == tmp && sh4r.t != 0) ? 1 : 0 );
1.2305 - break;
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.2309 - RN(ir) = tmp;
1.2310 - break;
1.2311 - default: UNDEF(ir);
1.2312 - }
1.2313 - break;
1.2314 - case 4: /* 0100nnnnxxxxxxxx */
1.2315 - switch( ir&0x00FF ) {
1.2316 - case 0x00: /* SHLL Rn */
1.2317 - sh4r.t = RN(ir) >> 31;
1.2318 - RN(ir) <<= 1;
1.2319 - break;
1.2320 - case 0x01: /* SHLR Rn */
1.2321 - sh4r.t = RN(ir) & 0x00000001;
1.2322 - RN(ir) >>= 1;
1.2323 - break;
1.2324 - case 0x02: /* STS.L MACH, [--Rn] */
1.2325 - RN(ir) -= 4;
1.2326 - CHECKWALIGN32( RN(ir) );
1.2327 - MEM_WRITE_LONG( RN(ir), (sh4r.mac>>32) );
1.2328 - break;
1.2329 - case 0x03: /* STC.L SR, [--Rn] */
1.2330 - CHECKPRIV();
1.2331 - RN(ir) -= 4;
1.2332 - CHECKWALIGN32( RN(ir) );
1.2333 - MEM_WRITE_LONG( RN(ir), sh4_read_sr() );
1.2334 - break;
1.2335 - case 0x04: /* ROTL Rn */
1.2336 - sh4r.t = RN(ir) >> 31;
1.2337 - RN(ir) <<= 1;
1.2338 - RN(ir) |= sh4r.t;
1.2339 - break;
1.2340 - case 0x05: /* ROTR Rn */
1.2341 - sh4r.t = RN(ir) & 0x00000001;
1.2342 - RN(ir) >>= 1;
1.2343 - RN(ir) |= (sh4r.t << 31);
1.2344 - break;
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.2349 - RN(ir) += 4;
1.2350 - break;
1.2351 - case 0x07: /* LDC.L [Rn++], SR */
1.2352 - CHECKSLOTILLEGAL();
1.2353 - CHECKPRIV();
1.2354 - CHECKWALIGN32( RN(ir) );
1.2355 - sh4_load_sr( MEM_READ_LONG(RN(ir)) );
1.2356 - RN(ir) +=4;
1.2357 - break;
1.2358 - case 0x08: /* SHLL2 Rn */
1.2359 - RN(ir) <<= 2;
1.2360 - break;
1.2361 - case 0x09: /* SHLR2 Rn */
1.2362 - RN(ir) >>= 2;
1.2363 - break;
1.2364 - case 0x0A: /* LDS Rn, MACH */
1.2365 - sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1.2366 - (((uint64_t)RN(ir))<<32);
1.2367 - break;
1.2368 - case 0x0B: /* JSR [Rn] */
1.2369 - CHECKDEST( RN(ir) );
1.2370 - CHECKSLOTILLEGAL();
1.2371 - sh4r.in_delay_slot = 1;
1.2372 - sh4r.pc = sh4r.new_pc;
1.2373 - sh4r.new_pc = RN(ir);
1.2374 - sh4r.pr = pc + 4;
1.2375 - TRACE_CALL( pc, sh4r.new_pc );
1.2376 - return TRUE;
1.2377 - case 0x0E: /* LDC Rn, SR */
1.2378 - CHECKSLOTILLEGAL();
1.2379 - CHECKPRIV();
1.2380 - sh4_load_sr( RN(ir) );
1.2381 - break;
1.2382 - case 0x10: /* DT Rn */
1.2383 - RN(ir) --;
1.2384 - sh4r.t = ( RN(ir) == 0 ? 1 : 0 );
1.2385 - break;
1.2386 - case 0x11: /* CMP/PZ Rn */
1.2387 - sh4r.t = ( ((int32_t)RN(ir)) >= 0 ? 1 : 0 );
1.2388 - break;
1.2389 - case 0x12: /* STS.L MACL, [--Rn] */
1.2390 - RN(ir) -= 4;
1.2391 - CHECKWALIGN32( RN(ir) );
1.2392 - MEM_WRITE_LONG( RN(ir), (uint32_t)sh4r.mac );
1.2393 - break;
1.2394 - case 0x13: /* STC.L GBR, [--Rn] */
1.2395 - RN(ir) -= 4;
1.2396 - CHECKWALIGN32( RN(ir) );
1.2397 - MEM_WRITE_LONG( RN(ir), sh4r.gbr );
1.2398 - break;
1.2399 - case 0x15: /* CMP/PL Rn */
1.2400 - sh4r.t = ( ((int32_t)RN(ir)) > 0 ? 1 : 0 );
1.2401 - break;
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.2406 - RN(ir) += 4;
1.2407 - break;
1.2408 - case 0x17: /* LDC.L [Rn++], GBR */
1.2409 - CHECKRALIGN32( RN(ir) );
1.2410 - sh4r.gbr = MEM_READ_LONG(RN(ir));
1.2411 - RN(ir) +=4;
1.2412 - break;
1.2413 - case 0x18: /* SHLL8 Rn */
1.2414 - RN(ir) <<= 8;
1.2415 - break;
1.2416 - case 0x19: /* SHLR8 Rn */
1.2417 - RN(ir) >>= 8;
1.2418 - break;
1.2419 - case 0x1A: /* LDS Rn, MACL */
1.2420 - sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1.2421 - (uint64_t)((uint32_t)(RN(ir)));
1.2422 - break;
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.2427 - break;
1.2428 - case 0x1E: /* LDC Rn, GBR */
1.2429 - sh4r.gbr = RN(ir);
1.2430 - break;
1.2431 - case 0x20: /* SHAL Rn */
1.2432 - sh4r.t = RN(ir) >> 31;
1.2433 - RN(ir) <<= 1;
1.2434 - break;
1.2435 - case 0x21: /* SHAR Rn */
1.2436 - sh4r.t = RN(ir) & 0x00000001;
1.2437 - RN(ir) = ((int32_t)RN(ir)) >> 1;
1.2438 - break;
1.2439 - case 0x22: /* STS.L PR, [--Rn] */
1.2440 - RN(ir) -= 4;
1.2441 - CHECKWALIGN32( RN(ir) );
1.2442 - MEM_WRITE_LONG( RN(ir), sh4r.pr );
1.2443 - break;
1.2444 - case 0x23: /* STC.L VBR, [--Rn] */
1.2445 - CHECKPRIV();
1.2446 - RN(ir) -= 4;
1.2447 - CHECKWALIGN32( RN(ir) );
1.2448 - MEM_WRITE_LONG( RN(ir), sh4r.vbr );
1.2449 - break;
1.2450 - case 0x24: /* ROTCL Rn */
1.2451 - tmp = RN(ir) >> 31;
1.2452 - RN(ir) <<= 1;
1.2453 - RN(ir) |= sh4r.t;
1.2454 - sh4r.t = tmp;
1.2455 - break;
1.2456 - case 0x25: /* ROTCR Rn */
1.2457 - tmp = RN(ir) & 0x00000001;
1.2458 - RN(ir) >>= 1;
1.2459 - RN(ir) |= (sh4r.t << 31 );
1.2460 - sh4r.t = tmp;
1.2461 - break;
1.2462 - case 0x26: /* LDS.L [Rn++], PR */
1.2463 - CHECKRALIGN32( RN(ir) );
1.2464 - sh4r.pr = MEM_READ_LONG( RN(ir) );
1.2465 - RN(ir) += 4;
1.2466 - break;
1.2467 - case 0x27: /* LDC.L [Rn++], VBR */
1.2468 - CHECKPRIV();
1.2469 - CHECKRALIGN32( RN(ir) );
1.2470 - sh4r.vbr = MEM_READ_LONG(RN(ir));
1.2471 - RN(ir) +=4;
1.2472 - break;
1.2473 - case 0x28: /* SHLL16 Rn */
1.2474 - RN(ir) <<= 16;
1.2475 - break;
1.2476 - case 0x29: /* SHLR16 Rn */
1.2477 - RN(ir) >>= 16;
1.2478 - break;
1.2479 - case 0x2A: /* LDS Rn, PR */
1.2480 - sh4r.pr = RN(ir);
1.2481 - break;
1.2482 - case 0x2B: /* JMP [Rn] */
1.2483 - CHECKDEST( RN(ir) );
1.2484 - CHECKSLOTILLEGAL();
1.2485 - sh4r.in_delay_slot = 1;
1.2486 - sh4r.pc = sh4r.new_pc;
1.2487 - sh4r.new_pc = RN(ir);
1.2488 - return TRUE;
1.2489 - case 0x2E: /* LDC Rn, VBR */
1.2490 - CHECKPRIV();
1.2491 - sh4r.vbr = RN(ir);
1.2492 - break;
1.2493 - case 0x32: /* STC.L SGR, [--Rn] */
1.2494 - CHECKPRIV();
1.2495 - RN(ir) -= 4;
1.2496 - CHECKWALIGN32( RN(ir) );
1.2497 - MEM_WRITE_LONG( RN(ir), sh4r.sgr );
1.2498 - break;
1.2499 - case 0x33: /* STC.L SSR, [--Rn] */
1.2500 - CHECKPRIV();
1.2501 - RN(ir) -= 4;
1.2502 - CHECKWALIGN32( RN(ir) );
1.2503 - MEM_WRITE_LONG( RN(ir), sh4r.ssr );
1.2504 - break;
1.2505 - case 0x37: /* LDC.L [Rn++], SSR */
1.2506 - CHECKPRIV();
1.2507 - CHECKRALIGN32( RN(ir) );
1.2508 - sh4r.ssr = MEM_READ_LONG(RN(ir));
1.2509 - RN(ir) +=4;
1.2510 - break;
1.2511 - case 0x3E: /* LDC Rn, SSR */
1.2512 - CHECKPRIV();
1.2513 - sh4r.ssr = RN(ir);
1.2514 - break;
1.2515 - case 0x43: /* STC.L SPC, [--Rn] */
1.2516 - CHECKPRIV();
1.2517 - RN(ir) -= 4;
1.2518 - CHECKWALIGN32( RN(ir) );
1.2519 - MEM_WRITE_LONG( RN(ir), sh4r.spc );
1.2520 - break;
1.2521 - case 0x47: /* LDC.L [Rn++], SPC */
1.2522 - CHECKPRIV();
1.2523 - CHECKRALIGN32( RN(ir) );
1.2524 - sh4r.spc = MEM_READ_LONG(RN(ir));
1.2525 - RN(ir) +=4;
1.2526 - break;
1.2527 - case 0x4E: /* LDC Rn, SPC */
1.2528 - CHECKPRIV();
1.2529 - sh4r.spc = RN(ir);
1.2530 - break;
1.2531 - case 0x52: /* STS.L FPUL, [--Rn] */
1.2532 - RN(ir) -= 4;
1.2533 - CHECKWALIGN32( RN(ir) );
1.2534 - MEM_WRITE_LONG( RN(ir), sh4r.fpul );
1.2535 - break;
1.2536 - case 0x56: /* LDS.L [Rn++], FPUL */
1.2537 - CHECKRALIGN32( RN(ir) );
1.2538 - sh4r.fpul = MEM_READ_LONG(RN(ir));
1.2539 - RN(ir) +=4;
1.2540 - break;
1.2541 - case 0x5A: /* LDS Rn, FPUL */
1.2542 - sh4r.fpul = RN(ir);
1.2543 - break;
1.2544 - case 0x62: /* STS.L FPSCR, [--Rn] */
1.2545 - RN(ir) -= 4;
1.2546 - CHECKWALIGN32( RN(ir) );
1.2547 - MEM_WRITE_LONG( RN(ir), sh4r.fpscr );
1.2548 - break;
1.2549 - case 0x66: /* LDS.L [Rn++], FPSCR */
1.2550 - CHECKRALIGN32( RN(ir) );
1.2551 - sh4r.fpscr = MEM_READ_LONG(RN(ir));
1.2552 - RN(ir) +=4;
1.2553 - break;
1.2554 - case 0x6A: /* LDS Rn, FPSCR */
1.2555 - sh4r.fpscr = RN(ir);
1.2556 - break;
1.2557 - case 0xF2: /* STC.L DBR, [--Rn] */
1.2558 - CHECKPRIV();
1.2559 - RN(ir) -= 4;
1.2560 - CHECKWALIGN32( RN(ir) );
1.2561 - MEM_WRITE_LONG( RN(ir), sh4r.dbr );
1.2562 - break;
1.2563 - case 0xF6: /* LDC.L [Rn++], DBR */
1.2564 - CHECKPRIV();
1.2565 - CHECKRALIGN32( RN(ir) );
1.2566 - sh4r.dbr = MEM_READ_LONG(RN(ir));
1.2567 - RN(ir) +=4;
1.2568 - break;
1.2569 - case 0xFA: /* LDC Rn, DBR */
1.2570 - CHECKPRIV();
1.2571 - sh4r.dbr = RN(ir);
1.2572 - break;
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.2575 - CHECKPRIV();
1.2576 - RN(ir) -= 4;
1.2577 - CHECKWALIGN32( RN(ir) );
1.2578 - MEM_WRITE_LONG( RN(ir), RN_BANK(ir) );
1.2579 - break;
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.2582 - CHECKPRIV();
1.2583 - CHECKRALIGN32( RN(ir) );
1.2584 - RN_BANK(ir) = MEM_READ_LONG( RN(ir) );
1.2585 - RN(ir) += 4;
1.2586 - break;
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.2589 - CHECKPRIV();
1.2590 - RN_BANK(ir) = RM(ir);
1.2591 - break;
1.2592 - default:
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.2599 - if( sh4r.s ) {
1.2600 - /* FIXME */
1.2601 - UNIMP(ir);
1.2602 - } else sh4r.mac += SIGNEXT32(tmp);
1.2603 - RM(ir) += 2;
1.2604 - RN(ir) += 2;
1.2605 - } else if( (ir&0x000F) == 0x0C ) {
1.2606 - /* SHAD Rm, Rn */
1.2607 - tmp = RM(ir);
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.2611 - else
1.2612 - RN(ir) = ((int32_t)RN(ir)) >> (((~RM(ir)) & 0x1F)+1);
1.2613 - } else if( (ir&0x000F) == 0x0D ) {
1.2614 - /* SHLD Rm, Rn */
1.2615 - tmp = RM(ir);
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.2619 - } else UNDEF(ir);
1.2620 - }
1.2621 - break;
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.2627 - break;
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.2632 - break;
1.2633 - case 1: /* MOV.W [Rm], Rn */
1.2634 - CHECKRALIGN16( RM(ir) );
1.2635 - RN(ir) = MEM_READ_WORD( RM(ir) );
1.2636 - break;
1.2637 - case 2: /* MOV.L [Rm], Rn */
1.2638 - CHECKRALIGN32( RM(ir) );
1.2639 - RN(ir) = MEM_READ_LONG( RM(ir) );
1.2640 - break;
1.2641 - case 3: /* MOV Rm, Rn */
1.2642 - RN(ir) = RM(ir);
1.2643 - break;
1.2644 - case 4: /* MOV.B [Rm++], Rn */
1.2645 - RN(ir) = MEM_READ_BYTE( RM(ir) );
1.2646 - RM(ir) ++;
1.2647 - break;
1.2648 - case 5: /* MOV.W [Rm++], Rn */
1.2649 - CHECKRALIGN16( RM(ir) );
1.2650 - RN(ir) = MEM_READ_WORD( RM(ir) );
1.2651 - RM(ir) += 2;
1.2652 - break;
1.2653 - case 6: /* MOV.L [Rm++], Rn */
1.2654 - CHECKRALIGN32( RM(ir) );
1.2655 - RN(ir) = MEM_READ_LONG( RM(ir) );
1.2656 - RM(ir) += 4;
1.2657 - break;
1.2658 - case 7: /* NOT Rm, Rn */
1.2659 - RN(ir) = ~RM(ir);
1.2660 - break;
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.2664 - break;
1.2665 - case 9: /* SWAP.W Rm, Rn */
1.2666 - RN(ir) = (RM(ir)>>16) | (RM(ir)<<16);
1.2667 - break;
1.2668 - case 10:/* NEGC Rm, Rn */
1.2669 - tmp = 0 - RM(ir);
1.2670 - RN(ir) = tmp - sh4r.t;
1.2671 - sh4r.t = ( 0<tmp || tmp<RN(ir) ? 1 : 0 );
1.2672 - break;
1.2673 - case 11:/* NEG Rm, Rn */
1.2674 - RN(ir) = 0 - RM(ir);
1.2675 - break;
1.2676 - case 12:/* EXTU.B Rm, Rn */
1.2677 - RN(ir) = RM(ir)&0x000000FF;
1.2678 - break;
1.2679 - case 13:/* EXTU.W Rm, Rn */
1.2680 - RN(ir) = RM(ir)&0x0000FFFF;
1.2681 - break;
1.2682 - case 14:/* EXTS.B Rm, Rn */
1.2683 - RN(ir) = SIGNEXT8( RM(ir)&0x000000FF );
1.2684 - break;
1.2685 - case 15:/* EXTS.W Rm, Rn */
1.2686 - RN(ir) = SIGNEXT16( RM(ir)&0x0000FFFF );
1.2687 - break;
1.2688 - }
1.2689 - break;
1.2690 - case 7: /* 0111nnnniiiiiiii */
1.2691 - /* ADD imm8, Rn */
1.2692 - RN(ir) += IMM8(ir);
1.2693 - break;
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.2698 - break;
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.2703 - break;
1.2704 - case 4: /* MOV.B [Rm + disp4], R0 */
1.2705 - R0 = MEM_READ_BYTE( RM(ir) + DISP4(ir) );
1.2706 - break;
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.2711 - break;
1.2712 - case 8: /* CMP/EQ imm, R0 */
1.2713 - sh4r.t = ( R0 == IMM8(ir) ? 1 : 0 );
1.2714 - break;
1.2715 - case 9: /* BT disp8 */
1.2716 - CHECKSLOTILLEGAL();
1.2717 - if( sh4r.t ) {
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.2721 - return TRUE;
1.2722 - }
1.2723 - break;
1.2724 - case 11:/* BF disp8 */
1.2725 - CHECKSLOTILLEGAL();
1.2726 - if( !sh4r.t ) {
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.2730 - return TRUE;
1.2731 - }
1.2732 - break;
1.2733 - case 13:/* BT/S disp8 */
1.2734 - CHECKSLOTILLEGAL();
1.2735 - if( sh4r.t ) {
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.2741 - return TRUE;
1.2742 - }
1.2743 - break;
1.2744 - case 15:/* BF/S disp8 */
1.2745 - CHECKSLOTILLEGAL();
1.2746 - if( !sh4r.t ) {
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.2751 - return TRUE;
1.2752 - }
1.2753 - break;
1.2754 - default: UNDEF(ir);
1.2755 - }
1.2756 - break;
1.2757 - case 9: /* 1001xxxxxxxxxxxx */
1.2758 - /* MOV.W [disp8*2 + pc + 4], Rn */
1.2759 - CHECKSLOTILLEGAL();
1.2760 - tmp = pc + 4 + (DISP8(ir)<<1);
1.2761 - RN(ir) = MEM_READ_WORD( tmp );
1.2762 - break;
1.2763 - case 10:/* 1010dddddddddddd */
1.2764 - /* BRA disp12 */
1.2765 - CHECKSLOTILLEGAL();
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.2770 - return TRUE;
1.2771 - case 11:/* 1011dddddddddddd */
1.2772 - /* BSR disp12 */
1.2773 - CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 );
1.2774 - CHECKSLOTILLEGAL();
1.2775 - sh4r.in_delay_slot = 1;
1.2776 - sh4r.pr = pc + 4;
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.2780 - return TRUE;
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.2785 - break;
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.2790 - break;
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.2795 - break;
1.2796 - case 3: /* TRAPA imm8 */
1.2797 - CHECKSLOTILLEGAL();
1.2798 - MMIO_WRITE( MMU, TRA, UIMM8(ir)<<2 );
1.2799 - sh4r.pc += 2;
1.2800 - sh4_raise_exception( EXC_TRAP );
1.2801 - break;
1.2802 - case 4: /* MOV.B [GBR + disp8], R0 */
1.2803 - R0 = MEM_READ_BYTE( sh4r.gbr + DISP8(ir) );
1.2804 - break;
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.2809 - break;
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.2814 - break;
1.2815 - case 7: /* MOVA disp8 + pc&~3 + 4, R0 */
1.2816 - CHECKSLOTILLEGAL();
1.2817 - R0 = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;
1.2818 - break;
1.2819 - case 8: /* TST imm8, R0 */
1.2820 - sh4r.t = (R0 & UIMM8(ir) ? 0 : 1);
1.2821 - break;
1.2822 - case 9: /* AND imm8, R0 */
1.2823 - R0 &= UIMM8(ir);
1.2824 - break;
1.2825 - case 10:/* XOR imm8, R0 */
1.2826 - R0 ^= UIMM8(ir);
1.2827 - break;
1.2828 - case 11:/* OR imm8, R0 */
1.2829 - R0 |= UIMM8(ir);
1.2830 - break;
1.2831 - case 12:/* TST.B imm8, [R0+GBR] */
1.2832 - sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & UIMM8(ir) ? 0 : 1 );
1.2833 - break;
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.2837 - break;
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.2841 - break;
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.2845 - break;
1.2846 - }
1.2847 - break;
1.2848 - case 13:/* 1101nnnndddddddd */
1.2849 - /* MOV.L [disp8*4 + pc&~3 + 4], Rn */
1.2850 - CHECKSLOTILLEGAL();
1.2851 - tmp = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;
1.2852 - RN(ir) = MEM_READ_LONG( tmp );
1.2853 - break;
1.2854 - case 14:/* 1110nnnniiiiiiii */
1.2855 - /* MOV imm8, Rn */
1.2856 - RN(ir) = IMM8(ir);
1.2857 - break;
1.2858 - case 15:/* 1111xxxxxxxxxxxx */
1.2859 - CHECKFPUEN();
1.2860 - if( IS_FPU_DOUBLEPREC() ) {
1.2861 - switch( ir&0x000F ) {
1.2862 - case 0: /* FADD FRm, FRn */
1.2863 - DRN(ir) += DRM(ir);
1.2864 - break;
1.2865 - case 1: /* FSUB FRm, FRn */
1.2866 - DRN(ir) -= DRM(ir);
1.2867 - break;
1.2868 - case 2: /* FMUL FRm, FRn */
1.2869 - DRN(ir) = DRN(ir) * DRM(ir);
1.2870 - break;
1.2871 - case 3: /* FDIV FRm, FRn */
1.2872 - DRN(ir) = DRN(ir) / DRM(ir);
1.2873 - break;
1.2874 - case 4: /* FCMP/EQ FRm, FRn */
1.2875 - sh4r.t = ( DRN(ir) == DRM(ir) ? 1 : 0 );
1.2876 - break;
1.2877 - case 5: /* FCMP/GT FRm, FRn */
1.2878 - sh4r.t = ( DRN(ir) > DRM(ir) ? 1 : 0 );
1.2879 - break;
1.2880 - case 6: /* FMOV.S [Rm+R0], FRn */
1.2881 - MEM_FP_READ( RM(ir) + R0, FRNn(ir) );
1.2882 - break;
1.2883 - case 7: /* FMOV.S FRm, [Rn+R0] */
1.2884 - MEM_FP_WRITE( RN(ir) + R0, FRMn(ir) );
1.2885 - break;
1.2886 - case 8: /* FMOV.S [Rm], FRn */
1.2887 - MEM_FP_READ( RM(ir), FRNn(ir) );
1.2888 - break;
1.2889 - case 9: /* FMOV.S [Rm++], FRn */
1.2890 - MEM_FP_READ( RM(ir), FRNn(ir) );
1.2891 - RM(ir) += FP_WIDTH;
1.2892 - break;
1.2893 - case 10:/* FMOV.S FRm, [Rn] */
1.2894 - MEM_FP_WRITE( RN(ir), FRMn(ir) );
1.2895 - break;
1.2896 - case 11:/* FMOV.S FRm, [--Rn] */
1.2897 - RN(ir) -= FP_WIDTH;
1.2898 - MEM_FP_WRITE( RN(ir), FRMn(ir) );
1.2899 - break;
1.2900 - case 12:/* FMOV FRm, FRn */
1.2901 - if( IS_FPU_DOUBLESIZE() )
1.2902 - DRN(ir) = DRM(ir);
1.2903 - else
1.2904 - FRN(ir) = FRM(ir);
1.2905 - break;
1.2906 - case 13:
1.2907 - switch( (ir&0x00F0) >> 4 ) {
1.2908 - case 0: /* FSTS FPUL, FRn */
1.2909 - FRN(ir) = FPULf;
1.2910 - break;
1.2911 - case 1: /* FLDS FRn,FPUL */
1.2912 - FPULf = FRN(ir);
1.2913 - break;
1.2914 - case 2: /* FLOAT FPUL, FRn */
1.2915 - DRN(ir) = (float)FPULi;
1.2916 - break;
1.2917 - case 3: /* FTRC FRn, FPUL */
1.2918 - dtmp = DRN(ir);
1.2919 - if( dtmp >= MAX_INTF )
1.2920 - FPULi = MAX_INT;
1.2921 - else if( dtmp <= MIN_INTF )
1.2922 - FPULi = MIN_INT;
1.2923 - else
1.2924 - FPULi = (int32_t)dtmp;
1.2925 - break;
1.2926 - case 4: /* FNEG FRn */
1.2927 - DRN(ir) = -DRN(ir);
1.2928 - break;
1.2929 - case 5: /* FABS FRn */
1.2930 - DRN(ir) = fabs(DRN(ir));
1.2931 - break;
1.2932 - case 6: /* FSQRT FRn */
1.2933 - DRN(ir) = sqrt(DRN(ir));
1.2934 - break;
1.2935 - case 7: /* FSRRA FRn */
1.2936 - /* NO-OP when PR=1 */
1.2937 - break;
1.2938 - case 8: /* FLDI0 FRn */
1.2939 - DRN(ir) = 0.0;
1.2940 - break;
1.2941 - case 9: /* FLDI1 FRn */
1.2942 - DRN(ir) = 1.0;
1.2943 - break;
1.2944 - case 10: /* FCNVSD FPUL, DRn */
1.2945 - if( ! IS_FPU_DOUBLESIZE() )
1.2946 - DRN(ir) = (double)FPULf;
1.2947 - break;
1.2948 - case 11: /* FCNVDS DRn, FPUL */
1.2949 - if( ! IS_FPU_DOUBLESIZE() )
1.2950 - FPULf = (float)DRN(ir);
1.2951 - break;
1.2952 - case 14:/* FIPR FVm, FVn */
1.2953 - /* NO-OP when PR=1 */
1.2954 - break;
1.2955 - case 15:
1.2956 - if( (ir&0x0300) == 0x0100 ) { /* FTRV XMTRX,FVn */
1.2957 - /* NO-OP when PR=1 */
1.2958 - break;
1.2959 - }
1.2960 - else if( (ir&0x0100) == 0 ) { /* FSCA FPUL, DRn */
1.2961 - /* NO-OP when PR=1 */
1.2962 - break;
1.2963 - }
1.2964 - else if( ir == 0xFBFD ) {
1.2965 - /* FRCHG */
1.2966 - sh4r.fpscr ^= FPSCR_FR;
1.2967 - break;
1.2968 - }
1.2969 - else if( ir == 0xF3FD ) {
1.2970 - /* FSCHG */
1.2971 - sh4r.fpscr ^= FPSCR_SZ;
1.2972 - break;
1.2973 - }
1.2974 - default: UNDEF(ir);
1.2975 - }
1.2976 - break;
1.2977 - case 14:/* FMAC FR0, FRm, FRn */
1.2978 - DRN(ir) += DRM(ir)*DR0;
1.2979 - break;
1.2980 - default: UNDEF(ir);
1.2981 - }
1.2982 - } else { /* Single precision */
1.2983 - switch( ir&0x000F ) {
1.2984 - case 0: /* FADD FRm, FRn */
1.2985 - FRN(ir) += FRM(ir);
1.2986 - break;
1.2987 - case 1: /* FSUB FRm, FRn */
1.2988 - FRN(ir) -= FRM(ir);
1.2989 - break;
1.2990 - case 2: /* FMUL FRm, FRn */
1.2991 - FRN(ir) = FRN(ir) * FRM(ir);
1.2992 - break;
1.2993 - case 3: /* FDIV FRm, FRn */
1.2994 - FRN(ir) = FRN(ir) / FRM(ir);
1.2995 - break;
1.2996 - case 4: /* FCMP/EQ FRm, FRn */
1.2997 - sh4r.t = ( FRN(ir) == FRM(ir) ? 1 : 0 );
1.2998 - break;
1.2999 - case 5: /* FCMP/GT FRm, FRn */
1.3000 - sh4r.t = ( FRN(ir) > FRM(ir) ? 1 : 0 );
1.3001 - break;
1.3002 - case 6: /* FMOV.S [Rm+R0], FRn */
1.3003 - MEM_FP_READ( RM(ir) + R0, FRNn(ir) );
1.3004 - break;
1.3005 - case 7: /* FMOV.S FRm, [Rn+R0] */
1.3006 - MEM_FP_WRITE( RN(ir) + R0, FRMn(ir) );
1.3007 - break;
1.3008 - case 8: /* FMOV.S [Rm], FRn */
1.3009 - MEM_FP_READ( RM(ir), FRNn(ir) );
1.3010 - break;
1.3011 - case 9: /* FMOV.S [Rm++], FRn */
1.3012 - MEM_FP_READ( RM(ir), FRNn(ir) );
1.3013 - RM(ir) += FP_WIDTH;
1.3014 - break;
1.3015 - case 10:/* FMOV.S FRm, [Rn] */
1.3016 - MEM_FP_WRITE( RN(ir), FRMn(ir) );
1.3017 - break;
1.3018 - case 11:/* FMOV.S FRm, [--Rn] */
1.3019 - RN(ir) -= FP_WIDTH;
1.3020 - MEM_FP_WRITE( RN(ir), FRMn(ir) );
1.3021 - break;
1.3022 - case 12:/* FMOV FRm, FRn */
1.3023 - if( IS_FPU_DOUBLESIZE() )
1.3024 - DRN(ir) = DRM(ir);
1.3025 - else
1.3026 - FRN(ir) = FRM(ir);
1.3027 - break;
1.3028 - case 13:
1.3029 - switch( (ir&0x00F0) >> 4 ) {
1.3030 - case 0: /* FSTS FPUL, FRn */
1.3031 - FRN(ir) = FPULf;
1.3032 - break;
1.3033 - case 1: /* FLDS FRn,FPUL */
1.3034 - FPULf = FRN(ir);
1.3035 - break;
1.3036 - case 2: /* FLOAT FPUL, FRn */
1.3037 - FRN(ir) = (float)FPULi;
1.3038 - break;
1.3039 - case 3: /* FTRC FRn, FPUL */
1.3040 - ftmp = FRN(ir);
1.3041 - if( ftmp >= MAX_INTF )
1.3042 - FPULi = MAX_INT;
1.3043 - else if( ftmp <= MIN_INTF )
1.3044 - FPULi = MIN_INT;
1.3045 - else
1.3046 - FPULi = (int32_t)ftmp;
1.3047 - break;
1.3048 - case 4: /* FNEG FRn */
1.3049 - FRN(ir) = -FRN(ir);
1.3050 - break;
1.3051 - case 5: /* FABS FRn */
1.3052 - FRN(ir) = fabsf(FRN(ir));
1.3053 - break;
1.3054 - case 6: /* FSQRT FRn */
1.3055 - FRN(ir) = sqrtf(FRN(ir));
1.3056 - break;
1.3057 - case 7: /* FSRRA FRn */
1.3058 - FRN(ir) = 1.0/sqrtf(FRN(ir));
1.3059 - break;
1.3060 - case 8: /* FLDI0 FRn */
1.3061 - FRN(ir) = 0.0;
1.3062 - break;
1.3063 - case 9: /* FLDI1 FRn */
1.3064 - FRN(ir) = 1.0;
1.3065 - break;
1.3066 - case 10: /* FCNVSD FPUL, DRn */
1.3067 - break;
1.3068 - case 11: /* FCNVDS DRn, FPUL */
1.3069 - break;
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.3074 - */
1.3075 - {
1.3076 - int tmp2 = FVN(ir);
1.3077 - tmp = FVM(ir);
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.3082 - break;
1.3083 - }
1.3084 - case 15:
1.3085 - if( (ir&0x0300) == 0x0100 ) { /* FTRV XMTRX,FVn */
1.3086 - tmp = FVN(ir);
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.3096 - break;
1.3097 - }
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.3101 - 2 * M_PI;
1.3102 - int reg = FRNn(ir);
1.3103 - FR(reg) = sinf(angle);
1.3104 - FR(reg+1) = cosf(angle);
1.3105 - break;
1.3106 - }
1.3107 - else if( ir == 0xFBFD ) {
1.3108 - /* FRCHG */
1.3109 - sh4r.fpscr ^= FPSCR_FR;
1.3110 - break;
1.3111 - }
1.3112 - else if( ir == 0xF3FD ) {
1.3113 - /* FSCHG */
1.3114 - sh4r.fpscr ^= FPSCR_SZ;
1.3115 - break;
1.3116 - }
1.3117 - default: UNDEF(ir);
1.3118 - }
1.3119 - break;
1.3120 - case 14:/* FMAC FR0, FRm, FRn */
1.3121 - FRN(ir) += FRM(ir)*FR0;
1.3122 - break;
1.3123 - default: UNDEF(ir);
1.3124 - }
1.3125 - }
1.3126 - break;
1.3127 - }
1.3128 sh4r.pc = sh4r.new_pc;
1.3129 sh4r.new_pc += 2;
1.3130 sh4r.in_delay_slot = 0;
.