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