Search
lxdream.org :: lxdream/src/sh4/sh4core.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4core.c
changeset 53:f2981805b929
prev43:0cf3e339cc59
next84:b993a8d8fbf3
author nkeynes
date Mon Jan 02 23:07:17 2006 +0000 (18 years ago)
permissions -rw-r--r--
last change Fix exception return address
Accidentally left UNIMP() on entire arith extension block, removed
view annotate diff log raw
     1 /**
     2  * $Id: sh4core.c,v 1.17 2005-12-29 12:52:29 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 "sh4core.h"
    24 #include "sh4mmio.h"
    25 #include "mem.h"
    26 #include "clock.h"
    27 #include "intc.h"
    29 /* CPU-generated exception code/vector pairs */
    30 #define EXC_POWER_RESET  0x000 /* vector special */
    31 #define EXC_MANUAL_RESET 0x020
    32 #define EXC_SLOT_ILLEGAL 0x1A0
    33 #define EXC_ILLEGAL      0x180
    34 #define EXV_ILLEGAL      0x100
    35 #define EXC_TRAP         0x160
    36 #define EXV_TRAP         0x100
    37 #define EXC_FPDISABLE    0x800
    38 #define EXV_FPDISABLE    0x100
    40 /********************** SH4 Module Definition ****************************/
    42 void sh4_init( void );
    43 void sh4_reset( void );
    44 uint32_t sh4_run_slice( uint32_t );
    45 void sh4_start( void );
    46 void sh4_stop( void );
    47 void sh4_save_state( FILE *f );
    48 int sh4_load_state( FILE *f );
    50 struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_reset, 
    51 				       NULL, sh4_run_slice, sh4_stop,
    52 				       sh4_save_state, sh4_load_state };
    54 struct sh4_registers sh4r;
    56 void sh4_init(void)
    57 {
    58     register_io_regions( mmio_list_sh4mmio );
    59     mmu_init();
    60     sh4_reset();
    61 }
    63 void sh4_reset(void)
    64 {
    65     /* zero everything out, for the sake of having a consistent state. */
    66     memset( &sh4r, 0, sizeof(sh4r) );
    68     /* Resume running if we were halted */
    69     sh4r.sh4_state = SH4_STATE_RUNNING;
    71     sh4r.pc    = 0xA0000000;
    72     sh4r.new_pc= 0xA0000002;
    73     sh4r.vbr   = 0x00000000;
    74     sh4r.fpscr = 0x00040001;
    75     sh4r.sr    = 0x700000F0;
    77     /* Mem reset will do this, but if we want to reset _just_ the SH4... */
    78     MMIO_WRITE( MMU, EXPEVT, EXC_POWER_RESET );
    80     /* Peripheral modules */
    81     intc_reset();
    82     SCIF_reset();
    83 }
    85 static struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];
    86 static int sh4_breakpoint_count = 0;
    88 void sh4_set_breakpoint( uint32_t pc, int type )
    89 {
    90     sh4_breakpoints[sh4_breakpoint_count].address = pc;
    91     sh4_breakpoints[sh4_breakpoint_count].type = type;
    92     sh4_breakpoint_count++;
    93 }
    95 gboolean sh4_clear_breakpoint( uint32_t pc, int type )
    96 {
    97     int i;
    99     for( i=0; i<sh4_breakpoint_count; i++ ) {
   100 	if( sh4_breakpoints[i].address == pc && 
   101 	    sh4_breakpoints[i].type == type ) {
   102 	    while( ++i < sh4_breakpoint_count ) {
   103 		sh4_breakpoints[i-1].address = sh4_breakpoints[i].address;
   104 		sh4_breakpoints[i-1].type = sh4_breakpoints[i].type;
   105 	    }
   106 	    sh4_breakpoint_count--;
   107 	    return TRUE;
   108 	}
   109     }
   110     return FALSE;
   111 }
   113 int sh4_get_breakpoint( uint32_t pc )
   114 {
   115     int i;
   116     for( i=0; i<sh4_breakpoint_count; i++ ) {
   117 	if( sh4_breakpoints[i].address == pc )
   118 	    return sh4_breakpoints[i].type;
   119     }
   120     return 0;
   121 }
   123 uint32_t sh4_run_slice( uint32_t nanosecs ) 
   124 {
   125     int target = sh4r.icount + nanosecs / sh4_cpu_period;
   126     int start = sh4r.icount;
   127     int i;
   129     if( sh4r.sh4_state != SH4_STATE_RUNNING ) {
   130 	if( sh4r.int_pending != 0 )
   131 	    sh4r.sh4_state = SH4_STATE_RUNNING;;
   132     }
   134     for( sh4r.slice_cycle = 0; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
   135 	if( !sh4_execute_instruction() )
   136 	    break;
   137 #ifdef ENABLE_DEBUG_MODE
   138 	for( i=0; i<sh4_breakpoint_count; i++ ) {
   139 	    if( sh4_breakpoints[i].address == sh4r.pc ) {
   140 		break;
   141 	    }
   142 	}
   143 	if( i != sh4_breakpoint_count ) {
   144 	    dreamcast_stop();
   145 	    if( sh4_breakpoints[i].type == BREAK_ONESHOT )
   146 		sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );
   147 	    break;
   148 	}
   149 #endif	
   150     }
   152     /* If we aborted early, but the cpu is still technically running,
   153      * we're doing a hard abort - cut the timeslice back to what we
   154      * actually executed
   155      */
   156     if( sh4r.slice_cycle != nanosecs && sh4r.sh4_state == SH4_STATE_RUNNING ) {
   157 	nanosecs = sh4r.slice_cycle;
   158     }
   159     if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
   160 	TMU_run_slice( nanosecs );
   161 	SCIF_run_slice( nanosecs );
   162     }
   163     sh4r.icount += sh4r.slice_cycle / sh4_cpu_period;
   164     return nanosecs;
   165 }
   167 void sh4_stop(void)
   168 {
   170 }
   172 void sh4_save_state( FILE *f )
   173 {
   174     fwrite( &sh4r, sizeof(sh4r), 1, f );
   175     TMU_save_state( f );
   176     SCIF_save_state( f );
   177 }
   179 int sh4_load_state( FILE * f )
   180 {
   181     fread( &sh4r, sizeof(sh4r), 1, f );
   182     TMU_load_state( f );
   183     return SCIF_load_state( f );
   184 }
   186 /********************** SH4 emulation core  ****************************/
   188 void sh4_set_pc( int pc )
   189 {
   190     sh4r.pc = pc;
   191     sh4r.new_pc = pc+2;
   192 }
   194 #define UNDEF(ir) do{ ERROR( "Raising exception on undefined instruction at %08x, opcode = %04x", sh4r.pc, ir ); RAISE( EXC_ILLEGAL, EXV_ILLEGAL ); }while(0)
   195 #define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", sh4r.pc, ir ); dreamcast_stop(); return FALSE; }while(0)
   197 #define RAISE( x, v ) do{ \
   198     if( sh4r.vbr == 0 ) { \
   199         ERROR( "%08X: VBR not initialized while raising exception %03X, halting", sh4r.pc, x ); \
   200         sh4_stop(); \
   201     } else { \
   202         sh4r.spc = sh4r.pc + 2; \
   203         sh4r.ssr = sh4_read_sr(); \
   204         sh4r.sgr = sh4r.r[15]; \
   205         MMIO_WRITE(MMU,EXPEVT,x); \
   206         sh4r.pc = sh4r.vbr + v; \
   207         sh4r.new_pc = sh4r.pc + 2; \
   208         sh4_load_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB ); \
   209     } \
   210     return TRUE; } while(0)
   212 #define MEM_READ_BYTE( addr ) sh4_read_byte(addr)
   213 #define MEM_READ_WORD( addr ) sh4_read_word(addr)
   214 #define MEM_READ_LONG( addr ) sh4_read_long(addr)
   215 #define MEM_WRITE_BYTE( addr, val ) sh4_write_byte(addr, val)
   216 #define MEM_WRITE_WORD( addr, val ) sh4_write_word(addr, val)
   217 #define MEM_WRITE_LONG( addr, val ) sh4_write_long(addr, val)
   219 #define MEM_FP_READ( addr, reg ) if( IS_FPU_DOUBLESIZE() ) { \
   220     ((uint32_t *)FR)[(reg)&0xE0] = sh4_read_long(addr); \
   221     ((uint32_t *)FR)[(reg)|1] = sh4_read_long(addr+4); \
   222 } else ((uint32_t *)FR)[reg] = sh4_read_long(addr)
   224 #define MEM_FP_WRITE( addr, reg ) if( IS_FPU_DOUBLESIZE() ) { \
   225     sh4_write_long( addr, ((uint32_t *)FR)[(reg)&0xE0] ); \
   226     sh4_write_long( addr+4, ((uint32_t *)FR)[(reg)|1] ); \
   227 } else sh4_write_long( addr, ((uint32_t *)FR)[reg] )
   229 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)
   231 #define CHECK( x, c, v ) if( !x ) RAISE( c, v )
   232 #define CHECKPRIV() CHECK( IS_SH4_PRIVMODE(), EXC_ILLEGAL, EXV_ILLEGAL )
   233 #define CHECKFPUEN() CHECK( IS_FPU_ENABLED(), EXC_FPDISABLE, EXV_FPDISABLE )
   234 #define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); sh4_stop(); return; }
   235 #define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) { RAISE(EXC_SLOT_ILLEGAL,EXV_ILLEGAL); }
   237 static void sh4_switch_banks( )
   238 {
   239     uint32_t tmp[8];
   241     memcpy( tmp, sh4r.r, sizeof(uint32_t)*8 );
   242     memcpy( sh4r.r, sh4r.r_bank, sizeof(uint32_t)*8 );
   243     memcpy( sh4r.r_bank, tmp, sizeof(uint32_t)*8 );
   244 }
   246 static void sh4_load_sr( uint32_t newval )
   247 {
   248     if( (newval ^ sh4r.sr) & SR_RB )
   249         sh4_switch_banks();
   250     sh4r.sr = newval;
   251     sh4r.t = (newval&SR_T) ? 1 : 0;
   252     sh4r.s = (newval&SR_S) ? 1 : 0;
   253     sh4r.m = (newval&SR_M) ? 1 : 0;
   254     sh4r.q = (newval&SR_Q) ? 1 : 0;
   255     intc_mask_changed();
   256 }
   258 static uint32_t sh4_read_sr( void )
   259 {
   260     /* synchronize sh4r.sr with the various bitflags */
   261     sh4r.sr &= SR_MQSTMASK;
   262     if( sh4r.t ) sh4r.sr |= SR_T;
   263     if( sh4r.s ) sh4r.sr |= SR_S;
   264     if( sh4r.m ) sh4r.sr |= SR_M;
   265     if( sh4r.q ) sh4r.sr |= SR_Q;
   266     return sh4r.sr;
   267 }
   268 /* function for external use */
   269 void sh4_raise_exception( int code, int vector )
   270 {
   271     RAISE(code, vector);
   272 }
   274 static void sh4_accept_interrupt( void )
   275 {
   276     uint32_t code = intc_accept_interrupt();
   277     sh4r.ssr = sh4_read_sr();
   278     sh4r.spc = sh4r.pc;
   279     sh4r.sgr = sh4r.r[15];
   280     sh4_load_sr( sh4r.ssr|SR_BL|SR_MD|SR_RB );
   281     MMIO_WRITE( MMU, INTEVT, code );
   282     sh4r.pc = sh4r.vbr + 0x600;
   283     sh4r.new_pc = sh4r.pc + 2;
   284     WARN( "Accepting interrupt %03X, from %08X => %08X", code, sh4r.spc, sh4r.pc );
   285 }
   287 gboolean sh4_execute_instruction( void )
   288 {
   289     int pc;
   290     unsigned short ir;
   291     uint32_t tmp;
   292     uint64_t tmpl;
   294 #define R0 sh4r.r[0]
   295 #define FR0 (FR[0])
   296 #define RN(ir) sh4r.r[(ir&0x0F00)>>8]
   297 #define RN_BANK(ir) sh4r.r_bank[(ir&0x0070)>>4]
   298 #define RM(ir) sh4r.r[(ir&0x00F0)>>4]
   299 #define DISP4(ir) (ir&0x000F) /* 4-bit displacements are *NOT* sign-extended */
   300 #define DISP8(ir) (ir&0x00FF)
   301 #define PCDISP8(ir) SIGNEXT8(ir&0x00FF)
   302 #define IMM8(ir) SIGNEXT8(ir&0x00FF)
   303 #define UIMM8(ir) (ir&0x00FF) /* Unsigned immmediate */
   304 #define DISP12(ir) SIGNEXT12(ir&0x0FFF)
   305 #define FVN(ir) ((ir&0x0C00)>>8)
   306 #define FVM(ir) ((ir&0x0300)>>6)
   307 #define FRN(ir) (FR[(ir&0x0F00)>>8])
   308 #define FRM(ir) (FR[(ir&0x00F0)>>4])
   309 #define FRNi(ir) (((uint32_t *)FR)[(ir&0x0F00)>>8])
   310 #define FRMi(ir) (((uint32_t *)FR)[(ir&0x00F0)>>4])
   311 #define DRN(ir) (((double *)FR)[(ir&0x0E00)>>9])
   312 #define DRM(ir) (((double *)FR)[(ir&0x00E0)>>5])
   313 #define DRNi(ir) (((uint64_t *)FR)[(ir&0x0E00)>>9])
   314 #define DRMi(ir) (((uint64_t *)FR)[(ir&0x00E0)>>5])
   315 #define FRNn(ir) ((ir&0x0F00)>>8)
   316 #define FRMn(ir) ((ir&0x00F0)>>4)
   317 #define FPULf   *((float *)&sh4r.fpul)
   318 #define FPULi    (sh4r.fpul)
   320     if( SH4_INT_PENDING() ) 
   321         sh4_accept_interrupt();
   323     pc = sh4r.pc;
   324     ir = MEM_READ_WORD(pc);
   325     sh4r.icount++;
   327     switch( (ir&0xF000)>>12 ) {
   328         case 0: /* 0000nnnnmmmmxxxx */
   329             switch( ir&0x000F ) {
   330                 case 2:
   331                     switch( (ir&0x00F0)>>4 ) {
   332                         case 0: /* STC     SR, Rn */
   333                             CHECKPRIV();
   334                             RN(ir) = sh4_read_sr();
   335                             break;
   336                         case 1: /* STC     GBR, Rn */
   337                             RN(ir) = sh4r.gbr;
   338                             break;
   339                         case 2: /* STC     VBR, Rn */
   340                             CHECKPRIV();
   341                             RN(ir) = sh4r.vbr;
   342                             break;
   343                         case 3: /* STC     SSR, Rn */
   344                             CHECKPRIV();
   345                             RN(ir) = sh4r.ssr;
   346                             break;
   347                         case 4: /* STC     SPC, Rn */
   348                             CHECKPRIV();
   349                             RN(ir) = sh4r.spc;
   350                             break;
   351                         case 8: case 9: case 10: case 11: case 12: case 13:
   352                         case 14: case 15:/* STC     Rm_bank, Rn */
   353                             CHECKPRIV();
   354                             RN(ir) = RN_BANK(ir);
   355                             break;
   356                         default: UNDEF(ir);
   357                     }
   358                     break;
   359                 case 3:
   360                     switch( (ir&0x00F0)>>4 ) {
   361                         case 0: /* BSRF    Rn */
   362                             CHECKDEST( pc + 4 + RN(ir) );
   363                             CHECKSLOTILLEGAL();
   364                             sh4r.in_delay_slot = 1;
   365                             sh4r.pr = sh4r.pc + 4;
   366                             sh4r.pc = sh4r.new_pc;
   367                             sh4r.new_pc = pc + 4 + RN(ir);
   368                             return TRUE;
   369                         case 2: /* BRAF    Rn */
   370                             CHECKDEST( pc + 4 + RN(ir) );
   371                             CHECKSLOTILLEGAL();
   372                             sh4r.in_delay_slot = 1;
   373                             sh4r.pc = sh4r.new_pc;
   374                             sh4r.new_pc = pc + 4 + RN(ir);
   375                             return TRUE;
   376                         case 8: /* PREF    [Rn] */
   377                             tmp = RN(ir);
   378                             if( (tmp & 0xFC000000) == 0xE0000000 ) {
   379                                 /* Store queue operation */
   380                                 int queue = (tmp&0x20)>>2;
   381                                 int32_t *src = &sh4r.store_queue[queue];
   382                                 uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;
   383                                 uint32_t target = tmp&0x03FFFFE0 | hi;
   384                                 mem_copy_to_sh4( target, src, 32 );
   385 				//                                WARN( "Executed SQ%c => %08X",
   386 				//                                      (queue == 0 ? '0' : '1'), target );
   387                             }
   388                             break;
   389                         case 9: /* OCBI    [Rn] */
   390                         case 10:/* OCBP    [Rn] */
   391                         case 11:/* OCBWB   [Rn] */
   392                             /* anything? */
   393                             break;
   394                         case 12:/* MOVCA.L R0, [Rn] */
   395                             UNIMP(ir);
   396                         default: UNDEF(ir);
   397                     }
   398                     break;
   399                 case 4: /* MOV.B   Rm, [R0 + Rn] */
   400                     MEM_WRITE_BYTE( R0 + RN(ir), RM(ir) );
   401                     break;
   402                 case 5: /* MOV.W   Rm, [R0 + Rn] */
   403                     MEM_WRITE_WORD( R0 + RN(ir), RM(ir) );
   404                     break;
   405                 case 6: /* MOV.L   Rm, [R0 + Rn] */
   406                     MEM_WRITE_LONG( R0 + RN(ir), RM(ir) );
   407                     break;
   408                 case 7: /* MUL.L   Rm, Rn */
   409                     sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
   410                         (RM(ir) * RN(ir));
   411                     break;
   412                 case 8: 
   413                     switch( (ir&0x0FF0)>>4 ) {
   414                         case 0: /* CLRT    */
   415                             sh4r.t = 0;
   416                             break;
   417                         case 1: /* SETT    */
   418                             sh4r.t = 1;
   419                             break;
   420                         case 2: /* CLRMAC  */
   421                             sh4r.mac = 0;
   422                             break;
   423                         case 3: /* LDTLB   */
   424                             break;
   425                         case 4: /* CLRS    */
   426                             sh4r.s = 0;
   427                             break;
   428                         case 5: /* SETS    */
   429                             sh4r.s = 1;
   430                             break;
   431                         default: UNDEF(ir);
   432                     }
   433                     break;
   434                 case 9: 
   435                     if( (ir&0x00F0) == 0x20 ) /* MOVT    Rn */
   436                         RN(ir) = sh4r.t;
   437                     else if( ir == 0x0019 ) /* DIV0U   */
   438                         sh4r.m = sh4r.q = sh4r.t = 0;
   439                     else if( ir == 0x0009 )
   440                         /* NOP     */;
   441                     else UNDEF(ir);
   442                     break;
   443                 case 10:
   444                     switch( (ir&0x00F0) >> 4 ) {
   445                         case 0: /* STS     MACH, Rn */
   446                             RN(ir) = sh4r.mac >> 32;
   447                             break;
   448                         case 1: /* STS     MACL, Rn */
   449                             RN(ir) = (uint32_t)sh4r.mac;
   450                             break;
   451                         case 2: /* STS     PR, Rn */
   452                             RN(ir) = sh4r.pr;
   453                             break;
   454                         case 3: /* STC     SGR, Rn */
   455                             CHECKPRIV();
   456                             RN(ir) = sh4r.sgr;
   457                             break;
   458                         case 5:/* STS      FPUL, Rn */
   459                             RN(ir) = sh4r.fpul;
   460                             break;
   461                         case 6: /* STS     FPSCR, Rn */
   462                             RN(ir) = sh4r.fpscr;
   463                             break;
   464                         case 15:/* STC     DBR, Rn */
   465                             CHECKPRIV();
   466                             RN(ir) = sh4r.dbr;
   467                             break;
   468                         default: UNDEF(ir);
   469                     }
   470                     break;
   471                 case 11:
   472                     switch( (ir&0x0FF0)>>4 ) {
   473                         case 0: /* RTS     */
   474                             CHECKDEST( sh4r.pr );
   475                             CHECKSLOTILLEGAL();
   476                             sh4r.in_delay_slot = 1;
   477                             sh4r.pc = sh4r.new_pc;
   478                             sh4r.new_pc = sh4r.pr;
   479                             return TRUE;
   480                         case 1: /* SLEEP   */
   481 			    if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
   482 				sh4r.sh4_state = SH4_STATE_STANDBY;
   483 			    } else {
   484 				sh4r.sh4_state = SH4_STATE_SLEEP;
   485 			    }
   486 			    return FALSE; /* Halt CPU */
   487                         case 2: /* RTE     */
   488                             CHECKPRIV();
   489                             CHECKDEST( sh4r.spc );
   490                             CHECKSLOTILLEGAL();
   491                             sh4r.in_delay_slot = 1;
   492                             sh4r.pc = sh4r.new_pc;
   493                             sh4r.new_pc = sh4r.spc;
   494                             sh4_load_sr( sh4r.ssr );
   495                             return TRUE;
   496                         default:UNDEF(ir);
   497                     }
   498                     break;
   499                 case 12:/* MOV.B   [R0+R%d], R%d */
   500                     RN(ir) = MEM_READ_BYTE( R0 + RM(ir) );
   501                     break;
   502                 case 13:/* MOV.W   [R0+R%d], R%d */
   503                     RN(ir) = MEM_READ_WORD( R0 + RM(ir) );
   504                     break;
   505                 case 14:/* MOV.L   [R0+R%d], R%d */
   506                     RN(ir) = MEM_READ_LONG( R0 + RM(ir) );
   507                     break;
   508                 case 15:/* MAC.L   [Rm++], [Rn++] */
   509                     tmpl = ( SIGNEXT32(MEM_READ_LONG(RM(ir))) *
   510                                   SIGNEXT32(MEM_READ_LONG(RN(ir))) );
   511                     if( sh4r.s ) {
   512                         /* 48-bit Saturation. Yuch */
   513                         tmpl += SIGNEXT48(sh4r.mac);
   514                         if( tmpl < 0xFFFF800000000000LL )
   515                             tmpl = 0xFFFF800000000000LL;
   516                         else if( tmpl > 0x00007FFFFFFFFFFFLL )
   517                             tmpl = 0x00007FFFFFFFFFFFLL;
   518                         sh4r.mac = (sh4r.mac&0xFFFF000000000000LL) |
   519                             (tmpl&0x0000FFFFFFFFFFFFLL);
   520                     } else sh4r.mac = tmpl;
   522                     RM(ir) += 4;
   523                     RN(ir) += 4;
   525                     break;
   526                 default: UNDEF(ir);
   527             }
   528             break;
   529         case 1: /* 0001nnnnmmmmdddd */
   530             /* MOV.L   Rm, [Rn + disp4*4] */
   531             MEM_WRITE_LONG( RN(ir) + (DISP4(ir)<<2), RM(ir) );
   532             break;
   533         case 2: /* 0010nnnnmmmmxxxx */
   534             switch( ir&0x000F ) {
   535                 case 0: /* MOV.B   Rm, [Rn] */
   536                     MEM_WRITE_BYTE( RN(ir), RM(ir) );
   537                     break;
   538                 case 1: /* MOV.W   Rm, [Rn] */
   539                     MEM_WRITE_WORD( RN(ir), RM(ir) );
   540                     break;
   541                 case 2: /* MOV.L   Rm, [Rn] */
   542                     MEM_WRITE_LONG( RN(ir), RM(ir) );
   543                     break;
   544                 case 3: UNDEF(ir);
   545                     break;
   546                 case 4: /* MOV.B   Rm, [--Rn] */
   547                     RN(ir) --;
   548                     MEM_WRITE_BYTE( RN(ir), RM(ir) );
   549                     break;
   550                 case 5: /* MOV.W   Rm, [--Rn] */
   551                     RN(ir) -= 2;
   552                     MEM_WRITE_WORD( RN(ir), RM(ir) );
   553                     break;
   554                 case 6: /* MOV.L   Rm, [--Rn] */
   555                     RN(ir) -= 4;
   556                     MEM_WRITE_LONG( RN(ir), RM(ir) );
   557                     break;
   558                 case 7: /* DIV0S   Rm, Rn */
   559                     sh4r.q = RN(ir)>>31;
   560                     sh4r.m = RM(ir)>>31;
   561                     sh4r.t = sh4r.q ^ sh4r.m;
   562                     break;
   563                 case 8: /* TST     Rm, Rn */
   564                     sh4r.t = (RN(ir)&RM(ir) ? 0 : 1);
   565                     break;
   566                 case 9: /* AND     Rm, Rn */
   567                     RN(ir) &= RM(ir);
   568                     break;
   569                 case 10:/* XOR     Rm, Rn */
   570                     RN(ir) ^= RM(ir);
   571                     break;
   572                 case 11:/* OR      Rm, Rn */
   573                     RN(ir) |= RM(ir);
   574                     break;
   575                 case 12:/* CMP/STR Rm, Rn */
   576                     /* set T = 1 if any byte in RM & RN is the same */
   577                     tmp = RM(ir) ^ RN(ir);
   578                     sh4r.t = ((tmp&0x000000FF)==0 || (tmp&0x0000FF00)==0 ||
   579                               (tmp&0x00FF0000)==0 || (tmp&0xFF000000)==0)?1:0;
   580                     break;
   581                 case 13:/* XTRCT   Rm, Rn */
   582                     RN(ir) = (RN(ir)>>16) | (RM(ir)<<16);
   583                     break;
   584                 case 14:/* MULU.W  Rm, Rn */
   585                     sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
   586                         (uint32_t)((RM(ir)&0xFFFF) * (RN(ir)&0xFFFF));
   587                     break;
   588                 case 15:/* MULS.W  Rm, Rn */
   589                     sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
   590                         (uint32_t)(SIGNEXT32(RM(ir)&0xFFFF) * SIGNEXT32(RN(ir)&0xFFFF));
   591                     break;
   592             }
   593             break;
   594         case 3: /* 0011nnnnmmmmxxxx */
   595             switch( ir&0x000F ) {
   596                 case 0: /* CMP/EQ  Rm, Rn */
   597                     sh4r.t = ( RM(ir) == RN(ir) ? 1 : 0 );
   598                     break;
   599                 case 2: /* CMP/HS  Rm, Rn */
   600                     sh4r.t = ( RN(ir) >= RM(ir) ? 1 : 0 );
   601                     break;
   602                 case 3: /* CMP/GE  Rm, Rn */
   603                     sh4r.t = ( ((int32_t)RN(ir)) >= ((int32_t)RM(ir)) ? 1 : 0 );
   604                     break;
   605                 case 4: { /* DIV1    Rm, Rn */
   606                     /* This is just from the sh4p manual with some
   607                      * simplifications (someone want to check it's correct? :)
   608                      * Why they couldn't just provide a real DIV instruction...
   609                      * Please oh please let the translator batch these things
   610                      * up into a single DIV... */
   611                     uint32_t tmp0, tmp1, tmp2, dir;
   613                     dir = sh4r.q ^ sh4r.m;
   614                     sh4r.q = (RN(ir) >> 31);
   615                     tmp2 = RM(ir);
   616                     RN(ir) = (RN(ir) << 1) | sh4r.t;
   617                     tmp0 = RN(ir);
   618                     if( dir ) {
   619                         RN(ir) += tmp2;
   620                         tmp1 = (RN(ir)<tmp0 ? 1 : 0 );
   621                     } else {
   622                         RN(ir) -= tmp2;
   623                         tmp1 = (RN(ir)>tmp0 ? 1 : 0 );
   624                     }
   625                     sh4r.q ^= sh4r.m ^ tmp1;
   626                     sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );
   627                     break; }
   628                 case 5: /* DMULU.L Rm, Rn */
   629                     sh4r.mac = ((uint64_t)RM(ir)) * ((uint64_t)RN(ir));
   630                     break;
   631                 case 6: /* CMP/HI  Rm, Rn */
   632                     sh4r.t = ( RN(ir) > RM(ir) ? 1 : 0 );
   633                     break;
   634                 case 7: /* CMP/GT  Rm, Rn */
   635                     sh4r.t = ( ((int32_t)RN(ir)) > ((int32_t)RM(ir)) ? 1 : 0 );
   636                     break;
   637                 case 8: /* SUB     Rm, Rn */
   638                     RN(ir) -= RM(ir);
   639                     break;
   640                 case 10:/* SUBC    Rm, Rn */
   641                     tmp = RN(ir);
   642                     RN(ir) = RN(ir) - RM(ir) - sh4r.t;
   643                     sh4r.t = (RN(ir) > tmp || (RN(ir) == tmp && sh4r.t == 1));
   644                     break;
   645                 case 11:/* SUBV    Rm, Rn */
   646                     UNIMP(ir);
   647                     break;
   648                 case 12:/* ADD     Rm, Rn */
   649                     RN(ir) += RM(ir);
   650                     break;
   651                 case 13:/* DMULS.L Rm, Rn */
   652                     sh4r.mac = SIGNEXT32(RM(ir)) * SIGNEXT32(RN(ir));
   653                     break;
   654                 case 14:/* ADDC    Rm, Rn */
   655                     tmp = RN(ir);
   656                     RN(ir) += RM(ir) + sh4r.t;
   657                     sh4r.t = ( RN(ir) < tmp || (RN(ir) == tmp && sh4r.t != 0) ? 1 : 0 );
   658                     break;
   659                 case 15:/* ADDV    Rm, Rn */
   660                     UNIMP(ir);
   661                     break;
   662                 default: UNDEF(ir);
   663             }
   664             break;
   665         case 4: /* 0100nnnnxxxxxxxx */
   666             switch( ir&0x00FF ) {
   667                 case 0x00: /* SHLL    Rn */
   668                     sh4r.t = RN(ir) >> 31;
   669                     RN(ir) <<= 1;
   670                     break;
   671                 case 0x01: /* SHLR    Rn */
   672                     sh4r.t = RN(ir) & 0x00000001;
   673                     RN(ir) >>= 1;
   674                     break;
   675                 case 0x02: /* STS.L   MACH, [--Rn] */
   676                     RN(ir) -= 4;
   677                     MEM_WRITE_LONG( RN(ir), (sh4r.mac>>32) );
   678                     break;
   679                 case 0x03: /* STC.L   SR, [--Rn] */
   680                     CHECKPRIV();
   681                     RN(ir) -= 4;
   682                     MEM_WRITE_LONG( RN(ir), sh4_read_sr() );
   683                     break;
   684                 case 0x04: /* ROTL    Rn */
   685                     sh4r.t = RN(ir) >> 31;
   686                     RN(ir) <<= 1;
   687                     RN(ir) |= sh4r.t;
   688                     break;
   689                 case 0x05: /* ROTR    Rn */
   690                     sh4r.t = RN(ir) & 0x00000001;
   691                     RN(ir) >>= 1;
   692                     RN(ir) |= (sh4r.t << 31);
   693                     break;
   694                 case 0x06: /* LDS.L   [Rn++], MACH */
   695                     sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
   696                         (((uint64_t)MEM_READ_LONG(RN(ir)))<<32);
   697                     RN(ir) += 4;
   698                     break;
   699                 case 0x07: /* LDC.L   [Rn++], SR */
   700                     CHECKPRIV();
   701                     sh4_load_sr( MEM_READ_LONG(RN(ir)) );
   702                     RN(ir) +=4;
   703                     break;
   704                 case 0x08: /* SHLL2   Rn */
   705                     RN(ir) <<= 2;
   706                     break;
   707                 case 0x09: /* SHLR2   Rn */
   708                     RN(ir) >>= 2;
   709                     break;
   710                 case 0x0A: /* LDS     Rn, MACH */
   711                     sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
   712                         (((uint64_t)RN(ir))<<32);
   713                     break;
   714                 case 0x0B: /* JSR     [Rn] */
   715                     CHECKDEST( RN(ir) );
   716                     CHECKSLOTILLEGAL();
   717                     sh4r.in_delay_slot = 1;
   718                     sh4r.pc = sh4r.new_pc;
   719                     sh4r.new_pc = RN(ir);
   720                     sh4r.pr = pc + 4;
   721                     return TRUE;
   722                 case 0x0E: /* LDC     Rn, SR */
   723                     CHECKPRIV();
   724                     sh4_load_sr( RN(ir) );
   725                     break;
   726                 case 0x10: /* DT      Rn */
   727                     RN(ir) --;
   728                     sh4r.t = ( RN(ir) == 0 ? 1 : 0 );
   729                     break;
   730                 case 0x11: /* CMP/PZ  Rn */
   731                     sh4r.t = ( ((int32_t)RN(ir)) >= 0 ? 1 : 0 );
   732                     break;
   733                 case 0x12: /* STS.L   MACL, [--Rn] */
   734                     RN(ir) -= 4;
   735                     MEM_WRITE_LONG( RN(ir), (uint32_t)sh4r.mac );
   736                     break;
   737                 case 0x13: /* STC.L   GBR, [--Rn] */
   738                     RN(ir) -= 4;
   739                     MEM_WRITE_LONG( RN(ir), sh4r.gbr );
   740                     break;
   741                 case 0x15: /* CMP/PL  Rn */
   742                     sh4r.t = ( ((int32_t)RN(ir)) > 0 ? 1 : 0 );
   743                     break;
   744                 case 0x16: /* LDS.L   [Rn++], MACL */
   745                     sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
   746                         (uint64_t)((uint32_t)MEM_READ_LONG(RN(ir)));
   747                     RN(ir) += 4;
   748                     break;
   749                 case 0x17: /* LDC.L   [Rn++], GBR */
   750                     sh4r.gbr = MEM_READ_LONG(RN(ir));
   751                     RN(ir) +=4;
   752                     break;
   753                 case 0x18: /* SHLL8   Rn */
   754                     RN(ir) <<= 8;
   755                     break;
   756                 case 0x19: /* SHLR8   Rn */
   757                     RN(ir) >>= 8;
   758                     break;
   759                 case 0x1A: /* LDS     Rn, MACL */
   760                     sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
   761                         (uint64_t)((uint32_t)(RN(ir)));
   762                     break;
   763                 case 0x1B: /* TAS.B   [Rn] */
   764                     tmp = MEM_READ_BYTE( RN(ir) );
   765                     sh4r.t = ( tmp == 0 ? 1 : 0 );
   766                     MEM_WRITE_BYTE( RN(ir), tmp | 0x80 );
   767                     break;
   768                 case 0x1E: /* LDC     Rn, GBR */
   769                     sh4r.gbr = RN(ir);
   770                     break;
   771                 case 0x20: /* SHAL    Rn */
   772                     sh4r.t = RN(ir) >> 31;
   773                     RN(ir) <<= 1;
   774                     break;
   775                 case 0x21: /* SHAR    Rn */
   776                     sh4r.t = RN(ir) & 0x00000001;
   777                     RN(ir) = ((int32_t)RN(ir)) >> 1;
   778                     break;
   779                 case 0x22: /* STS.L   PR, [--Rn] */
   780                     RN(ir) -= 4;
   781                     MEM_WRITE_LONG( RN(ir), sh4r.pr );
   782                     break;
   783                 case 0x23: /* STC.L   VBR, [--Rn] */
   784                     CHECKPRIV();
   785                     RN(ir) -= 4;
   786                     MEM_WRITE_LONG( RN(ir), sh4r.vbr );
   787                     break;
   788                 case 0x24: /* ROTCL   Rn */
   789                     tmp = RN(ir) >> 31;
   790                     RN(ir) <<= 1;
   791                     RN(ir) |= sh4r.t;
   792                     sh4r.t = tmp;
   793                     break;
   794                 case 0x25: /* ROTCR   Rn */
   795                     tmp = RN(ir) & 0x00000001;
   796                     RN(ir) >>= 1;
   797                     RN(ir) |= (sh4r.t << 31 );
   798                     sh4r.t = tmp;
   799                     break;
   800                 case 0x26: /* LDS.L   [Rn++], PR */
   801                     sh4r.pr = MEM_READ_LONG( RN(ir) );
   802                     RN(ir) += 4;
   803                     break;
   804                 case 0x27: /* LDC.L   [Rn++], VBR */
   805                     CHECKPRIV();
   806                     sh4r.vbr = MEM_READ_LONG(RN(ir));
   807                     RN(ir) +=4;
   808                     break;
   809                 case 0x28: /* SHLL16  Rn */
   810                     RN(ir) <<= 16;
   811                     break;
   812                 case 0x29: /* SHLR16  Rn */
   813                     RN(ir) >>= 16;
   814                     break;
   815                 case 0x2A: /* LDS     Rn, PR */
   816                     sh4r.pr = RN(ir);
   817                     break;
   818                 case 0x2B: /* JMP     [Rn] */
   819                     CHECKDEST( RN(ir) );
   820                     CHECKSLOTILLEGAL();
   821                     sh4r.in_delay_slot = 1;
   822                     sh4r.pc = sh4r.new_pc;
   823                     sh4r.new_pc = RN(ir);
   824                     return TRUE;
   825                 case 0x2E: /* LDC     Rn, VBR */
   826                     CHECKPRIV();
   827                     sh4r.vbr = RN(ir);
   828                     break;
   829                 case 0x32: /* STC.L   SGR, [--Rn] */
   830                     CHECKPRIV();
   831                     RN(ir) -= 4;
   832                     MEM_WRITE_LONG( RN(ir), sh4r.sgr );
   833                     break;
   834                 case 0x33: /* STC.L   SSR, [--Rn] */
   835                     CHECKPRIV();
   836                     RN(ir) -= 4;
   837                     MEM_WRITE_LONG( RN(ir), sh4r.ssr );
   838                     break;
   839                 case 0x37: /* LDC.L   [Rn++], SSR */
   840                     CHECKPRIV();
   841                     sh4r.ssr = MEM_READ_LONG(RN(ir));
   842                     RN(ir) +=4;
   843                     break;
   844                 case 0x3E: /* LDC     Rn, SSR */
   845                     CHECKPRIV();
   846                     sh4r.ssr = RN(ir);
   847                     break;
   848                 case 0x43: /* STC.L   SPC, [--Rn] */
   849                     CHECKPRIV();
   850                     RN(ir) -= 4;
   851                     MEM_WRITE_LONG( RN(ir), sh4r.spc );
   852                     break;
   853                 case 0x47: /* LDC.L   [Rn++], SPC */
   854                     CHECKPRIV();
   855                     sh4r.spc = MEM_READ_LONG(RN(ir));
   856                     RN(ir) +=4;
   857                     break;
   858                 case 0x4E: /* LDC     Rn, SPC */
   859                     CHECKPRIV();
   860                     sh4r.spc = RN(ir);
   861                     break;
   862                 case 0x52: /* STS.L   FPUL, [--Rn] */
   863                     RN(ir) -= 4;
   864                     MEM_WRITE_LONG( RN(ir), sh4r.fpul );
   865                     break;
   866                 case 0x56: /* LDS.L   [Rn++], FPUL */
   867                     sh4r.fpul = MEM_READ_LONG(RN(ir));
   868                     RN(ir) +=4;
   869                     break;
   870                 case 0x5A: /* LDS     Rn, FPUL */
   871                     sh4r.fpul = RN(ir);
   872                     break;
   873                 case 0x62: /* STS.L   FPSCR, [--Rn] */
   874                     RN(ir) -= 4;
   875                     MEM_WRITE_LONG( RN(ir), sh4r.fpscr );
   876                     break;
   877                 case 0x66: /* LDS.L   [Rn++], FPSCR */
   878                     sh4r.fpscr = MEM_READ_LONG(RN(ir));
   879                     RN(ir) +=4;
   880                     break;
   881                 case 0x6A: /* LDS     Rn, FPSCR */
   882                     sh4r.fpscr = RN(ir);
   883                     break;
   884                 case 0xF2: /* STC.L   DBR, [--Rn] */
   885                     CHECKPRIV();
   886                     RN(ir) -= 4;
   887                     MEM_WRITE_LONG( RN(ir), sh4r.dbr );
   888                     break;
   889                 case 0xF6: /* LDC.L   [Rn++], DBR */
   890                     CHECKPRIV();
   891                     sh4r.dbr = MEM_READ_LONG(RN(ir));
   892                     RN(ir) +=4;
   893                     break;
   894                 case 0xFA: /* LDC     Rn, DBR */
   895                     CHECKPRIV();
   896                     sh4r.dbr = RN(ir);
   897                     break;
   898                 case 0x83: case 0x93: case 0xA3: case 0xB3: case 0xC3:
   899                 case 0xD3: case 0xE3: case 0xF3: /* STC.L   Rn_BANK, [--Rn] */
   900                     CHECKPRIV();
   901                     RN(ir) -= 4;
   902                     MEM_WRITE_LONG( RN(ir), RN_BANK(ir) );
   903                     break;
   904                 case 0x87: case 0x97: case 0xA7: case 0xB7: case 0xC7:
   905                 case 0xD7: case 0xE7: case 0xF7: /* LDC.L   [Rn++], Rn_BANK */
   906                     CHECKPRIV();
   907                     RN_BANK(ir) = MEM_READ_LONG( RN(ir) );
   908                     RN(ir) += 4;
   909                     break;
   910                 case 0x8E: case 0x9E: case 0xAE: case 0xBE: case 0xCE:
   911                 case 0xDE: case 0xEE: case 0xFE: /* LDC     Rm, Rn_BANK */
   912                     CHECKPRIV();
   913                     RN_BANK(ir) = RM(ir);
   914                     break;
   915                 default:
   916                     if( (ir&0x000F) == 0x0F ) {
   917                         /* MAC.W   [Rm++], [Rn++] */
   918                         tmp = SIGNEXT16(MEM_READ_WORD(RM(ir))) *
   919                             SIGNEXT16(MEM_READ_WORD(RN(ir)));
   920                         if( sh4r.s ) {
   921                             /* FIXME */
   922                             UNIMP(ir);
   923                         } else sh4r.mac += SIGNEXT32(tmp);
   924                         RM(ir) += 2;
   925                         RN(ir) += 2;
   926                     } else if( (ir&0x000F) == 0x0C ) {
   927                         /* SHAD    Rm, Rn */
   928                         tmp = RM(ir);
   929                         if( (tmp & 0x80000000) == 0 ) RN(ir) <<= (tmp&0x1f);
   930                         else if( (tmp & 0x1F) == 0 )  
   931 			  RN(ir) = ((int32_t)RN(ir)) >> 31;
   932                         else 
   933 			  RN(ir) = ((int32_t)RN(ir)) >> (((~RM(ir)) & 0x1F)+1);
   934                     } else if( (ir&0x000F) == 0x0D ) {
   935                         /* SHLD    Rm, Rn */
   936                         tmp = RM(ir);
   937                         if( (tmp & 0x80000000) == 0 ) RN(ir) <<= (tmp&0x1f);
   938                         else if( (tmp & 0x1F) == 0 ) RN(ir) = 0;
   939                         else RN(ir) >>= (((~tmp) & 0x1F)+1);
   940                     } else UNDEF(ir);
   941             }
   942             break;
   943         case 5: /* 0101nnnnmmmmdddd */
   944             /* MOV.L   [Rm + disp4*4], Rn */
   945             RN(ir) = MEM_READ_LONG( RM(ir) + (DISP4(ir)<<2) );
   946             break;
   947         case 6: /* 0110xxxxxxxxxxxx */
   948             switch( ir&0x000f ) {
   949                 case 0: /* MOV.B   [Rm], Rn */
   950                     RN(ir) = MEM_READ_BYTE( RM(ir) );
   951                     break;
   952                 case 1: /* MOV.W   [Rm], Rn */
   953                     RN(ir) = MEM_READ_WORD( RM(ir) );
   954                     break;
   955                 case 2: /* MOV.L   [Rm], Rn */
   956                     RN(ir) = MEM_READ_LONG( RM(ir) );
   957                     break;
   958                 case 3: /* MOV     Rm, Rn */
   959                     RN(ir) = RM(ir);
   960                     break;
   961                 case 4: /* MOV.B   [Rm++], Rn */
   962                     RN(ir) = MEM_READ_BYTE( RM(ir) );
   963                     RM(ir) ++;
   964                     break;
   965                 case 5: /* MOV.W   [Rm++], Rn */
   966                     RN(ir) = MEM_READ_WORD( RM(ir) );
   967                     RM(ir) += 2;
   968                     break;
   969                 case 6: /* MOV.L   [Rm++], Rn */
   970                     RN(ir) = MEM_READ_LONG( RM(ir) );
   971                     RM(ir) += 4;
   972                     break;
   973                 case 7: /* NOT     Rm, Rn */
   974                     RN(ir) = ~RM(ir);
   975                     break;
   976                 case 8: /* SWAP.B  Rm, Rn */
   977                     RN(ir) = (RM(ir)&0xFFFF0000) | ((RM(ir)&0x0000FF00)>>8) |
   978                         ((RM(ir)&0x000000FF)<<8);
   979                     break;
   980                 case 9: /* SWAP.W  Rm, Rn */
   981                     RN(ir) = (RM(ir)>>16) | (RM(ir)<<16);
   982                     break;
   983                 case 10:/* NEGC    Rm, Rn */
   984                     tmp = 0 - RM(ir);
   985                     RN(ir) = tmp - sh4r.t;
   986                     sh4r.t = ( 0<tmp || tmp<RN(ir) ? 1 : 0 );
   987                     break;
   988                 case 11:/* NEG     Rm, Rn */
   989                     RN(ir) = 0 - RM(ir);
   990                     break;
   991                 case 12:/* EXTU.B  Rm, Rn */
   992                     RN(ir) = RM(ir)&0x000000FF;
   993                     break;
   994                 case 13:/* EXTU.W  Rm, Rn */
   995                     RN(ir) = RM(ir)&0x0000FFFF;
   996                     break;
   997                 case 14:/* EXTS.B  Rm, Rn */
   998                     RN(ir) = SIGNEXT8( RM(ir)&0x000000FF );
   999                     break;
  1000                 case 15:/* EXTS.W  Rm, Rn */
  1001                     RN(ir) = SIGNEXT16( RM(ir)&0x0000FFFF );
  1002                     break;
  1004             break;
  1005         case 7: /* 0111nnnniiiiiiii */
  1006             /* ADD    imm8, Rn */
  1007             RN(ir) += IMM8(ir);
  1008             break;
  1009         case 8: /* 1000xxxxxxxxxxxx */
  1010             switch( (ir&0x0F00) >> 8 ) {
  1011                 case 0: /* MOV.B   R0, [Rm + disp4] */
  1012                     MEM_WRITE_BYTE( RM(ir) + DISP4(ir), R0 );
  1013                     break;
  1014                 case 1: /* MOV.W   R0, [Rm + disp4*2] */
  1015                     MEM_WRITE_WORD( RM(ir) + (DISP4(ir)<<1), R0 );
  1016                     break;
  1017                 case 4: /* MOV.B   [Rm + disp4], R0 */
  1018                     R0 = MEM_READ_BYTE( RM(ir) + DISP4(ir) );
  1019                     break;
  1020                 case 5: /* MOV.W   [Rm + disp4*2], R0 */
  1021                     R0 = MEM_READ_WORD( RM(ir) + (DISP4(ir)<<1) );
  1022                     break;
  1023                 case 8: /* CMP/EQ  imm, R0 */
  1024                     sh4r.t = ( R0 == IMM8(ir) ? 1 : 0 );
  1025                     break;
  1026                 case 9: /* BT      disp8 */
  1027                     CHECKSLOTILLEGAL()
  1028                     if( sh4r.t ) {
  1029                         CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
  1030                         sh4r.pc += (PCDISP8(ir)<<1) + 4;
  1031                         sh4r.new_pc = sh4r.pc + 2;
  1032                         return TRUE;
  1034                     break;
  1035                 case 11:/* BF      disp8 */
  1036                     CHECKSLOTILLEGAL()
  1037                     if( !sh4r.t ) {
  1038                         CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
  1039                         sh4r.pc += (PCDISP8(ir)<<1) + 4;
  1040                         sh4r.new_pc = sh4r.pc + 2;
  1041                         return TRUE;
  1043                     break;
  1044                 case 13:/* BT/S    disp8 */
  1045                     CHECKSLOTILLEGAL()
  1046                     if( sh4r.t ) {
  1047                         CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
  1048                         sh4r.in_delay_slot = 1;
  1049                         sh4r.pc = sh4r.new_pc;
  1050                         sh4r.new_pc = pc + (PCDISP8(ir)<<1) + 4;
  1051                         sh4r.in_delay_slot = 1;
  1052                         return TRUE;
  1054                     break;
  1055                 case 15:/* BF/S    disp8 */
  1056                     CHECKSLOTILLEGAL()
  1057                     if( !sh4r.t ) {
  1058                         CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )
  1059                         sh4r.in_delay_slot = 1;
  1060                         sh4r.pc = sh4r.new_pc;
  1061                         sh4r.new_pc = pc + (PCDISP8(ir)<<1) + 4;
  1062                         return TRUE;
  1064                     break;
  1065                 default: UNDEF(ir);
  1067             break;
  1068         case 9: /* 1001xxxxxxxxxxxx */
  1069             /* MOV.W   [disp8*2 + pc + 4], Rn */
  1070             RN(ir) = MEM_READ_WORD( pc + 4 + (DISP8(ir)<<1) );
  1071             break;
  1072         case 10:/* 1010dddddddddddd */
  1073             /* BRA     disp12 */
  1074             CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 )
  1075             CHECKSLOTILLEGAL()
  1076             sh4r.in_delay_slot = 1;
  1077             sh4r.pc = sh4r.new_pc;
  1078             sh4r.new_pc = pc + 4 + (DISP12(ir)<<1);
  1079             return TRUE;
  1080         case 11:/* 1011dddddddddddd */
  1081             /* BSR     disp12 */
  1082             CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 )
  1083             CHECKSLOTILLEGAL()
  1084             sh4r.in_delay_slot = 1;
  1085             sh4r.pr = pc + 4;
  1086             sh4r.pc = sh4r.new_pc;
  1087             sh4r.new_pc = pc + 4 + (DISP12(ir)<<1);
  1088             return TRUE;
  1089         case 12:/* 1100xxxxdddddddd */
  1090         switch( (ir&0x0F00)>>8 ) {
  1091                 case 0: /* MOV.B  R0, [GBR + disp8] */
  1092                     MEM_WRITE_BYTE( sh4r.gbr + DISP8(ir), R0 );
  1093                     break;
  1094                 case 1: /* MOV.W  R0, [GBR + disp8*2] */
  1095                     MEM_WRITE_WORD( sh4r.gbr + (DISP8(ir)<<1), R0 );
  1096                     break;
  1097                 case  2: /*MOV.L   R0, [GBR + disp8*4] */
  1098                     MEM_WRITE_LONG( sh4r.gbr + (DISP8(ir)<<2), R0 );
  1099                     break;
  1100                 case 3: /* TRAPA   imm8 */
  1101                     CHECKSLOTILLEGAL()
  1102                     sh4r.in_delay_slot = 1;
  1103                     MMIO_WRITE( MMU, TRA, UIMM8(ir) );
  1104                     sh4r.pc = sh4r.new_pc;  /* RAISE ends the instruction */
  1105                     sh4r.new_pc += 2;
  1106                     RAISE( EXC_TRAP, EXV_TRAP );
  1107                     break;
  1108                 case 4: /* MOV.B   [GBR + disp8], R0 */
  1109                     R0 = MEM_READ_BYTE( sh4r.gbr + DISP8(ir) );
  1110                     break;
  1111                 case 5: /* MOV.W   [GBR + disp8*2], R0 */
  1112                     R0 = MEM_READ_WORD( sh4r.gbr + (DISP8(ir)<<1) );
  1113                     break;
  1114                 case 6: /* MOV.L   [GBR + disp8*4], R0 */
  1115                     R0 = MEM_READ_LONG( sh4r.gbr + (DISP8(ir)<<2) );
  1116                     break;
  1117                 case 7: /* MOVA    disp8 + pc&~3 + 4, R0 */
  1118                     R0 = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;
  1119                     break;
  1120                 case 8: /* TST     imm8, R0 */
  1121                     sh4r.t = (R0 & UIMM8(ir) ? 0 : 1);
  1122                     break;
  1123                 case 9: /* AND     imm8, R0 */
  1124                     R0 &= UIMM8(ir);
  1125                     break;
  1126                 case 10:/* XOR     imm8, R0 */
  1127                     R0 ^= UIMM8(ir);
  1128                     break;
  1129                 case 11:/* OR      imm8, R0 */
  1130                     R0 |= UIMM8(ir);
  1131                     break;
  1132                 case 12:/* TST.B   imm8, [R0+GBR] */
  1133                     sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & UIMM8(ir) ? 0 : 1 );
  1134                     break;
  1135                 case 13:/* AND.B   imm8, [R0+GBR] */
  1136                     MEM_WRITE_BYTE( R0 + sh4r.gbr,
  1137                                     UIMM8(ir) & MEM_READ_BYTE(R0 + sh4r.gbr) );
  1138                     break;
  1139                 case 14:/* XOR.B   imm8, [R0+GBR] */
  1140                     MEM_WRITE_BYTE( R0 + sh4r.gbr,
  1141                                     UIMM8(ir) ^ MEM_READ_BYTE(R0 + sh4r.gbr) );
  1142                     break;
  1143                 case 15:/* OR.B    imm8, [R0+GBR] */
  1144                     MEM_WRITE_BYTE( R0 + sh4r.gbr,
  1145                                     UIMM8(ir) | MEM_READ_BYTE(R0 + sh4r.gbr) );
  1146                     break;
  1148             break;
  1149         case 13:/* 1101nnnndddddddd */
  1150             /* MOV.L   [disp8*4 + pc&~3 + 4], Rn */
  1151             RN(ir) = MEM_READ_LONG( (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4 );
  1152             break;
  1153         case 14:/* 1110nnnniiiiiiii */
  1154             /* MOV     imm8, Rn */
  1155             RN(ir) = IMM8(ir);
  1156             break;
  1157         case 15:/* 1111xxxxxxxxxxxx */
  1158             CHECKFPUEN();
  1159             switch( ir&0x000F ) {
  1160                 case 0: /* FADD    FRm, FRn */
  1161                     FRN(ir) += FRM(ir);
  1162                     break;
  1163                 case 1: /* FSUB    FRm, FRn */
  1164                     FRN(ir) -= FRM(ir);
  1165                     break;
  1166                 case 2: /* FMUL    FRm, FRn */
  1167                     FRN(ir) = FRN(ir) * FRM(ir);
  1168                     break;
  1169                 case 3: /* FDIV    FRm, FRn */
  1170                     FRN(ir) = FRN(ir) / FRM(ir);
  1171                     break;
  1172                 case 4: /* FCMP/EQ FRm, FRn */
  1173                     sh4r.t = ( FRN(ir) == FRM(ir) ? 1 : 0 );
  1174                     break;
  1175                 case 5: /* FCMP/GT FRm, FRn */
  1176                     sh4r.t = ( FRN(ir) > FRM(ir) ? 1 : 0 );
  1177                     break;
  1178                 case 6: /* FMOV.S  [Rm+R0], FRn */
  1179                     MEM_FP_READ( RM(ir) + R0, FRNn(ir) );
  1180                     break;
  1181                 case 7: /* FMOV.S  FRm, [Rn+R0] */
  1182                     MEM_FP_WRITE( RN(ir) + R0, FRMn(ir) );
  1183                     break;
  1184                 case 8: /* FMOV.S  [Rm], FRn */
  1185                     MEM_FP_READ( RM(ir), FRNn(ir) );
  1186                     break;
  1187                 case 9: /* FMOV.S  [Rm++], FRn */
  1188                     MEM_FP_READ( RM(ir), FRNn(ir) );
  1189                     RM(ir) += FP_WIDTH;
  1190                     break;
  1191                 case 10:/* FMOV.S  FRm, [Rn] */
  1192                     MEM_FP_WRITE( RN(ir), FRMn(ir) );
  1193                     break;
  1194                 case 11:/* FMOV.S  FRm, [--Rn] */
  1195                     RN(ir) -= FP_WIDTH;
  1196                     MEM_FP_WRITE( RN(ir), FRMn(ir) );
  1197                     break;
  1198                 case 12:/* FMOV    FRm, FRn */
  1199                     if( IS_FPU_DOUBLESIZE() ) {
  1200                         DRN(ir) = DRM(ir);
  1201                     } else {
  1202                         FRN(ir) = FRM(ir);
  1204                     break;
  1205                 case 13:
  1206                     switch( (ir&0x00F0) >> 4 ) {
  1207                         case 0: /* FSTS    FPUL, FRn */
  1208                             FRN(ir) = FPULf;
  1209                             break;
  1210                         case 1: /* FLDS    FRn, FPUL */
  1211                             FPULf = FRN(ir);
  1212                             break;
  1213                         case 2: /* FLOAT   FPUL, FRn */
  1214                             FRN(ir) = (float)FPULi;
  1215                             break;
  1216                         case 3: /* FTRC    FRn, FPUL */
  1217                             FPULi = (uint32_t)FRN(ir);
  1218                             /* FIXME: is this sufficient? */
  1219                             break;
  1220                         case 4: /* FNEG    FRn */
  1221                             FRN(ir) = -FRN(ir);
  1222                             break;
  1223                         case 5: /* FABS    FRn */
  1224                             FRN(ir) = fabsf(FRN(ir));
  1225                             break;
  1226                         case 6: /* FSQRT   FRn */
  1227                             FRN(ir) = sqrtf(FRN(ir));
  1228                             break;
  1229                         case 7: /* FSRRA FRn */
  1230                             FRN(ir) = 1.0/sqrtf(FRN(ir));
  1231                             break;
  1232                         case 8: /* FLDI0   FRn */
  1233                             FRN(ir) = 0.0;
  1234                             break;
  1235                         case 9: /* FLDI1   FRn */
  1236                             FRN(ir) = 1.0;
  1237                             break;
  1238                         case 10: /* FCNVSD FPUL, DRn */
  1239                             if( IS_FPU_DOUBLEPREC() )
  1240                                 DRN(ir) = (double)FPULf;
  1241                             else UNDEF(ir);
  1242                             break;
  1243                         case 11: /* FCNVDS DRn, FPUL */
  1244                             if( IS_FPU_DOUBLEPREC() ) 
  1245                                 FPULf = (float)DRN(ir);
  1246                             else UNDEF(ir);
  1247                             break;
  1248                         case 14:/* FIPR    FVm, FVn */
  1249                             /* FIXME: This is not going to be entirely accurate
  1250                              * as the SH4 instruction is less precise. Also
  1251                              * need to check for 0s and infinities.
  1252                              */
  1254                             float *fr_bank = FR;
  1255                             int tmp2 = FVN(ir);
  1256                             tmp = FVM(ir);
  1257                             fr_bank[tmp2+3] = fr_bank[tmp]*fr_bank[tmp2] +
  1258                                 fr_bank[tmp+1]*fr_bank[tmp2+1] +
  1259                                 fr_bank[tmp+2]*fr_bank[tmp2+2] +
  1260                                 fr_bank[tmp+3]*fr_bank[tmp2+3];
  1261                             break;
  1263                         case 15:
  1264                             if( (ir&0x0300) == 0x0100 ) { /* FTRV    XMTRX,FVn */
  1265                                 float *fvout = FR+FVN(ir);
  1266                                 float *xm = XF;
  1267                                 float fv[4] = { fvout[0], fvout[1], fvout[2], fvout[3] };
  1268                                 fvout[0] = xm[0] * fv[0] + xm[4]*fv[1] +
  1269                                     xm[8]*fv[2] + xm[12]*fv[3];
  1270                                 fvout[1] = xm[1] * fv[0] + xm[5]*fv[1] +
  1271                                     xm[9]*fv[2] + xm[13]*fv[3];
  1272                                 fvout[2] = xm[2] * fv[0] + xm[6]*fv[1] +
  1273                                     xm[10]*fv[2] + xm[14]*fv[3];
  1274                                 fvout[3] = xm[3] * fv[0] + xm[7]*fv[1] +
  1275                                     xm[11]*fv[2] + xm[15]*fv[3];
  1276                                 break;
  1278                             else if( (ir&0x0100) == 0 ) { /* FSCA    FPUL, DRn */
  1279                                 float angle = (((float)(short)(FPULi>>16)) +
  1280                                                ((float)(FPULi&16)/65536.0)) *
  1281                                     2 * M_PI;
  1282                                 int reg = FRNn(ir);
  1283                                 FR[reg] = sinf(angle);
  1284                                 FR[reg+1] = cosf(angle);
  1285                                 break;
  1287                             else if( ir == 0xFBFD ) {
  1288                                 /* FRCHG   */
  1289                                 sh4r.fpscr ^= FPSCR_FR;
  1290                                 break;
  1292                             else if( ir == 0xF3FD ) {
  1293                                 /* FSCHG   */
  1294                                 sh4r.fpscr ^= FPSCR_SZ;
  1295                                 break;
  1297                         default: UNDEF(ir);
  1299                     break;
  1300                 case 14:/* FMAC    FR0, FRm, FRn */
  1301                     FRN(ir) += FRM(ir)*FR0;
  1302                     break;
  1303                 default: UNDEF(ir);
  1305             break;
  1307     sh4r.pc = sh4r.new_pc;
  1308     sh4r.new_pc += 2;
  1309     sh4r.in_delay_slot = 0;
.