2 * $Id: sh4core.c,v 1.48 2007-09-20 08:37:19 nkeynes Exp $
4 * SH4 emulation core, and parent module for all the SH4 peripheral
7 * Copyright (c) 2005 Nathan Keynes.
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.
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.
20 #define MODULE sh4_module
23 #include "sh4/sh4core.h"
24 #include "sh4/sh4mmio.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 )
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;
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 ) {
60 /* Eventq execute may (quite likely) deliver an immediate IRQ */
61 if( sh4r.event_types & PENDING_IRQ ) {
62 sh4_accept_interrupt();
65 if( !sh4_execute_instruction() ) {
70 for( ;sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
71 if( SH4_EVENT_PENDING() ) {
72 if( sh4r.event_types & PENDING_EVENT ) {
75 /* Eventq execute may (quite likely) deliver an immediate IRQ */
76 if( sh4r.event_types & PENDING_IRQ ) {
77 sh4_accept_interrupt();
81 if( !sh4_execute_instruction() )
83 #ifdef ENABLE_DEBUG_MODE
84 for( i=0; i<sh4_breakpoint_count; i++ ) {
85 if( sh4_breakpoints[i].address == sh4r.pc ) {
89 if( i != sh4_breakpoint_count ) {
91 if( sh4_breakpoints[i].type == BREAK_ONESHOT )
92 sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );
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
103 if( sh4r.slice_cycle != nanosecs && sh4r.sh4_state == SH4_STATE_RUNNING ) {
104 nanosecs = sh4r.slice_cycle;
106 if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
107 TMU_run_slice( nanosecs );
108 SCIF_run_slice( nanosecs );
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 {
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 )
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];
139 static inline trace_return( sh4addr_t source, sh4addr_t dest )
141 if( call_stack_depth > 0 ) {
146 void fprint_stack_trace( FILE *f )
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 );
158 #define TRACE_CALL( source, dest ) trace_call(source, dest)
159 #define TRACE_RETURN( source, dest ) trace_return(source, dest)
161 #define TRACE_CALL( dest, rts )
162 #define TRACE_RETURN( source, dest )
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 )
189 if( IS_FPU_DOUBLESIZE() ) {
191 sh4_write_long( addr, *((uint32_t *)&XF((reg)&0x0E)) );
192 sh4_write_long( addr+4, *((uint32_t *)&XF(reg)) );
194 sh4_write_long( addr, *((uint32_t *)&FR(reg)) );
195 sh4_write_long( addr+4, *((uint32_t *)&FR((reg)|0x01)) );
198 sh4_write_long( addr, *((uint32_t *)&FR((reg))) );
202 static void sh4_read_float( uint32_t addr, int reg )
204 if( IS_FPU_DOUBLESIZE() ) {
206 *((uint32_t *)&XF((reg) & 0x0E)) = sh4_read_long(addr);
207 *((uint32_t *)&XF(reg)) = sh4_read_long(addr+4);
209 *((uint32_t *)&FR(reg)) = sh4_read_long(addr);
210 *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(addr+4);
213 *((uint32_t *)&FR(reg)) = sh4_read_long(addr);
217 gboolean sh4_execute_instruction( void )
227 if( pc > 0xFFFFFF00 ) {
229 syscall_invoke( pc );
230 sh4r.in_delay_slot = 0;
231 pc = sh4r.pc = sh4r.pr;
232 sh4r.new_pc = sh4r.pc + 2;
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];
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
247 ir = MEM_READ_WORD(pc);
249 sh4_icache_addr = pageaddr;
250 ir = sh4_icache[(pc&0xFFF)>>1];
253 switch( (ir&0xF000) >> 12 ) {
257 switch( (ir&0x80) >> 7 ) {
259 switch( (ir&0x70) >> 4 ) {
262 uint32_t Rn = ((ir>>8)&0xF);
264 sh4r.r[Rn] = sh4_read_sr();
269 uint32_t Rn = ((ir>>8)&0xF);
271 sh4r.r[Rn] = sh4r.gbr;
276 uint32_t Rn = ((ir>>8)&0xF);
278 sh4r.r[Rn] = sh4r.vbr;
283 uint32_t Rn = ((ir>>8)&0xF);
285 sh4r.r[Rn] = sh4r.ssr;
290 uint32_t Rn = ((ir>>8)&0xF);
292 sh4r.r[Rn] = sh4r.spc;
301 { /* STC Rm_BANK, Rn */
302 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
304 sh4r.r[Rn] = sh4r.r_bank[Rm_BANK];
310 switch( (ir&0xF0) >> 4 ) {
313 uint32_t Rn = ((ir>>8)&0xF);
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 );
326 uint32_t Rn = ((ir>>8)&0xF);
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];
337 uint32_t Rn = ((ir>>8)&0xF);
339 if( (tmp & 0xFC000000) == 0xE0000000 ) {
340 sh4_flush_store_queue(tmp);
346 uint32_t Rn = ((ir>>8)&0xF);
351 uint32_t Rn = ((ir>>8)&0xF);
356 uint32_t Rn = ((ir>>8)&0xF);
360 { /* MOVCA.L R0, @Rn */
361 uint32_t Rn = ((ir>>8)&0xF);
364 MEM_WRITE_LONG( tmp, R0 );
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] );
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] );
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] );
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]);
400 switch( (ir&0xFF0) >> 4 ) {
437 switch( (ir&0xF0) >> 4 ) {
445 sh4r.m = sh4r.q = sh4r.t = 0;
450 uint32_t Rn = ((ir>>8)&0xF);
460 switch( (ir&0xF0) >> 4 ) {
463 uint32_t Rn = ((ir>>8)&0xF);
464 sh4r.r[Rn] = (sh4r.mac>>32);
469 uint32_t Rn = ((ir>>8)&0xF);
470 sh4r.r[Rn] = (uint32_t)sh4r.mac;
475 uint32_t Rn = ((ir>>8)&0xF);
476 sh4r.r[Rn] = sh4r.pr;
481 uint32_t Rn = ((ir>>8)&0xF);
483 sh4r.r[Rn] = sh4r.sgr;
488 uint32_t Rn = ((ir>>8)&0xF);
489 sh4r.r[Rn] = sh4r.fpul;
493 { /* STS FPSCR, Rn */
494 uint32_t Rn = ((ir>>8)&0xF);
495 sh4r.r[Rn] = sh4r.fpscr;
500 uint32_t Rn = ((ir>>8)&0xF);
501 CHECKPRIV(); sh4r.r[Rn] = sh4r.dbr;
510 switch( (ir&0xFF0) >> 4 ) {
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 );
524 if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
525 sh4r.sh4_state = SH4_STATE_STANDBY;
527 sh4r.sh4_state = SH4_STATE_SLEEP;
529 return FALSE; /* Halt CPU */
535 CHECKDEST( sh4r.spc );
537 sh4r.in_delay_slot = 1;
538 sh4r.pc = sh4r.new_pc;
539 sh4r.new_pc = sh4r.spc;
540 sh4_write_sr( sh4r.ssr );
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] );
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] );
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] );
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]));
576 tmpl = tmpl * SIGNEXT32(MEM_READ_LONG(sh4r.r[Rm])) + sh4r.mac;
579 /* 48-bit Saturation. Yuch */
580 if( tmpl < (int64_t)0xFFFF800000000000LL )
581 tmpl = 0xFFFF800000000000LL;
582 else if( tmpl > (int64_t)0x00007FFFFFFFFFFFLL )
583 tmpl = 0x00007FFFFFFFFFFFLL;
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] );
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] );
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] );
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] );
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] );
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] );
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] );
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;
649 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
650 sh4r.t = (sh4r.r[Rn]&sh4r.r[Rm] ? 0 : 1);
655 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
656 sh4r.r[Rn] &= sh4r.r[Rm];
661 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
662 sh4r.r[Rn] ^= sh4r.r[Rm];
667 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
668 sh4r.r[Rn] |= sh4r.r[Rm];
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;
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);
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));
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));
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 );
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 );
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 );
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);
734 sh4r.r[Rn] = (sh4r.r[Rn] << 1) | sh4r.t;
738 tmp1 = (sh4r.r[Rn]<tmp0 ? 1 : 0 );
741 tmp1 = (sh4r.r[Rn]>tmp0 ? 1 : 0 );
743 sh4r.q ^= sh4r.m ^ tmp1;
744 sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );
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]);
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 );
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 );
767 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
768 sh4r.r[Rn] -= sh4r.r[Rm];
773 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
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));
780 UNIMP(ir); /* SUBV Rm, Rn */
784 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
785 sh4r.r[Rn] += sh4r.r[Rm];
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]);
796 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
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 );
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)) );
818 switch( (ir&0xF0) >> 4 ) {
821 uint32_t Rn = ((ir>>8)&0xF);
822 sh4r.t = sh4r.r[Rn] >> 31; sh4r.r[Rn] <<= 1;
827 uint32_t Rn = ((ir>>8)&0xF);
829 sh4r.t = ( sh4r.r[Rn] == 0 ? 1 : 0 );
834 uint32_t Rn = ((ir>>8)&0xF);
835 sh4r.t = sh4r.r[Rn] >> 31;
845 switch( (ir&0xF0) >> 4 ) {
848 uint32_t Rn = ((ir>>8)&0xF);
849 sh4r.t = sh4r.r[Rn] & 0x00000001; sh4r.r[Rn] >>= 1;
854 uint32_t Rn = ((ir>>8)&0xF);
855 sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= 0 ? 1 : 0 );
860 uint32_t Rn = ((ir>>8)&0xF);
861 sh4r.t = sh4r.r[Rn] & 0x00000001;
862 sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 1;
871 switch( (ir&0xF0) >> 4 ) {
873 { /* STS.L MACH, @-Rn */
874 uint32_t Rn = ((ir>>8)&0xF);
876 CHECKWALIGN32( sh4r.r[Rn] );
877 MEM_WRITE_LONG( sh4r.r[Rn], (sh4r.mac>>32) );
881 { /* STS.L MACL, @-Rn */
882 uint32_t Rn = ((ir>>8)&0xF);
884 CHECKWALIGN32( sh4r.r[Rn] );
885 MEM_WRITE_LONG( sh4r.r[Rn], (uint32_t)sh4r.mac );
889 { /* STS.L PR, @-Rn */
890 uint32_t Rn = ((ir>>8)&0xF);
892 CHECKWALIGN32( sh4r.r[Rn] );
893 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.pr );
897 { /* STC.L SGR, @-Rn */
898 uint32_t Rn = ((ir>>8)&0xF);
901 CHECKWALIGN32( sh4r.r[Rn] );
902 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.sgr );
906 { /* STS.L FPUL, @-Rn */
907 uint32_t Rn = ((ir>>8)&0xF);
909 CHECKWALIGN32( sh4r.r[Rn] );
910 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpul );
914 { /* STS.L FPSCR, @-Rn */
915 uint32_t Rn = ((ir>>8)&0xF);
917 CHECKWALIGN32( sh4r.r[Rn] );
918 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpscr );
922 { /* STC.L DBR, @-Rn */
923 uint32_t Rn = ((ir>>8)&0xF);
926 CHECKWALIGN32( sh4r.r[Rn] );
927 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.dbr );
936 switch( (ir&0x80) >> 7 ) {
938 switch( (ir&0x70) >> 4 ) {
940 { /* STC.L SR, @-Rn */
941 uint32_t Rn = ((ir>>8)&0xF);
944 CHECKWALIGN32( sh4r.r[Rn] );
945 MEM_WRITE_LONG( sh4r.r[Rn], sh4_read_sr() );
949 { /* STC.L GBR, @-Rn */
950 uint32_t Rn = ((ir>>8)&0xF);
952 CHECKWALIGN32( sh4r.r[Rn] );
953 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.gbr );
957 { /* STC.L VBR, @-Rn */
958 uint32_t Rn = ((ir>>8)&0xF);
961 CHECKWALIGN32( sh4r.r[Rn] );
962 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.vbr );
966 { /* STC.L SSR, @-Rn */
967 uint32_t Rn = ((ir>>8)&0xF);
970 CHECKWALIGN32( sh4r.r[Rn] );
971 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.ssr );
975 { /* STC.L SPC, @-Rn */
976 uint32_t Rn = ((ir>>8)&0xF);
979 CHECKWALIGN32( sh4r.r[Rn] );
980 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.spc );
989 { /* STC.L Rm_BANK, @-Rn */
990 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
993 CHECKWALIGN32( sh4r.r[Rn] );
994 MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r_bank[Rm_BANK] );
1000 switch( (ir&0xF0) >> 4 ) {
1003 uint32_t Rn = ((ir>>8)&0xF);
1004 sh4r.t = sh4r.r[Rn] >> 31;
1006 sh4r.r[Rn] |= sh4r.t;
1011 uint32_t Rn = ((ir>>8)&0xF);
1012 tmp = sh4r.r[Rn] >> 31;
1014 sh4r.r[Rn] |= sh4r.t;
1024 switch( (ir&0xF0) >> 4 ) {
1027 uint32_t Rn = ((ir>>8)&0xF);
1028 sh4r.t = sh4r.r[Rn] & 0x00000001;
1030 sh4r.r[Rn] |= (sh4r.t << 31);
1035 uint32_t Rn = ((ir>>8)&0xF);
1036 sh4r.t = ( ((int32_t)sh4r.r[Rn]) > 0 ? 1 : 0 );
1041 uint32_t Rn = ((ir>>8)&0xF);
1042 tmp = sh4r.r[Rn] & 0x00000001;
1044 sh4r.r[Rn] |= (sh4r.t << 31 );
1054 switch( (ir&0xF0) >> 4 ) {
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);
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]));
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] );
1082 { /* LDC.L @Rm+, SGR */
1083 uint32_t Rm = ((ir>>8)&0xF);
1085 CHECKRALIGN32( sh4r.r[Rm] );
1086 sh4r.sgr = MEM_READ_LONG(sh4r.r[Rm]);
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]);
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]);
1104 sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
1108 { /* LDC.L @Rm+, DBR */
1109 uint32_t Rm = ((ir>>8)&0xF);
1111 CHECKRALIGN32( sh4r.r[Rm] );
1112 sh4r.dbr = MEM_READ_LONG(sh4r.r[Rm]);
1122 switch( (ir&0x80) >> 7 ) {
1124 switch( (ir&0x70) >> 4 ) {
1126 { /* LDC.L @Rm+, SR */
1127 uint32_t Rm = ((ir>>8)&0xF);
1130 CHECKWALIGN32( sh4r.r[Rm] );
1131 sh4_write_sr( MEM_READ_LONG(sh4r.r[Rm]) );
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]);
1144 { /* LDC.L @Rm+, VBR */
1145 uint32_t Rm = ((ir>>8)&0xF);
1147 CHECKRALIGN32( sh4r.r[Rm] );
1148 sh4r.vbr = MEM_READ_LONG(sh4r.r[Rm]);
1153 { /* LDC.L @Rm+, SSR */
1154 uint32_t Rm = ((ir>>8)&0xF);
1156 CHECKRALIGN32( sh4r.r[Rm] );
1157 sh4r.ssr = MEM_READ_LONG(sh4r.r[Rm]);
1162 { /* LDC.L @Rm+, SPC */
1163 uint32_t Rm = ((ir>>8)&0xF);
1165 CHECKRALIGN32( sh4r.r[Rm] );
1166 sh4r.spc = MEM_READ_LONG(sh4r.r[Rm]);
1176 { /* LDC.L @Rm+, Rn_BANK */
1177 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1179 CHECKRALIGN32( sh4r.r[Rm] );
1180 sh4r.r_bank[Rn_BANK] = MEM_READ_LONG( sh4r.r[Rm] );
1187 switch( (ir&0xF0) >> 4 ) {
1190 uint32_t Rn = ((ir>>8)&0xF);
1196 uint32_t Rn = ((ir>>8)&0xF);
1202 uint32_t Rn = ((ir>>8)&0xF);
1212 switch( (ir&0xF0) >> 4 ) {
1215 uint32_t Rn = ((ir>>8)&0xF);
1221 uint32_t Rn = ((ir>>8)&0xF);
1227 uint32_t Rn = ((ir>>8)&0xF);
1237 switch( (ir&0xF0) >> 4 ) {
1239 { /* LDS Rm, MACH */
1240 uint32_t Rm = ((ir>>8)&0xF);
1241 sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1242 (((uint64_t)sh4r.r[Rm])<<32);
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]));
1254 uint32_t Rm = ((ir>>8)&0xF);
1255 sh4r.pr = sh4r.r[Rm];
1260 uint32_t Rm = ((ir>>8)&0xF);
1262 sh4r.sgr = sh4r.r[Rm];
1266 { /* LDS Rm, FPUL */
1267 uint32_t Rm = ((ir>>8)&0xF);
1268 sh4r.fpul = sh4r.r[Rm];
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];
1280 uint32_t Rm = ((ir>>8)&0xF);
1282 sh4r.dbr = sh4r.r[Rm];
1291 switch( (ir&0xF0) >> 4 ) {
1294 uint32_t Rn = ((ir>>8)&0xF);
1295 CHECKDEST( sh4r.r[Rn] );
1297 sh4r.in_delay_slot = 1;
1298 sh4r.pc = sh4r.new_pc;
1299 sh4r.new_pc = sh4r.r[Rn];
1301 TRACE_CALL( pc, sh4r.new_pc );
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 );
1315 uint32_t Rn = ((ir>>8)&0xF);
1316 CHECKDEST( sh4r.r[Rn] );
1318 sh4r.in_delay_slot = 1;
1319 sh4r.pc = sh4r.new_pc;
1320 sh4r.new_pc = sh4r.r[Rn];
1331 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
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;
1337 sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> (((~sh4r.r[Rm]) & 0x1F)+1);
1342 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
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);
1350 switch( (ir&0x80) >> 7 ) {
1352 switch( (ir&0x70) >> 4 ) {
1355 uint32_t Rm = ((ir>>8)&0xF);
1358 sh4_write_sr( sh4r.r[Rm] );
1363 uint32_t Rm = ((ir>>8)&0xF);
1364 sh4r.gbr = sh4r.r[Rm];
1369 uint32_t Rm = ((ir>>8)&0xF);
1371 sh4r.vbr = sh4r.r[Rm];
1376 uint32_t Rm = ((ir>>8)&0xF);
1378 sh4r.ssr = sh4r.r[Rm];
1383 uint32_t Rm = ((ir>>8)&0xF);
1385 sh4r.spc = sh4r.r[Rm];
1394 { /* LDC Rm, Rn_BANK */
1395 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1397 sh4r.r_bank[Rn_BANK] = sh4r.r[Rm];
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]));
1409 stmp = stmp * SIGNEXT16(MEM_READ_WORD(sh4r.r[Rm]));
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;
1418 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1419 ((uint32_t)(sh4r.mac + stmp));
1422 sh4r.mac += SIGNEXT32(stmp);
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 );
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] );
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] );
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] );
1458 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1459 sh4r.r[Rn] = sh4r.r[Rm];
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] ++;
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;
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;
1482 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1483 sh4r.r[Rn] = ~sh4r.r[Rm];
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);
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);
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 );
1508 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1509 sh4r.r[Rn] = 0 - sh4r.r[Rm];
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;
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;
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 );
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 );
1539 { /* ADD #imm, Rn */
1540 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1545 switch( (ir&0xF00) >> 8 ) {
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 );
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 );
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 );
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 );
1575 { /* CMP/EQ #imm, R0 */
1576 int32_t imm = SIGNEXT8(ir&0xFF);
1577 sh4r.t = ( R0 == imm ? 1 : 0 );
1582 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1585 CHECKDEST( sh4r.pc + disp + 4 )
1586 sh4r.pc += disp + 4;
1587 sh4r.new_pc = sh4r.pc + 2;
1594 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1597 CHECKDEST( sh4r.pc + disp + 4 )
1598 sh4r.pc += disp + 4;
1599 sh4r.new_pc = sh4r.pc + 2;
1606 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
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;
1620 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
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;
1637 { /* MOV.W @(disp, PC), Rn */
1638 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
1640 tmp = pc + 4 + disp;
1641 sh4r.r[Rn] = MEM_READ_WORD( tmp );
1646 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
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;
1657 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1658 CHECKDEST( sh4r.pc + disp + 4 );
1660 sh4r.in_delay_slot = 1;
1662 sh4r.pc = sh4r.new_pc;
1663 sh4r.new_pc = pc + 4 + disp;
1664 TRACE_CALL( pc, sh4r.new_pc );
1669 switch( (ir&0xF00) >> 8 ) {
1671 { /* MOV.B R0, @(disp, GBR) */
1672 uint32_t disp = (ir&0xFF);
1673 MEM_WRITE_BYTE( sh4r.gbr + disp, R0 );
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 );
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 );
1694 uint32_t imm = (ir&0xFF);
1696 MMIO_WRITE( MMU, TRA, imm<<2 );
1698 sh4_raise_exception( EXC_TRAP );
1702 { /* MOV.B @(disp, GBR), R0 */
1703 uint32_t disp = (ir&0xFF);
1704 R0 = MEM_READ_BYTE( sh4r.gbr + disp );
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 );
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 );
1724 { /* MOVA @(disp, PC), R0 */
1725 uint32_t disp = (ir&0xFF)<<2;
1727 R0 = (pc&0xFFFFFFFC) + disp + 4;
1731 { /* TST #imm, R0 */
1732 uint32_t imm = (ir&0xFF);
1733 sh4r.t = (R0 & imm ? 0 : 1);
1737 { /* AND #imm, R0 */
1738 uint32_t imm = (ir&0xFF);
1743 { /* XOR #imm, R0 */
1744 uint32_t imm = (ir&0xFF);
1750 uint32_t imm = (ir&0xFF);
1755 { /* TST.B #imm, @(R0, GBR) */
1756 uint32_t imm = (ir&0xFF);
1757 sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & imm ? 0 : 1 );
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) );
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) );
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) );
1781 { /* MOV.L @(disp, PC), Rn */
1782 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
1784 tmp = (pc&0xFFFFFFFC) + disp + 4;
1785 sh4r.r[Rn] = MEM_READ_LONG( tmp );
1789 { /* MOV #imm, Rn */
1790 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1797 { /* FADD FRm, FRn */
1798 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1800 if( IS_FPU_DOUBLEPREC() ) {
1808 { /* FSUB FRm, FRn */
1809 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1811 if( IS_FPU_DOUBLEPREC() ) {
1819 { /* FMUL FRm, FRn */
1820 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1822 if( IS_FPU_DOUBLEPREC() ) {
1830 { /* FDIV FRm, FRn */
1831 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1833 if( IS_FPU_DOUBLEPREC() ) {
1841 { /* FCMP/EQ FRm, FRn */
1842 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1844 if( IS_FPU_DOUBLEPREC() ) {
1845 sh4r.t = ( DR(FRn) == DR(FRm) ? 1 : 0 );
1847 sh4r.t = ( FR(FRn) == FR(FRm) ? 1 : 0 );
1852 { /* FCMP/GT FRm, FRn */
1853 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1855 if( IS_FPU_DOUBLEPREC() ) {
1856 sh4r.t = ( DR(FRn) > DR(FRm) ? 1 : 0 );
1858 sh4r.t = ( FR(FRn) > FR(FRm) ? 1 : 0 );
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 );
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 );
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 );
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;
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 );
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 );
1899 { /* FMOV FRm, FRn */
1900 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1901 if( IS_FPU_DOUBLESIZE() )
1908 switch( (ir&0xF0) >> 4 ) {
1910 { /* FSTS FPUL, FRn */
1911 uint32_t FRn = ((ir>>8)&0xF);
1912 CHECKFPUEN(); FR(FRn) = FPULf;
1916 { /* FLDS FRm, FPUL */
1917 uint32_t FRm = ((ir>>8)&0xF);
1918 CHECKFPUEN(); FPULf = FR(FRm);
1922 { /* FLOAT FPUL, FRn */
1923 uint32_t FRn = ((ir>>8)&0xF);
1925 if( IS_FPU_DOUBLEPREC() ) {
1926 if( FRn&1 ) { // No, really...
1927 dtmp = (double)FPULi;
1928 FR(FRn) = *(((float *)&dtmp)+1);
1930 DRF(FRn>>1) = (double)FPULi;
1933 FR(FRn) = (float)FPULi;
1938 { /* FTRC FRm, FPUL */
1939 uint32_t FRm = ((ir>>8)&0xF);
1941 if( IS_FPU_DOUBLEPREC() ) {
1944 *(((float *)&dtmp)+1) = FR(FRm);
1948 if( dtmp >= MAX_INTF )
1950 else if( dtmp <= MIN_INTF )
1953 FPULi = (int32_t)dtmp;
1956 if( ftmp >= MAX_INTF )
1958 else if( ftmp <= MIN_INTF )
1961 FPULi = (int32_t)ftmp;
1967 uint32_t FRn = ((ir>>8)&0xF);
1969 if( IS_FPU_DOUBLEPREC() ) {
1978 uint32_t FRn = ((ir>>8)&0xF);
1980 if( IS_FPU_DOUBLEPREC() ) {
1981 DR(FRn) = fabs(DR(FRn));
1983 FR(FRn) = fabsf(FR(FRn));
1989 uint32_t FRn = ((ir>>8)&0xF);
1991 if( IS_FPU_DOUBLEPREC() ) {
1992 DR(FRn) = sqrt(DR(FRn));
1994 FR(FRn) = sqrtf(FR(FRn));
2000 uint32_t FRn = ((ir>>8)&0xF);
2002 if( !IS_FPU_DOUBLEPREC() ) {
2003 FR(FRn) = 1.0/sqrtf(FR(FRn));
2009 uint32_t FRn = ((ir>>8)&0xF);
2011 if( IS_FPU_DOUBLEPREC() ) {
2020 uint32_t FRn = ((ir>>8)&0xF);
2022 if( IS_FPU_DOUBLEPREC() ) {
2030 { /* FCNVSD FPUL, FRn */
2031 uint32_t FRn = ((ir>>8)&0xF);
2033 if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
2034 DR(FRn) = (double)FPULf;
2039 { /* FCNVDS FRm, FPUL */
2040 uint32_t FRm = ((ir>>8)&0xF);
2042 if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
2043 FPULf = (float)DR(FRm);
2048 { /* FIPR FVm, FVn */
2049 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
2051 if( !IS_FPU_DOUBLEPREC() ) {
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);
2062 switch( (ir&0x100) >> 8 ) {
2064 { /* FSCA FPUL, FRn */
2065 uint32_t FRn = ((ir>>9)&0x7)<<1;
2067 if( !IS_FPU_DOUBLEPREC() ) {
2068 sh4_fsca( FPULi, &(DRF(FRn>>1)) );
2070 float angle = (((float)(FPULi&0xFFFF))/65536.0) * 2 * M_PI;
2071 FR(FRn) = sinf(angle);
2072 FR((FRn)+1) = cosf(angle);
2078 switch( (ir&0x200) >> 9 ) {
2080 { /* FTRV XMTRX, FVn */
2081 uint32_t FVn = ((ir>>10)&0x3);
2083 if( !IS_FPU_DOUBLEPREC() ) {
2084 sh4_ftrv(&(DRF(FVn<<1)), &sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21][0]);
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];
2102 switch( (ir&0xC00) >> 10 ) {
2105 CHECKFPUEN(); sh4r.fpscr ^= FPSCR_SZ;
2111 sh4r.fpscr ^= FPSCR_FR;
2112 sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
2135 { /* FMAC FR0, FRm, FRn */
2136 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2138 if( IS_FPU_DOUBLEPREC() ) {
2139 DR(FRn) += DR(FRm)*DR(0);
2141 FR(FRn) += FR(FRm)*FR(0);
2152 sh4r.pc = sh4r.new_pc;
2154 sh4r.in_delay_slot = 0;
.