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
24 #include "dreamcast.h"
29 #include "sh4/sh4core.h"
30 #include "sh4/sh4mmio.h"
33 #define SH4_CALLTRACE 1
35 #define MAX_INT 0x7FFFFFFF
36 #define MIN_INT 0x80000000
37 #define MAX_INTF 2147483647.0
38 #define MIN_INTF -2147483648.0
40 /********************** SH4 Module Definition ****************************/
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 void 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 void 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, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_byte(memtmp); }
166 #define MEM_READ_WORD( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_word(memtmp); }
167 #define MEM_READ_LONG( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_long(memtmp); }
168 #define MEM_WRITE_BYTE( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_byte(memtmp, val); }
169 #define MEM_WRITE_WORD( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_word(memtmp, val); }
170 #define MEM_WRITE_LONG( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_long(memtmp, 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 )
224 int64_t memtmp; // temporary holder for memory reads
228 if( pc > 0xFFFFFF00 ) {
230 syscall_invoke( pc );
231 sh4r.in_delay_slot = 0;
232 pc = sh4r.pc = sh4r.pr;
233 sh4r.new_pc = sh4r.pc + 2;
237 /* Read instruction */
238 if( !IS_IN_ICACHE(pc) ) {
239 if( !mmu_update_icache(pc) ) {
240 // Fault - look for the fault handler
241 if( !mmu_update_icache(sh4r.pc) ) {
242 // double fault - halt
243 ERROR( "Double fault - halting" );
250 assert( IS_IN_ICACHE(pc) );
251 ir = *(uint16_t *)GET_ICACHE_PTR(sh4r.pc);
252 switch( (ir&0xF000) >> 12 ) {
256 switch( (ir&0x80) >> 7 ) {
258 switch( (ir&0x70) >> 4 ) {
261 uint32_t Rn = ((ir>>8)&0xF);
263 sh4r.r[Rn] = sh4_read_sr();
268 uint32_t Rn = ((ir>>8)&0xF);
270 sh4r.r[Rn] = sh4r.gbr;
275 uint32_t Rn = ((ir>>8)&0xF);
277 sh4r.r[Rn] = sh4r.vbr;
282 uint32_t Rn = ((ir>>8)&0xF);
284 sh4r.r[Rn] = sh4r.ssr;
289 uint32_t Rn = ((ir>>8)&0xF);
291 sh4r.r[Rn] = sh4r.spc;
300 { /* STC Rm_BANK, Rn */
301 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
303 sh4r.r[Rn] = sh4r.r_bank[Rm_BANK];
309 switch( (ir&0xF0) >> 4 ) {
312 uint32_t Rn = ((ir>>8)&0xF);
314 CHECKDEST( pc + 4 + sh4r.r[Rn] );
315 sh4r.in_delay_slot = 1;
316 sh4r.pr = sh4r.pc + 4;
317 sh4r.pc = sh4r.new_pc;
318 sh4r.new_pc = pc + 4 + sh4r.r[Rn];
319 TRACE_CALL( pc, sh4r.new_pc );
325 uint32_t Rn = ((ir>>8)&0xF);
327 CHECKDEST( pc + 4 + sh4r.r[Rn] );
328 sh4r.in_delay_slot = 1;
329 sh4r.pc = sh4r.new_pc;
330 sh4r.new_pc = pc + 4 + sh4r.r[Rn];
336 uint32_t Rn = ((ir>>8)&0xF);
338 if( (tmp & 0xFC000000) == 0xE0000000 ) {
339 sh4_flush_store_queue(tmp);
345 uint32_t Rn = ((ir>>8)&0xF);
350 uint32_t Rn = ((ir>>8)&0xF);
355 uint32_t Rn = ((ir>>8)&0xF);
359 { /* MOVCA.L R0, @Rn */
360 uint32_t Rn = ((ir>>8)&0xF);
363 MEM_WRITE_LONG( tmp, R0 );
372 { /* MOV.B Rm, @(R0, Rn) */
373 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
374 MEM_WRITE_BYTE( R0 + sh4r.r[Rn], sh4r.r[Rm] );
378 { /* MOV.W Rm, @(R0, Rn) */
379 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
380 CHECKWALIGN16( R0 + sh4r.r[Rn] );
381 MEM_WRITE_WORD( R0 + sh4r.r[Rn], sh4r.r[Rm] );
385 { /* MOV.L Rm, @(R0, Rn) */
386 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
387 CHECKWALIGN32( R0 + sh4r.r[Rn] );
388 MEM_WRITE_LONG( R0 + sh4r.r[Rn], sh4r.r[Rm] );
393 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
394 sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
395 (sh4r.r[Rm] * sh4r.r[Rn]);
399 switch( (ir&0xFF0) >> 4 ) {
436 switch( (ir&0xF0) >> 4 ) {
444 sh4r.m = sh4r.q = sh4r.t = 0;
449 uint32_t Rn = ((ir>>8)&0xF);
459 switch( (ir&0xF0) >> 4 ) {
462 uint32_t Rn = ((ir>>8)&0xF);
463 sh4r.r[Rn] = (sh4r.mac>>32);
468 uint32_t Rn = ((ir>>8)&0xF);
469 sh4r.r[Rn] = (uint32_t)sh4r.mac;
474 uint32_t Rn = ((ir>>8)&0xF);
475 sh4r.r[Rn] = sh4r.pr;
480 uint32_t Rn = ((ir>>8)&0xF);
482 sh4r.r[Rn] = sh4r.sgr;
487 uint32_t Rn = ((ir>>8)&0xF);
488 sh4r.r[Rn] = sh4r.fpul;
492 { /* STS FPSCR, Rn */
493 uint32_t Rn = ((ir>>8)&0xF);
494 sh4r.r[Rn] = sh4r.fpscr;
499 uint32_t Rn = ((ir>>8)&0xF);
500 CHECKPRIV(); sh4r.r[Rn] = sh4r.dbr;
509 switch( (ir&0xFF0) >> 4 ) {
513 CHECKDEST( sh4r.pr );
514 sh4r.in_delay_slot = 1;
515 sh4r.pc = sh4r.new_pc;
516 sh4r.new_pc = sh4r.pr;
517 TRACE_RETURN( pc, sh4r.new_pc );
523 if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
524 sh4r.sh4_state = SH4_STATE_STANDBY;
526 sh4r.sh4_state = SH4_STATE_SLEEP;
528 return FALSE; /* Halt CPU */
534 CHECKDEST( sh4r.spc );
536 sh4r.in_delay_slot = 1;
537 sh4r.pc = sh4r.new_pc;
538 sh4r.new_pc = sh4r.spc;
539 sh4_write_sr( sh4r.ssr );
549 { /* MOV.B @(R0, Rm), Rn */
550 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
551 MEM_READ_BYTE( R0 + sh4r.r[Rm], sh4r.r[Rn] );
555 { /* MOV.W @(R0, Rm), Rn */
556 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
557 CHECKRALIGN16( R0 + sh4r.r[Rm] );
558 MEM_READ_WORD( R0 + sh4r.r[Rm], sh4r.r[Rn] );
562 { /* MOV.L @(R0, Rm), Rn */
563 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
564 CHECKRALIGN32( R0 + sh4r.r[Rm] );
565 MEM_READ_LONG( R0 + sh4r.r[Rm], sh4r.r[Rn] );
569 { /* MAC.L @Rm+, @Rn+ */
570 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
573 CHECKRALIGN32( sh4r.r[Rn] );
574 MEM_READ_LONG(sh4r.r[Rn], tmp);
575 tmpl = SIGNEXT32(tmp);
576 MEM_READ_LONG(sh4r.r[Rn]+4, tmp);
577 tmpl = tmpl * SIGNEXT32(tmp) + sh4r.mac;
580 CHECKRALIGN32( sh4r.r[Rm] );
581 CHECKRALIGN32( sh4r.r[Rn] );
582 MEM_READ_LONG(sh4r.r[Rn], tmp);
583 tmpl = SIGNEXT32(tmp);
584 MEM_READ_LONG(sh4r.r[Rm], tmp);
585 tmpl = tmpl * SIGNEXT32(tmp) + sh4r.mac;
590 /* 48-bit Saturation. Yuch */
591 if( tmpl < (int64_t)0xFFFF800000000000LL )
592 tmpl = 0xFFFF800000000000LL;
593 else if( tmpl > (int64_t)0x00007FFFFFFFFFFFLL )
594 tmpl = 0x00007FFFFFFFFFFFLL;
605 { /* MOV.L Rm, @(disp, Rn) */
606 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
607 tmp = sh4r.r[Rn] + disp;
608 CHECKWALIGN32( tmp );
609 MEM_WRITE_LONG( tmp, sh4r.r[Rm] );
615 { /* MOV.B Rm, @Rn */
616 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
617 MEM_WRITE_BYTE( sh4r.r[Rn], sh4r.r[Rm] );
621 { /* MOV.W Rm, @Rn */
622 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
623 CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn], sh4r.r[Rm] );
627 { /* MOV.L Rm, @Rn */
628 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
629 CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r[Rm] );
633 { /* MOV.B Rm, @-Rn */
634 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
635 MEM_WRITE_BYTE( sh4r.r[Rn]-1, sh4r.r[Rm] ); sh4r.r[Rn]--;
639 { /* MOV.W Rm, @-Rn */
640 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
641 CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn]-2, sh4r.r[Rm] ); sh4r.r[Rn] -= 2;
645 { /* MOV.L Rm, @-Rn */
646 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
647 CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.r[Rm] ); sh4r.r[Rn] -= 4;
652 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
653 sh4r.q = sh4r.r[Rn]>>31;
654 sh4r.m = sh4r.r[Rm]>>31;
655 sh4r.t = sh4r.q ^ sh4r.m;
660 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
661 sh4r.t = (sh4r.r[Rn]&sh4r.r[Rm] ? 0 : 1);
666 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
667 sh4r.r[Rn] &= sh4r.r[Rm];
672 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
673 sh4r.r[Rn] ^= sh4r.r[Rm];
678 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
679 sh4r.r[Rn] |= sh4r.r[Rm];
683 { /* CMP/STR Rm, Rn */
684 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
685 /* set T = 1 if any byte in RM & RN is the same */
686 tmp = sh4r.r[Rm] ^ sh4r.r[Rn];
687 sh4r.t = ((tmp&0x000000FF)==0 || (tmp&0x0000FF00)==0 ||
688 (tmp&0x00FF0000)==0 || (tmp&0xFF000000)==0)?1:0;
693 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
694 sh4r.r[Rn] = (sh4r.r[Rn]>>16) | (sh4r.r[Rm]<<16);
698 { /* MULU.W Rm, Rn */
699 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
700 sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
701 (uint32_t)((sh4r.r[Rm]&0xFFFF) * (sh4r.r[Rn]&0xFFFF));
705 { /* MULS.W Rm, Rn */
706 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
707 sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
708 (uint32_t)(SIGNEXT32(sh4r.r[Rm]&0xFFFF) * SIGNEXT32(sh4r.r[Rn]&0xFFFF));
719 { /* CMP/EQ Rm, Rn */
720 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
721 sh4r.t = ( sh4r.r[Rm] == sh4r.r[Rn] ? 1 : 0 );
725 { /* CMP/HS Rm, Rn */
726 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
727 sh4r.t = ( sh4r.r[Rn] >= sh4r.r[Rm] ? 1 : 0 );
731 { /* CMP/GE Rm, Rn */
732 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
733 sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= ((int32_t)sh4r.r[Rm]) ? 1 : 0 );
738 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
739 /* This is derived from the sh4 manual with some simplifications */
740 uint32_t tmp0, tmp1, tmp2, dir;
742 dir = sh4r.q ^ sh4r.m;
743 sh4r.q = (sh4r.r[Rn] >> 31);
745 sh4r.r[Rn] = (sh4r.r[Rn] << 1) | sh4r.t;
749 tmp1 = (sh4r.r[Rn]<tmp0 ? 1 : 0 );
752 tmp1 = (sh4r.r[Rn]>tmp0 ? 1 : 0 );
754 sh4r.q ^= sh4r.m ^ tmp1;
755 sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );
759 { /* DMULU.L Rm, Rn */
760 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
761 sh4r.mac = ((uint64_t)sh4r.r[Rm]) * ((uint64_t)sh4r.r[Rn]);
765 { /* CMP/HI Rm, Rn */
766 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
767 sh4r.t = ( sh4r.r[Rn] > sh4r.r[Rm] ? 1 : 0 );
771 { /* CMP/GT Rm, Rn */
772 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
773 sh4r.t = ( ((int32_t)sh4r.r[Rn]) > ((int32_t)sh4r.r[Rm]) ? 1 : 0 );
778 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
779 sh4r.r[Rn] -= sh4r.r[Rm];
784 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
786 sh4r.r[Rn] = sh4r.r[Rn] - sh4r.r[Rm] - sh4r.t;
787 sh4r.t = (sh4r.r[Rn] > tmp || (sh4r.r[Rn] == tmp && sh4r.t == 1));
791 UNIMP(ir); /* SUBV Rm, Rn */
795 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
796 sh4r.r[Rn] += sh4r.r[Rm];
800 { /* DMULS.L Rm, Rn */
801 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
802 sh4r.mac = SIGNEXT32(sh4r.r[Rm]) * SIGNEXT32(sh4r.r[Rn]);
807 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
809 sh4r.r[Rn] += sh4r.r[Rm] + sh4r.t;
810 sh4r.t = ( sh4r.r[Rn] < tmp || (sh4r.r[Rn] == tmp && sh4r.t != 0) ? 1 : 0 );
815 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
816 tmp = sh4r.r[Rn] + sh4r.r[Rm];
817 sh4r.t = ( (sh4r.r[Rn]>>31) == (sh4r.r[Rm]>>31) && ((sh4r.r[Rn]>>31) != (tmp>>31)) );
829 switch( (ir&0xF0) >> 4 ) {
832 uint32_t Rn = ((ir>>8)&0xF);
833 sh4r.t = sh4r.r[Rn] >> 31; sh4r.r[Rn] <<= 1;
838 uint32_t Rn = ((ir>>8)&0xF);
840 sh4r.t = ( sh4r.r[Rn] == 0 ? 1 : 0 );
845 uint32_t Rn = ((ir>>8)&0xF);
846 sh4r.t = sh4r.r[Rn] >> 31;
856 switch( (ir&0xF0) >> 4 ) {
859 uint32_t Rn = ((ir>>8)&0xF);
860 sh4r.t = sh4r.r[Rn] & 0x00000001; sh4r.r[Rn] >>= 1;
865 uint32_t Rn = ((ir>>8)&0xF);
866 sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= 0 ? 1 : 0 );
871 uint32_t Rn = ((ir>>8)&0xF);
872 sh4r.t = sh4r.r[Rn] & 0x00000001;
873 sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 1;
882 switch( (ir&0xF0) >> 4 ) {
884 { /* STS.L MACH, @-Rn */
885 uint32_t Rn = ((ir>>8)&0xF);
886 CHECKWALIGN32( sh4r.r[Rn] );
887 MEM_WRITE_LONG( sh4r.r[Rn]-4, (sh4r.mac>>32) );
892 { /* STS.L MACL, @-Rn */
893 uint32_t Rn = ((ir>>8)&0xF);
894 CHECKWALIGN32( sh4r.r[Rn] );
895 MEM_WRITE_LONG( sh4r.r[Rn]-4, (uint32_t)sh4r.mac );
900 { /* STS.L PR, @-Rn */
901 uint32_t Rn = ((ir>>8)&0xF);
902 CHECKWALIGN32( sh4r.r[Rn] );
903 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.pr );
908 { /* STC.L SGR, @-Rn */
909 uint32_t Rn = ((ir>>8)&0xF);
911 CHECKWALIGN32( sh4r.r[Rn] );
912 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.sgr );
917 { /* STS.L FPUL, @-Rn */
918 uint32_t Rn = ((ir>>8)&0xF);
919 CHECKWALIGN32( sh4r.r[Rn] );
920 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.fpul );
925 { /* STS.L FPSCR, @-Rn */
926 uint32_t Rn = ((ir>>8)&0xF);
927 CHECKWALIGN32( sh4r.r[Rn] );
928 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.fpscr );
933 { /* STC.L DBR, @-Rn */
934 uint32_t Rn = ((ir>>8)&0xF);
936 CHECKWALIGN32( sh4r.r[Rn] );
937 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.dbr );
947 switch( (ir&0x80) >> 7 ) {
949 switch( (ir&0x70) >> 4 ) {
951 { /* STC.L SR, @-Rn */
952 uint32_t Rn = ((ir>>8)&0xF);
954 CHECKWALIGN32( sh4r.r[Rn] );
955 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4_read_sr() );
960 { /* STC.L GBR, @-Rn */
961 uint32_t Rn = ((ir>>8)&0xF);
962 CHECKWALIGN32( sh4r.r[Rn] );
963 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.gbr );
968 { /* STC.L VBR, @-Rn */
969 uint32_t Rn = ((ir>>8)&0xF);
971 CHECKWALIGN32( sh4r.r[Rn] );
972 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.vbr );
977 { /* STC.L SSR, @-Rn */
978 uint32_t Rn = ((ir>>8)&0xF);
980 CHECKWALIGN32( sh4r.r[Rn] );
981 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.ssr );
986 { /* STC.L SPC, @-Rn */
987 uint32_t Rn = ((ir>>8)&0xF);
989 CHECKWALIGN32( sh4r.r[Rn] );
990 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.spc );
1000 { /* STC.L Rm_BANK, @-Rn */
1001 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1003 CHECKWALIGN32( sh4r.r[Rn] );
1004 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.r_bank[Rm_BANK] );
1011 switch( (ir&0xF0) >> 4 ) {
1014 uint32_t Rn = ((ir>>8)&0xF);
1015 sh4r.t = sh4r.r[Rn] >> 31;
1017 sh4r.r[Rn] |= sh4r.t;
1022 uint32_t Rn = ((ir>>8)&0xF);
1023 tmp = sh4r.r[Rn] >> 31;
1025 sh4r.r[Rn] |= sh4r.t;
1035 switch( (ir&0xF0) >> 4 ) {
1038 uint32_t Rn = ((ir>>8)&0xF);
1039 sh4r.t = sh4r.r[Rn] & 0x00000001;
1041 sh4r.r[Rn] |= (sh4r.t << 31);
1046 uint32_t Rn = ((ir>>8)&0xF);
1047 sh4r.t = ( ((int32_t)sh4r.r[Rn]) > 0 ? 1 : 0 );
1052 uint32_t Rn = ((ir>>8)&0xF);
1053 tmp = sh4r.r[Rn] & 0x00000001;
1055 sh4r.r[Rn] |= (sh4r.t << 31 );
1065 switch( (ir&0xF0) >> 4 ) {
1067 { /* LDS.L @Rm+, MACH */
1068 uint32_t Rm = ((ir>>8)&0xF);
1069 CHECKRALIGN32( sh4r.r[Rm] );
1070 MEM_READ_LONG(sh4r.r[Rm], tmp);
1071 sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1072 (((uint64_t)tmp)<<32);
1077 { /* LDS.L @Rm+, MACL */
1078 uint32_t Rm = ((ir>>8)&0xF);
1079 CHECKRALIGN32( sh4r.r[Rm] );
1080 MEM_READ_LONG(sh4r.r[Rm], tmp);
1081 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1082 (uint64_t)((uint32_t)tmp);
1087 { /* LDS.L @Rm+, PR */
1088 uint32_t Rm = ((ir>>8)&0xF);
1089 CHECKRALIGN32( sh4r.r[Rm] );
1090 MEM_READ_LONG( sh4r.r[Rm], sh4r.pr );
1095 { /* LDC.L @Rm+, SGR */
1096 uint32_t Rm = ((ir>>8)&0xF);
1098 CHECKRALIGN32( sh4r.r[Rm] );
1099 MEM_READ_LONG(sh4r.r[Rm], sh4r.sgr);
1104 { /* LDS.L @Rm+, FPUL */
1105 uint32_t Rm = ((ir>>8)&0xF);
1106 CHECKRALIGN32( sh4r.r[Rm] );
1107 MEM_READ_LONG(sh4r.r[Rm], sh4r.fpul);
1112 { /* LDS.L @Rm+, FPSCR */
1113 uint32_t Rm = ((ir>>8)&0xF);
1114 CHECKRALIGN32( sh4r.r[Rm] );
1115 MEM_READ_LONG(sh4r.r[Rm], sh4r.fpscr);
1117 sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
1121 { /* LDC.L @Rm+, DBR */
1122 uint32_t Rm = ((ir>>8)&0xF);
1124 CHECKRALIGN32( sh4r.r[Rm] );
1125 MEM_READ_LONG(sh4r.r[Rm], sh4r.dbr);
1135 switch( (ir&0x80) >> 7 ) {
1137 switch( (ir&0x70) >> 4 ) {
1139 { /* LDC.L @Rm+, SR */
1140 uint32_t Rm = ((ir>>8)&0xF);
1143 CHECKWALIGN32( sh4r.r[Rm] );
1144 MEM_READ_LONG(sh4r.r[Rm], tmp);
1145 sh4_write_sr( tmp );
1150 { /* LDC.L @Rm+, GBR */
1151 uint32_t Rm = ((ir>>8)&0xF);
1152 CHECKRALIGN32( sh4r.r[Rm] );
1153 MEM_READ_LONG(sh4r.r[Rm], sh4r.gbr);
1158 { /* LDC.L @Rm+, VBR */
1159 uint32_t Rm = ((ir>>8)&0xF);
1161 CHECKRALIGN32( sh4r.r[Rm] );
1162 MEM_READ_LONG(sh4r.r[Rm], sh4r.vbr);
1167 { /* LDC.L @Rm+, SSR */
1168 uint32_t Rm = ((ir>>8)&0xF);
1170 CHECKRALIGN32( sh4r.r[Rm] );
1171 MEM_READ_LONG(sh4r.r[Rm], sh4r.ssr);
1176 { /* LDC.L @Rm+, SPC */
1177 uint32_t Rm = ((ir>>8)&0xF);
1179 CHECKRALIGN32( sh4r.r[Rm] );
1180 MEM_READ_LONG(sh4r.r[Rm], sh4r.spc);
1190 { /* LDC.L @Rm+, Rn_BANK */
1191 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1193 CHECKRALIGN32( sh4r.r[Rm] );
1194 MEM_READ_LONG( sh4r.r[Rm], sh4r.r_bank[Rn_BANK] );
1201 switch( (ir&0xF0) >> 4 ) {
1204 uint32_t Rn = ((ir>>8)&0xF);
1210 uint32_t Rn = ((ir>>8)&0xF);
1216 uint32_t Rn = ((ir>>8)&0xF);
1226 switch( (ir&0xF0) >> 4 ) {
1229 uint32_t Rn = ((ir>>8)&0xF);
1235 uint32_t Rn = ((ir>>8)&0xF);
1241 uint32_t Rn = ((ir>>8)&0xF);
1251 switch( (ir&0xF0) >> 4 ) {
1253 { /* LDS Rm, MACH */
1254 uint32_t Rm = ((ir>>8)&0xF);
1255 sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1256 (((uint64_t)sh4r.r[Rm])<<32);
1260 { /* LDS Rm, MACL */
1261 uint32_t Rm = ((ir>>8)&0xF);
1262 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1263 (uint64_t)((uint32_t)(sh4r.r[Rm]));
1268 uint32_t Rm = ((ir>>8)&0xF);
1269 sh4r.pr = sh4r.r[Rm];
1274 uint32_t Rm = ((ir>>8)&0xF);
1276 sh4r.sgr = sh4r.r[Rm];
1280 { /* LDS Rm, FPUL */
1281 uint32_t Rm = ((ir>>8)&0xF);
1282 sh4r.fpul = sh4r.r[Rm];
1286 { /* LDS Rm, FPSCR */
1287 uint32_t Rm = ((ir>>8)&0xF);
1288 sh4r.fpscr = sh4r.r[Rm];
1289 sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
1294 uint32_t Rm = ((ir>>8)&0xF);
1296 sh4r.dbr = sh4r.r[Rm];
1305 switch( (ir&0xF0) >> 4 ) {
1308 uint32_t Rn = ((ir>>8)&0xF);
1309 CHECKDEST( sh4r.r[Rn] );
1311 sh4r.in_delay_slot = 1;
1312 sh4r.pc = sh4r.new_pc;
1313 sh4r.new_pc = sh4r.r[Rn];
1315 TRACE_CALL( pc, sh4r.new_pc );
1321 uint32_t Rn = ((ir>>8)&0xF);
1322 MEM_READ_BYTE( sh4r.r[Rn], tmp );
1323 sh4r.t = ( tmp == 0 ? 1 : 0 );
1324 MEM_WRITE_BYTE( sh4r.r[Rn], tmp | 0x80 );
1329 uint32_t Rn = ((ir>>8)&0xF);
1330 CHECKDEST( sh4r.r[Rn] );
1332 sh4r.in_delay_slot = 1;
1333 sh4r.pc = sh4r.new_pc;
1334 sh4r.new_pc = sh4r.r[Rn];
1345 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1347 if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);
1348 else if( (tmp & 0x1F) == 0 )
1349 sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 31;
1351 sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> (((~sh4r.r[Rm]) & 0x1F)+1);
1356 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1358 if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);
1359 else if( (tmp & 0x1F) == 0 ) sh4r.r[Rn] = 0;
1360 else sh4r.r[Rn] >>= (((~tmp) & 0x1F)+1);
1364 switch( (ir&0x80) >> 7 ) {
1366 switch( (ir&0x70) >> 4 ) {
1369 uint32_t Rm = ((ir>>8)&0xF);
1372 sh4_write_sr( sh4r.r[Rm] );
1377 uint32_t Rm = ((ir>>8)&0xF);
1378 sh4r.gbr = sh4r.r[Rm];
1383 uint32_t Rm = ((ir>>8)&0xF);
1385 sh4r.vbr = sh4r.r[Rm];
1390 uint32_t Rm = ((ir>>8)&0xF);
1392 sh4r.ssr = sh4r.r[Rm];
1397 uint32_t Rm = ((ir>>8)&0xF);
1399 sh4r.spc = sh4r.r[Rm];
1408 { /* LDC Rm, Rn_BANK */
1409 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1411 sh4r.r_bank[Rn_BANK] = sh4r.r[Rm];
1417 { /* MAC.W @Rm+, @Rn+ */
1418 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1421 CHECKRALIGN16(sh4r.r[Rn]);
1422 MEM_READ_WORD( sh4r.r[Rn], tmp );
1423 stmp = SIGNEXT16(tmp);
1424 MEM_READ_WORD( sh4r.r[Rn]+2, tmp );
1425 stmp *= SIGNEXT16(tmp);
1428 CHECKRALIGN16( sh4r.r[Rn] );
1429 CHECKRALIGN16( sh4r.r[Rm] );
1430 MEM_READ_WORD(sh4r.r[Rn], tmp);
1431 stmp = SIGNEXT16(tmp);
1432 MEM_READ_WORD(sh4r.r[Rm], tmp);
1433 stmp = stmp * SIGNEXT16(tmp);
1438 int64_t tmpl = (int64_t)((int32_t)sh4r.mac) + (int64_t)stmp;
1439 if( tmpl > (int64_t)0x000000007FFFFFFFLL ) {
1440 sh4r.mac = 0x000000017FFFFFFFLL;
1441 } else if( tmpl < (int64_t)0xFFFFFFFF80000000LL ) {
1442 sh4r.mac = 0x0000000180000000LL;
1444 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1445 ((uint32_t)(sh4r.mac + stmp));
1448 sh4r.mac += SIGNEXT32(stmp);
1455 { /* MOV.L @(disp, Rm), Rn */
1456 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1457 tmp = sh4r.r[Rm] + disp;
1458 CHECKRALIGN32( tmp );
1459 MEM_READ_LONG( tmp, sh4r.r[Rn] );
1465 { /* MOV.B @Rm, Rn */
1466 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1467 MEM_READ_BYTE( sh4r.r[Rm], sh4r.r[Rn] );
1471 { /* MOV.W @Rm, Rn */
1472 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1473 CHECKRALIGN16( sh4r.r[Rm] ); MEM_READ_WORD( sh4r.r[Rm], sh4r.r[Rn] );
1477 { /* MOV.L @Rm, Rn */
1478 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1479 CHECKRALIGN32( sh4r.r[Rm] ); MEM_READ_LONG( sh4r.r[Rm], sh4r.r[Rn] );
1484 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1485 sh4r.r[Rn] = sh4r.r[Rm];
1489 { /* MOV.B @Rm+, Rn */
1490 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1491 MEM_READ_BYTE( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] ++;
1495 { /* MOV.W @Rm+, Rn */
1496 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1497 CHECKRALIGN16( sh4r.r[Rm] ); MEM_READ_WORD( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] += 2;
1501 { /* MOV.L @Rm+, Rn */
1502 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1503 CHECKRALIGN32( sh4r.r[Rm] ); MEM_READ_LONG( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] += 4;
1508 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1509 sh4r.r[Rn] = ~sh4r.r[Rm];
1513 { /* SWAP.B Rm, Rn */
1514 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1515 sh4r.r[Rn] = (sh4r.r[Rm]&0xFFFF0000) | ((sh4r.r[Rm]&0x0000FF00)>>8) | ((sh4r.r[Rm]&0x000000FF)<<8);
1519 { /* SWAP.W Rm, Rn */
1520 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1521 sh4r.r[Rn] = (sh4r.r[Rm]>>16) | (sh4r.r[Rm]<<16);
1526 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1527 tmp = 0 - sh4r.r[Rm];
1528 sh4r.r[Rn] = tmp - sh4r.t;
1529 sh4r.t = ( 0<tmp || tmp<sh4r.r[Rn] ? 1 : 0 );
1534 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1535 sh4r.r[Rn] = 0 - sh4r.r[Rm];
1539 { /* EXTU.B Rm, Rn */
1540 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1541 sh4r.r[Rn] = sh4r.r[Rm]&0x000000FF;
1545 { /* EXTU.W Rm, Rn */
1546 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1547 sh4r.r[Rn] = sh4r.r[Rm]&0x0000FFFF;
1551 { /* EXTS.B Rm, Rn */
1552 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1553 sh4r.r[Rn] = SIGNEXT8( sh4r.r[Rm]&0x000000FF );
1557 { /* EXTS.W Rm, Rn */
1558 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1559 sh4r.r[Rn] = SIGNEXT16( sh4r.r[Rm]&0x0000FFFF );
1565 { /* ADD #imm, Rn */
1566 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1571 switch( (ir&0xF00) >> 8 ) {
1573 { /* MOV.B R0, @(disp, Rn) */
1574 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1575 MEM_WRITE_BYTE( sh4r.r[Rn] + disp, R0 );
1579 { /* MOV.W R0, @(disp, Rn) */
1580 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1581 tmp = sh4r.r[Rn] + disp;
1582 CHECKWALIGN16( tmp );
1583 MEM_WRITE_WORD( tmp, R0 );
1587 { /* MOV.B @(disp, Rm), R0 */
1588 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1589 MEM_READ_BYTE( sh4r.r[Rm] + disp, R0 );
1593 { /* MOV.W @(disp, Rm), R0 */
1594 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1595 tmp = sh4r.r[Rm] + disp;
1596 CHECKRALIGN16( tmp );
1597 MEM_READ_WORD( tmp, R0 );
1601 { /* CMP/EQ #imm, R0 */
1602 int32_t imm = SIGNEXT8(ir&0xFF);
1603 sh4r.t = ( R0 == imm ? 1 : 0 );
1608 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1611 CHECKDEST( sh4r.pc + disp + 4 )
1612 sh4r.pc += disp + 4;
1613 sh4r.new_pc = sh4r.pc + 2;
1620 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1623 CHECKDEST( sh4r.pc + disp + 4 )
1624 sh4r.pc += disp + 4;
1625 sh4r.new_pc = sh4r.pc + 2;
1632 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1635 CHECKDEST( sh4r.pc + disp + 4 )
1636 sh4r.in_delay_slot = 1;
1637 sh4r.pc = sh4r.new_pc;
1638 sh4r.new_pc = pc + disp + 4;
1639 sh4r.in_delay_slot = 1;
1646 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1649 CHECKDEST( sh4r.pc + disp + 4 )
1650 sh4r.in_delay_slot = 1;
1651 sh4r.pc = sh4r.new_pc;
1652 sh4r.new_pc = pc + disp + 4;
1663 { /* MOV.W @(disp, PC), Rn */
1664 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
1666 tmp = pc + 4 + disp;
1667 MEM_READ_WORD( tmp, sh4r.r[Rn] );
1672 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1674 CHECKDEST( sh4r.pc + disp + 4 );
1675 sh4r.in_delay_slot = 1;
1676 sh4r.pc = sh4r.new_pc;
1677 sh4r.new_pc = pc + 4 + disp;
1683 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1684 CHECKDEST( sh4r.pc + disp + 4 );
1686 sh4r.in_delay_slot = 1;
1688 sh4r.pc = sh4r.new_pc;
1689 sh4r.new_pc = pc + 4 + disp;
1690 TRACE_CALL( pc, sh4r.new_pc );
1695 switch( (ir&0xF00) >> 8 ) {
1697 { /* MOV.B R0, @(disp, GBR) */
1698 uint32_t disp = (ir&0xFF);
1699 MEM_WRITE_BYTE( sh4r.gbr + disp, R0 );
1703 { /* MOV.W R0, @(disp, GBR) */
1704 uint32_t disp = (ir&0xFF)<<1;
1705 tmp = sh4r.gbr + disp;
1706 CHECKWALIGN16( tmp );
1707 MEM_WRITE_WORD( tmp, R0 );
1711 { /* MOV.L R0, @(disp, GBR) */
1712 uint32_t disp = (ir&0xFF)<<2;
1713 tmp = sh4r.gbr + disp;
1714 CHECKWALIGN32( tmp );
1715 MEM_WRITE_LONG( tmp, R0 );
1720 uint32_t imm = (ir&0xFF);
1723 sh4_raise_trap( imm );
1728 { /* MOV.B @(disp, GBR), R0 */
1729 uint32_t disp = (ir&0xFF);
1730 MEM_READ_BYTE( sh4r.gbr + disp, R0 );
1734 { /* MOV.W @(disp, GBR), R0 */
1735 uint32_t disp = (ir&0xFF)<<1;
1736 tmp = sh4r.gbr + disp;
1737 CHECKRALIGN16( tmp );
1738 MEM_READ_WORD( tmp, R0 );
1742 { /* MOV.L @(disp, GBR), R0 */
1743 uint32_t disp = (ir&0xFF)<<2;
1744 tmp = sh4r.gbr + disp;
1745 CHECKRALIGN32( tmp );
1746 MEM_READ_LONG( tmp, R0 );
1750 { /* MOVA @(disp, PC), R0 */
1751 uint32_t disp = (ir&0xFF)<<2;
1753 R0 = (pc&0xFFFFFFFC) + disp + 4;
1757 { /* TST #imm, R0 */
1758 uint32_t imm = (ir&0xFF);
1759 sh4r.t = (R0 & imm ? 0 : 1);
1763 { /* AND #imm, R0 */
1764 uint32_t imm = (ir&0xFF);
1769 { /* XOR #imm, R0 */
1770 uint32_t imm = (ir&0xFF);
1776 uint32_t imm = (ir&0xFF);
1781 { /* TST.B #imm, @(R0, GBR) */
1782 uint32_t imm = (ir&0xFF);
1783 MEM_READ_BYTE(R0+sh4r.gbr, tmp); sh4r.t = ( tmp & imm ? 0 : 1 );
1787 { /* AND.B #imm, @(R0, GBR) */
1788 uint32_t imm = (ir&0xFF);
1789 MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm & tmp );
1793 { /* XOR.B #imm, @(R0, GBR) */
1794 uint32_t imm = (ir&0xFF);
1795 MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm ^ tmp );
1799 { /* OR.B #imm, @(R0, GBR) */
1800 uint32_t imm = (ir&0xFF);
1801 MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm | tmp );
1807 { /* MOV.L @(disp, PC), Rn */
1808 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
1810 tmp = (pc&0xFFFFFFFC) + disp + 4;
1811 MEM_READ_LONG( tmp, sh4r.r[Rn] );
1815 { /* MOV #imm, Rn */
1816 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1823 { /* FADD FRm, FRn */
1824 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1826 if( IS_FPU_DOUBLEPREC() ) {
1834 { /* FSUB FRm, FRn */
1835 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1837 if( IS_FPU_DOUBLEPREC() ) {
1845 { /* FMUL FRm, FRn */
1846 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1848 if( IS_FPU_DOUBLEPREC() ) {
1856 { /* FDIV FRm, FRn */
1857 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1859 if( IS_FPU_DOUBLEPREC() ) {
1867 { /* FCMP/EQ FRm, FRn */
1868 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1870 if( IS_FPU_DOUBLEPREC() ) {
1871 sh4r.t = ( DR(FRn) == DR(FRm) ? 1 : 0 );
1873 sh4r.t = ( FR(FRn) == FR(FRm) ? 1 : 0 );
1878 { /* FCMP/GT FRm, FRn */
1879 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1881 if( IS_FPU_DOUBLEPREC() ) {
1882 sh4r.t = ( DR(FRn) > DR(FRm) ? 1 : 0 );
1884 sh4r.t = ( FR(FRn) > FR(FRm) ? 1 : 0 );
1889 { /* FMOV @(R0, Rm), FRn */
1890 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1891 MEM_FP_READ( sh4r.r[Rm] + R0, FRn );
1895 { /* FMOV FRm, @(R0, Rn) */
1896 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1897 MEM_FP_WRITE( sh4r.r[Rn] + R0, FRm );
1901 { /* FMOV @Rm, FRn */
1902 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1903 MEM_FP_READ( sh4r.r[Rm], FRn );
1907 { /* FMOV @Rm+, FRn */
1908 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1909 MEM_FP_READ( sh4r.r[Rm], FRn ); sh4r.r[Rm] += FP_WIDTH;
1913 { /* FMOV FRm, @Rn */
1914 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1915 MEM_FP_WRITE( sh4r.r[Rn], FRm );
1919 { /* FMOV FRm, @-Rn */
1920 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1921 MEM_FP_WRITE( sh4r.r[Rn] - FP_WIDTH, FRm ); sh4r.r[Rn] -= FP_WIDTH;
1925 { /* FMOV FRm, FRn */
1926 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1927 if( IS_FPU_DOUBLESIZE() )
1934 switch( (ir&0xF0) >> 4 ) {
1936 { /* FSTS FPUL, FRn */
1937 uint32_t FRn = ((ir>>8)&0xF);
1938 CHECKFPUEN(); FR(FRn) = FPULf;
1942 { /* FLDS FRm, FPUL */
1943 uint32_t FRm = ((ir>>8)&0xF);
1944 CHECKFPUEN(); FPULf = FR(FRm);
1948 { /* FLOAT FPUL, FRn */
1949 uint32_t FRn = ((ir>>8)&0xF);
1951 if( IS_FPU_DOUBLEPREC() ) {
1952 if( FRn&1 ) { // No, really...
1953 dtmp = (double)FPULi;
1954 FR(FRn) = *(((float *)&dtmp)+1);
1956 DRF(FRn>>1) = (double)FPULi;
1959 FR(FRn) = (float)FPULi;
1964 { /* FTRC FRm, FPUL */
1965 uint32_t FRm = ((ir>>8)&0xF);
1967 if( IS_FPU_DOUBLEPREC() ) {
1970 *(((float *)&dtmp)+1) = FR(FRm);
1974 if( dtmp >= MAX_INTF )
1976 else if( dtmp <= MIN_INTF )
1979 FPULi = (int32_t)dtmp;
1982 if( ftmp >= MAX_INTF )
1984 else if( ftmp <= MIN_INTF )
1987 FPULi = (int32_t)ftmp;
1993 uint32_t FRn = ((ir>>8)&0xF);
1995 if( IS_FPU_DOUBLEPREC() ) {
2004 uint32_t FRn = ((ir>>8)&0xF);
2006 if( IS_FPU_DOUBLEPREC() ) {
2007 DR(FRn) = fabs(DR(FRn));
2009 FR(FRn) = fabsf(FR(FRn));
2015 uint32_t FRn = ((ir>>8)&0xF);
2017 if( IS_FPU_DOUBLEPREC() ) {
2018 DR(FRn) = sqrt(DR(FRn));
2020 FR(FRn) = sqrtf(FR(FRn));
2026 uint32_t FRn = ((ir>>8)&0xF);
2028 if( !IS_FPU_DOUBLEPREC() ) {
2029 FR(FRn) = 1.0/sqrtf(FR(FRn));
2035 uint32_t FRn = ((ir>>8)&0xF);
2037 if( IS_FPU_DOUBLEPREC() ) {
2046 uint32_t FRn = ((ir>>8)&0xF);
2048 if( IS_FPU_DOUBLEPREC() ) {
2056 { /* FCNVSD FPUL, FRn */
2057 uint32_t FRn = ((ir>>8)&0xF);
2059 if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
2060 DR(FRn) = (double)FPULf;
2065 { /* FCNVDS FRm, FPUL */
2066 uint32_t FRm = ((ir>>8)&0xF);
2068 if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
2069 FPULf = (float)DR(FRm);
2074 { /* FIPR FVm, FVn */
2075 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
2077 if( !IS_FPU_DOUBLEPREC() ) {
2080 FR(tmp2+3) = FR(tmp)*FR(tmp2) +
2081 FR(tmp+1)*FR(tmp2+1) +
2082 FR(tmp+2)*FR(tmp2+2) +
2083 FR(tmp+3)*FR(tmp2+3);
2088 switch( (ir&0x100) >> 8 ) {
2090 { /* FSCA FPUL, FRn */
2091 uint32_t FRn = ((ir>>9)&0x7)<<1;
2093 if( !IS_FPU_DOUBLEPREC() ) {
2094 sh4_fsca( FPULi, &(DRF(FRn>>1)) );
2096 float angle = (((float)(FPULi&0xFFFF))/65536.0) * 2 * M_PI;
2097 FR(FRn) = sinf(angle);
2098 FR((FRn)+1) = cosf(angle);
2104 switch( (ir&0x200) >> 9 ) {
2106 { /* FTRV XMTRX, FVn */
2107 uint32_t FVn = ((ir>>10)&0x3);
2109 if( !IS_FPU_DOUBLEPREC() ) {
2110 sh4_ftrv(&(DRF(FVn<<1)), &sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21][0]);
2113 float *xf = &sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21][0];
2114 float fv[4] = { FR(tmp), FR(tmp+1), FR(tmp+2), FR(tmp+3) };
2115 FR(tmp) = xf[1] * fv[0] + xf[5]*fv[1] +
2116 xf[9]*fv[2] + xf[13]*fv[3];
2117 FR(tmp+1) = xf[0] * fv[0] + xf[4]*fv[1] +
2118 xf[8]*fv[2] + xf[12]*fv[3];
2119 FR(tmp+2) = xf[3] * fv[0] + xf[7]*fv[1] +
2120 xf[11]*fv[2] + xf[15]*fv[3];
2121 FR(tmp+3) = xf[2] * fv[0] + xf[6]*fv[1] +
2122 xf[10]*fv[2] + xf[14]*fv[3];
2128 switch( (ir&0xC00) >> 10 ) {
2131 CHECKFPUEN(); sh4r.fpscr ^= FPSCR_SZ;
2137 sh4r.fpscr ^= FPSCR_FR;
2138 sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
2161 { /* FMAC FR0, FRm, FRn */
2162 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2164 if( IS_FPU_DOUBLEPREC() ) {
2165 DR(FRn) += DR(FRm)*DR(0);
2167 FR(FRn) += FR(FRm)*FR(0);
2178 sh4r.pc = sh4r.new_pc;
2180 sh4r.in_delay_slot = 0;
.