Search
lxdream.org :: lxdream/src/aica/armcore.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armcore.c
changeset 73:0bb57e51ac9e
prev66:2ec5b6eb75e5
next80:1d59b19eb505
author nkeynes
date Thu Jan 12 11:30:19 2006 +0000 (18 years ago)
permissions -rw-r--r--
last change Render multiple samples per shot, should be mildly faster
Move timer logic down into armcore
Minor tweaks
view annotate diff log raw
     1 /**
     2  * $Id: armcore.c,v 1.17 2006-01-12 11:30:19 nkeynes Exp $
     3  * 
     4  * ARM7TDMI CPU emulation core.
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #define MODULE aica_module
    20 #include "dream.h"
    21 #include "mem.h"
    22 #include "aica/armcore.h"
    23 #include "aica/aica.h"
    25 #define STM_R15_OFFSET 12
    27 struct arm_registers armr;
    29 void arm_set_mode( int mode );
    31 uint32_t arm_exceptions[][2] = {{ MODE_SVC, 0x00000000 },
    32 				{ MODE_UND, 0x00000004 },
    33 				{ MODE_SVC, 0x00000008 },
    34 				{ MODE_ABT, 0x0000000C },
    35 				{ MODE_ABT, 0x00000010 },
    36 				{ MODE_IRQ, 0x00000018 },
    37 				{ MODE_FIQ, 0x0000001C } };
    39 #define EXC_RESET 0
    40 #define EXC_UNDEFINED 1
    41 #define EXC_SOFTWARE 2
    42 #define EXC_PREFETCH_ABORT 3
    43 #define EXC_DATA_ABORT 4
    44 #define EXC_IRQ 5
    45 #define EXC_FAST_IRQ 6
    47 uint32_t arm_cpu_freq = ARM_BASE_RATE;
    48 uint32_t arm_cpu_period = 1000 / ARM_BASE_RATE;
    50 #define CYCLES_PER_SAMPLE ((ARM_BASE_RATE * 1000000) / AICA_SAMPLE_RATE)
    52 static struct breakpoint_struct arm_breakpoints[MAX_BREAKPOINTS];
    53 static int arm_breakpoint_count = 0;
    55 void arm_set_breakpoint( uint32_t pc, int type )
    56 {
    57     arm_breakpoints[arm_breakpoint_count].address = pc;
    58     arm_breakpoints[arm_breakpoint_count].type = type;
    59     arm_breakpoint_count++;
    60 }
    62 gboolean arm_clear_breakpoint( uint32_t pc, int type )
    63 {
    64     int i;
    66     for( i=0; i<arm_breakpoint_count; i++ ) {
    67 	if( arm_breakpoints[i].address == pc && 
    68 	    arm_breakpoints[i].type == type ) {
    69 	    while( ++i < arm_breakpoint_count ) {
    70 		arm_breakpoints[i-1].address = arm_breakpoints[i].address;
    71 		arm_breakpoints[i-1].type = arm_breakpoints[i].type;
    72 	    }
    73 	    arm_breakpoint_count--;
    74 	    return TRUE;
    75 	}
    76     }
    77     return FALSE;
    78 }
    80 int arm_get_breakpoint( uint32_t pc )
    81 {
    82     int i;
    83     for( i=0; i<arm_breakpoint_count; i++ ) {
    84 	if( arm_breakpoints[i].address == pc )
    85 	    return arm_breakpoints[i].type;
    86     }
    87     return 0;
    88 }
    90 #define IS_TIMER_ENABLED() (MMIO_READ( AICA2, AICA_TCR ) & 0x40)
    92 uint32_t arm_run_slice( uint32_t num_samples )
    93 {
    94     int i,j,k;
    95     for( i=0; i<num_samples; i++ ) {
    96 	for( j=0; j < CYCLES_PER_SAMPLE; j++ ) {
    97 	    armr.icount++;
    98 	    if( !arm_execute_instruction() )
    99 		return i;
   100 #ifdef ENABLE_DEBUG_MODE
   101 	    for( k=0; k<arm_breakpoint_count; k++ ) {
   102 		if( arm_breakpoints[k].address == armr.r[15] ) {
   103 		    dreamcast_stop();
   104 		    if( arm_breakpoints[k].type == BREAK_ONESHOT )
   105 			arm_clear_breakpoint( armr.r[15], BREAK_ONESHOT );
   106 		    return i;
   107 		}
   108 	    }
   109 #endif	
   110 	}
   112 	if( IS_TIMER_ENABLED() ) {
   113 	    uint8_t val = MMIO_READ( AICA2, AICA_TIMER );
   114 	    val++;
   115 	    if( val == 0 )
   116 		aica_event( AICA_EVENT_TIMER );
   117 	    MMIO_WRITE( AICA2, AICA_TIMER, val );
   118 	}
   119 	if( !dreamcast_is_running() )
   120 	    break;
   121     }
   123     return i;
   124 }
   126 void arm_save_state( FILE *f )
   127 {
   128     fwrite( &armr, sizeof(armr), 1, f );
   129 }
   131 int arm_load_state( FILE *f )
   132 {
   133     fread( &armr, sizeof(armr), 1, f );
   134     return 0;
   135 }
   137 /* Exceptions */
   138 void arm_reset( void )
   139 {
   140     /* Wipe all processor state */
   141     memset( &armr, 0, sizeof(armr) );
   143     armr.cpsr = MODE_SVC | CPSR_I | CPSR_F;
   144     armr.r[15] = 0x00000000;
   145 }
   147 #define SET_CPSR_CONTROL   0x00010000
   148 #define SET_CPSR_EXTENSION 0x00020000
   149 #define SET_CPSR_STATUS    0x00040000
   150 #define SET_CPSR_FLAGS     0x00080000
   152 uint32_t arm_get_cpsr( void )
   153 {
   154     /* write back all flags to the cpsr */
   155     armr.cpsr = armr.cpsr & CPSR_COMPACT_MASK;
   156     if( armr.n ) armr.cpsr |= CPSR_N;
   157     if( armr.z ) armr.cpsr |= CPSR_Z;
   158     if( armr.c ) armr.cpsr |= CPSR_C;
   159     if( armr.v ) armr.cpsr |= CPSR_V;
   160     if( armr.t ) armr.cpsr |= CPSR_T;  
   161     return armr.cpsr;
   162 }
   164 /**
   165  * Return a pointer to the specified register in the user bank,
   166  * regardless of the active bank
   167  */
   168 static uint32_t *arm_user_reg( int reg )
   169 {
   170     if( IS_EXCEPTION_MODE() ) {
   171 	if( reg == 13 || reg == 14 )
   172 	    return &armr.user_r[reg-8];
   173 	if( IS_FIQ_MODE() ) {
   174 	    if( reg >= 8 || reg <= 12 )
   175 		return &armr.user_r[reg-8];
   176 	}
   177     }
   178     return &armr.r[reg];
   179 }
   181 #define USER_R(n) *arm_user_reg(n)
   183 /**
   184  * Set the CPSR to the specified value.
   185  *
   186  * @param value values to set in CPSR
   187  * @param fields set of mask values to define which sections of the 
   188  *   CPSR to set (one of the SET_CPSR_* values above)
   189  */
   190 void arm_set_cpsr( uint32_t value, uint32_t fields )
   191 {
   192     if( IS_PRIVILEGED_MODE() ) {
   193 	if( fields & SET_CPSR_CONTROL ) {
   194 	    int mode = value & CPSR_MODE;
   195 	    arm_set_mode( mode );
   196 	    armr.t = ( value & CPSR_T ); /* Technically illegal to change */
   197 	    armr.cpsr = (armr.cpsr & 0xFFFFFF00) | (value & 0x000000FF);
   198 	}
   200 	/* Middle 16 bits not currently defined */
   201     }
   202     if( fields & SET_CPSR_FLAGS ) {
   203 	/* Break flags directly out of given value - don't bother writing
   204 	 * back to CPSR 
   205 	 */
   206 	armr.n = ( value & CPSR_N );
   207 	armr.z = ( value & CPSR_Z );
   208 	armr.c = ( value & CPSR_C );
   209 	armr.v = ( value & CPSR_V );
   210     }
   211 }
   213 void arm_set_spsr( uint32_t value, uint32_t fields )
   214 {
   215     /* Only defined if we actually have an SPSR register */
   216     if( IS_EXCEPTION_MODE() ) {
   217 	if( fields & SET_CPSR_CONTROL ) {
   218 	    armr.spsr = (armr.spsr & 0xFFFFFF00) | (value & 0x000000FF);
   219 	}
   221 	/* Middle 16 bits not currently defined */
   223 	if( fields & SET_CPSR_FLAGS ) {
   224 	    armr.spsr = (armr.spsr & 0x00FFFFFF) | (value & 0xFF000000);
   225 	}
   226     }
   227 }
   229 /**
   230  * Raise an ARM exception (other than reset, which uses arm_reset().
   231  * @param exception one of the EXC_* exception codes defined above.
   232  */
   233 void arm_raise_exception( int exception )
   234 {
   235     int mode = arm_exceptions[exception][0];
   236     uint32_t spsr = arm_get_cpsr();
   237     arm_set_mode( mode );
   238     armr.spsr = spsr;
   239     armr.r[14] = armr.r[15] + 4;
   240     armr.cpsr = (spsr & 0xFFFFFF00) | mode | CPSR_I; 
   241     if( mode == MODE_FIQ )
   242 	armr.cpsr |= CPSR_F;
   243     armr.r[15] = arm_exceptions[exception][1];
   244 }
   246 void arm_restore_cpsr( void )
   247 {
   248     int spsr = armr.spsr;
   249     int mode = spsr & CPSR_MODE;
   250     arm_set_mode( mode );
   251     armr.cpsr = spsr;
   252     armr.n = ( spsr & CPSR_N );
   253     armr.z = ( spsr & CPSR_Z );
   254     armr.c = ( spsr & CPSR_C );
   255     armr.v = ( spsr & CPSR_V );
   256     armr.t = ( spsr & CPSR_T );
   257 }
   261 /**
   262  * Change the current executing ARM mode to the requested mode.
   263  * Saves any required registers to banks and restores those for the
   264  * correct mode. (Note does not actually update CPSR at the moment).
   265  */
   266 void arm_set_mode( int targetMode )
   267 {
   268     int currentMode = armr.cpsr & CPSR_MODE;
   269     if( currentMode == targetMode )
   270 	return;
   272     switch( currentMode ) {
   273     case MODE_USER:
   274     case MODE_SYS:
   275 	armr.user_r[5] = armr.r[13];
   276 	armr.user_r[6] = armr.r[14];
   277 	break;
   278     case MODE_SVC:
   279 	armr.svc_r[0] = armr.r[13];
   280 	armr.svc_r[1] = armr.r[14];
   281 	armr.svc_r[2] = armr.spsr;
   282 	break;
   283     case MODE_ABT:
   284 	armr.abt_r[0] = armr.r[13];
   285 	armr.abt_r[1] = armr.r[14];
   286 	armr.abt_r[2] = armr.spsr;
   287 	break;
   288     case MODE_UND:
   289 	armr.und_r[0] = armr.r[13];
   290 	armr.und_r[1] = armr.r[14];
   291 	armr.und_r[2] = armr.spsr;
   292 	break;
   293     case MODE_IRQ:
   294 	armr.irq_r[0] = armr.r[13];
   295 	armr.irq_r[1] = armr.r[14];
   296 	armr.irq_r[2] = armr.spsr;
   297 	break;
   298     case MODE_FIQ:
   299 	armr.fiq_r[0] = armr.r[8];
   300 	armr.fiq_r[1] = armr.r[9];
   301 	armr.fiq_r[2] = armr.r[10];
   302 	armr.fiq_r[3] = armr.r[11];
   303 	armr.fiq_r[4] = armr.r[12];
   304 	armr.fiq_r[5] = armr.r[13];
   305 	armr.fiq_r[6] = armr.r[14];
   306 	armr.fiq_r[7] = armr.spsr;
   307 	armr.r[8] = armr.user_r[0];
   308 	armr.r[9] = armr.user_r[1];
   309 	armr.r[10] = armr.user_r[2];
   310 	armr.r[11] = armr.user_r[3];
   311 	armr.r[12] = armr.user_r[4];
   312 	break;
   313     }
   315     switch( targetMode ) {
   316     case MODE_USER:
   317     case MODE_SYS:
   318 	armr.r[13] = armr.user_r[5];
   319 	armr.r[14] = armr.user_r[6];
   320 	break;
   321     case MODE_SVC:
   322 	armr.r[13] = armr.svc_r[0];
   323 	armr.r[14] = armr.svc_r[1];
   324 	armr.spsr = armr.svc_r[2];
   325 	break;
   326     case MODE_ABT:
   327 	armr.r[13] = armr.abt_r[0];
   328 	armr.r[14] = armr.abt_r[1];
   329 	armr.spsr = armr.abt_r[2];
   330 	break;
   331     case MODE_UND:
   332 	armr.r[13] = armr.und_r[0];
   333 	armr.r[14] = armr.und_r[1];
   334 	armr.spsr = armr.und_r[2];
   335 	break;
   336     case MODE_IRQ:
   337 	armr.r[13] = armr.irq_r[0];
   338 	armr.r[14] = armr.irq_r[1];
   339 	armr.spsr = armr.irq_r[2];
   340 	break;
   341     case MODE_FIQ:
   342 	armr.user_r[0] = armr.r[8];
   343 	armr.user_r[1] = armr.r[9];
   344 	armr.user_r[2] = armr.r[10];
   345 	armr.user_r[3] = armr.r[11];
   346 	armr.user_r[4] = armr.r[12];
   347 	armr.r[8] = armr.fiq_r[0];
   348 	armr.r[9] = armr.fiq_r[1];
   349 	armr.r[10] = armr.fiq_r[2];
   350 	armr.r[11] = armr.fiq_r[3];
   351 	armr.r[12] = armr.fiq_r[4];
   352 	armr.r[13] = armr.fiq_r[5];
   353 	armr.r[14] = armr.fiq_r[6];
   354 	armr.spsr = armr.fiq_r[7];
   355 	break;
   356     }
   357 }
   359 /* Page references are as per ARM DDI 0100E (June 2000) */
   361 #define MEM_READ_BYTE( addr ) arm_read_byte(addr)
   362 #define MEM_READ_WORD( addr ) arm_read_word(addr)
   363 #define MEM_READ_LONG( addr ) arm_read_long(addr)
   364 #define MEM_WRITE_BYTE( addr, val ) arm_write_byte(addr, val)
   365 #define MEM_WRITE_WORD( addr, val ) arm_write_word(addr, val)
   366 #define MEM_WRITE_LONG( addr, val ) arm_write_long(addr, val)
   369 #define IS_NOTBORROW( result, op1, op2 ) (op2 > op1 ? 0 : 1)
   370 #define IS_CARRY( result, op1, op2 ) (result < op1 ? 1 : 0)
   371 #define IS_SUBOVERFLOW( result, op1, op2 ) (((op1^op2) & (result^op1)) >> 31)
   372 #define IS_ADDOVERFLOW( result, op1, op2 ) (((op1&op2) & (result^op1)) >> 31)
   374 #define PC armr.r[15]
   376 /* Instruction fields */
   377 #define COND(ir) (ir>>28)
   378 #define GRP(ir) ((ir>>26)&0x03)
   379 #define OPCODE(ir) ((ir>>20)&0x1F)
   380 #define IFLAG(ir) (ir&0x02000000)
   381 #define SFLAG(ir) (ir&0x00100000)
   382 #define PFLAG(ir) (ir&0x01000000)
   383 #define UFLAG(ir) (ir&0x00800000)
   384 #define BFLAG(ir) (ir&0x00400000)
   385 #define WFLAG(ir) (ir&0x00200000)
   386 #define LFLAG(ir) SFLAG(ir)
   387 #define RN(ir) (armr.r[((ir>>16)&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))
   388 #define RD(ir) (armr.r[((ir>>12)&0x0F)] + (((ir>>12)&0x0F) == 0x0F ? 4 : 0))
   389 #define RDn(ir) ((ir>>12)&0x0F)
   390 #define RS(ir) (armr.r[((ir>>8)&0x0F)] + (((ir>>8)&0x0F) == 0x0F ? 4 : 0))
   391 #define RM(ir) (armr.r[(ir&0x0F)] + (((ir&0x0F) == 0x0F ? 4 : 0)) )
   392 #define LRN(ir) armr.r[((ir>>16)&0x0F)]
   393 #define LRD(ir) armr.r[((ir>>12)&0x0F)]
   394 #define LRS(ir) armr.r[((ir>>8)&0x0F)]
   395 #define LRM(ir) armr.r[(ir&0x0F)]
   397 #define IMM8(ir) (ir&0xFF)
   398 #define IMM12(ir) (ir&0xFFF)
   399 #define SHIFTIMM(ir) ((ir>>7)&0x1F)
   400 #define IMMROT(ir) ((ir>>7)&0x1E)
   401 #define ROTIMM12(ir) ROTATE_RIGHT_LONG(IMM8(ir),IMMROT(ir))
   402 #define SIGNEXT24(n) ((n&0x00800000) ? (n|0xFF000000) : (n&0x00FFFFFF))
   403 #define SHIFT(ir) ((ir>>4)&0x07)
   404 #define DISP24(ir) ((ir&0x00FFFFFF))
   405 #define UNDEF(ir) do{ arm_raise_exception( EXC_UNDEFINED ); return TRUE; } while(0)
   406 #define UNIMP(ir) do{ PC-=4; ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", PC, ir ); dreamcast_stop(); return FALSE; }while(0)
   408 /**
   409  * Determine the value of the shift-operand for a data processing instruction,
   410  * without determing a value for shift_C (optimized form for instructions that
   411  * don't require shift_C ).
   412  * @see s5.1 Addressing Mode 1 - Data-processing operands (p A5-2, 218)
   413  */
   414 static uint32_t arm_get_shift_operand( uint32_t ir )
   415 {
   416 	uint32_t operand, tmp;
   417 	if( IFLAG(ir) == 0 ) {
   418 		operand = RM(ir);
   419 		switch(SHIFT(ir)) {
   420 		case 0: /* (Rm << imm) */
   421 			operand = operand << SHIFTIMM(ir);
   422 			break;
   423 		case 1: /* (Rm << Rs) */
   424 			tmp = RS(ir)&0xFF;
   425 			if( tmp > 31 ) operand = 0;
   426 			else operand = operand << tmp;
   427 			break;
   428 		case 2: /* (Rm >> imm) */
   429 			operand = operand >> SHIFTIMM(ir);
   430 			break;
   431 		case 3: /* (Rm >> Rs) */
   432 			tmp = RS(ir) & 0xFF;
   433 			if( tmp > 31 ) operand = 0;
   434 			else operand = operand >> ir;
   435 			break;
   436 		case 4: /* (Rm >>> imm) */
   437 			tmp = SHIFTIMM(ir);
   438 			if( tmp == 0 ) operand = ((int32_t)operand) >> 31;
   439 			else operand = ((int32_t)operand) >> tmp;
   440 			break;
   441 		case 5: /* (Rm >>> Rs) */
   442 			tmp = RS(ir) & 0xFF;
   443 			if( tmp > 31 ) operand = ((int32_t)operand) >> 31;
   444 			else operand = ((int32_t)operand) >> tmp;
   445 			break;
   446 		case 6:
   447 			tmp = SHIFTIMM(ir);
   448 			if( tmp == 0 ) /* RRX aka rotate with carry */
   449 				operand = (operand >> 1) | (armr.c<<31);
   450 			else
   451 				operand = ROTATE_RIGHT_LONG(operand,tmp);
   452 			break;
   453 		case 7:
   454 			tmp = RS(ir)&0x1F;
   455 			operand = ROTATE_RIGHT_LONG(operand,tmp);
   456 			break;
   457 		}
   458 	} else {
   459 		operand = IMM8(ir);
   460 		tmp = IMMROT(ir);
   461 		operand = ROTATE_RIGHT_LONG(operand, tmp);
   462 	}
   463 	return operand;
   464 }
   466 /**
   467  * Determine the value of the shift-operand for a data processing instruction,
   468  * and set armr.shift_c accordingly.
   469  * @see s5.1 Addressing Mode 1 - Data-processing operands (p A5-2, 218)
   470  */
   471 static uint32_t arm_get_shift_operand_s( uint32_t ir )
   472 {
   473 	uint32_t operand, tmp;
   474 	if( IFLAG(ir) == 0 ) {
   475 		operand = RM(ir);
   476 		switch(SHIFT(ir)) {
   477 		case 0: /* (Rm << imm) */
   478 			tmp = SHIFTIMM(ir);
   479 			if( tmp == 0 ) { /* Rm */
   480 				armr.shift_c = armr.c;
   481 			} else { /* Rm << imm */
   482 				armr.shift_c = (operand >> (32-tmp)) & 0x01;
   483 				operand = operand << tmp;
   484 			}
   485 			break;
   486 		case 1: /* (Rm << Rs) */
   487 			tmp = RS(ir)&0xFF;
   488 			if( tmp == 0 ) {
   489 				armr.shift_c = armr.c;
   490 			} else {
   491 				if( tmp <= 32 )
   492 					armr.shift_c = (operand >> (32-tmp)) & 0x01;
   493 				else armr.shift_c = 0;
   494 				if( tmp < 32 )
   495 					operand = operand << tmp;
   496 				else operand = 0;
   497 			}
   498 			break;
   499 		case 2: /* (Rm >> imm) */
   500 			tmp = SHIFTIMM(ir);
   501 			if( tmp == 0 ) {
   502 				armr.shift_c = operand >> 31;
   503 				operand = 0;
   504 			} else {
   505 				armr.shift_c = (operand >> (tmp-1)) & 0x01;
   506 				operand = RM(ir) >> tmp;
   507 			}
   508 			break;
   509 		case 3: /* (Rm >> Rs) */
   510 			tmp = RS(ir) & 0xFF;
   511 			if( tmp == 0 ) {
   512 				armr.shift_c = armr.c;
   513 			} else {
   514 				if( tmp <= 32 )
   515 					armr.shift_c = (operand >> (tmp-1))&0x01;
   516 				else armr.shift_c = 0;
   517 				if( tmp < 32 )
   518 					operand = operand >> tmp;
   519 				else operand = 0;
   520 			}
   521 			break;
   522 		case 4: /* (Rm >>> imm) */
   523 			tmp = SHIFTIMM(ir);
   524 			if( tmp == 0 ) {
   525 				armr.shift_c = operand >> 31;
   526 				operand = -armr.shift_c;
   527 			} else {
   528 				armr.shift_c = (operand >> (tmp-1)) & 0x01;
   529 				operand = ((int32_t)operand) >> tmp;
   530 			}
   531 			break;
   532 		case 5: /* (Rm >>> Rs) */
   533 			tmp = RS(ir) & 0xFF;
   534 			if( tmp == 0 ) {
   535 				armr.shift_c = armr.c;
   536 			} else {
   537 				if( tmp < 32 ) {
   538 					armr.shift_c = (operand >> (tmp-1))&0x01;
   539 					operand = ((int32_t)operand) >> tmp;
   540 				} else {
   541 					armr.shift_c = operand >> 31;
   542 					operand = ((int32_t)operand) >> 31;
   543 				}
   544 			}
   545 			break;
   546 		case 6:
   547 			tmp = SHIFTIMM(ir);
   548 			if( tmp == 0 ) { /* RRX aka rotate with carry */
   549 				armr.shift_c = operand&0x01;
   550 				operand = (operand >> 1) | (armr.c<<31);
   551 			} else {
   552 				armr.shift_c = operand>>(tmp-1);
   553 				operand = ROTATE_RIGHT_LONG(operand,tmp);
   554 			}
   555 			break;
   556 		case 7:
   557 			tmp = RS(ir)&0xFF;
   558 			if( tmp == 0 ) {
   559 				armr.shift_c = armr.c;
   560 			} else {
   561 				tmp &= 0x1F;
   562 				if( tmp == 0 ) {
   563 					armr.shift_c = operand>>31;
   564 				} else {
   565 					armr.shift_c = (operand>>(tmp-1))&0x1;
   566 					operand = ROTATE_RIGHT_LONG(operand,tmp);
   567 				}
   568 			}
   569 			break;
   570 		}
   571 	} else {
   572 		operand = IMM8(ir);
   573 		tmp = IMMROT(ir);
   574 		if( tmp == 0 ) {
   575 			armr.shift_c = armr.c;
   576 		} else {
   577 			operand = ROTATE_RIGHT_LONG(operand, tmp);
   578 			armr.shift_c = operand>>31;
   579 		}
   580 	}
   581 	return operand;
   582 }
   584 /**
   585  * Another variant of the shifter code for index-based memory addressing.
   586  * Distinguished by the fact that it doesn't support register shifts, and
   587  * ignores the I flag (WTF do the load/store instructions use the I flag to
   588  * mean the _exact opposite_ of what it means for the data processing 
   589  * instructions ???)
   590  */
   591 static uint32_t arm_get_address_index( uint32_t ir )
   592 {
   593 	uint32_t operand = RM(ir);
   594 	uint32_t tmp;
   596 	switch(SHIFT(ir)) {
   597 	case 0: /* (Rm << imm) */
   598 		operand = operand << SHIFTIMM(ir);
   599 		break;
   600 	case 2: /* (Rm >> imm) */
   601 		operand = operand >> SHIFTIMM(ir);
   602 		break;
   603 	case 4: /* (Rm >>> imm) */
   604 		tmp = SHIFTIMM(ir);
   605 		if( tmp == 0 ) operand = ((int32_t)operand) >> 31;
   606 		else operand = ((int32_t)operand) >> tmp;
   607 		break;
   608 	case 6:
   609 		tmp = SHIFTIMM(ir);
   610 		if( tmp == 0 ) /* RRX aka rotate with carry */
   611 			operand = (operand >> 1) | (armr.c<<31);
   612 		else
   613 			operand = ROTATE_RIGHT_LONG(operand,tmp);
   614 		break;
   615 	default: UNIMP(ir);
   616 	}
   617 	return operand;	
   618 }
   620 /**
   621  * Determine the address operand of a load/store instruction, including
   622  * applying any pre/post adjustments to the address registers.
   623  * @see s5.2 Addressing Mode 2 - Load and Store Word or Unsigned Byte
   624  * @param The instruction word.
   625  * @return The calculated address
   626  */
   627 static uint32_t arm_get_address_operand( uint32_t ir )
   628 {
   629 	uint32_t addr;
   631 	/* I P U . W */
   632 	switch( (ir>>21)&0x1D ) {
   633 	case 0: /* Rn -= imm offset (post-indexed) [5.2.8 A5-28] */
   634 	case 1:
   635 		addr = RN(ir);
   636 		LRN(ir) = addr - IMM12(ir);
   637 		break;
   638 	case 4: /* Rn += imm offsett (post-indexed) [5.2.8 A5-28] */
   639 	case 5:
   640 		addr = RN(ir);
   641 		LRN(ir) = addr + IMM12(ir);
   642 		break;
   643 	case 8: /* Rn - imm offset  [5.2.2 A5-20] */
   644 		addr = RN(ir) - IMM12(ir);
   645 		break;
   646 	case 9: /* Rn -= imm offset (pre-indexed)  [5.2.5 A5-24] */
   647 		addr = RN(ir) - IMM12(ir);
   648 		LRN(ir) = addr;
   649 		break;
   650 	case 12: /* Rn + imm offset  [5.2.2 A5-20] */
   651 		addr = RN(ir) + IMM12(ir);
   652 		break;
   653 	case 13: /* Rn += imm offset  [5.2.5 A5-24 ] */
   654 		addr = RN(ir) + IMM12(ir);
   655 		LRN(ir) = addr;
   656 		break;
   657 	case 16: /* Rn -= Rm (post-indexed)  [5.2.10 A5-32 ] */
   658 	case 17:
   659 		addr = RN(ir);
   660 		LRN(ir) = addr - arm_get_address_index(ir);
   661 		break;
   662 	case 20: /* Rn += Rm (post-indexed)  [5.2.10 A5-32 ] */
   663 	case 21:
   664 		addr = RN(ir);
   665 		LRN(ir) = addr - arm_get_address_index(ir);
   666 		break;
   667 	case 24: /* Rn - Rm  [5.2.4 A5-23] */
   668 		addr = RN(ir) - arm_get_address_index(ir);
   669 		break;
   670 	case 25: /* RN -= Rm (pre-indexed)  [5.2.7 A5-26] */
   671 		addr = RN(ir) - arm_get_address_index(ir);
   672 		LRN(ir) = addr;
   673 		break;
   674 	case 28: /* Rn + Rm  [5.2.4 A5-23] */
   675 		addr = RN(ir) + arm_get_address_index(ir);
   676 		break;
   677 	case 29: /* RN += Rm (pre-indexed) [5.2.7 A5-26] */
   678 		addr = RN(ir) + arm_get_address_index(ir);
   679 		LRN(ir) = addr;
   680 		break;
   681 	}
   682 	return addr;
   683 }
   685 gboolean arm_execute_instruction( void ) 
   686 {
   687     uint32_t pc;
   688     uint32_t ir;
   689     uint32_t operand, operand2, tmp, tmp2, cond;
   690     int i;
   692     tmp = armr.int_pending & (~armr.cpsr);
   693     if( tmp ) {
   694 	if( tmp & CPSR_F ) {
   695 	    arm_raise_exception( EXC_FAST_IRQ );
   696 	} else {
   697 	    arm_raise_exception( EXC_IRQ );
   698 	}
   699     }
   701     ir = MEM_READ_LONG(PC);
   702     pc = PC + 4;
   703     PC = pc;
   705     /** 
   706      * Check the condition bits first - if the condition fails return 
   707      * immediately without actually looking at the rest of the instruction.
   708      */
   709     switch( COND(ir) ) {
   710     case 0: /* EQ */ 
   711 	cond = armr.z;
   712 	break;
   713     case 1: /* NE */
   714 	cond = !armr.z;
   715 	break;
   716     case 2: /* CS/HS */
   717 	cond = armr.c;
   718 	break;
   719     case 3: /* CC/LO */
   720 	cond = !armr.c;
   721 	break;
   722     case 4: /* MI */
   723 	cond = armr.n;
   724 	break;
   725     case 5: /* PL */
   726 	cond = !armr.n;
   727 	break;
   728     case 6: /* VS */
   729 	cond = armr.v;
   730 	break;
   731     case 7: /* VC */
   732 	cond = !armr.v;
   733 	break;
   734     case 8: /* HI */
   735 	cond = armr.c && !armr.z;
   736 	break;
   737     case 9: /* LS */
   738 	cond = (!armr.c) || armr.z;
   739 	break;
   740     case 10: /* GE */
   741 	cond = (armr.n == armr.v);
   742 	break;
   743     case 11: /* LT */
   744 	cond = (armr.n != armr.v);
   745 	break;
   746     case 12: /* GT */
   747 	cond = (!armr.z) && (armr.n == armr.v);
   748 	break;
   749     case 13: /* LE */
   750 	cond = armr.z || (armr.n != armr.v);
   751 	break;
   752     case 14: /* AL */
   753 	cond = 1;
   754 	break;
   755     case 15: /* (NV) */
   756 	cond = 0;
   757 	UNDEF(ir);
   758     }
   759     if( !cond )
   760 	return TRUE;
   762     /**
   763      * Condition passed, now for the actual instructions...
   764      */
   765     switch( GRP(ir) ) {
   766     case 0:
   767 	if( (ir & 0x0D900000) == 0x01000000 ) {
   768 	    /* Instructions that aren't actual data processing even though
   769 	     * they sit in the DP instruction block.
   770 	     */
   771 	    switch( ir & 0x0FF000F0 ) {
   772 	    case 0x01200010: /* BX Rd */
   773 		armr.t = ir & 0x01;
   774 		armr.r[15] = RM(ir) & 0xFFFFFFFE;
   775 		break;
   776 	    case 0x01000000: /* MRS Rd, CPSR */
   777 		LRD(ir) = arm_get_cpsr();
   778 		break;
   779 	    case 0x01400000: /* MRS Rd, SPSR */
   780 		LRD(ir) = armr.spsr;
   781 		break;
   782 	    case 0x01200000: /* MSR CPSR, Rd */
   783 		arm_set_cpsr( RM(ir), ir );
   784 		break;
   785 	    case 0x01600000: /* MSR SPSR, Rd */
   786 		arm_set_spsr( RM(ir), ir );
   787 		break;
   788 	    case 0x03200000: /* MSR CPSR, imm */
   789 		arm_set_cpsr( ROTIMM12(ir), ir );
   790 		break;
   791 	    case 0x03600000: /* MSR SPSR, imm */
   792 		arm_set_spsr( ROTIMM12(ir), ir );
   793 		break;
   794 	    default:
   795 		UNIMP(ir);
   796 	    }
   797 	} else if( (ir & 0x0E000090) == 0x00000090 ) {
   798 	    /* Neither are these */
   799 	    switch( (ir>>5)&0x03 ) {
   800 	    case 0:
   801 		/* Arithmetic extension area */
   802 		switch(OPCODE(ir)) {
   803 		case 0: /* MUL */
   804 		    LRN(ir) = RM(ir) * RS(ir);
   805 		    break;
   806 		case 1: /* MULS */
   807 		    tmp = RM(ir) * RS(ir);
   808 		    LRN(ir) = tmp;
   809 		    armr.n = tmp>>31;
   810 		    armr.z = (tmp == 0);
   811 		    break;
   812 		case 2: /* MLA */
   813 		    LRN(ir) = RM(ir) * RS(ir) + RD(ir);
   814 		    break;
   815 		case 3: /* MLAS */
   816 		    tmp = RM(ir) * RS(ir) + RD(ir);
   817 		    LRN(ir) = tmp;
   818 		    armr.n = tmp>>31;
   819 		    armr.z = (tmp == 0);
   820 		    break;
   821 		case 8: /* UMULL */
   822 		case 9: /* UMULLS */
   823 		case 10: /* UMLAL */
   824 		case 11: /* UMLALS */
   825 		case 12: /* SMULL */
   826 		case 13: /* SMULLS */
   827 		case 14: /* SMLAL */
   828 		case 15: /* SMLALS */
   829 		    UNIMP(ir);
   830 		    break;
   831 		case 16: /* SWP */
   832 		    tmp = arm_read_long( RN(ir) );
   833 		    switch( RN(ir) & 0x03 ) {
   834 		    case 1:
   835 			tmp = ROTATE_RIGHT_LONG(tmp, 8);
   836 			break;
   837 		    case 2:
   838 			tmp = ROTATE_RIGHT_LONG(tmp, 16);
   839 			break;
   840 		    case 3:
   841 			tmp = ROTATE_RIGHT_LONG(tmp, 24);
   842 			break;
   843 		    }
   844 		    arm_write_long( RN(ir), RM(ir) );
   845 		    LRD(ir) = tmp;
   846 		    break;
   847 		case 20: /* SWPB */
   848 		    tmp = arm_read_byte( RN(ir) );
   849 		    arm_write_byte( RN(ir), RM(ir) );
   850 		    LRD(ir) = tmp;
   851 		    break;
   852 		default:
   853 		    UNIMP(ir);
   854 		}
   855 		break;
   856 	    case 1:
   857 		if( LFLAG(ir) ) {
   858 		    /* LDRH */
   859 		} else {
   860 		    /* STRH */
   861 		}
   862 		UNIMP(ir);
   863 		break;
   864 	    case 2:
   865 		if( LFLAG(ir) ) {
   866 		    /* LDRSB */
   867 		} else {
   868 		}
   869 		UNIMP(ir);
   870 		break;
   871 	    case 3:
   872 		if( LFLAG(ir) ) {
   873 		    /* LDRSH */
   874 		} else {
   875 		}
   876 		UNIMP(ir);
   877 		break;
   878 	    }
   879 	} else {
   880 	    /* Data processing */
   882 	    switch(OPCODE(ir)) {
   883 	    case 0: /* AND Rd, Rn, operand */
   884 		LRD(ir) = RN(ir) & arm_get_shift_operand(ir);
   885 		break;
   886 	    case 1: /* ANDS Rd, Rn, operand */
   887 		operand = arm_get_shift_operand_s(ir) & RN(ir);
   888 		LRD(ir) = operand;
   889 		if( RDn(ir) == 15 ) {
   890 		    arm_restore_cpsr();
   891 		} else {
   892 		    armr.n = operand>>31;
   893 		    armr.z = (operand == 0);
   894 		    armr.c = armr.shift_c;
   895 		}
   896 		break;
   897 	    case 2: /* EOR Rd, Rn, operand */
   898 		LRD(ir) = RN(ir) ^ arm_get_shift_operand(ir);
   899 		break;
   900 	    case 3: /* EORS Rd, Rn, operand */
   901 		operand = arm_get_shift_operand_s(ir) ^ RN(ir);
   902 		LRD(ir) = operand;
   903 		if( RDn(ir) == 15 ) {
   904 		    arm_restore_cpsr();
   905 		} else {
   906 		    armr.n = operand>>31;
   907 		    armr.z = (operand == 0);
   908 		    armr.c = armr.shift_c;
   909 		}
   910 		break;
   911 	    case 4: /* SUB Rd, Rn, operand */
   912 		LRD(ir) = RN(ir) - arm_get_shift_operand(ir);
   913 		break;
   914 	    case 5: /* SUBS Rd, Rn, operand */
   915 		operand = RN(ir);
   916 		operand2 = arm_get_shift_operand(ir);
   917 		tmp = operand - operand2;
   918 		LRD(ir) = tmp;
   919 		if( RDn(ir) == 15 ) {
   920 		    arm_restore_cpsr();
   921 		} else {
   922 		    armr.n = tmp>>31;
   923 		    armr.z = (tmp == 0);
   924 		    armr.c = IS_NOTBORROW(tmp,operand,operand2);
   925 		    armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
   926 		}
   927 		break;
   928 	    case 6: /* RSB Rd, operand, Rn */
   929 		LRD(ir) = arm_get_shift_operand(ir) - RN(ir);
   930 		break;
   931 	    case 7: /* RSBS Rd, operand, Rn */
   932 		operand = arm_get_shift_operand(ir);
   933 		operand2 = RN(ir);
   934 		tmp = operand - operand2;
   935 		LRD(ir) = tmp;
   936 		if( RDn(ir) == 15 ) {
   937 		    arm_restore_cpsr();
   938 		} else {
   939 		    armr.n = tmp>>31;
   940 		    armr.z = (tmp == 0);
   941 		    armr.c = IS_NOTBORROW(tmp,operand,operand2);
   942 		    armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
   943 		}
   944 		break;
   945 	    case 8: /* ADD Rd, Rn, operand */
   946 		LRD(ir) = RN(ir) + arm_get_shift_operand(ir);
   947 		break;
   948 	    case 9: /* ADDS Rd, Rn, operand */
   949 		operand = arm_get_shift_operand(ir);
   950 		operand2 = RN(ir);
   951 		tmp = operand + operand2;
   952 		LRD(ir) = tmp;
   953 		if( RDn(ir) == 15 ) {
   954 		    arm_restore_cpsr();
   955 		} else {
   956 		    armr.n = tmp>>31;
   957 		    armr.z = (tmp == 0);
   958 		    armr.c = IS_CARRY(tmp,operand,operand2);
   959 		    armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
   960 		}
   961 		break;			
   962 	    case 10: /* ADC */
   963 		LRD(ir) = RN(ir) + arm_get_shift_operand(ir) + 
   964 		    (armr.c ? 1 : 0);
   965 		break;
   966 	    case 11: /* ADCS */
   967 		operand = arm_get_shift_operand(ir);
   968 		operand2 = RN(ir);
   969 		tmp = operand + operand2;
   970 		tmp2 = tmp + armr.c ? 1 : 0;
   971 		LRD(ir) = tmp2;
   972 		if( RDn(ir) == 15 ) {
   973 		    arm_restore_cpsr();
   974 		} else {
   975 		    armr.n = tmp >> 31;
   976 		    armr.z = (tmp == 0 );
   977 		    armr.c = IS_CARRY(tmp,operand,operand2) ||
   978 			(tmp2 < tmp);
   979 		    armr.v = IS_ADDOVERFLOW(tmp,operand, operand2) ||
   980 			((tmp&0x80000000) != (tmp2&0x80000000));
   981 		}
   982 		break;
   983 	    case 12: /* SBC */
   984 		LRD(ir) = RN(ir) - arm_get_shift_operand(ir) - 
   985 		    (armr.c ? 0 : 1);
   986 		break;
   987 	    case 13: /* SBCS */
   988 		operand = RN(ir);
   989 		operand2 = arm_get_shift_operand(ir);
   990 		tmp = operand - operand2;
   991 		tmp2 = tmp - (armr.c ? 0 : 1);
   992 		if( RDn(ir) == 15 ) {
   993 		    arm_restore_cpsr();
   994 		} else {
   995 		    armr.n = tmp >> 31;
   996 		    armr.z = (tmp == 0 );
   997 		    armr.c = IS_NOTBORROW(tmp,operand,operand2) &&
   998 			(tmp2<tmp);
   999 		    armr.v = IS_SUBOVERFLOW(tmp,operand,operand2) ||
  1000 			((tmp&0x80000000) != (tmp2&0x80000000));
  1002 		break;
  1003 	    case 14: /* RSC */
  1004 		LRD(ir) = arm_get_shift_operand(ir) - RN(ir) -
  1005 		    (armr.c ? 0 : 1);
  1006 		break;
  1007 	    case 15: /* RSCS */
  1008 		operand = arm_get_shift_operand(ir);
  1009 		operand2 = RN(ir);
  1010 		tmp = operand - operand2;
  1011 		tmp2 = tmp - (armr.c ? 0 : 1);
  1012 		if( RDn(ir) == 15 ) {
  1013 		    arm_restore_cpsr();
  1014 		} else {
  1015 		    armr.n = tmp >> 31;
  1016 		    armr.z = (tmp == 0 );
  1017 		    armr.c = IS_NOTBORROW(tmp,operand,operand2) &&
  1018 			(tmp2<tmp);
  1019 		    armr.v = IS_SUBOVERFLOW(tmp,operand,operand2) ||
  1020 			((tmp&0x80000000) != (tmp2&0x80000000));
  1022 		break;
  1023 	    case 17: /* TST Rn, operand */
  1024 		operand = arm_get_shift_operand_s(ir) & RN(ir);
  1025 		armr.n = operand>>31;
  1026 		armr.z = (operand == 0);
  1027 		armr.c = armr.shift_c;
  1028 		break;
  1029 	    case 19: /* TEQ Rn, operand */
  1030 		operand = arm_get_shift_operand_s(ir) ^ RN(ir);
  1031 		armr.n = operand>>31;
  1032 		armr.z = (operand == 0);
  1033 		armr.c = armr.shift_c;
  1034 		break;				
  1035 	    case 21: /* CMP Rn, operand */
  1036 		operand = RN(ir);
  1037 		operand2 = arm_get_shift_operand(ir);
  1038 		tmp = operand - operand2;
  1039 		armr.n = tmp>>31;
  1040 		armr.z = (tmp == 0);
  1041 		armr.c = IS_NOTBORROW(tmp,operand,operand2);
  1042 		armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
  1043 		break;
  1044 	    case 23: /* CMN Rn, operand */
  1045 		operand = RN(ir);
  1046 		operand2 = arm_get_shift_operand(ir);
  1047 		tmp = operand + operand2;
  1048 		armr.n = tmp>>31;
  1049 		armr.z = (tmp == 0);
  1050 		armr.c = IS_CARRY(tmp,operand,operand2);
  1051 		armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
  1052 		break;
  1053 	    case 24: /* ORR Rd, Rn, operand */
  1054 		LRD(ir) = RN(ir) | arm_get_shift_operand(ir);
  1055 		break;
  1056 	    case 25: /* ORRS Rd, Rn, operand */
  1057 		operand = arm_get_shift_operand_s(ir) | RN(ir);
  1058 		LRD(ir) = operand;
  1059 		if( RDn(ir) == 15 ) {
  1060 		    arm_restore_cpsr();
  1061 		} else {
  1062 		    armr.n = operand>>31;
  1063 		    armr.z = (operand == 0);
  1064 		    armr.c = armr.shift_c;
  1066 		break;
  1067 	    case 26: /* MOV Rd, operand */
  1068 		LRD(ir) = arm_get_shift_operand(ir);
  1069 		break;
  1070 	    case 27: /* MOVS Rd, operand */
  1071 		operand = arm_get_shift_operand_s(ir);
  1072 		LRD(ir) = operand;
  1073 		if( RDn(ir) == 15 ) {
  1074 		    arm_restore_cpsr();
  1075 		} else {
  1076 		    armr.n = operand>>31;
  1077 		    armr.z = (operand == 0);
  1078 		    armr.c = armr.shift_c;
  1080 		break;
  1081 	    case 28: /* BIC Rd, Rn, operand */
  1082 		LRD(ir) = RN(ir) & (~arm_get_shift_operand(ir));
  1083 		break;
  1084 	    case 29: /* BICS Rd, Rn, operand */
  1085 		operand = RN(ir) & (~arm_get_shift_operand_s(ir));
  1086 		LRD(ir) = operand;
  1087 		if( RDn(ir) == 15 ) {
  1088 		    arm_restore_cpsr();
  1089 		} else {
  1090 		    armr.n = operand>>31;
  1091 		    armr.z = (operand == 0);
  1092 		    armr.c = armr.shift_c;
  1094 		break;
  1095 	    case 30: /* MVN Rd, operand */
  1096 		LRD(ir) = ~arm_get_shift_operand(ir);
  1097 		break;
  1098 	    case 31: /* MVNS Rd, operand */
  1099 		operand = ~arm_get_shift_operand_s(ir);
  1100 		LRD(ir) = operand;
  1101 		if( RDn(ir) == 15 ) {
  1102 		    arm_restore_cpsr();
  1103 		} else {
  1104 		    armr.n = operand>>31;
  1105 		    armr.z = (operand == 0);
  1106 		    armr.c = armr.shift_c;
  1108 		break;
  1109 	    default:
  1110 		UNIMP(ir);
  1113 	break;
  1114     case 1: /* Load/store */
  1115 	operand = arm_get_address_operand(ir);
  1116 	switch( (ir>>20)&0x17 ) {
  1117 	case 0: case 16: case 18: /* STR Rd, address */
  1118 	    arm_write_long( operand, RD(ir) );
  1119 	    break;
  1120 	case 1: case 17: case 19: /* LDR Rd, address */
  1121 	    LRD(ir) = arm_read_long(operand);
  1122 	    break;
  1123 	case 2: /* STRT Rd, address */
  1124 	    arm_write_long_user( operand, RD(ir) );
  1125 	    break;
  1126 	case 3: /* LDRT Rd, address */
  1127 	    LRD(ir) = arm_read_long_user( operand );
  1128 	    break;
  1129 	case 4: case 20: case 22: /* STRB Rd, address */
  1130 	    arm_write_byte( operand, RD(ir) );
  1131 	    break;
  1132 	case 5: case 21: case 23: /* LDRB Rd, address */
  1133 	    LRD(ir) = arm_read_byte( operand );
  1134 	    break;
  1135 	case 6: /* STRBT Rd, address */
  1136 	    arm_write_byte_user( operand, RD(ir) );
  1137 	    break;
  1138 	case 7: /* LDRBT Rd, address */
  1139 	    LRD(ir) = arm_read_byte_user( operand );
  1140 	    break;
  1142 	break;
  1143     case 2: /* Load/store multiple, branch*/
  1144 	if( (ir & 0x02000000) == 0x02000000 ) { /* B[L] imm24 */
  1145 	    operand = (SIGNEXT24(ir&0x00FFFFFF) << 2);
  1146 	    if( (ir & 0x01000000) == 0x01000000 ) { 
  1147 		armr.r[14] = pc; /* BL */
  1149 	    armr.r[15] = pc + 4 + operand;
  1150 	} else { /* Load/store multiple */
  1151 	    operand = RN(ir);
  1153 	    switch( (ir & 0x01D00000) >> 20 ) {
  1154 	    case 0: /* STMDA */
  1155 		for( i=15; i>= 0; i-- ) {
  1156 		    if( (ir & (1<<i)) ) {
  1157 			arm_write_long( operand, armr.r[i] );
  1158 			operand -= 4;
  1161 		break;
  1162 	    case 1: /* LDMDA */
  1163 		for( i=15; i>= 0; i-- ) {
  1164 		    if( (ir & (1<<i)) ) {
  1165 			armr.r[i] = arm_read_long( operand );
  1166 			operand -= 4;
  1169 		break;
  1170 	    case 4: /* STMDA (S) */
  1171 		for( i=15; i>= 0; i-- ) {
  1172 		    if( (ir & (1<<i)) ) {
  1173 			arm_write_long( operand, USER_R(i) );
  1174 			operand -= 4;
  1177 		break;
  1178 	    case 5: /* LDMDA (S) */
  1179 		if( (ir&0x00008000) ) { /* Load PC */
  1180 		    for( i=15; i>= 0; i-- ) {
  1181 			if( (ir & (1<<i)) ) {
  1182 			    armr.r[i] = arm_read_long( operand );
  1183 			    operand -= 4;
  1186 		    arm_restore_cpsr();
  1187 		} else {
  1188 		    for( i=15; i>= 0; i-- ) {
  1189 			if( (ir & (1<<i)) ) {
  1190 			    USER_R(i) = arm_read_long( operand );
  1191 			    operand -= 4;
  1195 		break;
  1196 	    case 8: /* STMIA */
  1197 		for( i=0; i< 16; i++ ) {
  1198 		    if( (ir & (1<<i)) ) {
  1199 			arm_write_long( operand, armr.r[i] );
  1200 			operand += 4;
  1203 		break;
  1204 	    case 9: /* LDMIA */
  1205 		for( i=0; i< 16; i++ ) {
  1206 		    if( (ir & (1<<i)) ) {
  1207 			armr.r[i] = arm_read_long( operand );
  1208 			operand += 4;
  1211 		break;
  1212 	    case 12: /* STMIA (S) */
  1213 		for( i=0; i< 16; i++ ) {
  1214 		    if( (ir & (1<<i)) ) {
  1215 			arm_write_long( operand, USER_R(i) );
  1216 			operand += 4;
  1219 		break;
  1220 	    case 13: /* LDMIA (S) */
  1221 		if( (ir&0x00008000) ) { /* Load PC */
  1222 		    for( i=0; i < 16; i++ ) {
  1223 			if( (ir & (1<<i)) ) {
  1224 			    armr.r[i] = arm_read_long( operand );
  1225 			    operand += 4;
  1228 		    arm_restore_cpsr();
  1229 		} else {
  1230 		    for( i=0; i < 16; i++ ) {
  1231 			if( (ir & (1<<i)) ) {
  1232 			    USER_R(i) = arm_read_long( operand );
  1233 			    operand += 4;
  1237 		break;
  1238 	    case 16: /* STMDB */
  1239 		for( i=15; i>= 0; i-- ) {
  1240 		    if( (ir & (1<<i)) ) {
  1241 			operand -= 4;
  1242 			arm_write_long( operand, armr.r[i] );
  1245 		break;
  1246 	    case 17: /* LDMDB */
  1247 		for( i=15; i>= 0; i-- ) {
  1248 		    if( (ir & (1<<i)) ) {
  1249 			operand -= 4;
  1250 			armr.r[i] = arm_read_long( operand );
  1253 		break;
  1254 	    case 20: /* STMDB (S) */
  1255 		for( i=15; i>= 0; i-- ) {
  1256 		    if( (ir & (1<<i)) ) {
  1257 			operand -= 4;
  1258 			arm_write_long( operand, USER_R(i) );
  1261 		break;
  1262 	    case 21: /* LDMDB (S) */
  1263 		if( (ir&0x00008000) ) { /* Load PC */
  1264 		    for( i=15; i>= 0; i-- ) {
  1265 			if( (ir & (1<<i)) ) {
  1266 			    operand -= 4;
  1267 			    armr.r[i] = arm_read_long( operand );
  1270 		    arm_restore_cpsr();
  1271 		} else {
  1272 		    for( i=15; i>= 0; i-- ) {
  1273 			if( (ir & (1<<i)) ) {
  1274 			    operand -= 4;
  1275 			    USER_R(i) = arm_read_long( operand );
  1279 		break;
  1280 	    case 24: /* STMIB */
  1281 		for( i=0; i< 16; i++ ) {
  1282 		    if( (ir & (1<<i)) ) {
  1283 			operand += 4;
  1284 			arm_write_long( operand, armr.r[i] );
  1287 		break;
  1288 	    case 25: /* LDMIB */
  1289 		for( i=0; i< 16; i++ ) {
  1290 		    if( (ir & (1<<i)) ) {
  1291 			operand += 4;
  1292 			armr.r[i] = arm_read_long( operand );
  1295 		break;
  1296 	    case 28: /* STMIB (S) */
  1297 		for( i=0; i< 16; i++ ) {
  1298 		    if( (ir & (1<<i)) ) {
  1299 			operand += 4;
  1300 			arm_write_long( operand, USER_R(i) );
  1303 		break;
  1304 	    case 29: /* LDMIB (S) */
  1305 		if( (ir&0x00008000) ) { /* Load PC */
  1306 		    for( i=0; i < 16; i++ ) {
  1307 			if( (ir & (1<<i)) ) {
  1308 			    operand += 4;
  1309 			    armr.r[i] = arm_read_long( operand );
  1312 		    arm_restore_cpsr();
  1313 		} else {
  1314 		    for( i=0; i < 16; i++ ) {
  1315 			if( (ir & (1<<i)) ) {
  1316 			    operand += 4;
  1317 			    USER_R(i) = arm_read_long( operand );
  1321 		break;
  1324 	    if( WFLAG(ir) ) 
  1325 		LRN(ir) = operand;
  1327 	break;
  1328     case 3: /* Copro */
  1329 	if( (ir & 0x0F000000) == 0x0F000000 ) { /* SWI */
  1330 	    arm_raise_exception( EXC_SOFTWARE );
  1331 	} else {
  1332 	    UNIMP(ir);
  1334 	break;
  1336     return TRUE;
.