1.1 --- a/src/aica/armcore.c Mon Dec 26 03:54:55 2005 +0000
1.2 +++ b/src/aica/armcore.c Mon Dec 26 06:38:51 2005 +0000
1.5 - * $Id: armcore.c,v 1.6 2005-12-26 03:54:55 nkeynes Exp $
1.6 + * $Id: armcore.c,v 1.7 2005-12-26 06:38:51 nkeynes Exp $
1.8 * ARM7TDMI CPU emulation core.
1.11 * GNU General Public License for more details.
1.14 +#define MODULE aica_module
1.16 #include "aica/armcore.h"
1.18 struct arm_registers armr;
1.20 armr.r[15] = 0x00000000;
1.23 +#define SET_CPSR_CONTROL 0x00010000
1.24 +#define SET_CPSR_EXTENSION 0x00020000
1.25 +#define SET_CPSR_STATUS 0x00040000
1.26 +#define SET_CPSR_FLAGS 0x00080000
1.28 +uint32_t arm_get_cpsr( void )
1.30 + /* write back all flags to the cpsr */
1.31 + armr.cpsr = armr.cpsr & CPSR_COMPACT_MASK;
1.32 + if( armr.n ) armr.cpsr |= CPSR_N;
1.33 + if( armr.z ) armr.cpsr |= CPSR_Z;
1.34 + if( armr.c ) armr.cpsr |= CPSR_C;
1.35 + if( armr.v ) armr.cpsr |= CPSR_V;
1.36 + if( armr.t ) armr.cpsr |= CPSR_T;
1.41 + * Set the CPSR to the specified value.
1.43 + * @param value values to set in CPSR
1.44 + * @param fields set of mask values to define which sections of the
1.45 + * CPSR to set (one of the SET_CPSR_* values above)
1.47 +void arm_set_cpsr( uint32_t value, uint32_t fields )
1.49 + if( IS_PRIVILEGED_MODE() ) {
1.50 + if( fields & SET_CPSR_CONTROL ) {
1.51 + int mode = value & CPSR_MODE;
1.52 + arm_set_mode( mode );
1.53 + armr.t = ( value & CPSR_T ); /* Technically illegal to change */
1.54 + armr.cpsr = (armr.cpsr & 0xFFFFFF00) | (value & 0x000000FF);
1.57 + /* Middle 16 bits not currently defined */
1.59 + if( fields & SET_CPSR_FLAGS ) {
1.60 + /* Break flags directly out of given value - don't bother writing
1.63 + armr.n = ( value & CPSR_N );
1.64 + armr.z = ( value & CPSR_Z );
1.65 + armr.c = ( value & CPSR_C );
1.66 + armr.v = ( value & CPSR_V );
1.70 +void arm_set_spsr( uint32_t value, uint32_t fields )
1.72 + /* Only defined if we actually have an SPSR register */
1.73 + if( IS_EXCEPTION_MODE() ) {
1.74 + if( fields & SET_CPSR_CONTROL ) {
1.75 + armr.spsr = (armr.spsr & 0xFFFFFF00) | (value & 0x000000FF);
1.78 + /* Middle 16 bits not currently defined */
1.80 + if( fields & SET_CPSR_FLAGS ) {
1.81 + armr.spsr = (armr.spsr & 0x00FFFFFF) | (value & 0xFF000000);
1.87 * Raise an ARM exception (other than reset, which uses arm_reset().
1.88 * @param exception one of the EXC_* exception codes defined above.
1.89 @@ -86,26 +151,27 @@
1.90 void arm_raise_exception( int exception )
1.92 int mode = arm_exceptions[exception][0];
1.93 + uint32_t spsr = arm_get_cpsr();
1.94 arm_set_mode( mode );
1.95 - armr.spsr = armr.cpsr;
1.97 armr.r[14] = armr.r[15];
1.98 - armr.cpsr = (armr.cpsr & (~CPSR_T)) | CPSR_I;
1.99 + armr.cpsr = (spsr & (~CPSR_T)) | CPSR_I;
1.100 if( mode == MODE_FIQ )
1.101 armr.cpsr |= CPSR_F;
1.102 armr.r[15] = arm_exceptions[exception][1];
1.106 - * Restore CPSR from SPSR, effectively (under most circumstances) executing
1.107 - * a return-from-exception.
1.109 -void arm_restore_cpsr()
1.110 +void arm_restore_cpsr( void )
1.112 int spsr = armr.spsr;
1.113 int mode = spsr & CPSR_MODE;
1.115 arm_set_mode( mode );
1.117 + armr.n = ( spsr & CPSR_N );
1.118 + armr.z = ( spsr & CPSR_Z );
1.119 + armr.c = ( spsr & CPSR_C );
1.120 + armr.v = ( spsr & CPSR_V );
1.121 + armr.t = ( spsr & CPSR_T );
1.125 @@ -237,10 +303,10 @@
1.126 #define WFLAG(ir) (IR&0x00200000)
1.127 #define LFLAG(ir) SFLAG(ir)
1.128 #define RN(ir) (armr.r[((ir>>16)&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))
1.129 -#define RD(ir) (armr.r[((ir>>12)&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))
1.130 +#define RD(ir) (armr.r[((ir>>12)&0x0F)] + (((ir>>12)&0x0F) == 0x0F ? 4 : 0))
1.131 #define RDn(ir) ((ir>>12)&0x0F)
1.132 -#define RS(ir) (armr.r[((ir>>8)&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))
1.133 -#define RM(ir) (armr.r[(ir&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))
1.134 +#define RS(ir) (armr.r[((ir>>8)&0x0F)] + (((ir>>8)&0x0F) == 0x0F ? 4 : 0))
1.135 +#define RM(ir) (armr.r[(ir&0x0F)] + (((ir&0x0F) == 0x0F ? 4 : 0)) )
1.136 #define LRN(ir) armr.r[((ir>>16)&0x0F)]
1.137 #define LRD(ir) armr.r[((ir>>12)&0x0F)]
1.138 #define LRS(ir) armr.r[((ir>>8)&0x0F)]
1.139 @@ -250,11 +316,19 @@
1.140 #define IMM12(ir) (ir&0xFFF)
1.141 #define SHIFTIMM(ir) ((ir>>7)&0x1F)
1.142 #define IMMROT(ir) ((ir>>7)&0x1E)
1.143 +#define ROTIMM12(ir) ROTATE_RIGHT_LONG(IMM8(ir),IMMROT(ir))
1.144 +#define SIGNEXT24(n) ((n&0x00800000) ? (n|0xFF000000) : (n&0x00FFFFFF))
1.145 #define SHIFT(ir) ((ir>>4)&0x07)
1.146 #define DISP24(ir) ((ir&0x00FFFFFF))
1.147 -#define UNDEF(ir) do{ ERROR( "Raising exception on undefined instruction at %08x, opcode = %04x", PC, ir ); return TRUE; } while(0)
1.148 +#define UNDEF(ir) do{ arm_raise_exception( EXC_UNDEFINED ); return TRUE; } while(0)
1.149 #define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", PC, ir ); return FALSE; }while(0)
1.152 + * Determine the value of the shift-operand for a data processing instruction,
1.153 + * without determing a value for shift_C (optimized form for instructions that
1.154 + * don't require shift_C ).
1.155 + * @see s5.1 Addressing Mode 1 - Data-processing operands (p A5-2, 218)
1.157 static uint32_t arm_get_shift_operand( uint32_t ir )
1.159 uint32_t operand, tmp;
1.160 @@ -308,9 +382,9 @@
1.164 - * Compute the "shift operand" of the instruction for the data processing
1.165 - * instructions. This variant also sets armr.shift_c (carry result for shifter)
1.166 - * Reason for the variants is that most cases don't actually need the shift_c.
1.167 + * Determine the value of the shift-operand for a data processing instruction,
1.168 + * and set armr.shift_c accordingly.
1.169 + * @see s5.1 Addressing Mode 1 - Data-processing operands (p A5-2, 218)
1.171 static uint32_t arm_get_shift_operand_s( uint32_t ir )
1.173 @@ -461,6 +535,13 @@
1.178 + * Determine the address operand of a load/store instruction, including
1.179 + * applying any pre/post adjustments to the address registers.
1.180 + * @see s5.2 Addressing Mode 2 - Load and Store Word or Unsigned Byte
1.181 + * @param The instruction word.
1.182 + * @return The calculated address
1.184 static uint32_t arm_get_address_operand( uint32_t ir )
1.187 @@ -515,341 +596,395 @@
1.188 addr = RN(ir) + arm_get_address_index(ir);
1.192 - UNIMP(ir); /* Unreachable */
1.197 gboolean arm_execute_instruction( void )
1.199 - uint32_t pc = PC;
1.200 - uint32_t ir = MEM_READ_LONG(pc);
1.201 - uint32_t operand, operand2, tmp, cond;
1.202 + uint32_t pc = PC;
1.203 + uint32_t ir = MEM_READ_LONG(pc);
1.204 + uint32_t operand, operand2, tmp, cond;
1.211 - switch( COND(ir) ) {
1.218 - case 2: /* CS/HS */
1.221 - case 3: /* CC/LO */
1.237 - cond = armr.c && !armr.z;
1.240 - cond = (!armr.c) || armr.z;
1.242 - case 10: /* GE */
1.243 - cond = (armr.n == armr.v);
1.245 - case 11: /* LT */
1.246 - cond = (armr.n != armr.v);
1.248 - case 12: /* GT */
1.249 - cond = (!armr.z) && (armr.n == armr.v);
1.251 - case 13: /* LE */
1.252 - cond = armr.z || (armr.n != armr.v);
1.254 - case 14: /* AL */
1.257 - case 15: /* (NV) */
1.262 + * Check the condition bits first - if the condition fails return
1.263 + * immediately without actually looking at the rest of the instruction.
1.265 + switch( COND(ir) ) {
1.272 + case 2: /* CS/HS */
1.275 + case 3: /* CC/LO */
1.291 + cond = armr.c && !armr.z;
1.294 + cond = (!armr.c) || armr.z;
1.296 + case 10: /* GE */
1.297 + cond = (armr.n == armr.v);
1.299 + case 11: /* LT */
1.300 + cond = (armr.n != armr.v);
1.302 + case 12: /* GT */
1.303 + cond = (!armr.z) && (armr.n == armr.v);
1.305 + case 13: /* LE */
1.306 + cond = armr.z || (armr.n != armr.v);
1.308 + case 14: /* AL */
1.311 + case 15: /* (NV) */
1.318 - switch( GRP(ir) ) {
1.320 - if( (ir & 0x0D900000) == 0x01000000 ) {
1.321 - /* Instructions that aren't actual data processing */
1.322 - switch( ir & 0x0FF000F0 ) {
1.323 - case 0x01200010: /* BX */
1.325 - case 0x01000000: /* MRS Rd, CPSR */
1.327 - case 0x01400000: /* MRS Rd, SPSR */
1.329 - case 0x01200000: /* MSR CPSR, Rd */
1.331 - case 0x01600000: /* MSR SPSR, Rd */
1.333 - case 0x03200000: /* MSR CPSR, imm */
1.335 - case 0x03600000: /* MSR SPSR, imm */
1.340 - } else if( (ir & 0x0E000090) == 0x00000090 ) {
1.341 - /* Neither are these */
1.342 - switch( (ir>>5)&0x03 ) {
1.344 - /* Arithmetic extension area */
1.345 - switch(OPCODE(ir)) {
1.346 - case 0: /* MUL */
1.348 - case 1: /* MULS */
1.350 - case 2: /* MLA */
1.352 - case 3: /* MLAS */
1.354 - case 8: /* UMULL */
1.356 - case 9: /* UMULLS */
1.358 - case 10: /* UMLAL */
1.360 - case 11: /* UMLALS */
1.362 - case 12: /* SMULL */
1.364 - case 13: /* SMULLS */
1.366 - case 14: /* SMLAL */
1.368 - case 15: /* SMLALS */
1.370 - case 16: /* SWP */
1.372 - case 20: /* SWPB */
1.379 - if( LFLAG(ir) ) {
1.386 - if( LFLAG(ir) ) {
1.393 - if( LFLAG(ir) ) {
1.401 - /* Data processing */
1.403 - switch(OPCODE(ir)) {
1.404 - case 0: /* AND Rd, Rn, operand */
1.405 - LRD(ir) = RN(ir) & arm_get_shift_operand(ir);
1.407 - case 1: /* ANDS Rd, Rn, operand */
1.408 - operand = arm_get_shift_operand_s(ir) & RN(ir);
1.409 - LRD(ir) = operand;
1.410 - if( RDn(ir) == 15 ) {
1.411 - arm_restore_cpsr();
1.413 - armr.n = operand>>31;
1.414 - armr.z = (operand == 0);
1.415 - armr.c = armr.shift_c;
1.418 - case 2: /* EOR Rd, Rn, operand */
1.419 - LRD(ir) = RN(ir) ^ arm_get_shift_operand(ir);
1.421 - case 3: /* EORS Rd, Rn, operand */
1.422 - operand = arm_get_shift_operand_s(ir) ^ RN(ir);
1.423 - LRD(ir) = operand;
1.424 - if( RDn(ir) == 15 ) {
1.425 - arm_restore_cpsr();
1.427 - armr.n = operand>>31;
1.428 - armr.z = (operand == 0);
1.429 - armr.c = armr.shift_c;
1.432 - case 4: /* SUB Rd, Rn, operand */
1.433 - LRD(ir) = RN(ir) - arm_get_shift_operand(ir);
1.435 - case 5: /* SUBS Rd, Rn, operand */
1.436 - operand = RN(ir);
1.437 - operand2 = arm_get_shift_operand(ir);
1.438 - tmp = operand - operand2;
1.440 - if( RDn(ir) == 15 ) {
1.441 - arm_restore_cpsr();
1.443 - armr.n = tmp>>31;
1.444 - armr.z = (tmp == 0);
1.445 - armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.446 - armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.449 - case 6: /* RSB Rd, operand, Rn */
1.450 - LRD(ir) = arm_get_shift_operand(ir) - RN(ir);
1.452 - case 7: /* RSBS Rd, operand, Rn */
1.453 - operand = arm_get_shift_operand(ir);
1.454 - operand2 = RN(ir);
1.455 - tmp = operand - operand2;
1.457 - if( RDn(ir) == 15 ) {
1.458 - arm_restore_cpsr();
1.460 - armr.n = tmp>>31;
1.461 - armr.z = (tmp == 0);
1.462 - armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.463 - armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.466 - case 8: /* ADD Rd, Rn, operand */
1.467 - LRD(ir) = RN(ir) + arm_get_shift_operand(ir);
1.469 - case 9: /* ADDS Rd, Rn, operand */
1.470 - operand = arm_get_shift_operand(ir);
1.471 - operand2 = RN(ir);
1.472 - tmp = operand + operand2;
1.474 - if( RDn(ir) == 15 ) {
1.475 - arm_restore_cpsr();
1.477 - armr.n = tmp>>31;
1.478 - armr.z = (tmp == 0);
1.479 - armr.c = IS_CARRY(tmp,operand,operand2);
1.480 - armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
1.483 - case 10: /* ADC */
1.484 - case 11: /* ADCS */
1.485 - case 12: /* SBC */
1.486 - case 13: /* SBCS */
1.487 - case 14: /* RSC */
1.488 - case 15: /* RSCS */
1.490 - case 17: /* TST Rn, operand */
1.491 - operand = arm_get_shift_operand_s(ir) & RN(ir);
1.492 - armr.n = operand>>31;
1.493 - armr.z = (operand == 0);
1.494 - armr.c = armr.shift_c;
1.496 - case 19: /* TEQ Rn, operand */
1.497 - operand = arm_get_shift_operand_s(ir) ^ RN(ir);
1.498 - armr.n = operand>>31;
1.499 - armr.z = (operand == 0);
1.500 - armr.c = armr.shift_c;
1.502 - case 21: /* CMP Rn, operand */
1.503 - operand = RN(ir);
1.504 - operand2 = arm_get_shift_operand(ir);
1.505 - tmp = operand - operand2;
1.506 - armr.n = tmp>>31;
1.507 - armr.z = (tmp == 0);
1.508 - armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.509 - armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.511 - case 23: /* CMN Rn, operand */
1.512 - operand = RN(ir);
1.513 - operand2 = arm_get_shift_operand(ir);
1.514 - tmp = operand + operand2;
1.515 - armr.n = tmp>>31;
1.516 - armr.z = (tmp == 0);
1.517 - armr.c = IS_CARRY(tmp,operand,operand2);
1.518 - armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
1.520 - case 24: /* ORR Rd, Rn, operand */
1.521 - LRD(ir) = RN(ir) | arm_get_shift_operand(ir);
1.523 - case 25: /* ORRS Rd, Rn, operand */
1.524 - operand = arm_get_shift_operand_s(ir) | RN(ir);
1.525 - LRD(ir) = operand;
1.526 - if( RDn(ir) == 15 ) {
1.527 - arm_restore_cpsr();
1.529 - armr.n = operand>>31;
1.530 - armr.z = (operand == 0);
1.531 - armr.c = armr.shift_c;
1.534 - case 26: /* MOV Rd, operand */
1.535 - LRD(ir) = arm_get_shift_operand(ir);
1.537 - case 27: /* MOVS Rd, operand */
1.538 - operand = arm_get_shift_operand_s(ir);
1.539 - LRD(ir) = operand;
1.540 - if( RDn(ir) == 15 ) {
1.541 - arm_restore_cpsr();
1.543 - armr.n = operand>>31;
1.544 - armr.z = (operand == 0);
1.545 - armr.c = armr.shift_c;
1.548 - case 28: /* BIC Rd, Rn, operand */
1.549 - LRD(ir) = RN(ir) & (~arm_get_shift_operand(ir));
1.551 - case 29: /* BICS Rd, Rn, operand */
1.552 - operand = RN(ir) & (~arm_get_shift_operand_s(ir));
1.553 - LRD(ir) = operand;
1.554 - if( RDn(ir) == 15 ) {
1.555 - arm_restore_cpsr();
1.557 - armr.n = operand>>31;
1.558 - armr.z = (operand == 0);
1.559 - armr.c = armr.shift_c;
1.562 - case 30: /* MVN Rd, operand */
1.563 - LRD(ir) = ~arm_get_shift_operand(ir);
1.565 - case 31: /* MVNS Rd, operand */
1.566 - operand = ~arm_get_shift_operand_s(ir);
1.567 - LRD(ir) = operand;
1.568 - if( RDn(ir) == 15 ) {
1.569 - arm_restore_cpsr();
1.571 - armr.n = operand>>31;
1.572 - armr.z = (operand == 0);
1.573 - armr.c = armr.shift_c;
1.580 + * Condition passed, now for the actual instructions...
1.582 + switch( GRP(ir) ) {
1.584 + if( (ir & 0x0D900000) == 0x01000000 ) {
1.585 + /* Instructions that aren't actual data processing even though
1.586 + * they sit in the DP instruction block.
1.588 + switch( ir & 0x0FF000F0 ) {
1.589 + case 0x01200010: /* BX Rd */
1.590 + armr.t = ir & 0x01;
1.591 + armr.r[15] = RM(ir) & 0xFFFFFFFE;
1.593 + case 0x01000000: /* MRS Rd, CPSR */
1.594 + LRD(ir) = arm_get_cpsr();
1.596 + case 0x01400000: /* MRS Rd, SPSR */
1.597 + LRD(ir) = armr.spsr;
1.599 + case 0x01200000: /* MSR CPSR, Rd */
1.600 + arm_set_cpsr( RM(ir), ir );
1.602 + case 0x01600000: /* MSR SPSR, Rd */
1.603 + arm_set_spsr( RM(ir), ir );
1.605 + case 0x03200000: /* MSR CPSR, imm */
1.606 + arm_set_cpsr( ROTIMM12(ir), ir );
1.608 + case 0x03600000: /* MSR SPSR, imm */
1.609 + arm_set_spsr( ROTIMM12(ir), ir );
1.614 + } else if( (ir & 0x0E000090) == 0x00000090 ) {
1.615 + /* Neither are these */
1.616 + switch( (ir>>5)&0x03 ) {
1.618 + /* Arithmetic extension area */
1.619 + switch(OPCODE(ir)) {
1.620 + case 0: /* MUL */
1.622 + case 1: /* MULS */
1.624 + case 2: /* MLA */
1.626 + case 3: /* MLAS */
1.628 + case 8: /* UMULL */
1.630 + case 9: /* UMULLS */
1.632 + case 10: /* UMLAL */
1.634 + case 11: /* UMLALS */
1.636 + case 12: /* SMULL */
1.638 + case 13: /* SMULLS */
1.640 + case 14: /* SMLAL */
1.642 + case 15: /* SMLALS */
1.644 + case 16: /* SWP */
1.646 + case 20: /* SWPB */
1.652 - case 1: /* Load/store */
1.654 + if( LFLAG(ir) ) {
1.660 - case 2: /* Load/store multiple, branch*/
1.662 + if( LFLAG(ir) ) {
1.668 - case 3: /* Copro */
1.670 + if( LFLAG(ir) ) {
1.678 + /* Data processing */
1.680 + switch(OPCODE(ir)) {
1.681 + case 0: /* AND Rd, Rn, operand */
1.682 + LRD(ir) = RN(ir) & arm_get_shift_operand(ir);
1.684 + case 1: /* ANDS Rd, Rn, operand */
1.685 + operand = arm_get_shift_operand_s(ir) & RN(ir);
1.686 + LRD(ir) = operand;
1.687 + if( RDn(ir) == 15 ) {
1.688 + arm_restore_cpsr();
1.690 + armr.n = operand>>31;
1.691 + armr.z = (operand == 0);
1.692 + armr.c = armr.shift_c;
1.695 + case 2: /* EOR Rd, Rn, operand */
1.696 + LRD(ir) = RN(ir) ^ arm_get_shift_operand(ir);
1.698 + case 3: /* EORS Rd, Rn, operand */
1.699 + operand = arm_get_shift_operand_s(ir) ^ RN(ir);
1.700 + LRD(ir) = operand;
1.701 + if( RDn(ir) == 15 ) {
1.702 + arm_restore_cpsr();
1.704 + armr.n = operand>>31;
1.705 + armr.z = (operand == 0);
1.706 + armr.c = armr.shift_c;
1.709 + case 4: /* SUB Rd, Rn, operand */
1.710 + LRD(ir) = RN(ir) - arm_get_shift_operand(ir);
1.712 + case 5: /* SUBS Rd, Rn, operand */
1.713 + operand = RN(ir);
1.714 + operand2 = arm_get_shift_operand(ir);
1.715 + tmp = operand - operand2;
1.717 + if( RDn(ir) == 15 ) {
1.718 + arm_restore_cpsr();
1.720 + armr.n = tmp>>31;
1.721 + armr.z = (tmp == 0);
1.722 + armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.723 + armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.726 + case 6: /* RSB Rd, operand, Rn */
1.727 + LRD(ir) = arm_get_shift_operand(ir) - RN(ir);
1.729 + case 7: /* RSBS Rd, operand, Rn */
1.730 + operand = arm_get_shift_operand(ir);
1.731 + operand2 = RN(ir);
1.732 + tmp = operand - operand2;
1.734 + if( RDn(ir) == 15 ) {
1.735 + arm_restore_cpsr();
1.737 + armr.n = tmp>>31;
1.738 + armr.z = (tmp == 0);
1.739 + armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.740 + armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.743 + case 8: /* ADD Rd, Rn, operand */
1.744 + LRD(ir) = RN(ir) + arm_get_shift_operand(ir);
1.746 + case 9: /* ADDS Rd, Rn, operand */
1.747 + operand = arm_get_shift_operand(ir);
1.748 + operand2 = RN(ir);
1.749 + tmp = operand + operand2;
1.751 + if( RDn(ir) == 15 ) {
1.752 + arm_restore_cpsr();
1.754 + armr.n = tmp>>31;
1.755 + armr.z = (tmp == 0);
1.756 + armr.c = IS_CARRY(tmp,operand,operand2);
1.757 + armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
1.760 + case 10: /* ADC */
1.761 + case 11: /* ADCS */
1.762 + case 12: /* SBC */
1.763 + case 13: /* SBCS */
1.764 + case 14: /* RSC */
1.765 + case 15: /* RSCS */
1.767 + case 17: /* TST Rn, operand */
1.768 + operand = arm_get_shift_operand_s(ir) & RN(ir);
1.769 + armr.n = operand>>31;
1.770 + armr.z = (operand == 0);
1.771 + armr.c = armr.shift_c;
1.773 + case 19: /* TEQ Rn, operand */
1.774 + operand = arm_get_shift_operand_s(ir) ^ RN(ir);
1.775 + armr.n = operand>>31;
1.776 + armr.z = (operand == 0);
1.777 + armr.c = armr.shift_c;
1.779 + case 21: /* CMP Rn, operand */
1.780 + operand = RN(ir);
1.781 + operand2 = arm_get_shift_operand(ir);
1.782 + tmp = operand - operand2;
1.783 + armr.n = tmp>>31;
1.784 + armr.z = (tmp == 0);
1.785 + armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.786 + armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.788 + case 23: /* CMN Rn, operand */
1.789 + operand = RN(ir);
1.790 + operand2 = arm_get_shift_operand(ir);
1.791 + tmp = operand + operand2;
1.792 + armr.n = tmp>>31;
1.793 + armr.z = (tmp == 0);
1.794 + armr.c = IS_CARRY(tmp,operand,operand2);
1.795 + armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
1.797 + case 24: /* ORR Rd, Rn, operand */
1.798 + LRD(ir) = RN(ir) | arm_get_shift_operand(ir);
1.800 + case 25: /* ORRS Rd, Rn, operand */
1.801 + operand = arm_get_shift_operand_s(ir) | RN(ir);
1.802 + LRD(ir) = operand;
1.803 + if( RDn(ir) == 15 ) {
1.804 + arm_restore_cpsr();
1.806 + armr.n = operand>>31;
1.807 + armr.z = (operand == 0);
1.808 + armr.c = armr.shift_c;
1.811 + case 26: /* MOV Rd, operand */
1.812 + LRD(ir) = arm_get_shift_operand(ir);
1.814 + case 27: /* MOVS Rd, operand */
1.815 + operand = arm_get_shift_operand_s(ir);
1.816 + LRD(ir) = operand;
1.817 + if( RDn(ir) == 15 ) {
1.818 + arm_restore_cpsr();
1.820 + armr.n = operand>>31;
1.821 + armr.z = (operand == 0);
1.822 + armr.c = armr.shift_c;
1.825 + case 28: /* BIC Rd, Rn, operand */
1.826 + LRD(ir) = RN(ir) & (~arm_get_shift_operand(ir));
1.828 + case 29: /* BICS Rd, Rn, operand */
1.829 + operand = RN(ir) & (~arm_get_shift_operand_s(ir));
1.830 + LRD(ir) = operand;
1.831 + if( RDn(ir) == 15 ) {
1.832 + arm_restore_cpsr();
1.834 + armr.n = operand>>31;
1.835 + armr.z = (operand == 0);
1.836 + armr.c = armr.shift_c;
1.839 + case 30: /* MVN Rd, operand */
1.840 + LRD(ir) = ~arm_get_shift_operand(ir);
1.842 + case 31: /* MVNS Rd, operand */
1.843 + operand = ~arm_get_shift_operand_s(ir);
1.844 + LRD(ir) = operand;
1.845 + if( RDn(ir) == 15 ) {
1.846 + arm_restore_cpsr();
1.848 + armr.n = operand>>31;
1.849 + armr.z = (operand == 0);
1.850 + armr.c = armr.shift_c;
1.859 + case 1: /* Load/store */
1.860 + operand = arm_get_address_operand(ir);
1.861 + switch( (ir>>20)&0x17 ) {
1.862 + case 0: case 16: case 18: /* STR Rd, address */
1.863 + arm_write_long( operand, RD(ir) );
1.865 + case 1: case 17: case 19: /* LDR Rd, address */
1.866 + LRD(ir) = arm_read_long(operand);
1.868 + case 2: /* STRT Rd, address */
1.869 + arm_write_long_user( operand, RD(ir) );
1.871 + case 3: /* LDRT Rd, address */
1.872 + LRD(ir) = arm_read_long_user( operand );
1.874 + case 4: case 20: case 22: /* STRB Rd, address */
1.875 + arm_write_byte( operand, RD(ir) );
1.877 + case 5: case 21: case 23: /* LDRB Rd, address */
1.878 + LRD(ir) = arm_read_byte( operand );
1.880 + case 6: /* STRBT Rd, address */
1.881 + arm_write_byte_user( operand, RD(ir) );
1.883 + case 7: /* LDRBT Rd, address */
1.884 + LRD(ir) = arm_read_byte_user( operand );
1.888 + case 2: /* Load/store multiple, branch*/
1.889 + if( (ir & 0x02000000) == 0x02000000 ) { /* B[L] imm24 */
1.890 + operand = (SIGNEXT24(ir&0x00FFFFFF) << 2);
1.891 + if( (ir & 0x01000000) == 0x01000000 ) {
1.892 + armr.r[14] = pc; /* BL */
1.894 + armr.r[15] = pc + 4 + operand;
1.895 + } else { /* Load/store multiple */
1.899 + case 3: /* Copro */