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