Search
lxdream.org :: lxdream/src/sh4/sh4core.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4core.c
changeset 260:c82e26ec0cac
prev246:98054d036a24
next265:5daf59b7f31b
author nkeynes
date Wed Jan 03 09:00:17 2007 +0000 (13 years ago)
permissions -rw-r--r--
last change Adjust timers when they're read rather than waiting until the next time
slice. Also temporarily cut the CPU time by 4.
Initialize the FRQCR register to 0x0E0A for convenience
view annotate diff log raw
     1 /**
     2  * $Id: sh4core.c,v 1.36 2007-01-03 09:00:17 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 /* CPU-generated exception code/vector pairs */
    38 #define EXC_POWER_RESET  0x000 /* vector special */
    39 #define EXC_MANUAL_RESET 0x020
    40 #define EXC_READ_ADDR_ERR 0x0E0
    41 #define EXC_WRITE_ADDR_ERR 0x100
    42 #define EXC_SLOT_ILLEGAL 0x1A0
    43 #define EXC_ILLEGAL      0x180
    44 #define EXC_TRAP         0x160
    45 #define EXC_FPDISABLE    0x800
    46 #define EXC_SLOT_FPDISABLE 0x820
    48 #define EXV_EXCEPTION    0x100  /* General exception vector */
    49 #define EXV_TLBMISS      0x400  /* TLB-miss exception vector */
    50 #define EXV_INTERRUPT    0x600  /* External interrupt vector */
    52 /********************** SH4 Module Definition ****************************/
    54 void sh4_init( void );
    55 void sh4_reset( void );
    56 uint32_t sh4_run_slice( uint32_t );
    57 void sh4_start( void );
    58 void sh4_stop( void );
    59 void sh4_save_state( FILE *f );
    60 int sh4_load_state( FILE *f );
    62 struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_reset, 
    63 				       NULL, sh4_run_slice, sh4_stop,
    64 				       sh4_save_state, sh4_load_state };
    66 struct sh4_registers sh4r;
    68 void sh4_init(void)
    69 {
    70     register_io_regions( mmio_list_sh4mmio );
    71     mmu_init();
    72     sh4_reset();
    73 }
    75 void sh4_reset(void)
    76 {
    77     /* zero everything out, for the sake of having a consistent state. */
    78     memset( &sh4r, 0, sizeof(sh4r) );
    80     /* Resume running if we were halted */
    81     sh4r.sh4_state = SH4_STATE_RUNNING;
    83     sh4r.pc    = 0xA0000000;
    84     sh4r.new_pc= 0xA0000002;
    85     sh4r.vbr   = 0x00000000;
    86     sh4r.fpscr = 0x00040001;
    87     sh4r.sr    = 0x700000F0;
    89     /* Mem reset will do this, but if we want to reset _just_ the SH4... */
    90     MMIO_WRITE( MMU, EXPEVT, EXC_POWER_RESET );
    92     /* Peripheral modules */
    93     CPG_reset();
    94     INTC_reset();
    95     TMU_reset();
    96     SCIF_reset();
    97 }
    99 static struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];
   100 static int sh4_breakpoint_count = 0;
   101 static uint16_t *sh4_icache = NULL;
   102 static uint32_t sh4_icache_addr = 0;
   104 void sh4_set_breakpoint( uint32_t pc, int type )
   105 {
   106     sh4_breakpoints[sh4_breakpoint_count].address = pc;
   107     sh4_breakpoints[sh4_breakpoint_count].type = type;
   108     sh4_breakpoint_count++;
   109 }
   111 gboolean sh4_clear_breakpoint( uint32_t pc, int type )
   112 {
   113     int i;
   115     for( i=0; i<sh4_breakpoint_count; i++ ) {
   116 	if( sh4_breakpoints[i].address == pc && 
   117 	    sh4_breakpoints[i].type == type ) {
   118 	    while( ++i < sh4_breakpoint_count ) {
   119 		sh4_breakpoints[i-1].address = sh4_breakpoints[i].address;
   120 		sh4_breakpoints[i-1].type = sh4_breakpoints[i].type;
   121 	    }
   122 	    sh4_breakpoint_count--;
   123 	    return TRUE;
   124 	}
   125     }
   126     return FALSE;
   127 }
   129 int sh4_get_breakpoint( uint32_t pc )
   130 {
   131     int i;
   132     for( i=0; i<sh4_breakpoint_count; i++ ) {
   133 	if( sh4_breakpoints[i].address == pc )
   134 	    return sh4_breakpoints[i].type;
   135     }
   136     return 0;
   137 }
   139 uint32_t sh4_run_slice( uint32_t nanosecs ) 
   140 {
   141     int target = sh4r.icount + nanosecs / sh4_cpu_period;
   142     int start = sh4r.icount;
   143     int i;
   145     if( sh4r.sh4_state != SH4_STATE_RUNNING ) {
   146 	if( sh4r.int_pending != 0 )
   147 	    sh4r.sh4_state = SH4_STATE_RUNNING;;
   148     }
   150     if( sh4_breakpoint_count == 0 ) {
   151 	for( sh4r.slice_cycle = 0; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
   152 	    if( !sh4_execute_instruction() ) {
   153 		break;
   154 	    }
   155 	}
   156     } else {
   158 	for( sh4r.slice_cycle = 0; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
   159 	    if( !sh4_execute_instruction() )
   160 		break;
   161 #ifdef ENABLE_DEBUG_MODE
   162 	    for( i=0; i<sh4_breakpoint_count; i++ ) {
   163 		if( sh4_breakpoints[i].address == sh4r.pc ) {
   164 		    break;
   165 		}
   166 	    }
   167 	    if( i != sh4_breakpoint_count ) {
   168 		dreamcast_stop();
   169 		if( sh4_breakpoints[i].type == BREAK_ONESHOT )
   170 		    sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );
   171 		break;
   172 	    }
   173 #endif	
   174 	}
   175     }
   177     /* If we aborted early, but the cpu is still technically running,
   178      * we're doing a hard abort - cut the timeslice back to what we
   179      * actually executed
   180      */
   181     if( sh4r.slice_cycle != nanosecs && sh4r.sh4_state == SH4_STATE_RUNNING ) {
   182 	nanosecs = sh4r.slice_cycle;
   183     }
   184     if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
   185 	TMU_run_slice( nanosecs );
   186 	SCIF_run_slice( nanosecs );
   187     }
   188     sh4r.icount += sh4r.slice_cycle / sh4_cpu_period;
   189     return nanosecs;
   190 }
   192 void sh4_stop(void)
   193 {
   195 }
   197 void sh4_save_state( FILE *f )
   198 {
   199     fwrite( &sh4r, sizeof(sh4r), 1, f );
   200     INTC_save_state( f );
   201     TMU_save_state( f );
   202     SCIF_save_state( f );
   203 }
   205 int sh4_load_state( FILE * f )
   206 {
   207     fread( &sh4r, sizeof(sh4r), 1, f );
   208     INTC_load_state( f );
   209     TMU_load_state( f );
   210     return SCIF_load_state( f );
   211 }
   213 /********************** SH4 emulation core  ****************************/
   215 void sh4_set_pc( int pc )
   216 {
   217     sh4r.pc = pc;
   218     sh4r.new_pc = pc+2;
   219 }
   221 #define UNDEF(ir) return sh4_raise_slot_exception(EXC_ILLEGAL, EXC_SLOT_ILLEGAL)
   222 #define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", sh4r.pc, ir ); dreamcast_stop(); return FALSE; }while(0)
   224 #if(SH4_CALLTRACE == 1)
   225 #define MAX_CALLSTACK 32
   226 static struct call_stack {
   227     sh4addr_t call_addr;
   228     sh4addr_t target_addr;
   229     sh4addr_t stack_pointer;
   230 } call_stack[MAX_CALLSTACK];
   232 static int call_stack_depth = 0;
   233 int sh4_call_trace_on = 0;
   235 static inline trace_call( sh4addr_t source, sh4addr_t dest ) 
   236 {
   237     if( call_stack_depth < MAX_CALLSTACK ) {
   238 	call_stack[call_stack_depth].call_addr = source;
   239 	call_stack[call_stack_depth].target_addr = dest;
   240 	call_stack[call_stack_depth].stack_pointer = sh4r.r[15];
   241     }
   242     call_stack_depth++;
   243 }
   245 static inline trace_return( sh4addr_t source, sh4addr_t dest )
   246 {
   247     if( call_stack_depth > 0 ) {
   248 	call_stack_depth--;
   249     }
   250 }
   252 void fprint_stack_trace( FILE *f )
   253 {
   254     int i = call_stack_depth -1;
   255     if( i >= MAX_CALLSTACK )
   256 	i = MAX_CALLSTACK - 1;
   257     for( ; i >= 0; i-- ) {
   258 	fprintf( f, "%d. Call from %08X => %08X, SP=%08X\n", 
   259 		 (call_stack_depth - i), call_stack[i].call_addr,
   260 		 call_stack[i].target_addr, call_stack[i].stack_pointer );
   261     }
   262 }
   264 #define TRACE_CALL( source, dest ) trace_call(source, dest)
   265 #define TRACE_RETURN( source, dest ) trace_return(source, dest)
   266 #else
   267 #define TRACE_CALL( dest, rts ) 
   268 #define TRACE_RETURN( source, dest )
   269 #endif
   271 #define RAISE( x, v ) do{			\
   272     if( sh4r.vbr == 0 ) { \
   273         ERROR( "%08X: VBR not initialized while raising exception %03X, halting", sh4r.pc, x ); \
   274         dreamcast_stop(); return FALSE;	\
   275     } else { \
   276         sh4r.spc = sh4r.pc;	\
   277         sh4r.ssr = sh4_read_sr(); \
   278         sh4r.sgr = sh4r.r[15]; \
   279         MMIO_WRITE(MMU,EXPEVT,x); \
   280         sh4r.pc = sh4r.vbr + v; \
   281         sh4r.new_pc = sh4r.pc + 2; \
   282         sh4_load_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB ); \
   283 	if( sh4r.in_delay_slot ) { \
   284 	    sh4r.in_delay_slot = 0; \
   285 	    sh4r.spc -= 2; \
   286 	} \
   287     } \
   288     return TRUE; } while(0)
   290 #define MEM_READ_BYTE( addr ) sh4_read_byte(addr)
   291 #define MEM_READ_WORD( addr ) sh4_read_word(addr)
   292 #define MEM_READ_LONG( addr ) sh4_read_long(addr)
   293 #define MEM_WRITE_BYTE( addr, val ) sh4_write_byte(addr, val)
   294 #define MEM_WRITE_WORD( addr, val ) sh4_write_word(addr, val)
   295 #define MEM_WRITE_LONG( addr, val ) sh4_write_long(addr, val)
   297 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)
   299 #define MEM_FP_READ( addr, reg ) sh4_read_float( addr, reg );
   300 #define MEM_FP_WRITE( addr, reg ) sh4_write_float( addr, reg );
   302 #define CHECKPRIV() if( !IS_SH4_PRIVMODE() ) return sh4_raise_slot_exception( EXC_ILLEGAL, EXC_SLOT_ILLEGAL )
   303 #define CHECKRALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_READ_ADDR_ERR )
   304 #define CHECKRALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_READ_ADDR_ERR )
   305 #define CHECKWALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_WRITE_ADDR_ERR )
   306 #define CHECKWALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_WRITE_ADDR_ERR )
   308 #define CHECKFPUEN() if( !IS_FPU_ENABLED() ) return sh4_raise_slot_exception( EXC_FPDISABLE, EXC_SLOT_FPDISABLE )
   309 #define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }
   310 #define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)
   312 static void sh4_switch_banks( )
   313 {
   314     uint32_t tmp[8];
   316     memcpy( tmp, sh4r.r, sizeof(uint32_t)*8 );
   317     memcpy( sh4r.r, sh4r.r_bank, sizeof(uint32_t)*8 );
   318     memcpy( sh4r.r_bank, tmp, sizeof(uint32_t)*8 );
   319 }
   321 static void sh4_load_sr( uint32_t newval )
   322 {
   323     if( (newval ^ sh4r.sr) & SR_RB )
   324         sh4_switch_banks();
   325     sh4r.sr = newval;
   326     sh4r.t = (newval&SR_T) ? 1 : 0;
   327     sh4r.s = (newval&SR_S) ? 1 : 0;
   328     sh4r.m = (newval&SR_M) ? 1 : 0;
   329     sh4r.q = (newval&SR_Q) ? 1 : 0;
   330     intc_mask_changed();
   331 }
   333 static void sh4_write_float( uint32_t addr, int reg )
   334 {
   335     if( IS_FPU_DOUBLESIZE() ) {
   336 	if( reg & 1 ) {
   337 	    sh4_write_long( addr, *((uint32_t *)&XF((reg)&0x0E)) );
   338 	    sh4_write_long( addr+4, *((uint32_t *)&XF(reg)) );
   339 	} else {
   340 	    sh4_write_long( addr, *((uint32_t *)&FR(reg)) ); 
   341 	    sh4_write_long( addr+4, *((uint32_t *)&FR((reg)|0x01)) );
   342 	}
   343     } else {
   344 	sh4_write_long( addr, *((uint32_t *)&FR((reg))) );
   345     }
   346 }
   348 static void sh4_read_float( uint32_t addr, int reg )
   349 {
   350     if( IS_FPU_DOUBLESIZE() ) {
   351 	if( reg & 1 ) {
   352 	    *((uint32_t *)&XF((reg) & 0x0E)) = sh4_read_long(addr);
   353 	    *((uint32_t *)&XF(reg)) = sh4_read_long(addr+4);
   354 	} else {
   355 	    *((uint32_t *)&FR(reg)) = sh4_read_long(addr);
   356 	    *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(addr+4);
   357 	}
   358     } else {
   359 	*((uint32_t *)&FR(reg)) = sh4_read_long(addr);
   360     }
   361 }
   363 static uint32_t sh4_read_sr( void )
   364 {
   365     /* synchronize sh4r.sr with the various bitflags */
   366     sh4r.sr &= SR_MQSTMASK;
   367     if( sh4r.t ) sh4r.sr |= SR_T;
   368     if( sh4r.s ) sh4r.sr |= SR_S;
   369     if( sh4r.m ) sh4r.sr |= SR_M;
   370     if( sh4r.q ) sh4r.sr |= SR_Q;
   371     return sh4r.sr;
   372 }
   374 /**
   375  * Raise a general CPU exception for the specified exception code.
   376  * (NOT for TRAPA or TLB exceptions)
   377  */
   378 gboolean sh4_raise_exception( int code )
   379 {
   380     RAISE( code, EXV_EXCEPTION );
   381 }
   383 gboolean sh4_raise_slot_exception( int normal_code, int slot_code ) {
   384     if( sh4r.in_delay_slot ) {
   385 	return sh4_raise_exception(slot_code);
   386     } else {
   387 	return sh4_raise_exception(normal_code);
   388     }
   389 }
   391 gboolean sh4_raise_tlb_exception( int code )
   392 {
   393     RAISE( code, EXV_TLBMISS );
   394 }
   396 static void sh4_accept_interrupt( void )
   397 {
   398     uint32_t code = intc_accept_interrupt();
   399     sh4r.ssr = sh4_read_sr();
   400     sh4r.spc = sh4r.pc;
   401     sh4r.sgr = sh4r.r[15];
   402     sh4_load_sr( sh4r.ssr|SR_BL|SR_MD|SR_RB );
   403     MMIO_WRITE( MMU, INTEVT, code );
   404     sh4r.pc = sh4r.vbr + 0x600;
   405     sh4r.new_pc = sh4r.pc + 2;
   406     //    WARN( "Accepting interrupt %03X, from %08X => %08X", code, sh4r.spc, sh4r.pc );
   407 }
   409 gboolean sh4_execute_instruction( void )
   410 {
   411     uint32_t pc;
   412     unsigned short ir;
   413     uint32_t tmp;
   414     uint64_t tmpl;
   415     float ftmp;
   416     double dtmp;
   418 #define R0 sh4r.r[0]
   419 #define FR0 FR(0)
   420 #define DR0 DR(0)
   421 #define RN(ir) sh4r.r[(ir&0x0F00)>>8]
   422 #define RN_BANK(ir) sh4r.r_bank[(ir&0x0070)>>4]
   423 #define RM(ir) sh4r.r[(ir&0x00F0)>>4]
   424 #define DISP4(ir) (ir&0x000F) /* 4-bit displacements are *NOT* sign-extended */
   425 #define DISP8(ir) (ir&0x00FF)
   426 #define PCDISP8(ir) SIGNEXT8(ir&0x00FF)
   427 #define IMM8(ir) SIGNEXT8(ir&0x00FF)
   428 #define UIMM8(ir) (ir&0x00FF) /* Unsigned immmediate */
   429 #define DISP12(ir) SIGNEXT12(ir&0x0FFF)
   430 #define FRNn(ir) ((ir&0x0F00)>>8)
   431 #define FRMn(ir) ((ir&0x00F0)>>4)
   432 #define DRNn(ir) ((ir&0x0E00)>>9)
   433 #define DRMn(ir) ((ir&0x00E0)>>5)
   434 #define FVN(ir) ((ir&0x0C00)>>8)
   435 #define FVM(ir) ((ir&0x0300)>>6)
   436 #define FRN(ir) FR(FRNn(ir))
   437 #define FRM(ir) FR(FRMn(ir))
   438 #define FRNi(ir) (*((uint32_t *)&FR(FRNn(ir))))
   439 #define FRMi(ir) (*((uint32_t *)&FR(FRMn(ir))))
   440 #define DRN(ir) DRb(DRNn(ir), ir&0x0100)
   441 #define DRM(ir) DRb(DRMn(ir),ir&0x0010)
   442 #define DRNi(ir) (*((uint64_t *)&DR(FRNn(ir))))
   443 #define DRMi(ir) (*((uint64_t *)&DR(FRMn(ir))))
   444 #define FPULf   *((float *)&sh4r.fpul)
   445 #define FPULi    (sh4r.fpul)
   447     if( SH4_INT_PENDING() ) 
   448         sh4_accept_interrupt();
   450     pc = sh4r.pc;
   451     if( pc > 0xFFFFFF00 ) {
   452 	/* SYSCALL Magic */
   453 	syscall_invoke( pc );
   454 	sh4r.in_delay_slot = 0;
   455 	pc = sh4r.pc = sh4r.pr;
   456 	sh4r.new_pc = sh4r.pc + 2;
   457     }
   458     CHECKRALIGN16(pc);
   460     /* Read instruction */
   461     uint32_t pageaddr = pc >> 12;
   462     if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {
   463 	ir = sh4_icache[(pc&0xFFF)>>1];
   464     } else {
   465 	sh4_icache = (uint16_t *)mem_get_page(pc);
   466 	if( ((uint32_t)sh4_icache) < MAX_IO_REGIONS ) {
   467 	    /* If someone's actually been so daft as to try to execute out of an IO
   468 	     * region, fallback on the full-blown memory read
   469 	     */
   470 	    sh4_icache = NULL;
   471 	    ir = MEM_READ_WORD(pc);
   472 	} else {
   473 	    sh4_icache_addr = pageaddr;
   474 	    ir = sh4_icache[(pc&0xFFF)>>1];
   475 	}
   476     }
   477     sh4r.icount++;
   479     switch( (ir&0xF000)>>12 ) {
   480         case 0: /* 0000nnnnmmmmxxxx */
   481             switch( ir&0x000F ) {
   482                 case 2:
   483                     switch( (ir&0x00F0)>>4 ) {
   484                         case 0: /* STC     SR, Rn */
   485                             CHECKPRIV();
   486                             RN(ir) = sh4_read_sr();
   487                             break;
   488                         case 1: /* STC     GBR, Rn */
   489                             RN(ir) = sh4r.gbr;
   490                             break;
   491                         case 2: /* STC     VBR, Rn */
   492                             CHECKPRIV();
   493                             RN(ir) = sh4r.vbr;
   494                             break;
   495                         case 3: /* STC     SSR, Rn */
   496                             CHECKPRIV();
   497                             RN(ir) = sh4r.ssr;
   498                             break;
   499                         case 4: /* STC     SPC, Rn */
   500                             CHECKPRIV();
   501                             RN(ir) = sh4r.spc;
   502                             break;
   503                         case 8: case 9: case 10: case 11: case 12: case 13:
   504                         case 14: case 15:/* STC     Rm_bank, Rn */
   505                             CHECKPRIV();
   506                             RN(ir) = RN_BANK(ir);
   507                             break;
   508                         default: UNDEF(ir);
   509                     }
   510                     break;
   511                 case 3:
   512                     switch( (ir&0x00F0)>>4 ) {
   513                         case 0: /* BSRF    Rn */
   514                             CHECKSLOTILLEGAL();
   515                             CHECKDEST( pc + 4 + RN(ir) );
   516                             sh4r.in_delay_slot = 1;
   517                             sh4r.pr = sh4r.pc + 4;
   518                             sh4r.pc = sh4r.new_pc;
   519                             sh4r.new_pc = pc + 4 + RN(ir);
   520 			    TRACE_CALL( pc, sh4r.new_pc );
   521                             return TRUE;
   522                         case 2: /* BRAF    Rn */
   523                             CHECKSLOTILLEGAL();
   524                             CHECKDEST( pc + 4 + RN(ir) );
   525                             sh4r.in_delay_slot = 1;
   526                             sh4r.pc = sh4r.new_pc;
   527                             sh4r.new_pc = pc + 4 + RN(ir);
   528                             return TRUE;
   529                         case 8: /* PREF    [Rn] */
   530                             tmp = RN(ir);
   531                             if( (tmp & 0xFC000000) == 0xE0000000 ) {
   532                                 /* Store queue operation */
   533                                 int queue = (tmp&0x20)>>2;
   534                                 int32_t *src = &sh4r.store_queue[queue];
   535                                 uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;
   536                                 uint32_t target = tmp&0x03FFFFE0 | hi;
   537                                 mem_copy_to_sh4( target, src, 32 );
   538                             }
   539                             break;
   540                         case 9: /* OCBI    [Rn] */
   541                         case 10:/* OCBP    [Rn] */
   542                         case 11:/* OCBWB   [Rn] */
   543                             /* anything? */
   544                             break;
   545                         case 12:/* MOVCA.L R0, [Rn] */
   546 			    tmp = RN(ir);
   547 			    CHECKWALIGN32(tmp);
   548 			    MEM_WRITE_LONG( tmp, R0 );
   549 			    break;
   550                         default: UNDEF(ir);
   551                     }
   552                     break;
   553                 case 4: /* MOV.B   Rm, [R0 + Rn] */
   554                     MEM_WRITE_BYTE( R0 + RN(ir), RM(ir) );
   555                     break;
   556                 case 5: /* MOV.W   Rm, [R0 + Rn] */
   557 		    CHECKWALIGN16( R0 + RN(ir) );
   558                     MEM_WRITE_WORD( R0 + RN(ir), RM(ir) );
   559                     break;
   560                 case 6: /* MOV.L   Rm, [R0 + Rn] */
   561 		    CHECKWALIGN32( R0 + RN(ir) );
   562                     MEM_WRITE_LONG( R0 + RN(ir), RM(ir) );
   563                     break;
   564                 case 7: /* MUL.L   Rm, Rn */
   565                     sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
   566                         (RM(ir) * RN(ir));
   567                     break;
   568                 case 8: 
   569                     switch( (ir&0x0FF0)>>4 ) {
   570                         case 0: /* CLRT    */
   571                             sh4r.t = 0;
   572                             break;
   573                         case 1: /* SETT    */
   574                             sh4r.t = 1;
   575                             break;
   576                         case 2: /* CLRMAC  */
   577                             sh4r.mac = 0;
   578                             break;
   579                         case 3: /* LDTLB   */
   580                             break;
   581                         case 4: /* CLRS    */
   582                             sh4r.s = 0;
   583                             break;
   584                         case 5: /* SETS    */
   585                             sh4r.s = 1;
   586                             break;
   587                         default: UNDEF(ir);
   588                     }
   589                     break;
   590                 case 9: 
   591                     if( (ir&0x00F0) == 0x20 ) /* MOVT    Rn */
   592                         RN(ir) = sh4r.t;
   593                     else if( ir == 0x0019 ) /* DIV0U   */
   594                         sh4r.m = sh4r.q = sh4r.t = 0;
   595                     else if( ir == 0x0009 )
   596                         /* NOP     */;
   597                     else UNDEF(ir);
   598                     break;
   599                 case 10:
   600                     switch( (ir&0x00F0) >> 4 ) {
   601                         case 0: /* STS     MACH, Rn */
   602                             RN(ir) = sh4r.mac >> 32;
   603                             break;
   604                         case 1: /* STS     MACL, Rn */
   605                             RN(ir) = (uint32_t)sh4r.mac;
   606                             break;
   607                         case 2: /* STS     PR, Rn */
   608                             RN(ir) = sh4r.pr;
   609                             break;
   610                         case 3: /* STC     SGR, Rn */
   611                             CHECKPRIV();
   612                             RN(ir) = sh4r.sgr;
   613                             break;
   614                         case 5:/* STS      FPUL, Rn */
   615                             RN(ir) = sh4r.fpul;
   616                             break;
   617                         case 6: /* STS     FPSCR, Rn */
   618                             RN(ir) = sh4r.fpscr;
   619                             break;
   620                         case 15:/* STC     DBR, Rn */
   621                             CHECKPRIV();
   622                             RN(ir) = sh4r.dbr;
   623                             break;
   624                         default: UNDEF(ir);
   625                     }
   626                     break;
   627                 case 11:
   628                     switch( (ir&0x0FF0)>>4 ) {
   629                         case 0: /* RTS     */
   630                             CHECKSLOTILLEGAL();
   631                             CHECKDEST( sh4r.pr );
   632                             sh4r.in_delay_slot = 1;
   633                             sh4r.pc = sh4r.new_pc;
   634                             sh4r.new_pc = sh4r.pr;
   635                             TRACE_RETURN( pc, sh4r.new_pc );
   636                             return TRUE;
   637                         case 1: /* SLEEP   */
   638 			    if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
   639 				sh4r.sh4_state = SH4_STATE_STANDBY;
   640 			    } else {
   641 				sh4r.sh4_state = SH4_STATE_SLEEP;
   642 			    }
   643 			    return FALSE; /* Halt CPU */
   644                         case 2: /* RTE     */
   645                             CHECKPRIV();
   646                             CHECKDEST( sh4r.spc );
   647                             CHECKSLOTILLEGAL();
   648                             sh4r.in_delay_slot = 1;
   649                             sh4r.pc = sh4r.new_pc;
   650                             sh4r.new_pc = sh4r.spc;
   651                             sh4_load_sr( sh4r.ssr );
   652                             return TRUE;
   653                         default:UNDEF(ir);
   654                     }
   655                     break;
   656                 case 12:/* MOV.B   [R0+R%d], R%d */
   657                     RN(ir) = MEM_READ_BYTE( R0 + RM(ir) );
   658                     break;
   659                 case 13:/* MOV.W   [R0+R%d], R%d */
   660 		    CHECKRALIGN16( R0 + RM(ir) );
   661                     RN(ir) = MEM_READ_WORD( R0 + RM(ir) );
   662                     break;
   663                 case 14:/* MOV.L   [R0+R%d], R%d */
   664 		    CHECKRALIGN32( R0 + RM(ir) );
   665                     RN(ir) = MEM_READ_LONG( R0 + RM(ir) );
   666                     break;
   667                 case 15:/* MAC.L   [Rm++], [Rn++] */
   668 		    CHECKRALIGN32( RM(ir) );
   669 		    CHECKRALIGN32( RN(ir) );
   670                     tmpl = ( SIGNEXT32(MEM_READ_LONG(RM(ir))) *
   671                                   SIGNEXT32(MEM_READ_LONG(RN(ir))) );
   672                     if( sh4r.s ) {
   673                         /* 48-bit Saturation. Yuch */
   674                         tmpl += SIGNEXT48(sh4r.mac);
   675                         if( tmpl < 0xFFFF800000000000LL )
   676                             tmpl = 0xFFFF800000000000LL;
   677                         else if( tmpl > 0x00007FFFFFFFFFFFLL )
   678                             tmpl = 0x00007FFFFFFFFFFFLL;
   679                         sh4r.mac = (sh4r.mac&0xFFFF000000000000LL) |
   680                             (tmpl&0x0000FFFFFFFFFFFFLL);
   681                     } else sh4r.mac = tmpl;
   683                     RM(ir) += 4;
   684                     RN(ir) += 4;
   686                     break;
   687                 default: UNDEF(ir);
   688             }
   689             break;
   690         case 1: /* 0001nnnnmmmmdddd */
   691             /* MOV.L   Rm, [Rn + disp4*4] */
   692 	    tmp = RN(ir) + (DISP4(ir)<<2);
   693 	    CHECKWALIGN32( tmp );
   694             MEM_WRITE_LONG( tmp, RM(ir) );
   695             break;
   696         case 2: /* 0010nnnnmmmmxxxx */
   697             switch( ir&0x000F ) {
   698                 case 0: /* MOV.B   Rm, [Rn] */
   699                     MEM_WRITE_BYTE( RN(ir), RM(ir) );
   700                     break;
   701                 case 1: /* MOV.W   Rm, [Rn] */
   702                	    CHECKWALIGN16( RN(ir) );
   703 		    MEM_WRITE_WORD( RN(ir), RM(ir) );
   704                     break;
   705                 case 2: /* MOV.L   Rm, [Rn] */
   706 		    CHECKWALIGN32( RN(ir) );
   707                     MEM_WRITE_LONG( RN(ir), RM(ir) );
   708                     break;
   709                 case 3: UNDEF(ir);
   710                     break;
   711                 case 4: /* MOV.B   Rm, [--Rn] */
   712                     RN(ir) --;
   713                     MEM_WRITE_BYTE( RN(ir), RM(ir) );
   714                     break;
   715                 case 5: /* MOV.W   Rm, [--Rn] */
   716                     RN(ir) -= 2;
   717 		    CHECKWALIGN16( RN(ir) );
   718                     MEM_WRITE_WORD( RN(ir), RM(ir) );
   719                     break;
   720                 case 6: /* MOV.L   Rm, [--Rn] */
   721                     RN(ir) -= 4;
   722 		    CHECKWALIGN32( RN(ir) );
   723                     MEM_WRITE_LONG( RN(ir), RM(ir) );
   724                     break;
   725                 case 7: /* DIV0S   Rm, Rn */
   726                     sh4r.q = RN(ir)>>31;
   727                     sh4r.m = RM(ir)>>31;
   728                     sh4r.t = sh4r.q ^ sh4r.m;
   729                     break;
   730                 case 8: /* TST     Rm, Rn */
   731                     sh4r.t = (RN(ir)&RM(ir) ? 0 : 1);
   732                     break;
   733                 case 9: /* AND     Rm, Rn */
   734                     RN(ir) &= RM(ir);
   735                     break;
   736                 case 10:/* XOR     Rm, Rn */
   737                     RN(ir) ^= RM(ir);
   738                     break;
   739                 case 11:/* OR      Rm, Rn */
   740                     RN(ir) |= RM(ir);
   741                     break;
   742                 case 12:/* CMP/STR Rm, Rn */
   743                     /* set T = 1 if any byte in RM & RN is the same */
   744                     tmp = RM(ir) ^ RN(ir);
   745                     sh4r.t = ((tmp&0x000000FF)==0 || (tmp&0x0000FF00)==0 ||
   746                               (tmp&0x00FF0000)==0 || (tmp&0xFF000000)==0)?1:0;
   747                     break;
   748                 case 13:/* XTRCT   Rm, Rn */
   749                     RN(ir) = (RN(ir)>>16) | (RM(ir)<<16);
   750                     break;
   751                 case 14:/* MULU.W  Rm, Rn */
   752                     sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
   753                         (uint32_t)((RM(ir)&0xFFFF) * (RN(ir)&0xFFFF));
   754                     break;
   755                 case 15:/* MULS.W  Rm, Rn */
   756                     sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
   757                         (uint32_t)(SIGNEXT32(RM(ir)&0xFFFF) * SIGNEXT32(RN(ir)&0xFFFF));
   758                     break;
   759             }
   760             break;
   761         case 3: /* 0011nnnnmmmmxxxx */
   762             switch( ir&0x000F ) {
   763                 case 0: /* CMP/EQ  Rm, Rn */
   764                     sh4r.t = ( RM(ir) == RN(ir) ? 1 : 0 );
   765                     break;
   766                 case 2: /* CMP/HS  Rm, Rn */
   767                     sh4r.t = ( RN(ir) >= RM(ir) ? 1 : 0 );
   768                     break;
   769                 case 3: /* CMP/GE  Rm, Rn */
   770                     sh4r.t = ( ((int32_t)RN(ir)) >= ((int32_t)RM(ir)) ? 1 : 0 );
   771                     break;
   772                 case 4: { /* DIV1    Rm, Rn */
   773                     /* This is just from the sh4p manual with some
   774                      * simplifications (someone want to check it's correct? :)
   775                      * Why they couldn't just provide a real DIV instruction...
   776                      * Please oh please let the translator batch these things
   777                      * up into a single DIV... */
   778                     uint32_t tmp0, tmp1, tmp2, dir;
   780                     dir = sh4r.q ^ sh4r.m;
   781                     sh4r.q = (RN(ir) >> 31);
   782                     tmp2 = RM(ir);
   783                     RN(ir) = (RN(ir) << 1) | sh4r.t;
   784                     tmp0 = RN(ir);
   785                     if( dir ) {
   786                         RN(ir) += tmp2;
   787                         tmp1 = (RN(ir)<tmp0 ? 1 : 0 );
   788                     } else {
   789                         RN(ir) -= tmp2;
   790                         tmp1 = (RN(ir)>tmp0 ? 1 : 0 );
   791                     }
   792                     sh4r.q ^= sh4r.m ^ tmp1;
   793                     sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );
   794                     break; }
   795                 case 5: /* DMULU.L Rm, Rn */
   796                     sh4r.mac = ((uint64_t)RM(ir)) * ((uint64_t)RN(ir));
   797                     break;
   798                 case 6: /* CMP/HI  Rm, Rn */
   799                     sh4r.t = ( RN(ir) > RM(ir) ? 1 : 0 );
   800                     break;
   801                 case 7: /* CMP/GT  Rm, Rn */
   802                     sh4r.t = ( ((int32_t)RN(ir)) > ((int32_t)RM(ir)) ? 1 : 0 );
   803                     break;
   804                 case 8: /* SUB     Rm, Rn */
   805                     RN(ir) -= RM(ir);
   806                     break;
   807                 case 10:/* SUBC    Rm, Rn */
   808                     tmp = RN(ir);
   809                     RN(ir) = RN(ir) - RM(ir) - sh4r.t;
   810                     sh4r.t = (RN(ir) > tmp || (RN(ir) == tmp && sh4r.t == 1));
   811                     break;
   812                 case 11:/* SUBV    Rm, Rn */
   813                     UNIMP(ir);
   814                     break;
   815                 case 12:/* ADD     Rm, Rn */
   816                     RN(ir) += RM(ir);
   817                     break;
   818                 case 13:/* DMULS.L Rm, Rn */
   819                     sh4r.mac = SIGNEXT32(RM(ir)) * SIGNEXT32(RN(ir));
   820                     break;
   821                 case 14:/* ADDC    Rm, Rn */
   822                     tmp = RN(ir);
   823                     RN(ir) += RM(ir) + sh4r.t;
   824                     sh4r.t = ( RN(ir) < tmp || (RN(ir) == tmp && sh4r.t != 0) ? 1 : 0 );
   825                     break;
   826                 case 15:/* ADDV    Rm, Rn */
   827 		    tmp = RN(ir) + RM(ir);
   828 		    sh4r.t = ( (RN(ir)>>31) == (RM(ir)>>31) && ((RN(ir)>>31) != (tmp>>31)) );
   829 		    RN(ir) = tmp;
   830                     break;
   831                 default: UNDEF(ir);
   832             }
   833             break;
   834         case 4: /* 0100nnnnxxxxxxxx */
   835             switch( ir&0x00FF ) {
   836                 case 0x00: /* SHLL    Rn */
   837                     sh4r.t = RN(ir) >> 31;
   838                     RN(ir) <<= 1;
   839                     break;
   840                 case 0x01: /* SHLR    Rn */
   841                     sh4r.t = RN(ir) & 0x00000001;
   842                     RN(ir) >>= 1;
   843                     break;
   844                 case 0x02: /* STS.L   MACH, [--Rn] */
   845                     RN(ir) -= 4;
   846 		    CHECKWALIGN32( RN(ir) );
   847                     MEM_WRITE_LONG( RN(ir), (sh4r.mac>>32) );
   848                     break;
   849                 case 0x03: /* STC.L   SR, [--Rn] */
   850                     CHECKPRIV();
   851                     RN(ir) -= 4;
   852 		    CHECKWALIGN32( RN(ir) );
   853                     MEM_WRITE_LONG( RN(ir), sh4_read_sr() );
   854                     break;
   855                 case 0x04: /* ROTL    Rn */
   856                     sh4r.t = RN(ir) >> 31;
   857                     RN(ir) <<= 1;
   858                     RN(ir) |= sh4r.t;
   859                     break;
   860                 case 0x05: /* ROTR    Rn */
   861                     sh4r.t = RN(ir) & 0x00000001;
   862                     RN(ir) >>= 1;
   863                     RN(ir) |= (sh4r.t << 31);
   864                     break;
   865                 case 0x06: /* LDS.L   [Rn++], MACH */
   866 		    CHECKRALIGN32( RN(ir) );
   867                     sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
   868                         (((uint64_t)MEM_READ_LONG(RN(ir)))<<32);
   869                     RN(ir) += 4;
   870                     break;
   871                 case 0x07: /* LDC.L   [Rn++], SR */
   872 		    CHECKSLOTILLEGAL();
   873                     CHECKPRIV();
   874 		    CHECKWALIGN32( RN(ir) );
   875                     sh4_load_sr( MEM_READ_LONG(RN(ir)) );
   876                     RN(ir) +=4;
   877                     break;
   878                 case 0x08: /* SHLL2   Rn */
   879                     RN(ir) <<= 2;
   880                     break;
   881                 case 0x09: /* SHLR2   Rn */
   882                     RN(ir) >>= 2;
   883                     break;
   884                 case 0x0A: /* LDS     Rn, MACH */
   885                     sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
   886                         (((uint64_t)RN(ir))<<32);
   887                     break;
   888                 case 0x0B: /* JSR     [Rn] */
   889                     CHECKDEST( RN(ir) );
   890                     CHECKSLOTILLEGAL();
   891                     sh4r.in_delay_slot = 1;
   892                     sh4r.pc = sh4r.new_pc;
   893                     sh4r.new_pc = RN(ir);
   894                     sh4r.pr = pc + 4;
   895 		    TRACE_CALL( pc, sh4r.new_pc );
   896                     return TRUE;
   897                 case 0x0E: /* LDC     Rn, SR */
   898 		    CHECKSLOTILLEGAL();
   899                     CHECKPRIV();
   900                     sh4_load_sr( RN(ir) );
   901                     break;
   902                 case 0x10: /* DT      Rn */
   903                     RN(ir) --;
   904                     sh4r.t = ( RN(ir) == 0 ? 1 : 0 );
   905                     break;
   906                 case 0x11: /* CMP/PZ  Rn */
   907                     sh4r.t = ( ((int32_t)RN(ir)) >= 0 ? 1 : 0 );
   908                     break;
   909                 case 0x12: /* STS.L   MACL, [--Rn] */
   910                     RN(ir) -= 4;
   911 		    CHECKWALIGN32( RN(ir) );
   912                     MEM_WRITE_LONG( RN(ir), (uint32_t)sh4r.mac );
   913                     break;
   914                 case 0x13: /* STC.L   GBR, [--Rn] */
   915                     RN(ir) -= 4;
   916 		    CHECKWALIGN32( RN(ir) );
   917                     MEM_WRITE_LONG( RN(ir), sh4r.gbr );
   918                     break;
   919                 case 0x15: /* CMP/PL  Rn */
   920                     sh4r.t = ( ((int32_t)RN(ir)) > 0 ? 1 : 0 );
   921                     break;
   922                 case 0x16: /* LDS.L   [Rn++], MACL */
   923 		    CHECKRALIGN32( RN(ir) );
   924                     sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
   925                         (uint64_t)((uint32_t)MEM_READ_LONG(RN(ir)));
   926                     RN(ir) += 4;
   927                     break;
   928                 case 0x17: /* LDC.L   [Rn++], GBR */
   929 		    CHECKRALIGN32( RN(ir) );
   930                     sh4r.gbr = MEM_READ_LONG(RN(ir));
   931                     RN(ir) +=4;
   932                     break;
   933                 case 0x18: /* SHLL8   Rn */
   934                     RN(ir) <<= 8;
   935                     break;
   936                 case 0x19: /* SHLR8   Rn */
   937                     RN(ir) >>= 8;
   938                     break;
   939                 case 0x1A: /* LDS     Rn, MACL */
   940                     sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
   941                         (uint64_t)((uint32_t)(RN(ir)));
   942                     break;
   943                 case 0x1B: /* TAS.B   [Rn] */
   944                     tmp = MEM_READ_BYTE( RN(ir) );
   945                     sh4r.t = ( tmp == 0 ? 1 : 0 );
   946                     MEM_WRITE_BYTE( RN(ir), tmp | 0x80 );
   947                     break;
   948                 case 0x1E: /* LDC     Rn, GBR */
   949                     sh4r.gbr = RN(ir);
   950                     break;
   951                 case 0x20: /* SHAL    Rn */
   952                     sh4r.t = RN(ir) >> 31;
   953                     RN(ir) <<= 1;
   954                     break;
   955                 case 0x21: /* SHAR    Rn */
   956                     sh4r.t = RN(ir) & 0x00000001;
   957                     RN(ir) = ((int32_t)RN(ir)) >> 1;
   958                     break;
   959                 case 0x22: /* STS.L   PR, [--Rn] */
   960                     RN(ir) -= 4;
   961 		    CHECKWALIGN32( RN(ir) );
   962                     MEM_WRITE_LONG( RN(ir), sh4r.pr );
   963                     break;
   964                 case 0x23: /* STC.L   VBR, [--Rn] */
   965                     CHECKPRIV();
   966                     RN(ir) -= 4;
   967 		    CHECKWALIGN32( RN(ir) );
   968                     MEM_WRITE_LONG( RN(ir), sh4r.vbr );
   969                     break;
   970                 case 0x24: /* ROTCL   Rn */
   971                     tmp = RN(ir) >> 31;
   972                     RN(ir) <<= 1;
   973                     RN(ir) |= sh4r.t;
   974                     sh4r.t = tmp;
   975                     break;
   976                 case 0x25: /* ROTCR   Rn */
   977                     tmp = RN(ir) & 0x00000001;
   978                     RN(ir) >>= 1;
   979                     RN(ir) |= (sh4r.t << 31 );
   980                     sh4r.t = tmp;
   981                     break;
   982                 case 0x26: /* LDS.L   [Rn++], PR */
   983 		    CHECKRALIGN32( RN(ir) );
   984                     sh4r.pr = MEM_READ_LONG( RN(ir) );
   985                     RN(ir) += 4;
   986                     break;
   987                 case 0x27: /* LDC.L   [Rn++], VBR */
   988                     CHECKPRIV();
   989 		    CHECKRALIGN32( RN(ir) );
   990                     sh4r.vbr = MEM_READ_LONG(RN(ir));
   991                     RN(ir) +=4;
   992                     break;
   993                 case 0x28: /* SHLL16  Rn */
   994                     RN(ir) <<= 16;
   995                     break;
   996                 case 0x29: /* SHLR16  Rn */
   997                     RN(ir) >>= 16;
   998                     break;
   999                 case 0x2A: /* LDS     Rn, PR */
  1000                     sh4r.pr = RN(ir);
  1001                     break;
  1002                 case 0x2B: /* JMP     [Rn] */
  1003                     CHECKDEST( RN(ir) );
  1004                     CHECKSLOTILLEGAL();
  1005                     sh4r.in_delay_slot = 1;
  1006                     sh4r.pc = sh4r.new_pc;
  1007                     sh4r.new_pc = RN(ir);
  1008                     return TRUE;
  1009                 case 0x2E: /* LDC     Rn, VBR */
  1010                     CHECKPRIV();
  1011                     sh4r.vbr = RN(ir);
  1012                     break;
  1013                 case 0x32: /* STC.L   SGR, [--Rn] */
  1014                     CHECKPRIV();
  1015                     RN(ir) -= 4;
  1016 		    CHECKWALIGN32( RN(ir) );
  1017                     MEM_WRITE_LONG( RN(ir), sh4r.sgr );
  1018                     break;
  1019                 case 0x33: /* STC.L   SSR, [--Rn] */
  1020                     CHECKPRIV();
  1021                     RN(ir) -= 4;
  1022 		    CHECKWALIGN32( RN(ir) );
  1023                     MEM_WRITE_LONG( RN(ir), sh4r.ssr );
  1024                     break;
  1025                 case 0x37: /* LDC.L   [Rn++], SSR */
  1026                     CHECKPRIV();
  1027 		    CHECKRALIGN32( RN(ir) );
  1028                     sh4r.ssr = MEM_READ_LONG(RN(ir));
  1029                     RN(ir) +=4;
  1030                     break;
  1031                 case 0x3E: /* LDC     Rn, SSR */
  1032                     CHECKPRIV();
  1033                     sh4r.ssr = RN(ir);
  1034                     break;
  1035                 case 0x43: /* STC.L   SPC, [--Rn] */
  1036                     CHECKPRIV();
  1037                     RN(ir) -= 4;
  1038 		    CHECKWALIGN32( RN(ir) );
  1039                     MEM_WRITE_LONG( RN(ir), sh4r.spc );
  1040                     break;
  1041                 case 0x47: /* LDC.L   [Rn++], SPC */
  1042                     CHECKPRIV();
  1043 		    CHECKRALIGN32( RN(ir) );
  1044                     sh4r.spc = MEM_READ_LONG(RN(ir));
  1045                     RN(ir) +=4;
  1046                     break;
  1047                 case 0x4E: /* LDC     Rn, SPC */
  1048                     CHECKPRIV();
  1049                     sh4r.spc = RN(ir);
  1050                     break;
  1051                 case 0x52: /* STS.L   FPUL, [--Rn] */
  1052                     RN(ir) -= 4;
  1053 		    CHECKWALIGN32( RN(ir) );
  1054                     MEM_WRITE_LONG( RN(ir), sh4r.fpul );
  1055                     break;
  1056                 case 0x56: /* LDS.L   [Rn++], FPUL */
  1057 		    CHECKRALIGN32( RN(ir) );
  1058                     sh4r.fpul = MEM_READ_LONG(RN(ir));
  1059                     RN(ir) +=4;
  1060                     break;
  1061                 case 0x5A: /* LDS     Rn, FPUL */
  1062                     sh4r.fpul = RN(ir);
  1063                     break;
  1064                 case 0x62: /* STS.L   FPSCR, [--Rn] */
  1065                     RN(ir) -= 4;
  1066 		    CHECKWALIGN32( RN(ir) );
  1067                     MEM_WRITE_LONG( RN(ir), sh4r.fpscr );
  1068                     break;
  1069                 case 0x66: /* LDS.L   [Rn++], FPSCR */
  1070 		    CHECKRALIGN32( RN(ir) );
  1071                     sh4r.fpscr = MEM_READ_LONG(RN(ir));
  1072                     RN(ir) +=4;
  1073                     break;
  1074                 case 0x6A: /* LDS     Rn, FPSCR */
  1075                     sh4r.fpscr = RN(ir);
  1076                     break;
  1077                 case 0xF2: /* STC.L   DBR, [--Rn] */
  1078                     CHECKPRIV();
  1079                     RN(ir) -= 4;
  1080 		    CHECKWALIGN32( RN(ir) );
  1081                     MEM_WRITE_LONG( RN(ir), sh4r.dbr );
  1082                     break;
  1083                 case 0xF6: /* LDC.L   [Rn++], DBR */
  1084                     CHECKPRIV();
  1085 		    CHECKRALIGN32( RN(ir) );
  1086                     sh4r.dbr = MEM_READ_LONG(RN(ir));
  1087                     RN(ir) +=4;
  1088                     break;
  1089                 case 0xFA: /* LDC     Rn, DBR */
  1090                     CHECKPRIV();
  1091                     sh4r.dbr = RN(ir);
  1092                     break;
  1093                 case 0x83: case 0x93: case 0xA3: case 0xB3: case 0xC3:
  1094                 case 0xD3: case 0xE3: case 0xF3: /* STC.L   Rn_BANK, [--Rn] */
  1095                     CHECKPRIV();
  1096                     RN(ir) -= 4;
  1097 		    CHECKWALIGN32( RN(ir) );
  1098                     MEM_WRITE_LONG( RN(ir), RN_BANK(ir) );
  1099                     break;
  1100                 case 0x87: case 0x97: case 0xA7: case 0xB7: case 0xC7:
  1101                 case 0xD7: case 0xE7: case 0xF7: /* LDC.L   [Rn++], Rn_BANK */
  1102                     CHECKPRIV();
  1103 		    CHECKRALIGN32( RN(ir) );
  1104                     RN_BANK(ir) = MEM_READ_LONG( RN(ir) );
  1105                     RN(ir) += 4;
  1106                     break;
  1107                 case 0x8E: case 0x9E: case 0xAE: case 0xBE: case 0xCE:
  1108                 case 0xDE: case 0xEE: case 0xFE: /* LDC     Rm, Rn_BANK */
  1109                     CHECKPRIV();
  1110                     RN_BANK(ir) = RM(ir);
  1111                     break;
  1112                 default:
  1113                     if( (ir&0x000F) == 0x0F ) {
  1114                         /* MAC.W   [Rm++], [Rn++] */
  1115 			CHECKRALIGN16( RN(ir) );
  1116 			CHECKRALIGN16( RM(ir) );
  1117                         tmp = SIGNEXT16(MEM_READ_WORD(RM(ir))) *
  1118                             SIGNEXT16(MEM_READ_WORD(RN(ir)));
  1119                         if( sh4r.s ) {
  1120                             /* FIXME */
  1121                             UNIMP(ir);
  1122                         } else sh4r.mac += SIGNEXT32(tmp);
  1123                         RM(ir) += 2;
  1124                         RN(ir) += 2;
  1125                     } else if( (ir&0x000F) == 0x0C ) {
  1126                         /* SHAD    Rm, Rn */
  1127                         tmp = RM(ir);
  1128                         if( (tmp & 0x80000000) == 0 ) RN(ir) <<= (tmp&0x1f);
  1129                         else if( (tmp & 0x1F) == 0 )  
  1130 			  RN(ir) = ((int32_t)RN(ir)) >> 31;
  1131                         else 
  1132 			  RN(ir) = ((int32_t)RN(ir)) >> (((~RM(ir)) & 0x1F)+1);
  1133                     } else if( (ir&0x000F) == 0x0D ) {
  1134                         /* SHLD    Rm, Rn */
  1135                         tmp = RM(ir);
  1136                         if( (tmp & 0x80000000) == 0 ) RN(ir) <<= (tmp&0x1f);
  1137                         else if( (tmp & 0x1F) == 0 ) RN(ir) = 0;
  1138                         else RN(ir) >>= (((~tmp) & 0x1F)+1);
  1139                     } else UNDEF(ir);
  1141             break;
  1142         case 5: /* 0101nnnnmmmmdddd */
  1143             /* MOV.L   [Rm + disp4*4], Rn */
  1144 	    tmp = RM(ir) + (DISP4(ir)<<2);
  1145 	    CHECKRALIGN32( tmp );
  1146             RN(ir) = MEM_READ_LONG( tmp );
  1147             break;
  1148         case 6: /* 0110xxxxxxxxxxxx */
  1149             switch( ir&0x000f ) {
  1150                 case 0: /* MOV.B   [Rm], Rn */
  1151                     RN(ir) = MEM_READ_BYTE( RM(ir) );
  1152                     break;
  1153                 case 1: /* MOV.W   [Rm], Rn */
  1154 		    CHECKRALIGN16( RM(ir) );
  1155                     RN(ir) = MEM_READ_WORD( RM(ir) );
  1156                     break;
  1157                 case 2: /* MOV.L   [Rm], Rn */
  1158 		    CHECKRALIGN32( RM(ir) );
  1159                     RN(ir) = MEM_READ_LONG( RM(ir) );
  1160                     break;
  1161                 case 3: /* MOV     Rm, Rn */
  1162                     RN(ir) = RM(ir);
  1163                     break;
  1164                 case 4: /* MOV.B   [Rm++], Rn */
  1165                     RN(ir) = MEM_READ_BYTE( RM(ir) );
  1166                     RM(ir) ++;
  1167                     break;
  1168                 case 5: /* MOV.W   [Rm++], Rn */
  1169 		    CHECKRALIGN16( RM(ir) );
  1170                     RN(ir) = MEM_READ_WORD( RM(ir) );
  1171                     RM(ir) += 2;
  1172                     break;
  1173                 case 6: /* MOV.L   [Rm++], Rn */
  1174 		    CHECKRALIGN32( RM(ir) );
  1175                     RN(ir) = MEM_READ_LONG( RM(ir) );
  1176                     RM(ir) += 4;
  1177                     break;
  1178                 case 7: /* NOT     Rm, Rn */
  1179                     RN(ir) = ~RM(ir);
  1180                     break;
  1181                 case 8: /* SWAP.B  Rm, Rn */
  1182                     RN(ir) = (RM(ir)&0xFFFF0000) | ((RM(ir)&0x0000FF00)>>8) |
  1183                         ((RM(ir)&0x000000FF)<<8);
  1184                     break;
  1185                 case 9: /* SWAP.W  Rm, Rn */
  1186                     RN(ir) = (RM(ir)>>16) | (RM(ir)<<16);
  1187                     break;
  1188                 case 10:/* NEGC    Rm, Rn */
  1189                     tmp = 0 - RM(ir);
  1190                     RN(ir) = tmp - sh4r.t;
  1191                     sh4r.t = ( 0<tmp || tmp<RN(ir) ? 1 : 0 );
  1192                     break;
  1193                 case 11:/* NEG     Rm, Rn */
  1194                     RN(ir) = 0 - RM(ir);
  1195                     break;
  1196                 case 12:/* EXTU.B  Rm, Rn */
  1197                     RN(ir) = RM(ir)&0x000000FF;
  1198                     break;
  1199                 case 13:/* EXTU.W  Rm, Rn */
  1200                     RN(ir) = RM(ir)&0x0000FFFF;
  1201                     break;
  1202                 case 14:/* EXTS.B  Rm, Rn */
  1203                     RN(ir) = SIGNEXT8( RM(ir)&0x000000FF );
  1204                     break;
  1205                 case 15:/* EXTS.W  Rm, Rn */
  1206                     RN(ir) = SIGNEXT16( RM(ir)&0x0000FFFF );
  1207                     break;
  1209             break;
  1210         case 7: /* 0111nnnniiiiiiii */
  1211             /* ADD    imm8, Rn */
  1212             RN(ir) += IMM8(ir);
  1213             break;
  1214         case 8: /* 1000xxxxxxxxxxxx */
  1215             switch( (ir&0x0F00) >> 8 ) {
  1216                 case 0: /* MOV.B   R0, [Rm + disp4] */
  1217                     MEM_WRITE_BYTE( RM(ir) + DISP4(ir), R0 );
  1218                     break;
  1219                 case 1: /* MOV.W   R0, [Rm + disp4*2] */
  1220 		    tmp = RM(ir) + (DISP4(ir)<<1);
  1221 		    CHECKWALIGN16( tmp );
  1222                     MEM_WRITE_WORD( tmp, R0 );
  1223                     break;
  1224                 case 4: /* MOV.B   [Rm + disp4], R0 */
  1225                     R0 = MEM_READ_BYTE( RM(ir) + DISP4(ir) );
  1226                     break;
  1227                 case 5: /* MOV.W   [Rm + disp4*2], R0 */
  1228 		    tmp = RM(ir) + (DISP4(ir)<<1);
  1229 		    CHECKRALIGN16( tmp );
  1230                     R0 = MEM_READ_WORD( tmp );
  1231                     break;
  1232                 case 8: /* CMP/EQ  imm, R0 */
  1233                     sh4r.t = ( R0 == IMM8(ir) ? 1 : 0 );
  1234                     break;
  1235                 case 9: /* BT      disp8 */
  1236                     CHECKSLOTILLEGAL();
  1237                     if( sh4r.t ) {
  1238                         CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
  1239                         sh4r.pc += (PCDISP8(ir)<<1) + 4;
  1240                         sh4r.new_pc = sh4r.pc + 2;
  1241                         return TRUE;
  1243                     break;
  1244                 case 11:/* BF      disp8 */
  1245                     CHECKSLOTILLEGAL();
  1246                     if( !sh4r.t ) {
  1247                         CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
  1248                         sh4r.pc += (PCDISP8(ir)<<1) + 4;
  1249                         sh4r.new_pc = sh4r.pc + 2;
  1250                         return TRUE;
  1252                     break;
  1253                 case 13:/* BT/S    disp8 */
  1254                     CHECKSLOTILLEGAL();
  1255                     if( sh4r.t ) {
  1256                         CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
  1257                         sh4r.in_delay_slot = 1;
  1258                         sh4r.pc = sh4r.new_pc;
  1259                         sh4r.new_pc = pc + (PCDISP8(ir)<<1) + 4;
  1260                         sh4r.in_delay_slot = 1;
  1261                         return TRUE;
  1263                     break;
  1264                 case 15:/* BF/S    disp8 */
  1265                     CHECKSLOTILLEGAL();
  1266                     if( !sh4r.t ) {
  1267                         CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
  1268                         sh4r.in_delay_slot = 1;
  1269                         sh4r.pc = sh4r.new_pc;
  1270                         sh4r.new_pc = pc + (PCDISP8(ir)<<1) + 4;
  1271                         return TRUE;
  1273                     break;
  1274                 default: UNDEF(ir);
  1276             break;
  1277         case 9: /* 1001xxxxxxxxxxxx */
  1278             /* MOV.W   [disp8*2 + pc + 4], Rn */
  1279 	    CHECKSLOTILLEGAL();
  1280 	    tmp = pc + 4 + (DISP8(ir)<<1);
  1281             RN(ir) = MEM_READ_WORD( tmp );
  1282             break;
  1283         case 10:/* 1010dddddddddddd */
  1284             /* BRA     disp12 */
  1285             CHECKSLOTILLEGAL();
  1286             CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 );
  1287             sh4r.in_delay_slot = 1;
  1288             sh4r.pc = sh4r.new_pc;
  1289             sh4r.new_pc = pc + 4 + (DISP12(ir)<<1);
  1290             return TRUE;
  1291         case 11:/* 1011dddddddddddd */
  1292             /* BSR     disp12 */
  1293             CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 );
  1294 	    CHECKSLOTILLEGAL();
  1295             sh4r.in_delay_slot = 1;
  1296             sh4r.pr = pc + 4;
  1297             sh4r.pc = sh4r.new_pc;
  1298             sh4r.new_pc = pc + 4 + (DISP12(ir)<<1);
  1299 	    TRACE_CALL( pc, sh4r.new_pc );
  1300             return TRUE;
  1301         case 12:/* 1100xxxxdddddddd */
  1302         switch( (ir&0x0F00)>>8 ) {
  1303                 case 0: /* MOV.B  R0, [GBR + disp8] */
  1304                     MEM_WRITE_BYTE( sh4r.gbr + DISP8(ir), R0 );
  1305                     break;
  1306                 case 1: /* MOV.W  R0, [GBR + disp8*2] */
  1307 		    tmp = sh4r.gbr + (DISP8(ir)<<1);
  1308 		    CHECKWALIGN16( tmp );
  1309                     MEM_WRITE_WORD( tmp, R0 );
  1310                     break;
  1311                 case  2: /*MOV.L   R0, [GBR + disp8*4] */
  1312 		    tmp = sh4r.gbr + (DISP8(ir)<<2);
  1313 		    CHECKWALIGN32( tmp );
  1314                     MEM_WRITE_LONG( tmp, R0 );
  1315                     break;
  1316                 case 3: /* TRAPA   imm8 */
  1317                     CHECKSLOTILLEGAL();
  1318                     MMIO_WRITE( MMU, TRA, UIMM8(ir)<<2 );
  1319 		    sh4r.pc += 2;
  1320                     sh4_raise_exception( EXC_TRAP );
  1321                     break;
  1322                 case 4: /* MOV.B   [GBR + disp8], R0 */
  1323                     R0 = MEM_READ_BYTE( sh4r.gbr + DISP8(ir) );
  1324                     break;
  1325                 case 5: /* MOV.W   [GBR + disp8*2], R0 */
  1326 		    tmp = sh4r.gbr + (DISP8(ir)<<1);
  1327 		    CHECKRALIGN16( tmp );
  1328                     R0 = MEM_READ_WORD( tmp );
  1329                     break;
  1330                 case 6: /* MOV.L   [GBR + disp8*4], R0 */
  1331 		    tmp = sh4r.gbr + (DISP8(ir)<<2);
  1332 		    CHECKRALIGN32( tmp );
  1333                     R0 = MEM_READ_LONG( tmp );
  1334                     break;
  1335                 case 7: /* MOVA    disp8 + pc&~3 + 4, R0 */
  1336 		    CHECKSLOTILLEGAL();
  1337                     R0 = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;
  1338                     break;
  1339                 case 8: /* TST     imm8, R0 */
  1340                     sh4r.t = (R0 & UIMM8(ir) ? 0 : 1);
  1341                     break;
  1342                 case 9: /* AND     imm8, R0 */
  1343                     R0 &= UIMM8(ir);
  1344                     break;
  1345                 case 10:/* XOR     imm8, R0 */
  1346                     R0 ^= UIMM8(ir);
  1347                     break;
  1348                 case 11:/* OR      imm8, R0 */
  1349                     R0 |= UIMM8(ir);
  1350                     break;
  1351                 case 12:/* TST.B   imm8, [R0+GBR] */		    
  1352                     sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & UIMM8(ir) ? 0 : 1 );
  1353                     break;
  1354                 case 13:/* AND.B   imm8, [R0+GBR] */
  1355                     MEM_WRITE_BYTE( R0 + sh4r.gbr,
  1356                                     UIMM8(ir) & MEM_READ_BYTE(R0 + sh4r.gbr) );
  1357                     break;
  1358                 case 14:/* XOR.B   imm8, [R0+GBR] */
  1359                     MEM_WRITE_BYTE( R0 + sh4r.gbr,
  1360                                     UIMM8(ir) ^ MEM_READ_BYTE(R0 + sh4r.gbr) );
  1361                     break;
  1362                 case 15:/* OR.B    imm8, [R0+GBR] */
  1363                     MEM_WRITE_BYTE( R0 + sh4r.gbr,
  1364                                     UIMM8(ir) | MEM_READ_BYTE(R0 + sh4r.gbr) );
  1365                     break;
  1367             break;
  1368         case 13:/* 1101nnnndddddddd */
  1369             /* MOV.L   [disp8*4 + pc&~3 + 4], Rn */
  1370 	    CHECKSLOTILLEGAL();
  1371 	    tmp = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;
  1372             RN(ir) = MEM_READ_LONG( tmp );
  1373             break;
  1374         case 14:/* 1110nnnniiiiiiii */
  1375             /* MOV     imm8, Rn */
  1376             RN(ir) = IMM8(ir);
  1377             break;
  1378         case 15:/* 1111xxxxxxxxxxxx */
  1379             CHECKFPUEN();
  1380 	    if( IS_FPU_DOUBLEPREC() ) {
  1381 		switch( ir&0x000F ) {
  1382                 case 0: /* FADD    FRm, FRn */
  1383                     DRN(ir) += DRM(ir);
  1384                     break;
  1385                 case 1: /* FSUB    FRm, FRn */
  1386                     DRN(ir) -= DRM(ir);
  1387                     break;
  1388                 case 2: /* FMUL    FRm, FRn */
  1389                     DRN(ir) = DRN(ir) * DRM(ir);
  1390                     break;
  1391                 case 3: /* FDIV    FRm, FRn */
  1392                     DRN(ir) = DRN(ir) / DRM(ir);
  1393                     break;
  1394                 case 4: /* FCMP/EQ FRm, FRn */
  1395                     sh4r.t = ( DRN(ir) == DRM(ir) ? 1 : 0 );
  1396                     break;
  1397                 case 5: /* FCMP/GT FRm, FRn */
  1398                     sh4r.t = ( DRN(ir) > DRM(ir) ? 1 : 0 );
  1399                     break;
  1400                 case 6: /* FMOV.S  [Rm+R0], FRn */
  1401                     MEM_FP_READ( RM(ir) + R0, FRNn(ir) );
  1402                     break;
  1403                 case 7: /* FMOV.S  FRm, [Rn+R0] */
  1404                     MEM_FP_WRITE( RN(ir) + R0, FRMn(ir) );
  1405                     break;
  1406                 case 8: /* FMOV.S  [Rm], FRn */
  1407                     MEM_FP_READ( RM(ir), FRNn(ir) );
  1408                     break;
  1409                 case 9: /* FMOV.S  [Rm++], FRn */
  1410                     MEM_FP_READ( RM(ir), FRNn(ir) );
  1411                     RM(ir) += FP_WIDTH;
  1412                     break;
  1413                 case 10:/* FMOV.S  FRm, [Rn] */
  1414                     MEM_FP_WRITE( RN(ir), FRMn(ir) );
  1415                     break;
  1416                 case 11:/* FMOV.S  FRm, [--Rn] */
  1417                     RN(ir) -= FP_WIDTH;
  1418                     MEM_FP_WRITE( RN(ir), FRMn(ir) );
  1419                     break;
  1420                 case 12:/* FMOV    FRm, FRn */
  1421 		    if( IS_FPU_DOUBLESIZE() )
  1422 			DRN(ir) = DRM(ir);
  1423 		    else
  1424 			FRN(ir) = FRM(ir);
  1425                     break;
  1426                 case 13:
  1427                     switch( (ir&0x00F0) >> 4 ) {
  1428 		    case 0: /* FSTS    FPUL, FRn */
  1429 			FRN(ir) = FPULf;
  1430 			break;
  1431 		    case 1: /* FLDS    FRn,FPUL */
  1432 			FPULf = FRN(ir);
  1433 			break;
  1434 		    case 2: /* FLOAT   FPUL, FRn */
  1435 			DRN(ir) = (float)FPULi;
  1436 			break;
  1437 		    case 3: /* FTRC    FRn, FPUL */
  1438 			dtmp = DRN(ir);
  1439 			if( dtmp >= MAX_INTF )
  1440 			    FPULi = MAX_INT;
  1441 			else if( dtmp <= MIN_INTF )
  1442 			    FPULi = MIN_INT;
  1443 			else 
  1444 			    FPULi = (int32_t)dtmp;
  1445 			break;
  1446 		    case 4: /* FNEG    FRn */
  1447 			DRN(ir) = -DRN(ir);
  1448 			break;
  1449 		    case 5: /* FABS    FRn */
  1450 			DRN(ir) = fabs(DRN(ir));
  1451 			break;
  1452 		    case 6: /* FSQRT   FRn */
  1453 			DRN(ir) = sqrt(DRN(ir));
  1454 			break;
  1455 		    case 7: /* FSRRA FRn */
  1456 			/* NO-OP when PR=1 */
  1457 			break;
  1458 		    case 8: /* FLDI0   FRn */
  1459 			DRN(ir) = 0.0;
  1460 			break;
  1461 		    case 9: /* FLDI1   FRn */
  1462 			DRN(ir) = 1.0;
  1463 			break;
  1464 		    case 10: /* FCNVSD FPUL, DRn */
  1465 			if( ! IS_FPU_DOUBLESIZE() )
  1466 			    DRN(ir) = (double)FPULf;
  1467 			break;
  1468 		    case 11: /* FCNVDS DRn, FPUL */
  1469 			if( ! IS_FPU_DOUBLESIZE() )
  1470 			    FPULf = (float)DRN(ir);
  1471 			break;
  1472 		    case 14:/* FIPR    FVm, FVn */
  1473 			/* NO-OP when PR=1 */
  1474 			break;
  1475 		    case 15:
  1476 			if( (ir&0x0300) == 0x0100 ) { /* FTRV    XMTRX,FVn */
  1477 			    /* NO-OP when PR=1 */
  1478 			    break;
  1480 			else if( (ir&0x0100) == 0 ) { /* FSCA    FPUL, DRn */	
  1481 			    /* NO-OP when PR=1 */
  1482 			    break;
  1484 			else if( ir == 0xFBFD ) {
  1485 			    /* FRCHG   */
  1486 			    sh4r.fpscr ^= FPSCR_FR;
  1487 			    break;
  1489 			else if( ir == 0xF3FD ) {
  1490 			    /* FSCHG   */
  1491 			    sh4r.fpscr ^= FPSCR_SZ;
  1492 			    break;
  1494 		    default: UNDEF(ir);
  1496                     break;
  1497                 case 14:/* FMAC    FR0, FRm, FRn */
  1498                     DRN(ir) += DRM(ir)*DR0;
  1499                     break;
  1500                 default: UNDEF(ir);
  1502 	    } else { /* Single precision */
  1503 		switch( ir&0x000F ) {
  1504                 case 0: /* FADD    FRm, FRn */
  1505                     FRN(ir) += FRM(ir);
  1506                     break;
  1507                 case 1: /* FSUB    FRm, FRn */
  1508                     FRN(ir) -= FRM(ir);
  1509                     break;
  1510                 case 2: /* FMUL    FRm, FRn */
  1511                     FRN(ir) = FRN(ir) * FRM(ir);
  1512                     break;
  1513                 case 3: /* FDIV    FRm, FRn */
  1514                     FRN(ir) = FRN(ir) / FRM(ir);
  1515                     break;
  1516                 case 4: /* FCMP/EQ FRm, FRn */
  1517                     sh4r.t = ( FRN(ir) == FRM(ir) ? 1 : 0 );
  1518                     break;
  1519                 case 5: /* FCMP/GT FRm, FRn */
  1520                     sh4r.t = ( FRN(ir) > FRM(ir) ? 1 : 0 );
  1521                     break;
  1522                 case 6: /* FMOV.S  [Rm+R0], FRn */
  1523                     MEM_FP_READ( RM(ir) + R0, FRNn(ir) );
  1524                     break;
  1525                 case 7: /* FMOV.S  FRm, [Rn+R0] */
  1526                     MEM_FP_WRITE( RN(ir) + R0, FRMn(ir) );
  1527                     break;
  1528                 case 8: /* FMOV.S  [Rm], FRn */
  1529                     MEM_FP_READ( RM(ir), FRNn(ir) );
  1530                     break;
  1531                 case 9: /* FMOV.S  [Rm++], FRn */
  1532                     MEM_FP_READ( RM(ir), FRNn(ir) );
  1533                     RM(ir) += FP_WIDTH;
  1534                     break;
  1535                 case 10:/* FMOV.S  FRm, [Rn] */
  1536                     MEM_FP_WRITE( RN(ir), FRMn(ir) );
  1537                     break;
  1538                 case 11:/* FMOV.S  FRm, [--Rn] */
  1539                     RN(ir) -= FP_WIDTH;
  1540                     MEM_FP_WRITE( RN(ir), FRMn(ir) );
  1541                     break;
  1542                 case 12:/* FMOV    FRm, FRn */
  1543 		    if( IS_FPU_DOUBLESIZE() )
  1544 			DRN(ir) = DRM(ir);
  1545 		    else
  1546 			FRN(ir) = FRM(ir);
  1547                     break;
  1548                 case 13:
  1549                     switch( (ir&0x00F0) >> 4 ) {
  1550 		    case 0: /* FSTS    FPUL, FRn */
  1551 			FRN(ir) = FPULf;
  1552 			break;
  1553 		    case 1: /* FLDS    FRn,FPUL */
  1554 			FPULf = FRN(ir);
  1555 			break;
  1556 		    case 2: /* FLOAT   FPUL, FRn */
  1557 			FRN(ir) = (float)FPULi;
  1558 			break;
  1559 		    case 3: /* FTRC    FRn, FPUL */
  1560 			ftmp = FRN(ir);
  1561 			if( ftmp >= MAX_INTF )
  1562 			    FPULi = MAX_INT;
  1563 			else if( ftmp <= MIN_INTF )
  1564 			    FPULi = MIN_INT;
  1565 			else
  1566 			    FPULi = (int32_t)ftmp;
  1567 			break;
  1568 		    case 4: /* FNEG    FRn */
  1569 			FRN(ir) = -FRN(ir);
  1570 			break;
  1571 		    case 5: /* FABS    FRn */
  1572 			FRN(ir) = fabsf(FRN(ir));
  1573 			break;
  1574 		    case 6: /* FSQRT   FRn */
  1575 			FRN(ir) = sqrtf(FRN(ir));
  1576 			break;
  1577 		    case 7: /* FSRRA FRn */
  1578 			FRN(ir) = 1.0/sqrtf(FRN(ir));
  1579 			break;
  1580 		    case 8: /* FLDI0   FRn */
  1581 			FRN(ir) = 0.0;
  1582 			break;
  1583 		    case 9: /* FLDI1   FRn */
  1584 			FRN(ir) = 1.0;
  1585 			break;
  1586 		    case 10: /* FCNVSD FPUL, DRn */
  1587 			break;
  1588 		    case 11: /* FCNVDS DRn, FPUL */
  1589 			break;
  1590 		    case 14:/* FIPR    FVm, FVn */
  1591                             /* FIXME: This is not going to be entirely accurate
  1592                              * as the SH4 instruction is less precise. Also
  1593                              * need to check for 0s and infinities.
  1594                              */
  1596                             int tmp2 = FVN(ir);
  1597                             tmp = FVM(ir);
  1598                             FR(tmp2+3) = FR(tmp)*FR(tmp2) +
  1599                                 FR(tmp+1)*FR(tmp2+1) +
  1600                                 FR(tmp+2)*FR(tmp2+2) +
  1601                                 FR(tmp+3)*FR(tmp2+3);
  1602                             break;
  1604 		    case 15:
  1605 			if( (ir&0x0300) == 0x0100 ) { /* FTRV    XMTRX,FVn */
  1606 			    tmp = FVN(ir);
  1607 			    float fv[4] = { FR(tmp), FR(tmp+1), FR(tmp+2), FR(tmp+3) };
  1608 			    FR(tmp) = XF(0) * fv[0] + XF(4)*fv[1] +
  1609 				XF(8)*fv[2] + XF(12)*fv[3];
  1610 			    FR(tmp+1) = XF(1) * fv[0] + XF(5)*fv[1] +
  1611 				XF(9)*fv[2] + XF(13)*fv[3];
  1612 			    FR(tmp+2) = XF(2) * fv[0] + XF(6)*fv[1] +
  1613 				XF(10)*fv[2] + XF(14)*fv[3];
  1614 			    FR(tmp+3) = XF(3) * fv[0] + XF(7)*fv[1] +
  1615 				XF(11)*fv[2] + XF(15)*fv[3];
  1616 			    break;
  1618 			else if( (ir&0x0100) == 0 ) { /* FSCA    FPUL, DRn */
  1619 			    float angle = (((float)(short)(FPULi>>16)) +
  1620 					   (((float)(FPULi&0xFFFF))/65536.0)) *
  1621 				2 * M_PI;
  1622 			    int reg = FRNn(ir);
  1623 			    FR(reg) = sinf(angle);
  1624 			    FR(reg+1) = cosf(angle);
  1625 			    break;
  1627 			else if( ir == 0xFBFD ) {
  1628 			    /* FRCHG   */
  1629 			    sh4r.fpscr ^= FPSCR_FR;
  1630 			    break;
  1632 			else if( ir == 0xF3FD ) {
  1633 			    /* FSCHG   */
  1634 			    sh4r.fpscr ^= FPSCR_SZ;
  1635 			    break;
  1637 		    default: UNDEF(ir);
  1639                     break;
  1640                 case 14:/* FMAC    FR0, FRm, FRn */
  1641                     FRN(ir) += FRM(ir)*FR0;
  1642                     break;
  1643                 default: UNDEF(ir);
  1646 	    break;
  1648     sh4r.pc = sh4r.new_pc;
  1649     sh4r.new_pc += 2;
  1650     sh4r.in_delay_slot = 0;
.