filename | src/sh4/sh4core.c |
changeset | 401:f79327f39818 |
prev | 391:16afb90b5d47 |
next | 430:467519b050f4 |
author | nkeynes |
date | Thu Oct 04 08:47:27 2007 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Suppress redundant T flag loads Tweak run_slice for performance |
view | annotate | diff | log | raw |
1 /**
2 * $Id: sh4core.c,v 1.48 2007-09-20 08:37:19 nkeynes Exp $
3 *
4 * SH4 emulation core, and parent module for all the SH4 peripheral
5 * modules.
6 *
7 * Copyright (c) 2005 Nathan Keynes.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
20 #define MODULE sh4_module
21 #include <math.h>
22 #include "dream.h"
23 #include "sh4/sh4core.h"
24 #include "sh4/sh4mmio.h"
25 #include "sh4/intc.h"
26 #include "mem.h"
27 #include "clock.h"
28 #include "syscall.h"
30 #define SH4_CALLTRACE 1
32 #define MAX_INT 0x7FFFFFFF
33 #define MIN_INT 0x80000000
34 #define MAX_INTF 2147483647.0
35 #define MIN_INTF -2147483648.0
37 /********************** SH4 Module Definition ****************************/
39 uint16_t *sh4_icache = NULL;
40 uint32_t sh4_icache_addr = 0;
42 uint32_t sh4_run_slice( uint32_t nanosecs )
43 {
44 int i;
45 sh4r.slice_cycle = 0;
47 if( sh4r.sh4_state != SH4_STATE_RUNNING ) {
48 if( sh4r.event_pending < nanosecs ) {
49 sh4r.sh4_state = SH4_STATE_RUNNING;
50 sh4r.slice_cycle = sh4r.event_pending;
51 }
52 }
54 if( sh4_breakpoint_count == 0 ) {
55 for( ; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
56 if( SH4_EVENT_PENDING() ) {
57 if( sh4r.event_types & PENDING_EVENT ) {
58 event_execute();
59 }
60 /* Eventq execute may (quite likely) deliver an immediate IRQ */
61 if( sh4r.event_types & PENDING_IRQ ) {
62 sh4_accept_interrupt();
63 }
64 }
65 if( !sh4_execute_instruction() ) {
66 break;
67 }
68 }
69 } else {
70 for( ;sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
71 if( SH4_EVENT_PENDING() ) {
72 if( sh4r.event_types & PENDING_EVENT ) {
73 event_execute();
74 }
75 /* Eventq execute may (quite likely) deliver an immediate IRQ */
76 if( sh4r.event_types & PENDING_IRQ ) {
77 sh4_accept_interrupt();
78 }
79 }
81 if( !sh4_execute_instruction() )
82 break;
83 #ifdef ENABLE_DEBUG_MODE
84 for( i=0; i<sh4_breakpoint_count; i++ ) {
85 if( sh4_breakpoints[i].address == sh4r.pc ) {
86 break;
87 }
88 }
89 if( i != sh4_breakpoint_count ) {
90 dreamcast_stop();
91 if( sh4_breakpoints[i].type == BREAK_ONESHOT )
92 sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );
93 break;
94 }
95 #endif
96 }
97 }
99 /* If we aborted early, but the cpu is still technically running,
100 * we're doing a hard abort - cut the timeslice back to what we
101 * actually executed
102 */
103 if( sh4r.slice_cycle != nanosecs && sh4r.sh4_state == SH4_STATE_RUNNING ) {
104 nanosecs = sh4r.slice_cycle;
105 }
106 if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
107 TMU_run_slice( nanosecs );
108 SCIF_run_slice( nanosecs );
109 }
110 return nanosecs;
111 }
113 /********************** SH4 emulation core ****************************/
115 #define UNDEF(ir) return sh4_raise_slot_exception(EXC_ILLEGAL, EXC_SLOT_ILLEGAL)
116 #define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", sh4r.pc, ir ); dreamcast_stop(); return FALSE; }while(0)
118 #if(SH4_CALLTRACE == 1)
119 #define MAX_CALLSTACK 32
120 static struct call_stack {
121 sh4addr_t call_addr;
122 sh4addr_t target_addr;
123 sh4addr_t stack_pointer;
124 } call_stack[MAX_CALLSTACK];
126 static int call_stack_depth = 0;
127 int sh4_call_trace_on = 0;
129 static inline trace_call( sh4addr_t source, sh4addr_t dest )
130 {
131 if( call_stack_depth < MAX_CALLSTACK ) {
132 call_stack[call_stack_depth].call_addr = source;
133 call_stack[call_stack_depth].target_addr = dest;
134 call_stack[call_stack_depth].stack_pointer = sh4r.r[15];
135 }
136 call_stack_depth++;
137 }
139 static inline trace_return( sh4addr_t source, sh4addr_t dest )
140 {
141 if( call_stack_depth > 0 ) {
142 call_stack_depth--;
143 }
144 }
146 void fprint_stack_trace( FILE *f )
147 {
148 int i = call_stack_depth -1;
149 if( i >= MAX_CALLSTACK )
150 i = MAX_CALLSTACK - 1;
151 for( ; i >= 0; i-- ) {
152 fprintf( f, "%d. Call from %08X => %08X, SP=%08X\n",
153 (call_stack_depth - i), call_stack[i].call_addr,
154 call_stack[i].target_addr, call_stack[i].stack_pointer );
155 }
156 }
158 #define TRACE_CALL( source, dest ) trace_call(source, dest)
159 #define TRACE_RETURN( source, dest ) trace_return(source, dest)
160 #else
161 #define TRACE_CALL( dest, rts )
162 #define TRACE_RETURN( source, dest )
163 #endif
165 #define MEM_READ_BYTE( addr ) sh4_read_byte(addr)
166 #define MEM_READ_WORD( addr ) sh4_read_word(addr)
167 #define MEM_READ_LONG( addr ) sh4_read_long(addr)
168 #define MEM_WRITE_BYTE( addr, val ) sh4_write_byte(addr, val)
169 #define MEM_WRITE_WORD( addr, val ) sh4_write_word(addr, val)
170 #define MEM_WRITE_LONG( addr, val ) sh4_write_long(addr, val)
172 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)
174 #define MEM_FP_READ( addr, reg ) sh4_read_float( addr, reg );
175 #define MEM_FP_WRITE( addr, reg ) sh4_write_float( addr, reg );
177 #define CHECKPRIV() if( !IS_SH4_PRIVMODE() ) return sh4_raise_slot_exception( EXC_ILLEGAL, EXC_SLOT_ILLEGAL )
178 #define CHECKRALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )
179 #define CHECKRALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )
180 #define CHECKWALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )
181 #define CHECKWALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )
183 #define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPU_DISABLED, EXC_SLOT_FPU_DISABLED ); } }
184 #define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }
185 #define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)
187 static void sh4_write_float( uint32_t addr, int reg )
188 {
189 if( IS_FPU_DOUBLESIZE() ) {
190 if( reg & 1 ) {
191 sh4_write_long( addr, *((uint32_t *)&XF((reg)&0x0E)) );
192 sh4_write_long( addr+4, *((uint32_t *)&XF(reg)) );
193 } else {
194 sh4_write_long( addr, *((uint32_t *)&FR(reg)) );
195 sh4_write_long( addr+4, *((uint32_t *)&FR((reg)|0x01)) );
196 }
197 } else {
198 sh4_write_long( addr, *((uint32_t *)&FR((reg))) );
199 }
200 }
202 static void sh4_read_float( uint32_t addr, int reg )
203 {
204 if( IS_FPU_DOUBLESIZE() ) {
205 if( reg & 1 ) {
206 *((uint32_t *)&XF((reg) & 0x0E)) = sh4_read_long(addr);
207 *((uint32_t *)&XF(reg)) = sh4_read_long(addr+4);
208 } else {
209 *((uint32_t *)&FR(reg)) = sh4_read_long(addr);
210 *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(addr+4);
211 }
212 } else {
213 *((uint32_t *)&FR(reg)) = sh4_read_long(addr);
214 }
215 }
217 gboolean sh4_execute_instruction( void )
218 {
219 uint32_t pc;
220 unsigned short ir;
221 uint32_t tmp;
222 float ftmp;
223 double dtmp;
225 #define R0 sh4r.r[0]
226 pc = sh4r.pc;
227 if( pc > 0xFFFFFF00 ) {
228 /* SYSCALL Magic */
229 syscall_invoke( pc );
230 sh4r.in_delay_slot = 0;
231 pc = sh4r.pc = sh4r.pr;
232 sh4r.new_pc = sh4r.pc + 2;
233 }
234 CHECKRALIGN16(pc);
236 /* Read instruction */
237 uint32_t pageaddr = pc >> 12;
238 if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {
239 ir = sh4_icache[(pc&0xFFF)>>1];
240 } else {
241 sh4_icache = (uint16_t *)mem_get_page(pc);
242 if( ((uint32_t)sh4_icache) < MAX_IO_REGIONS ) {
243 /* If someone's actually been so daft as to try to execute out of an IO
244 * region, fallback on the full-blown memory read
245 */
246 sh4_icache = NULL;
247 ir = MEM_READ_WORD(pc);
248 } else {
249 sh4_icache_addr = pageaddr;
250 ir = sh4_icache[(pc&0xFFF)>>1];
251 }
252 }
253 switch( (ir&0xF000) >> 12 ) {
254 case 0x0:
255 switch( ir&0xF ) {
256 case 0x2:
257 switch( (ir&0x80) >> 7 ) {
258 case 0x0:
259 switch( (ir&0x70) >> 4 ) {
260 case 0x0:
261 { /* STC SR, Rn */
262 uint32_t Rn = ((ir>>8)&0xF);
263 CHECKPRIV();
264 sh4r.r[Rn] = sh4_read_sr();
265 }
266 break;
267 case 0x1:
268 { /* STC GBR, Rn */
269 uint32_t Rn = ((ir>>8)&0xF);
270 CHECKPRIV();
271 sh4r.r[Rn] = sh4r.gbr;
272 }
273 break;
274 case 0x2:
275 { /* STC VBR, Rn */
276 uint32_t Rn = ((ir>>8)&0xF);
277 CHECKPRIV();
278 sh4r.r[Rn] = sh4r.vbr;
279 }
280 break;
281 case 0x3:
282 { /* STC SSR, Rn */
283 uint32_t Rn = ((ir>>8)&0xF);
284 CHECKPRIV();
285 sh4r.r[Rn] = sh4r.ssr;
286 }
287 break;
288 case 0x4:
289 { /* STC SPC, Rn */
290 uint32_t Rn = ((ir>>8)&0xF);
291 CHECKPRIV();
292 sh4r.r[Rn] = sh4r.spc;
293 }
294 break;
295 default:
296 UNDEF();
297 break;
298 }
299 break;
300 case 0x1:
301 { /* STC Rm_BANK, Rn */
302 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
303 CHECKPRIV();
304 sh4r.r[Rn] = sh4r.r_bank[Rm_BANK];
305 }
306 break;
307 }
308 break;
309 case 0x3:
310 switch( (ir&0xF0) >> 4 ) {
311 case 0x0:
312 { /* BSRF Rn */
313 uint32_t Rn = ((ir>>8)&0xF);
314 CHECKSLOTILLEGAL();
315 CHECKDEST( pc + 4 + sh4r.r[Rn] );
316 sh4r.in_delay_slot = 1;
317 sh4r.pr = sh4r.pc + 4;
318 sh4r.pc = sh4r.new_pc;
319 sh4r.new_pc = pc + 4 + sh4r.r[Rn];
320 TRACE_CALL( pc, sh4r.new_pc );
321 return TRUE;
322 }
323 break;
324 case 0x2:
325 { /* BRAF Rn */
326 uint32_t Rn = ((ir>>8)&0xF);
327 CHECKSLOTILLEGAL();
328 CHECKDEST( pc + 4 + sh4r.r[Rn] );
329 sh4r.in_delay_slot = 1;
330 sh4r.pc = sh4r.new_pc;
331 sh4r.new_pc = pc + 4 + sh4r.r[Rn];
332 return TRUE;
333 }
334 break;
335 case 0x8:
336 { /* PREF @Rn */
337 uint32_t Rn = ((ir>>8)&0xF);
338 tmp = sh4r.r[Rn];
339 if( (tmp & 0xFC000000) == 0xE0000000 ) {
340 sh4_flush_store_queue(tmp);
341 }
342 }
343 break;
344 case 0x9:
345 { /* OCBI @Rn */
346 uint32_t Rn = ((ir>>8)&0xF);
347 }
348 break;
349 case 0xA:
350 { /* OCBP @Rn */
351 uint32_t Rn = ((ir>>8)&0xF);
352 }
353 break;
354 case 0xB:
355 { /* OCBWB @Rn */
356 uint32_t Rn = ((ir>>8)&0xF);
357 }
358 break;
359 case 0xC:
360 { /* MOVCA.L R0, @Rn */
361 uint32_t Rn = ((ir>>8)&0xF);
362 tmp = sh4r.r[Rn];
363 CHECKWALIGN32(tmp);
364 MEM_WRITE_LONG( tmp, R0 );
365 }
366 break;
367 default:
368 UNDEF();
369 break;
370 }
371 break;
372 case 0x4:
373 { /* MOV.B Rm, @(R0, Rn) */
374 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
375 MEM_WRITE_BYTE( R0 + sh4r.r[Rn], sh4r.r[Rm] );
376 }
377 break;
378 case 0x5:
379 { /* MOV.W Rm, @(R0, Rn) */
380 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
381 CHECKWALIGN16( R0 + sh4r.r[Rn] );
382 MEM_WRITE_WORD( R0 + sh4r.r[Rn], sh4r.r[Rm] );
383 }
384 break;
385 case 0x6:
386 { /* MOV.L Rm, @(R0, Rn) */
387 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
388 CHECKWALIGN32( R0 + sh4r.r[Rn] );
389 MEM_WRITE_LONG( R0 + sh4r.r[Rn], sh4r.r[Rm] );
390 }
391 break;
392 case 0x7:
393 { /* MUL.L Rm, Rn */
394 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
395 sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
396 (sh4r.r[Rm] * sh4r.r[Rn]);
397 }
398 break;
399 case 0x8:
400 switch( (ir&0xFF0) >> 4 ) {
401 case 0x0:
402 { /* CLRT */
403 sh4r.t = 0;
404 }
405 break;
406 case 0x1:
407 { /* SETT */
408 sh4r.t = 1;
409 }
410 break;
411 case 0x2:
412 { /* CLRMAC */
413 sh4r.mac = 0;
414 }
415 break;
416 case 0x3:
417 { /* LDTLB */
418 /* TODO */
419 }
420 break;
421 case 0x4:
422 { /* CLRS */
423 sh4r.s = 0;
424 }
425 break;
426 case 0x5:
427 { /* SETS */
428 sh4r.s = 1;
429 }
430 break;
431 default:
432 UNDEF();
433 break;
434 }
435 break;
436 case 0x9:
437 switch( (ir&0xF0) >> 4 ) {
438 case 0x0:
439 { /* NOP */
440 /* NOP */
441 }
442 break;
443 case 0x1:
444 { /* DIV0U */
445 sh4r.m = sh4r.q = sh4r.t = 0;
446 }
447 break;
448 case 0x2:
449 { /* MOVT Rn */
450 uint32_t Rn = ((ir>>8)&0xF);
451 sh4r.r[Rn] = sh4r.t;
452 }
453 break;
454 default:
455 UNDEF();
456 break;
457 }
458 break;
459 case 0xA:
460 switch( (ir&0xF0) >> 4 ) {
461 case 0x0:
462 { /* STS MACH, Rn */
463 uint32_t Rn = ((ir>>8)&0xF);
464 sh4r.r[Rn] = (sh4r.mac>>32);
465 }
466 break;
467 case 0x1:
468 { /* STS MACL, Rn */
469 uint32_t Rn = ((ir>>8)&0xF);
470 sh4r.r[Rn] = (uint32_t)sh4r.mac;
471 }
472 break;
473 case 0x2:
474 { /* STS PR, Rn */
475 uint32_t Rn = ((ir>>8)&0xF);
476 sh4r.r[Rn] = sh4r.pr;
477 }
478 break;
479 case 0x3:
480 { /* STC SGR, Rn */
481 uint32_t Rn = ((ir>>8)&0xF);
482 CHECKPRIV();
483 sh4r.r[Rn] = sh4r.sgr;
484 }
485 break;
486 case 0x5:
487 { /* STS FPUL, Rn */
488 uint32_t Rn = ((ir>>8)&0xF);
489 sh4r.r[Rn] = sh4r.fpul;
490 }
491 break;
492 case 0x6:
493 { /* STS FPSCR, Rn */
494 uint32_t Rn = ((ir>>8)&0xF);
495 sh4r.r[Rn] = sh4r.fpscr;
496 }
497 break;
498 case 0xF:
499 { /* STC DBR, Rn */
500 uint32_t Rn = ((ir>>8)&0xF);
501 CHECKPRIV(); sh4r.r[Rn] = sh4r.dbr;
502 }
503 break;
504 default:
505 UNDEF();
506 break;
507 }
508 break;
509 case 0xB:
510 switch( (ir&0xFF0) >> 4 ) {
511 case 0x0:
512 { /* RTS */
513 CHECKSLOTILLEGAL();
514 CHECKDEST( sh4r.pr );
515 sh4r.in_delay_slot = 1;
516 sh4r.pc = sh4r.new_pc;
517 sh4r.new_pc = sh4r.pr;
518 TRACE_RETURN( pc, sh4r.new_pc );
519 return TRUE;
520 }
521 break;
522 case 0x1:
523 { /* SLEEP */
524 if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
525 sh4r.sh4_state = SH4_STATE_STANDBY;
526 } else {
527 sh4r.sh4_state = SH4_STATE_SLEEP;
528 }
529 return FALSE; /* Halt CPU */
530 }
531 break;
532 case 0x2:
533 { /* RTE */
534 CHECKPRIV();
535 CHECKDEST( sh4r.spc );
536 CHECKSLOTILLEGAL();
537 sh4r.in_delay_slot = 1;
538 sh4r.pc = sh4r.new_pc;
539 sh4r.new_pc = sh4r.spc;
540 sh4_write_sr( sh4r.ssr );
541 return TRUE;
542 }
543 break;
544 default:
545 UNDEF();
546 break;
547 }
548 break;
549 case 0xC:
550 { /* MOV.B @(R0, Rm), Rn */
551 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
552 sh4r.r[Rn] = MEM_READ_BYTE( R0 + sh4r.r[Rm] );
553 }
554 break;
555 case 0xD:
556 { /* MOV.W @(R0, Rm), Rn */
557 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
558 CHECKRALIGN16( R0 + sh4r.r[Rm] );
559 sh4r.r[Rn] = MEM_READ_WORD( R0 + sh4r.r[Rm] );
560 }
561 break;
562 case 0xE:
563 { /* MOV.L @(R0, Rm), Rn */
564 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
565 CHECKRALIGN32( R0 + sh4r.r[Rm] );
566 sh4r.r[Rn] = MEM_READ_LONG( R0 + sh4r.r[Rm] );
567 }
568 break;
569 case 0xF:
570 { /* MAC.L @Rm+, @Rn+ */
571 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
572 CHECKRALIGN32( sh4r.r[Rm] );
573 CHECKRALIGN32( sh4r.r[Rn] );
574 int64_t tmpl = SIGNEXT32(MEM_READ_LONG(sh4r.r[Rn]));
575 sh4r.r[Rn] += 4;
576 tmpl = tmpl * SIGNEXT32(MEM_READ_LONG(sh4r.r[Rm])) + sh4r.mac;
577 sh4r.r[Rm] += 4;
578 if( sh4r.s ) {
579 /* 48-bit Saturation. Yuch */
580 if( tmpl < (int64_t)0xFFFF800000000000LL )
581 tmpl = 0xFFFF800000000000LL;
582 else if( tmpl > (int64_t)0x00007FFFFFFFFFFFLL )
583 tmpl = 0x00007FFFFFFFFFFFLL;
584 }
585 sh4r.mac = tmpl;
586 }
587 break;
588 default:
589 UNDEF();
590 break;
591 }
592 break;
593 case 0x1:
594 { /* MOV.L Rm, @(disp, Rn) */
595 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
596 tmp = sh4r.r[Rn] + disp;
597 CHECKWALIGN32( tmp );
598 MEM_WRITE_LONG( tmp, sh4r.r[Rm] );
599 }
600 break;
601 case 0x2:
602 switch( ir&0xF ) {
603 case 0x0:
604 { /* MOV.B Rm, @Rn */
605 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
606 MEM_WRITE_BYTE( sh4r.r[Rn], sh4r.r[Rm] );
607 }
608 break;
609 case 0x1:
610 { /* MOV.W Rm, @Rn */
611 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
612 CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn], sh4r.r[Rm] );
613 }
614 break;
615 case 0x2:
616 { /* MOV.L Rm, @Rn */
617 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
618 CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r[Rm] );
619 }
620 break;
621 case 0x4:
622 { /* MOV.B Rm, @-Rn */
623 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
624 sh4r.r[Rn] --; MEM_WRITE_BYTE( sh4r.r[Rn], sh4r.r[Rm] );
625 }
626 break;
627 case 0x5:
628 { /* MOV.W Rm, @-Rn */
629 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
630 sh4r.r[Rn] -= 2; CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn], sh4r.r[Rm] );
631 }
632 break;
633 case 0x6:
634 { /* MOV.L Rm, @-Rn */
635 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
636 sh4r.r[Rn] -= 4; CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r[Rm] );
637 }
638 break;
639 case 0x7:
640 { /* DIV0S Rm, Rn */
641 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
642 sh4r.q = sh4r.r[Rn]>>31;
643 sh4r.m = sh4r.r[Rm]>>31;
644 sh4r.t = sh4r.q ^ sh4r.m;
645 }
646 break;
647 case 0x8:
648 { /* TST Rm, Rn */
649 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
650 sh4r.t = (sh4r.r[Rn]&sh4r.r[Rm] ? 0 : 1);
651 }
652 break;
653 case 0x9:
654 { /* AND Rm, Rn */
655 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
656 sh4r.r[Rn] &= sh4r.r[Rm];
657 }
658 break;
659 case 0xA:
660 { /* XOR Rm, Rn */
661 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
662 sh4r.r[Rn] ^= sh4r.r[Rm];
663 }
664 break;
665 case 0xB:
666 { /* OR Rm, Rn */
667 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
668 sh4r.r[Rn] |= sh4r.r[Rm];
669 }
670 break;
671 case 0xC:
672 { /* CMP/STR Rm, Rn */
673 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
674 /* set T = 1 if any byte in RM & RN is the same */
675 tmp = sh4r.r[Rm] ^ sh4r.r[Rn];
676 sh4r.t = ((tmp&0x000000FF)==0 || (tmp&0x0000FF00)==0 ||
677 (tmp&0x00FF0000)==0 || (tmp&0xFF000000)==0)?1:0;
678 }
679 break;
680 case 0xD:
681 { /* XTRCT Rm, Rn */
682 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
683 sh4r.r[Rn] = (sh4r.r[Rn]>>16) | (sh4r.r[Rm]<<16);
684 }
685 break;
686 case 0xE:
687 { /* MULU.W Rm, Rn */
688 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
689 sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
690 (uint32_t)((sh4r.r[Rm]&0xFFFF) * (sh4r.r[Rn]&0xFFFF));
691 }
692 break;
693 case 0xF:
694 { /* MULS.W Rm, Rn */
695 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
696 sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
697 (uint32_t)(SIGNEXT32(sh4r.r[Rm]&0xFFFF) * SIGNEXT32(sh4r.r[Rn]&0xFFFF));
698 }
699 break;
700 default:
701 UNDEF();
702 break;
703 }
704 break;
705 case 0x3:
706 switch( ir&0xF ) {
707 case 0x0:
708 { /* CMP/EQ Rm, Rn */
709 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
710 sh4r.t = ( sh4r.r[Rm] == sh4r.r[Rn] ? 1 : 0 );
711 }
712 break;
713 case 0x2:
714 { /* CMP/HS Rm, Rn */
715 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
716 sh4r.t = ( sh4r.r[Rn] >= sh4r.r[Rm] ? 1 : 0 );
717 }
718 break;
719 case 0x3:
720 { /* CMP/GE Rm, Rn */
721 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
722 sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= ((int32_t)sh4r.r[Rm]) ? 1 : 0 );
723 }
724 break;
725 case 0x4:
726 { /* DIV1 Rm, Rn */
727 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
728 /* This is derived from the sh4 manual with some simplifications */
729 uint32_t tmp0, tmp1, tmp2, dir;
731 dir = sh4r.q ^ sh4r.m;
732 sh4r.q = (sh4r.r[Rn] >> 31);
733 tmp2 = sh4r.r[Rm];
734 sh4r.r[Rn] = (sh4r.r[Rn] << 1) | sh4r.t;
735 tmp0 = sh4r.r[Rn];
736 if( dir ) {
737 sh4r.r[Rn] += tmp2;
738 tmp1 = (sh4r.r[Rn]<tmp0 ? 1 : 0 );
739 } else {
740 sh4r.r[Rn] -= tmp2;
741 tmp1 = (sh4r.r[Rn]>tmp0 ? 1 : 0 );
742 }
743 sh4r.q ^= sh4r.m ^ tmp1;
744 sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );
745 }
746 break;
747 case 0x5:
748 { /* DMULU.L Rm, Rn */
749 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
750 sh4r.mac = ((uint64_t)sh4r.r[Rm]) * ((uint64_t)sh4r.r[Rn]);
751 }
752 break;
753 case 0x6:
754 { /* CMP/HI Rm, Rn */
755 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
756 sh4r.t = ( sh4r.r[Rn] > sh4r.r[Rm] ? 1 : 0 );
757 }
758 break;
759 case 0x7:
760 { /* CMP/GT Rm, Rn */
761 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
762 sh4r.t = ( ((int32_t)sh4r.r[Rn]) > ((int32_t)sh4r.r[Rm]) ? 1 : 0 );
763 }
764 break;
765 case 0x8:
766 { /* SUB Rm, Rn */
767 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
768 sh4r.r[Rn] -= sh4r.r[Rm];
769 }
770 break;
771 case 0xA:
772 { /* SUBC Rm, Rn */
773 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
774 tmp = sh4r.r[Rn];
775 sh4r.r[Rn] = sh4r.r[Rn] - sh4r.r[Rm] - sh4r.t;
776 sh4r.t = (sh4r.r[Rn] > tmp || (sh4r.r[Rn] == tmp && sh4r.t == 1));
777 }
778 break;
779 case 0xB:
780 UNIMP(ir); /* SUBV Rm, Rn */
781 break;
782 case 0xC:
783 { /* ADD Rm, Rn */
784 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
785 sh4r.r[Rn] += sh4r.r[Rm];
786 }
787 break;
788 case 0xD:
789 { /* DMULS.L Rm, Rn */
790 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
791 sh4r.mac = SIGNEXT32(sh4r.r[Rm]) * SIGNEXT32(sh4r.r[Rn]);
792 }
793 break;
794 case 0xE:
795 { /* ADDC Rm, Rn */
796 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
797 tmp = sh4r.r[Rn];
798 sh4r.r[Rn] += sh4r.r[Rm] + sh4r.t;
799 sh4r.t = ( sh4r.r[Rn] < tmp || (sh4r.r[Rn] == tmp && sh4r.t != 0) ? 1 : 0 );
800 }
801 break;
802 case 0xF:
803 { /* ADDV Rm, Rn */
804 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
805 tmp = sh4r.r[Rn] + sh4r.r[Rm];
806 sh4r.t = ( (sh4r.r[Rn]>>31) == (sh4r.r[Rm]>>31) && ((sh4r.r[Rn]>>31) != (tmp>>31)) );
807 sh4r.r[Rn] = tmp;
808 }
809 break;
810 default:
811 UNDEF();
812 break;
813 }
814 break;
815 case 0x4:
816 switch( ir&0xF ) {
817 case 0x0:
818 switch( (ir&0xF0) >> 4 ) {
819 case 0x0:
820 { /* SHLL Rn */
821 uint32_t Rn = ((ir>>8)&0xF);
822 sh4r.t = sh4r.r[Rn] >> 31; sh4r.r[Rn] <<= 1;
823 }
824 break;
825 case 0x1:
826 { /* DT Rn */
827 uint32_t Rn = ((ir>>8)&0xF);
828 sh4r.r[Rn] --;
829 sh4r.t = ( sh4r.r[Rn] == 0 ? 1 : 0 );
830 }
831 break;
832 case 0x2:
833 { /* SHAL Rn */
834 uint32_t Rn = ((ir>>8)&0xF);
835 sh4r.t = sh4r.r[Rn] >> 31;
836 sh4r.r[Rn] <<= 1;
837 }
838 break;
839 default:
840 UNDEF();
841 break;
842 }
843 break;
844 case 0x1:
845 switch( (ir&0xF0) >> 4 ) {
846 case 0x0:
847 { /* SHLR Rn */
848 uint32_t Rn = ((ir>>8)&0xF);
849 sh4r.t = sh4r.r[Rn] & 0x00000001; sh4r.r[Rn] >>= 1;
850 }
851 break;
852 case 0x1:
853 { /* CMP/PZ Rn */
854 uint32_t Rn = ((ir>>8)&0xF);
855 sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= 0 ? 1 : 0 );
856 }
857 break;
858 case 0x2:
859 { /* SHAR Rn */
860 uint32_t Rn = ((ir>>8)&0xF);
861 sh4r.t = sh4r.r[Rn] & 0x00000001;
862 sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 1;
863 }
864 break;
865 default:
866 UNDEF();
867 break;
868 }
869 break;
870 case 0x2:
871 switch( (ir&0xF0) >> 4 ) {
872 case 0x0:
873 { /* STS.L MACH, @-Rn */
874 uint32_t Rn = ((ir>>8)&0xF);
875 sh4r.r[Rn] -= 4;
876 CHECKWALIGN32( sh4r.r[Rn] );
877 MEM_WRITE_LONG( sh4r.r[Rn], (sh4r.mac>>32) );
878 }
879 break;
880 case 0x1:
881 { /* STS.L MACL, @-Rn */
882 uint32_t Rn = ((ir>>8)&0xF);
883 sh4r.r[Rn] -= 4;
884 CHECKWALIGN32( sh4r.r[Rn] );
885 MEM_WRITE_LONG( sh4r.r[Rn], (uint32_t)sh4r.mac );
886 }
887 break;
888 case 0x2:
889 { /* STS.L PR, @-Rn */
890 uint32_t Rn = ((ir>>8)&0xF);
891 sh4r.r[Rn] -= 4;
892 CHECKWALIGN32( sh4r.r[Rn] );
893 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.pr );
894 }
895 break;
896 case 0x3:
897 { /* STC.L SGR, @-Rn */
898 uint32_t Rn = ((ir>>8)&0xF);
899 CHECKPRIV();
900 sh4r.r[Rn] -= 4;
901 CHECKWALIGN32( sh4r.r[Rn] );
902 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.sgr );
903 }
904 break;
905 case 0x5:
906 { /* STS.L FPUL, @-Rn */
907 uint32_t Rn = ((ir>>8)&0xF);
908 sh4r.r[Rn] -= 4;
909 CHECKWALIGN32( sh4r.r[Rn] );
910 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpul );
911 }
912 break;
913 case 0x6:
914 { /* STS.L FPSCR, @-Rn */
915 uint32_t Rn = ((ir>>8)&0xF);
916 sh4r.r[Rn] -= 4;
917 CHECKWALIGN32( sh4r.r[Rn] );
918 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpscr );
919 }
920 break;
921 case 0xF:
922 { /* STC.L DBR, @-Rn */
923 uint32_t Rn = ((ir>>8)&0xF);
924 CHECKPRIV();
925 sh4r.r[Rn] -= 4;
926 CHECKWALIGN32( sh4r.r[Rn] );
927 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.dbr );
928 }
929 break;
930 default:
931 UNDEF();
932 break;
933 }
934 break;
935 case 0x3:
936 switch( (ir&0x80) >> 7 ) {
937 case 0x0:
938 switch( (ir&0x70) >> 4 ) {
939 case 0x0:
940 { /* STC.L SR, @-Rn */
941 uint32_t Rn = ((ir>>8)&0xF);
942 CHECKPRIV();
943 sh4r.r[Rn] -= 4;
944 CHECKWALIGN32( sh4r.r[Rn] );
945 MEM_WRITE_LONG( sh4r.r[Rn], sh4_read_sr() );
946 }
947 break;
948 case 0x1:
949 { /* STC.L GBR, @-Rn */
950 uint32_t Rn = ((ir>>8)&0xF);
951 sh4r.r[Rn] -= 4;
952 CHECKWALIGN32( sh4r.r[Rn] );
953 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.gbr );
954 }
955 break;
956 case 0x2:
957 { /* STC.L VBR, @-Rn */
958 uint32_t Rn = ((ir>>8)&0xF);
959 CHECKPRIV();
960 sh4r.r[Rn] -= 4;
961 CHECKWALIGN32( sh4r.r[Rn] );
962 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.vbr );
963 }
964 break;
965 case 0x3:
966 { /* STC.L SSR, @-Rn */
967 uint32_t Rn = ((ir>>8)&0xF);
968 CHECKPRIV();
969 sh4r.r[Rn] -= 4;
970 CHECKWALIGN32( sh4r.r[Rn] );
971 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.ssr );
972 }
973 break;
974 case 0x4:
975 { /* STC.L SPC, @-Rn */
976 uint32_t Rn = ((ir>>8)&0xF);
977 CHECKPRIV();
978 sh4r.r[Rn] -= 4;
979 CHECKWALIGN32( sh4r.r[Rn] );
980 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.spc );
981 }
982 break;
983 default:
984 UNDEF();
985 break;
986 }
987 break;
988 case 0x1:
989 { /* STC.L Rm_BANK, @-Rn */
990 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
991 CHECKPRIV();
992 sh4r.r[Rn] -= 4;
993 CHECKWALIGN32( sh4r.r[Rn] );
994 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r_bank[Rm_BANK] );
995 }
996 break;
997 }
998 break;
999 case 0x4:
1000 switch( (ir&0xF0) >> 4 ) {
1001 case 0x0:
1002 { /* ROTL Rn */
1003 uint32_t Rn = ((ir>>8)&0xF);
1004 sh4r.t = sh4r.r[Rn] >> 31;
1005 sh4r.r[Rn] <<= 1;
1006 sh4r.r[Rn] |= sh4r.t;
1007 }
1008 break;
1009 case 0x2:
1010 { /* ROTCL Rn */
1011 uint32_t Rn = ((ir>>8)&0xF);
1012 tmp = sh4r.r[Rn] >> 31;
1013 sh4r.r[Rn] <<= 1;
1014 sh4r.r[Rn] |= sh4r.t;
1015 sh4r.t = tmp;
1016 }
1017 break;
1018 default:
1019 UNDEF();
1020 break;
1021 }
1022 break;
1023 case 0x5:
1024 switch( (ir&0xF0) >> 4 ) {
1025 case 0x0:
1026 { /* ROTR Rn */
1027 uint32_t Rn = ((ir>>8)&0xF);
1028 sh4r.t = sh4r.r[Rn] & 0x00000001;
1029 sh4r.r[Rn] >>= 1;
1030 sh4r.r[Rn] |= (sh4r.t << 31);
1031 }
1032 break;
1033 case 0x1:
1034 { /* CMP/PL Rn */
1035 uint32_t Rn = ((ir>>8)&0xF);
1036 sh4r.t = ( ((int32_t)sh4r.r[Rn]) > 0 ? 1 : 0 );
1037 }
1038 break;
1039 case 0x2:
1040 { /* ROTCR Rn */
1041 uint32_t Rn = ((ir>>8)&0xF);
1042 tmp = sh4r.r[Rn] & 0x00000001;
1043 sh4r.r[Rn] >>= 1;
1044 sh4r.r[Rn] |= (sh4r.t << 31 );
1045 sh4r.t = tmp;
1046 }
1047 break;
1048 default:
1049 UNDEF();
1050 break;
1051 }
1052 break;
1053 case 0x6:
1054 switch( (ir&0xF0) >> 4 ) {
1055 case 0x0:
1056 { /* LDS.L @Rm+, MACH */
1057 uint32_t Rm = ((ir>>8)&0xF);
1058 CHECKRALIGN32( sh4r.r[Rm] );
1059 sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1060 (((uint64_t)MEM_READ_LONG(sh4r.r[Rm]))<<32);
1061 sh4r.r[Rm] += 4;
1062 }
1063 break;
1064 case 0x1:
1065 { /* LDS.L @Rm+, MACL */
1066 uint32_t Rm = ((ir>>8)&0xF);
1067 CHECKRALIGN32( sh4r.r[Rm] );
1068 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1069 (uint64_t)((uint32_t)MEM_READ_LONG(sh4r.r[Rm]));
1070 sh4r.r[Rm] += 4;
1071 }
1072 break;
1073 case 0x2:
1074 { /* LDS.L @Rm+, PR */
1075 uint32_t Rm = ((ir>>8)&0xF);
1076 CHECKRALIGN32( sh4r.r[Rm] );
1077 sh4r.pr = MEM_READ_LONG( sh4r.r[Rm] );
1078 sh4r.r[Rm] += 4;
1079 }
1080 break;
1081 case 0x3:
1082 { /* LDC.L @Rm+, SGR */
1083 uint32_t Rm = ((ir>>8)&0xF);
1084 CHECKPRIV();
1085 CHECKRALIGN32( sh4r.r[Rm] );
1086 sh4r.sgr = MEM_READ_LONG(sh4r.r[Rm]);
1087 sh4r.r[Rm] +=4;
1088 }
1089 break;
1090 case 0x5:
1091 { /* LDS.L @Rm+, FPUL */
1092 uint32_t Rm = ((ir>>8)&0xF);
1093 CHECKRALIGN32( sh4r.r[Rm] );
1094 sh4r.fpul = MEM_READ_LONG(sh4r.r[Rm]);
1095 sh4r.r[Rm] +=4;
1096 }
1097 break;
1098 case 0x6:
1099 { /* LDS.L @Rm+, FPSCR */
1100 uint32_t Rm = ((ir>>8)&0xF);
1101 CHECKRALIGN32( sh4r.r[Rm] );
1102 sh4r.fpscr = MEM_READ_LONG(sh4r.r[Rm]);
1103 sh4r.r[Rm] +=4;
1104 sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
1105 }
1106 break;
1107 case 0xF:
1108 { /* LDC.L @Rm+, DBR */
1109 uint32_t Rm = ((ir>>8)&0xF);
1110 CHECKPRIV();
1111 CHECKRALIGN32( sh4r.r[Rm] );
1112 sh4r.dbr = MEM_READ_LONG(sh4r.r[Rm]);
1113 sh4r.r[Rm] +=4;
1114 }
1115 break;
1116 default:
1117 UNDEF();
1118 break;
1119 }
1120 break;
1121 case 0x7:
1122 switch( (ir&0x80) >> 7 ) {
1123 case 0x0:
1124 switch( (ir&0x70) >> 4 ) {
1125 case 0x0:
1126 { /* LDC.L @Rm+, SR */
1127 uint32_t Rm = ((ir>>8)&0xF);
1128 CHECKSLOTILLEGAL();
1129 CHECKPRIV();
1130 CHECKWALIGN32( sh4r.r[Rm] );
1131 sh4_write_sr( MEM_READ_LONG(sh4r.r[Rm]) );
1132 sh4r.r[Rm] +=4;
1133 }
1134 break;
1135 case 0x1:
1136 { /* LDC.L @Rm+, GBR */
1137 uint32_t Rm = ((ir>>8)&0xF);
1138 CHECKRALIGN32( sh4r.r[Rm] );
1139 sh4r.gbr = MEM_READ_LONG(sh4r.r[Rm]);
1140 sh4r.r[Rm] +=4;
1141 }
1142 break;
1143 case 0x2:
1144 { /* LDC.L @Rm+, VBR */
1145 uint32_t Rm = ((ir>>8)&0xF);
1146 CHECKPRIV();
1147 CHECKRALIGN32( sh4r.r[Rm] );
1148 sh4r.vbr = MEM_READ_LONG(sh4r.r[Rm]);
1149 sh4r.r[Rm] +=4;
1150 }
1151 break;
1152 case 0x3:
1153 { /* LDC.L @Rm+, SSR */
1154 uint32_t Rm = ((ir>>8)&0xF);
1155 CHECKPRIV();
1156 CHECKRALIGN32( sh4r.r[Rm] );
1157 sh4r.ssr = MEM_READ_LONG(sh4r.r[Rm]);
1158 sh4r.r[Rm] +=4;
1159 }
1160 break;
1161 case 0x4:
1162 { /* LDC.L @Rm+, SPC */
1163 uint32_t Rm = ((ir>>8)&0xF);
1164 CHECKPRIV();
1165 CHECKRALIGN32( sh4r.r[Rm] );
1166 sh4r.spc = MEM_READ_LONG(sh4r.r[Rm]);
1167 sh4r.r[Rm] +=4;
1168 }
1169 break;
1170 default:
1171 UNDEF();
1172 break;
1173 }
1174 break;
1175 case 0x1:
1176 { /* LDC.L @Rm+, Rn_BANK */
1177 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1178 CHECKPRIV();
1179 CHECKRALIGN32( sh4r.r[Rm] );
1180 sh4r.r_bank[Rn_BANK] = MEM_READ_LONG( sh4r.r[Rm] );
1181 sh4r.r[Rm] += 4;
1182 }
1183 break;
1184 }
1185 break;
1186 case 0x8:
1187 switch( (ir&0xF0) >> 4 ) {
1188 case 0x0:
1189 { /* SHLL2 Rn */
1190 uint32_t Rn = ((ir>>8)&0xF);
1191 sh4r.r[Rn] <<= 2;
1192 }
1193 break;
1194 case 0x1:
1195 { /* SHLL8 Rn */
1196 uint32_t Rn = ((ir>>8)&0xF);
1197 sh4r.r[Rn] <<= 8;
1198 }
1199 break;
1200 case 0x2:
1201 { /* SHLL16 Rn */
1202 uint32_t Rn = ((ir>>8)&0xF);
1203 sh4r.r[Rn] <<= 16;
1204 }
1205 break;
1206 default:
1207 UNDEF();
1208 break;
1209 }
1210 break;
1211 case 0x9:
1212 switch( (ir&0xF0) >> 4 ) {
1213 case 0x0:
1214 { /* SHLR2 Rn */
1215 uint32_t Rn = ((ir>>8)&0xF);
1216 sh4r.r[Rn] >>= 2;
1217 }
1218 break;
1219 case 0x1:
1220 { /* SHLR8 Rn */
1221 uint32_t Rn = ((ir>>8)&0xF);
1222 sh4r.r[Rn] >>= 8;
1223 }
1224 break;
1225 case 0x2:
1226 { /* SHLR16 Rn */
1227 uint32_t Rn = ((ir>>8)&0xF);
1228 sh4r.r[Rn] >>= 16;
1229 }
1230 break;
1231 default:
1232 UNDEF();
1233 break;
1234 }
1235 break;
1236 case 0xA:
1237 switch( (ir&0xF0) >> 4 ) {
1238 case 0x0:
1239 { /* LDS Rm, MACH */
1240 uint32_t Rm = ((ir>>8)&0xF);
1241 sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1242 (((uint64_t)sh4r.r[Rm])<<32);
1243 }
1244 break;
1245 case 0x1:
1246 { /* LDS Rm, MACL */
1247 uint32_t Rm = ((ir>>8)&0xF);
1248 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1249 (uint64_t)((uint32_t)(sh4r.r[Rm]));
1250 }
1251 break;
1252 case 0x2:
1253 { /* LDS Rm, PR */
1254 uint32_t Rm = ((ir>>8)&0xF);
1255 sh4r.pr = sh4r.r[Rm];
1256 }
1257 break;
1258 case 0x3:
1259 { /* LDC Rm, SGR */
1260 uint32_t Rm = ((ir>>8)&0xF);
1261 CHECKPRIV();
1262 sh4r.sgr = sh4r.r[Rm];
1263 }
1264 break;
1265 case 0x5:
1266 { /* LDS Rm, FPUL */
1267 uint32_t Rm = ((ir>>8)&0xF);
1268 sh4r.fpul = sh4r.r[Rm];
1269 }
1270 break;
1271 case 0x6:
1272 { /* LDS Rm, FPSCR */
1273 uint32_t Rm = ((ir>>8)&0xF);
1274 sh4r.fpscr = sh4r.r[Rm];
1275 sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
1276 }
1277 break;
1278 case 0xF:
1279 { /* LDC Rm, DBR */
1280 uint32_t Rm = ((ir>>8)&0xF);
1281 CHECKPRIV();
1282 sh4r.dbr = sh4r.r[Rm];
1283 }
1284 break;
1285 default:
1286 UNDEF();
1287 break;
1288 }
1289 break;
1290 case 0xB:
1291 switch( (ir&0xF0) >> 4 ) {
1292 case 0x0:
1293 { /* JSR @Rn */
1294 uint32_t Rn = ((ir>>8)&0xF);
1295 CHECKDEST( sh4r.r[Rn] );
1296 CHECKSLOTILLEGAL();
1297 sh4r.in_delay_slot = 1;
1298 sh4r.pc = sh4r.new_pc;
1299 sh4r.new_pc = sh4r.r[Rn];
1300 sh4r.pr = pc + 4;
1301 TRACE_CALL( pc, sh4r.new_pc );
1302 return TRUE;
1303 }
1304 break;
1305 case 0x1:
1306 { /* TAS.B @Rn */
1307 uint32_t Rn = ((ir>>8)&0xF);
1308 tmp = MEM_READ_BYTE( sh4r.r[Rn] );
1309 sh4r.t = ( tmp == 0 ? 1 : 0 );
1310 MEM_WRITE_BYTE( sh4r.r[Rn], tmp | 0x80 );
1311 }
1312 break;
1313 case 0x2:
1314 { /* JMP @Rn */
1315 uint32_t Rn = ((ir>>8)&0xF);
1316 CHECKDEST( sh4r.r[Rn] );
1317 CHECKSLOTILLEGAL();
1318 sh4r.in_delay_slot = 1;
1319 sh4r.pc = sh4r.new_pc;
1320 sh4r.new_pc = sh4r.r[Rn];
1321 return TRUE;
1322 }
1323 break;
1324 default:
1325 UNDEF();
1326 break;
1327 }
1328 break;
1329 case 0xC:
1330 { /* SHAD Rm, Rn */
1331 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1332 tmp = sh4r.r[Rm];
1333 if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);
1334 else if( (tmp & 0x1F) == 0 )
1335 sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 31;
1336 else
1337 sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> (((~sh4r.r[Rm]) & 0x1F)+1);
1338 }
1339 break;
1340 case 0xD:
1341 { /* SHLD Rm, Rn */
1342 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1343 tmp = sh4r.r[Rm];
1344 if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);
1345 else if( (tmp & 0x1F) == 0 ) sh4r.r[Rn] = 0;
1346 else sh4r.r[Rn] >>= (((~tmp) & 0x1F)+1);
1347 }
1348 break;
1349 case 0xE:
1350 switch( (ir&0x80) >> 7 ) {
1351 case 0x0:
1352 switch( (ir&0x70) >> 4 ) {
1353 case 0x0:
1354 { /* LDC Rm, SR */
1355 uint32_t Rm = ((ir>>8)&0xF);
1356 CHECKSLOTILLEGAL();
1357 CHECKPRIV();
1358 sh4_write_sr( sh4r.r[Rm] );
1359 }
1360 break;
1361 case 0x1:
1362 { /* LDC Rm, GBR */
1363 uint32_t Rm = ((ir>>8)&0xF);
1364 sh4r.gbr = sh4r.r[Rm];
1365 }
1366 break;
1367 case 0x2:
1368 { /* LDC Rm, VBR */
1369 uint32_t Rm = ((ir>>8)&0xF);
1370 CHECKPRIV();
1371 sh4r.vbr = sh4r.r[Rm];
1372 }
1373 break;
1374 case 0x3:
1375 { /* LDC Rm, SSR */
1376 uint32_t Rm = ((ir>>8)&0xF);
1377 CHECKPRIV();
1378 sh4r.ssr = sh4r.r[Rm];
1379 }
1380 break;
1381 case 0x4:
1382 { /* LDC Rm, SPC */
1383 uint32_t Rm = ((ir>>8)&0xF);
1384 CHECKPRIV();
1385 sh4r.spc = sh4r.r[Rm];
1386 }
1387 break;
1388 default:
1389 UNDEF();
1390 break;
1391 }
1392 break;
1393 case 0x1:
1394 { /* LDC Rm, Rn_BANK */
1395 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1396 CHECKPRIV();
1397 sh4r.r_bank[Rn_BANK] = sh4r.r[Rm];
1398 }
1399 break;
1400 }
1401 break;
1402 case 0xF:
1403 { /* MAC.W @Rm+, @Rn+ */
1404 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1405 CHECKRALIGN16( sh4r.r[Rn] );
1406 CHECKRALIGN16( sh4r.r[Rm] );
1407 int32_t stmp = SIGNEXT16(MEM_READ_WORD(sh4r.r[Rn]));
1408 sh4r.r[Rn] += 2;
1409 stmp = stmp * SIGNEXT16(MEM_READ_WORD(sh4r.r[Rm]));
1410 sh4r.r[Rm] += 2;
1411 if( sh4r.s ) {
1412 int64_t tmpl = (int64_t)((int32_t)sh4r.mac) + (int64_t)stmp;
1413 if( tmpl > (int64_t)0x000000007FFFFFFFLL ) {
1414 sh4r.mac = 0x000000017FFFFFFFLL;
1415 } else if( tmpl < (int64_t)0xFFFFFFFF80000000LL ) {
1416 sh4r.mac = 0x0000000180000000LL;
1417 } else {
1418 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1419 ((uint32_t)(sh4r.mac + stmp));
1420 }
1421 } else {
1422 sh4r.mac += SIGNEXT32(stmp);
1423 }
1424 }
1425 break;
1426 }
1427 break;
1428 case 0x5:
1429 { /* MOV.L @(disp, Rm), Rn */
1430 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1431 tmp = sh4r.r[Rm] + disp;
1432 CHECKRALIGN32( tmp );
1433 sh4r.r[Rn] = MEM_READ_LONG( tmp );
1434 }
1435 break;
1436 case 0x6:
1437 switch( ir&0xF ) {
1438 case 0x0:
1439 { /* MOV.B @Rm, Rn */
1440 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1441 sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] );
1442 }
1443 break;
1444 case 0x1:
1445 { /* MOV.W @Rm, Rn */
1446 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1447 CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] );
1448 }
1449 break;
1450 case 0x2:
1451 { /* MOV.L @Rm, Rn */
1452 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1453 CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] );
1454 }
1455 break;
1456 case 0x3:
1457 { /* MOV Rm, Rn */
1458 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1459 sh4r.r[Rn] = sh4r.r[Rm];
1460 }
1461 break;
1462 case 0x4:
1463 { /* MOV.B @Rm+, Rn */
1464 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1465 sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] ); sh4r.r[Rm] ++;
1466 }
1467 break;
1468 case 0x5:
1469 { /* MOV.W @Rm+, Rn */
1470 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1471 CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] ); sh4r.r[Rm] += 2;
1472 }
1473 break;
1474 case 0x6:
1475 { /* MOV.L @Rm+, Rn */
1476 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1477 CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] ); sh4r.r[Rm] += 4;
1478 }
1479 break;
1480 case 0x7:
1481 { /* NOT Rm, Rn */
1482 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1483 sh4r.r[Rn] = ~sh4r.r[Rm];
1484 }
1485 break;
1486 case 0x8:
1487 { /* SWAP.B Rm, Rn */
1488 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1489 sh4r.r[Rn] = (sh4r.r[Rm]&0xFFFF0000) | ((sh4r.r[Rm]&0x0000FF00)>>8) | ((sh4r.r[Rm]&0x000000FF)<<8);
1490 }
1491 break;
1492 case 0x9:
1493 { /* SWAP.W Rm, Rn */
1494 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1495 sh4r.r[Rn] = (sh4r.r[Rm]>>16) | (sh4r.r[Rm]<<16);
1496 }
1497 break;
1498 case 0xA:
1499 { /* NEGC Rm, Rn */
1500 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1501 tmp = 0 - sh4r.r[Rm];
1502 sh4r.r[Rn] = tmp - sh4r.t;
1503 sh4r.t = ( 0<tmp || tmp<sh4r.r[Rn] ? 1 : 0 );
1504 }
1505 break;
1506 case 0xB:
1507 { /* NEG Rm, Rn */
1508 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1509 sh4r.r[Rn] = 0 - sh4r.r[Rm];
1510 }
1511 break;
1512 case 0xC:
1513 { /* EXTU.B Rm, Rn */
1514 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1515 sh4r.r[Rn] = sh4r.r[Rm]&0x000000FF;
1516 }
1517 break;
1518 case 0xD:
1519 { /* EXTU.W Rm, Rn */
1520 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1521 sh4r.r[Rn] = sh4r.r[Rm]&0x0000FFFF;
1522 }
1523 break;
1524 case 0xE:
1525 { /* EXTS.B Rm, Rn */
1526 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1527 sh4r.r[Rn] = SIGNEXT8( sh4r.r[Rm]&0x000000FF );
1528 }
1529 break;
1530 case 0xF:
1531 { /* EXTS.W Rm, Rn */
1532 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1533 sh4r.r[Rn] = SIGNEXT16( sh4r.r[Rm]&0x0000FFFF );
1534 }
1535 break;
1536 }
1537 break;
1538 case 0x7:
1539 { /* ADD #imm, Rn */
1540 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1541 sh4r.r[Rn] += imm;
1542 }
1543 break;
1544 case 0x8:
1545 switch( (ir&0xF00) >> 8 ) {
1546 case 0x0:
1547 { /* MOV.B R0, @(disp, Rn) */
1548 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1549 MEM_WRITE_BYTE( sh4r.r[Rn] + disp, R0 );
1550 }
1551 break;
1552 case 0x1:
1553 { /* MOV.W R0, @(disp, Rn) */
1554 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1555 tmp = sh4r.r[Rn] + disp;
1556 CHECKWALIGN16( tmp );
1557 MEM_WRITE_WORD( tmp, R0 );
1558 }
1559 break;
1560 case 0x4:
1561 { /* MOV.B @(disp, Rm), R0 */
1562 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1563 R0 = MEM_READ_BYTE( sh4r.r[Rm] + disp );
1564 }
1565 break;
1566 case 0x5:
1567 { /* MOV.W @(disp, Rm), R0 */
1568 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1569 tmp = sh4r.r[Rm] + disp;
1570 CHECKRALIGN16( tmp );
1571 R0 = MEM_READ_WORD( tmp );
1572 }
1573 break;
1574 case 0x8:
1575 { /* CMP/EQ #imm, R0 */
1576 int32_t imm = SIGNEXT8(ir&0xFF);
1577 sh4r.t = ( R0 == imm ? 1 : 0 );
1578 }
1579 break;
1580 case 0x9:
1581 { /* BT disp */
1582 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1583 CHECKSLOTILLEGAL();
1584 if( sh4r.t ) {
1585 CHECKDEST( sh4r.pc + disp + 4 )
1586 sh4r.pc += disp + 4;
1587 sh4r.new_pc = sh4r.pc + 2;
1588 return TRUE;
1589 }
1590 }
1591 break;
1592 case 0xB:
1593 { /* BF disp */
1594 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1595 CHECKSLOTILLEGAL();
1596 if( !sh4r.t ) {
1597 CHECKDEST( sh4r.pc + disp + 4 )
1598 sh4r.pc += disp + 4;
1599 sh4r.new_pc = sh4r.pc + 2;
1600 return TRUE;
1601 }
1602 }
1603 break;
1604 case 0xD:
1605 { /* BT/S disp */
1606 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1607 CHECKSLOTILLEGAL();
1608 if( sh4r.t ) {
1609 CHECKDEST( sh4r.pc + disp + 4 )
1610 sh4r.in_delay_slot = 1;
1611 sh4r.pc = sh4r.new_pc;
1612 sh4r.new_pc = pc + disp + 4;
1613 sh4r.in_delay_slot = 1;
1614 return TRUE;
1615 }
1616 }
1617 break;
1618 case 0xF:
1619 { /* BF/S disp */
1620 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1621 CHECKSLOTILLEGAL();
1622 if( !sh4r.t ) {
1623 CHECKDEST( sh4r.pc + disp + 4 )
1624 sh4r.in_delay_slot = 1;
1625 sh4r.pc = sh4r.new_pc;
1626 sh4r.new_pc = pc + disp + 4;
1627 return TRUE;
1628 }
1629 }
1630 break;
1631 default:
1632 UNDEF();
1633 break;
1634 }
1635 break;
1636 case 0x9:
1637 { /* MOV.W @(disp, PC), Rn */
1638 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
1639 CHECKSLOTILLEGAL();
1640 tmp = pc + 4 + disp;
1641 sh4r.r[Rn] = MEM_READ_WORD( tmp );
1642 }
1643 break;
1644 case 0xA:
1645 { /* BRA disp */
1646 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1647 CHECKSLOTILLEGAL();
1648 CHECKDEST( sh4r.pc + disp + 4 );
1649 sh4r.in_delay_slot = 1;
1650 sh4r.pc = sh4r.new_pc;
1651 sh4r.new_pc = pc + 4 + disp;
1652 return TRUE;
1653 }
1654 break;
1655 case 0xB:
1656 { /* BSR disp */
1657 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1658 CHECKDEST( sh4r.pc + disp + 4 );
1659 CHECKSLOTILLEGAL();
1660 sh4r.in_delay_slot = 1;
1661 sh4r.pr = pc + 4;
1662 sh4r.pc = sh4r.new_pc;
1663 sh4r.new_pc = pc + 4 + disp;
1664 TRACE_CALL( pc, sh4r.new_pc );
1665 return TRUE;
1666 }
1667 break;
1668 case 0xC:
1669 switch( (ir&0xF00) >> 8 ) {
1670 case 0x0:
1671 { /* MOV.B R0, @(disp, GBR) */
1672 uint32_t disp = (ir&0xFF);
1673 MEM_WRITE_BYTE( sh4r.gbr + disp, R0 );
1674 }
1675 break;
1676 case 0x1:
1677 { /* MOV.W R0, @(disp, GBR) */
1678 uint32_t disp = (ir&0xFF)<<1;
1679 tmp = sh4r.gbr + disp;
1680 CHECKWALIGN16( tmp );
1681 MEM_WRITE_WORD( tmp, R0 );
1682 }
1683 break;
1684 case 0x2:
1685 { /* MOV.L R0, @(disp, GBR) */
1686 uint32_t disp = (ir&0xFF)<<2;
1687 tmp = sh4r.gbr + disp;
1688 CHECKWALIGN32( tmp );
1689 MEM_WRITE_LONG( tmp, R0 );
1690 }
1691 break;
1692 case 0x3:
1693 { /* TRAPA #imm */
1694 uint32_t imm = (ir&0xFF);
1695 CHECKSLOTILLEGAL();
1696 MMIO_WRITE( MMU, TRA, imm<<2 );
1697 sh4r.pc += 2;
1698 sh4_raise_exception( EXC_TRAP );
1699 }
1700 break;
1701 case 0x4:
1702 { /* MOV.B @(disp, GBR), R0 */
1703 uint32_t disp = (ir&0xFF);
1704 R0 = MEM_READ_BYTE( sh4r.gbr + disp );
1705 }
1706 break;
1707 case 0x5:
1708 { /* MOV.W @(disp, GBR), R0 */
1709 uint32_t disp = (ir&0xFF)<<1;
1710 tmp = sh4r.gbr + disp;
1711 CHECKRALIGN16( tmp );
1712 R0 = MEM_READ_WORD( tmp );
1713 }
1714 break;
1715 case 0x6:
1716 { /* MOV.L @(disp, GBR), R0 */
1717 uint32_t disp = (ir&0xFF)<<2;
1718 tmp = sh4r.gbr + disp;
1719 CHECKRALIGN32( tmp );
1720 R0 = MEM_READ_LONG( tmp );
1721 }
1722 break;
1723 case 0x7:
1724 { /* MOVA @(disp, PC), R0 */
1725 uint32_t disp = (ir&0xFF)<<2;
1726 CHECKSLOTILLEGAL();
1727 R0 = (pc&0xFFFFFFFC) + disp + 4;
1728 }
1729 break;
1730 case 0x8:
1731 { /* TST #imm, R0 */
1732 uint32_t imm = (ir&0xFF);
1733 sh4r.t = (R0 & imm ? 0 : 1);
1734 }
1735 break;
1736 case 0x9:
1737 { /* AND #imm, R0 */
1738 uint32_t imm = (ir&0xFF);
1739 R0 &= imm;
1740 }
1741 break;
1742 case 0xA:
1743 { /* XOR #imm, R0 */
1744 uint32_t imm = (ir&0xFF);
1745 R0 ^= imm;
1746 }
1747 break;
1748 case 0xB:
1749 { /* OR #imm, R0 */
1750 uint32_t imm = (ir&0xFF);
1751 R0 |= imm;
1752 }
1753 break;
1754 case 0xC:
1755 { /* TST.B #imm, @(R0, GBR) */
1756 uint32_t imm = (ir&0xFF);
1757 sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & imm ? 0 : 1 );
1758 }
1759 break;
1760 case 0xD:
1761 { /* AND.B #imm, @(R0, GBR) */
1762 uint32_t imm = (ir&0xFF);
1763 MEM_WRITE_BYTE( R0 + sh4r.gbr, imm & MEM_READ_BYTE(R0 + sh4r.gbr) );
1764 }
1765 break;
1766 case 0xE:
1767 { /* XOR.B #imm, @(R0, GBR) */
1768 uint32_t imm = (ir&0xFF);
1769 MEM_WRITE_BYTE( R0 + sh4r.gbr, imm ^ MEM_READ_BYTE(R0 + sh4r.gbr) );
1770 }
1771 break;
1772 case 0xF:
1773 { /* OR.B #imm, @(R0, GBR) */
1774 uint32_t imm = (ir&0xFF);
1775 MEM_WRITE_BYTE( R0 + sh4r.gbr, imm | MEM_READ_BYTE(R0 + sh4r.gbr) );
1776 }
1777 break;
1778 }
1779 break;
1780 case 0xD:
1781 { /* MOV.L @(disp, PC), Rn */
1782 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
1783 CHECKSLOTILLEGAL();
1784 tmp = (pc&0xFFFFFFFC) + disp + 4;
1785 sh4r.r[Rn] = MEM_READ_LONG( tmp );
1786 }
1787 break;
1788 case 0xE:
1789 { /* MOV #imm, Rn */
1790 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1791 sh4r.r[Rn] = imm;
1792 }
1793 break;
1794 case 0xF:
1795 switch( ir&0xF ) {
1796 case 0x0:
1797 { /* FADD FRm, FRn */
1798 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1799 CHECKFPUEN();
1800 if( IS_FPU_DOUBLEPREC() ) {
1801 DR(FRn) += DR(FRm);
1802 } else {
1803 FR(FRn) += FR(FRm);
1804 }
1805 }
1806 break;
1807 case 0x1:
1808 { /* FSUB FRm, FRn */
1809 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1810 CHECKFPUEN();
1811 if( IS_FPU_DOUBLEPREC() ) {
1812 DR(FRn) -= DR(FRm);
1813 } else {
1814 FR(FRn) -= FR(FRm);
1815 }
1816 }
1817 break;
1818 case 0x2:
1819 { /* FMUL FRm, FRn */
1820 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1821 CHECKFPUEN();
1822 if( IS_FPU_DOUBLEPREC() ) {
1823 DR(FRn) *= DR(FRm);
1824 } else {
1825 FR(FRn) *= FR(FRm);
1826 }
1827 }
1828 break;
1829 case 0x3:
1830 { /* FDIV FRm, FRn */
1831 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1832 CHECKFPUEN();
1833 if( IS_FPU_DOUBLEPREC() ) {
1834 DR(FRn) /= DR(FRm);
1835 } else {
1836 FR(FRn) /= FR(FRm);
1837 }
1838 }
1839 break;
1840 case 0x4:
1841 { /* FCMP/EQ FRm, FRn */
1842 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1843 CHECKFPUEN();
1844 if( IS_FPU_DOUBLEPREC() ) {
1845 sh4r.t = ( DR(FRn) == DR(FRm) ? 1 : 0 );
1846 } else {
1847 sh4r.t = ( FR(FRn) == FR(FRm) ? 1 : 0 );
1848 }
1849 }
1850 break;
1851 case 0x5:
1852 { /* FCMP/GT FRm, FRn */
1853 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1854 CHECKFPUEN();
1855 if( IS_FPU_DOUBLEPREC() ) {
1856 sh4r.t = ( DR(FRn) > DR(FRm) ? 1 : 0 );
1857 } else {
1858 sh4r.t = ( FR(FRn) > FR(FRm) ? 1 : 0 );
1859 }
1860 }
1861 break;
1862 case 0x6:
1863 { /* FMOV @(R0, Rm), FRn */
1864 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1865 MEM_FP_READ( sh4r.r[Rm] + R0, FRn );
1866 }
1867 break;
1868 case 0x7:
1869 { /* FMOV FRm, @(R0, Rn) */
1870 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1871 MEM_FP_WRITE( sh4r.r[Rn] + R0, FRm );
1872 }
1873 break;
1874 case 0x8:
1875 { /* FMOV @Rm, FRn */
1876 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1877 MEM_FP_READ( sh4r.r[Rm], FRn );
1878 }
1879 break;
1880 case 0x9:
1881 { /* FMOV @Rm+, FRn */
1882 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1883 MEM_FP_READ( sh4r.r[Rm], FRn ); sh4r.r[Rm] += FP_WIDTH;
1884 }
1885 break;
1886 case 0xA:
1887 { /* FMOV FRm, @Rn */
1888 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1889 MEM_FP_WRITE( sh4r.r[Rn], FRm );
1890 }
1891 break;
1892 case 0xB:
1893 { /* FMOV FRm, @-Rn */
1894 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1895 sh4r.r[Rn] -= FP_WIDTH; MEM_FP_WRITE( sh4r.r[Rn], FRm );
1896 }
1897 break;
1898 case 0xC:
1899 { /* FMOV FRm, FRn */
1900 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1901 if( IS_FPU_DOUBLESIZE() )
1902 DR(FRn) = DR(FRm);
1903 else
1904 FR(FRn) = FR(FRm);
1905 }
1906 break;
1907 case 0xD:
1908 switch( (ir&0xF0) >> 4 ) {
1909 case 0x0:
1910 { /* FSTS FPUL, FRn */
1911 uint32_t FRn = ((ir>>8)&0xF);
1912 CHECKFPUEN(); FR(FRn) = FPULf;
1913 }
1914 break;
1915 case 0x1:
1916 { /* FLDS FRm, FPUL */
1917 uint32_t FRm = ((ir>>8)&0xF);
1918 CHECKFPUEN(); FPULf = FR(FRm);
1919 }
1920 break;
1921 case 0x2:
1922 { /* FLOAT FPUL, FRn */
1923 uint32_t FRn = ((ir>>8)&0xF);
1924 CHECKFPUEN();
1925 if( IS_FPU_DOUBLEPREC() ) {
1926 if( FRn&1 ) { // No, really...
1927 dtmp = (double)FPULi;
1928 FR(FRn) = *(((float *)&dtmp)+1);
1929 } else {
1930 DRF(FRn>>1) = (double)FPULi;
1931 }
1932 } else {
1933 FR(FRn) = (float)FPULi;
1934 }
1935 }
1936 break;
1937 case 0x3:
1938 { /* FTRC FRm, FPUL */
1939 uint32_t FRm = ((ir>>8)&0xF);
1940 CHECKFPUEN();
1941 if( IS_FPU_DOUBLEPREC() ) {
1942 if( FRm&1 ) {
1943 dtmp = 0;
1944 *(((float *)&dtmp)+1) = FR(FRm);
1945 } else {
1946 dtmp = DRF(FRm>>1);
1947 }
1948 if( dtmp >= MAX_INTF )
1949 FPULi = MAX_INT;
1950 else if( dtmp <= MIN_INTF )
1951 FPULi = MIN_INT;
1952 else
1953 FPULi = (int32_t)dtmp;
1954 } else {
1955 ftmp = FR(FRm);
1956 if( ftmp >= MAX_INTF )
1957 FPULi = MAX_INT;
1958 else if( ftmp <= MIN_INTF )
1959 FPULi = MIN_INT;
1960 else
1961 FPULi = (int32_t)ftmp;
1962 }
1963 }
1964 break;
1965 case 0x4:
1966 { /* FNEG FRn */
1967 uint32_t FRn = ((ir>>8)&0xF);
1968 CHECKFPUEN();
1969 if( IS_FPU_DOUBLEPREC() ) {
1970 DR(FRn) = -DR(FRn);
1971 } else {
1972 FR(FRn) = -FR(FRn);
1973 }
1974 }
1975 break;
1976 case 0x5:
1977 { /* FABS FRn */
1978 uint32_t FRn = ((ir>>8)&0xF);
1979 CHECKFPUEN();
1980 if( IS_FPU_DOUBLEPREC() ) {
1981 DR(FRn) = fabs(DR(FRn));
1982 } else {
1983 FR(FRn) = fabsf(FR(FRn));
1984 }
1985 }
1986 break;
1987 case 0x6:
1988 { /* FSQRT FRn */
1989 uint32_t FRn = ((ir>>8)&0xF);
1990 CHECKFPUEN();
1991 if( IS_FPU_DOUBLEPREC() ) {
1992 DR(FRn) = sqrt(DR(FRn));
1993 } else {
1994 FR(FRn) = sqrtf(FR(FRn));
1995 }
1996 }
1997 break;
1998 case 0x7:
1999 { /* FSRRA FRn */
2000 uint32_t FRn = ((ir>>8)&0xF);
2001 CHECKFPUEN();
2002 if( !IS_FPU_DOUBLEPREC() ) {
2003 FR(FRn) = 1.0/sqrtf(FR(FRn));
2004 }
2005 }
2006 break;
2007 case 0x8:
2008 { /* FLDI0 FRn */
2009 uint32_t FRn = ((ir>>8)&0xF);
2010 CHECKFPUEN();
2011 if( IS_FPU_DOUBLEPREC() ) {
2012 DR(FRn) = 0.0;
2013 } else {
2014 FR(FRn) = 0.0;
2015 }
2016 }
2017 break;
2018 case 0x9:
2019 { /* FLDI1 FRn */
2020 uint32_t FRn = ((ir>>8)&0xF);
2021 CHECKFPUEN();
2022 if( IS_FPU_DOUBLEPREC() ) {
2023 DR(FRn) = 1.0;
2024 } else {
2025 FR(FRn) = 1.0;
2026 }
2027 }
2028 break;
2029 case 0xA:
2030 { /* FCNVSD FPUL, FRn */
2031 uint32_t FRn = ((ir>>8)&0xF);
2032 CHECKFPUEN();
2033 if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
2034 DR(FRn) = (double)FPULf;
2035 }
2036 }
2037 break;
2038 case 0xB:
2039 { /* FCNVDS FRm, FPUL */
2040 uint32_t FRm = ((ir>>8)&0xF);
2041 CHECKFPUEN();
2042 if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
2043 FPULf = (float)DR(FRm);
2044 }
2045 }
2046 break;
2047 case 0xE:
2048 { /* FIPR FVm, FVn */
2049 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
2050 CHECKFPUEN();
2051 if( !IS_FPU_DOUBLEPREC() ) {
2052 int tmp2 = FVn<<2;
2053 tmp = FVm<<2;
2054 FR(tmp2+3) = FR(tmp)*FR(tmp2) +
2055 FR(tmp+1)*FR(tmp2+1) +
2056 FR(tmp+2)*FR(tmp2+2) +
2057 FR(tmp+3)*FR(tmp2+3);
2058 }
2059 }
2060 break;
2061 case 0xF:
2062 switch( (ir&0x100) >> 8 ) {
2063 case 0x0:
2064 { /* FSCA FPUL, FRn */
2065 uint32_t FRn = ((ir>>9)&0x7)<<1;
2066 CHECKFPUEN();
2067 if( !IS_FPU_DOUBLEPREC() ) {
2068 sh4_fsca( FPULi, &(DRF(FRn>>1)) );
2069 /*
2070 float angle = (((float)(FPULi&0xFFFF))/65536.0) * 2 * M_PI;
2071 FR(FRn) = sinf(angle);
2072 FR((FRn)+1) = cosf(angle);
2073 */
2074 }
2075 }
2076 break;
2077 case 0x1:
2078 switch( (ir&0x200) >> 9 ) {
2079 case 0x0:
2080 { /* FTRV XMTRX, FVn */
2081 uint32_t FVn = ((ir>>10)&0x3);
2082 CHECKFPUEN();
2083 if( !IS_FPU_DOUBLEPREC() ) {
2084 sh4_ftrv(&(DRF(FVn<<1)), &sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21][0]);
2085 /*
2086 tmp = FVn<<2;
2087 float *xf = &sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21][0];
2088 float fv[4] = { FR(tmp), FR(tmp+1), FR(tmp+2), FR(tmp+3) };
2089 FR(tmp) = xf[1] * fv[0] + xf[5]*fv[1] +
2090 xf[9]*fv[2] + xf[13]*fv[3];
2091 FR(tmp+1) = xf[0] * fv[0] + xf[4]*fv[1] +
2092 xf[8]*fv[2] + xf[12]*fv[3];
2093 FR(tmp+2) = xf[3] * fv[0] + xf[7]*fv[1] +
2094 xf[11]*fv[2] + xf[15]*fv[3];
2095 FR(tmp+3) = xf[2] * fv[0] + xf[6]*fv[1] +
2096 xf[10]*fv[2] + xf[14]*fv[3];
2097 */
2098 }
2099 }
2100 break;
2101 case 0x1:
2102 switch( (ir&0xC00) >> 10 ) {
2103 case 0x0:
2104 { /* FSCHG */
2105 CHECKFPUEN(); sh4r.fpscr ^= FPSCR_SZ;
2106 }
2107 break;
2108 case 0x2:
2109 { /* FRCHG */
2110 CHECKFPUEN();
2111 sh4r.fpscr ^= FPSCR_FR;
2112 sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
2113 }
2114 break;
2115 case 0x3:
2116 { /* UNDEF */
2117 UNDEF(ir);
2118 }
2119 break;
2120 default:
2121 UNDEF();
2122 break;
2123 }
2124 break;
2125 }
2126 break;
2127 }
2128 break;
2129 default:
2130 UNDEF();
2131 break;
2132 }
2133 break;
2134 case 0xE:
2135 { /* FMAC FR0, FRm, FRn */
2136 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2137 CHECKFPUEN();
2138 if( IS_FPU_DOUBLEPREC() ) {
2139 DR(FRn) += DR(FRm)*DR(0);
2140 } else {
2141 FR(FRn) += FR(FRm)*FR(0);
2142 }
2143 }
2144 break;
2145 default:
2146 UNDEF();
2147 break;
2148 }
2149 break;
2150 }
2152 sh4r.pc = sh4r.new_pc;
2153 sh4r.new_pc += 2;
2154 sh4r.in_delay_slot = 0;
2155 return TRUE;
2156 }
.