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