1.1 --- a/src/aica/armcore.c Tue Feb 26 01:06:59 2008 +0000
1.2 +++ b/src/aica/armcore.c Sat Jul 19 02:41:30 2008 +0000
1.4 void arm_set_mode( int mode );
1.6 uint32_t arm_exceptions[][2] = {{ MODE_SVC, 0x00000000 },
1.7 - { MODE_UND, 0x00000004 },
1.8 - { MODE_SVC, 0x00000008 },
1.9 - { MODE_ABT, 0x0000000C },
1.10 - { MODE_ABT, 0x00000010 },
1.11 - { MODE_IRQ, 0x00000018 },
1.12 - { MODE_FIQ, 0x0000001C } };
1.13 + { MODE_UND, 0x00000004 },
1.14 + { MODE_SVC, 0x00000008 },
1.15 + { MODE_ABT, 0x0000000C },
1.16 + { MODE_ABT, 0x00000010 },
1.17 + { MODE_IRQ, 0x00000018 },
1.18 + { MODE_FIQ, 0x0000001C } };
1.21 #define EXC_UNDEFINED 1
1.25 for( i=0; i<arm_breakpoint_count; i++ ) {
1.26 - if( arm_breakpoints[i].address == pc &&
1.27 - arm_breakpoints[i].type == type ) {
1.28 - while( ++i < arm_breakpoint_count ) {
1.29 - arm_breakpoints[i-1].address = arm_breakpoints[i].address;
1.30 - arm_breakpoints[i-1].type = arm_breakpoints[i].type;
1.32 - arm_breakpoint_count--;
1.35 + if( arm_breakpoints[i].address == pc &&
1.36 + arm_breakpoints[i].type == type ) {
1.37 + while( ++i < arm_breakpoint_count ) {
1.38 + arm_breakpoints[i-1].address = arm_breakpoints[i].address;
1.39 + arm_breakpoints[i-1].type = arm_breakpoints[i].type;
1.41 + arm_breakpoint_count--;
1.50 for( i=0; i<arm_breakpoint_count; i++ ) {
1.51 - if( arm_breakpoints[i].address == pc )
1.52 - return arm_breakpoints[i].type;
1.53 + if( arm_breakpoints[i].address == pc )
1.54 + return arm_breakpoints[i].type;
1.62 - return num_samples;
1.63 + return num_samples;
1.65 for( i=0; i<num_samples; i++ ) {
1.66 - for( j=0; j < CYCLES_PER_SAMPLE; j++ ) {
1.68 - if( !arm_execute_instruction() )
1.70 + for( j=0; j < CYCLES_PER_SAMPLE; j++ ) {
1.72 + if( !arm_execute_instruction() )
1.74 #ifdef ENABLE_DEBUG_MODE
1.75 - for( k=0; k<arm_breakpoint_count; k++ ) {
1.76 - if( arm_breakpoints[k].address == armr.r[15] ) {
1.78 - if( arm_breakpoints[k].type == BREAK_ONESHOT )
1.79 - arm_clear_breakpoint( armr.r[15], BREAK_ONESHOT );
1.83 + for( k=0; k<arm_breakpoint_count; k++ ) {
1.84 + if( arm_breakpoints[k].address == armr.r[15] ) {
1.86 + if( arm_breakpoints[k].type == BREAK_ONESHOT )
1.87 + arm_clear_breakpoint( armr.r[15], BREAK_ONESHOT );
1.94 - k = MMIO_READ( AICA2, AICA_TCR );
1.95 - uint8_t val = MMIO_READ( AICA2, AICA_TIMER );
1.98 - aica_event( AICA_EVENT_TIMER );
1.99 - // MMIO_WRITE( AICA2, AICA_TCR, k & ~0x40 );
1.101 - MMIO_WRITE( AICA2, AICA_TIMER, val );
1.102 - if( !dreamcast_is_running() )
1.106 + k = MMIO_READ( AICA2, AICA_TCR );
1.107 + uint8_t val = MMIO_READ( AICA2, AICA_TIMER );
1.110 + aica_event( AICA_EVENT_TIMER );
1.111 + // MMIO_WRITE( AICA2, AICA_TCR, k & ~0x40 );
1.113 + MMIO_WRITE( AICA2, AICA_TIMER, val );
1.114 + if( !dreamcast_is_running() )
1.119 @@ -173,12 +173,12 @@
1.120 static uint32_t *arm_user_reg( int reg )
1.122 if( IS_EXCEPTION_MODE() ) {
1.123 - if( reg == 13 || reg == 14 )
1.124 - return &armr.user_r[reg-8];
1.125 - if( IS_FIQ_MODE() ) {
1.126 - if( reg >= 8 || reg <= 12 )
1.127 - return &armr.user_r[reg-8];
1.129 + if( reg == 13 || reg == 14 )
1.130 + return &armr.user_r[reg-8];
1.131 + if( IS_FIQ_MODE() ) {
1.132 + if( reg >= 8 || reg <= 12 )
1.133 + return &armr.user_r[reg-8];
1.136 return &armr.r[reg];
1.138 @@ -195,23 +195,23 @@
1.139 void arm_set_cpsr( uint32_t value, uint32_t fields )
1.141 if( IS_PRIVILEGED_MODE() ) {
1.142 - if( fields & SET_CPSR_CONTROL ) {
1.143 - int mode = value & CPSR_MODE;
1.144 - arm_set_mode( mode );
1.145 - armr.t = ( value & CPSR_T ); /* Technically illegal to change */
1.146 - armr.cpsr = (armr.cpsr & 0xFFFFFF00) | (value & 0x000000FF);
1.148 + if( fields & SET_CPSR_CONTROL ) {
1.149 + int mode = value & CPSR_MODE;
1.150 + arm_set_mode( mode );
1.151 + armr.t = ( value & CPSR_T ); /* Technically illegal to change */
1.152 + armr.cpsr = (armr.cpsr & 0xFFFFFF00) | (value & 0x000000FF);
1.155 - /* Middle 16 bits not currently defined */
1.156 + /* Middle 16 bits not currently defined */
1.158 if( fields & SET_CPSR_FLAGS ) {
1.159 - /* Break flags directly out of given value - don't bother writing
1.162 - armr.n = ( value & CPSR_N );
1.163 - armr.z = ( value & CPSR_Z );
1.164 - armr.c = ( value & CPSR_C );
1.165 - armr.v = ( value & CPSR_V );
1.166 + /* Break flags directly out of given value - don't bother writing
1.169 + armr.n = ( value & CPSR_N );
1.170 + armr.z = ( value & CPSR_Z );
1.171 + armr.c = ( value & CPSR_C );
1.172 + armr.v = ( value & CPSR_V );
1.176 @@ -219,15 +219,15 @@
1.178 /* Only defined if we actually have an SPSR register */
1.179 if( IS_EXCEPTION_MODE() ) {
1.180 - if( fields & SET_CPSR_CONTROL ) {
1.181 - armr.spsr = (armr.spsr & 0xFFFFFF00) | (value & 0x000000FF);
1.183 + if( fields & SET_CPSR_CONTROL ) {
1.184 + armr.spsr = (armr.spsr & 0xFFFFFF00) | (value & 0x000000FF);
1.187 - /* Middle 16 bits not currently defined */
1.188 + /* Middle 16 bits not currently defined */
1.190 - if( fields & SET_CPSR_FLAGS ) {
1.191 - armr.spsr = (armr.spsr & 0x00FFFFFF) | (value & 0xFF000000);
1.193 + if( fields & SET_CPSR_FLAGS ) {
1.194 + armr.spsr = (armr.spsr & 0x00FFFFFF) | (value & 0xFF000000);
1.199 @@ -244,7 +244,7 @@
1.200 armr.r[14] = armr.r[15] + 4;
1.201 armr.cpsr = (spsr & 0xFFFFFF00) | mode | CPSR_I;
1.202 if( mode == MODE_FIQ )
1.203 - armr.cpsr |= CPSR_F;
1.204 + armr.cpsr |= CPSR_F;
1.205 armr.r[15] = arm_exceptions[exception][1];
1.208 @@ -272,92 +272,92 @@
1.210 int currentMode = armr.cpsr & CPSR_MODE;
1.211 if( currentMode == targetMode )
1.215 switch( currentMode ) {
1.218 - armr.user_r[5] = armr.r[13];
1.219 - armr.user_r[6] = armr.r[14];
1.221 + armr.user_r[5] = armr.r[13];
1.222 + armr.user_r[6] = armr.r[14];
1.225 - armr.svc_r[0] = armr.r[13];
1.226 - armr.svc_r[1] = armr.r[14];
1.227 - armr.svc_r[2] = armr.spsr;
1.229 + armr.svc_r[0] = armr.r[13];
1.230 + armr.svc_r[1] = armr.r[14];
1.231 + armr.svc_r[2] = armr.spsr;
1.234 - armr.abt_r[0] = armr.r[13];
1.235 - armr.abt_r[1] = armr.r[14];
1.236 - armr.abt_r[2] = armr.spsr;
1.238 + armr.abt_r[0] = armr.r[13];
1.239 + armr.abt_r[1] = armr.r[14];
1.240 + armr.abt_r[2] = armr.spsr;
1.243 - armr.und_r[0] = armr.r[13];
1.244 - armr.und_r[1] = armr.r[14];
1.245 - armr.und_r[2] = armr.spsr;
1.247 + armr.und_r[0] = armr.r[13];
1.248 + armr.und_r[1] = armr.r[14];
1.249 + armr.und_r[2] = armr.spsr;
1.252 - armr.irq_r[0] = armr.r[13];
1.253 - armr.irq_r[1] = armr.r[14];
1.254 - armr.irq_r[2] = armr.spsr;
1.256 + armr.irq_r[0] = armr.r[13];
1.257 + armr.irq_r[1] = armr.r[14];
1.258 + armr.irq_r[2] = armr.spsr;
1.261 - armr.fiq_r[0] = armr.r[8];
1.262 - armr.fiq_r[1] = armr.r[9];
1.263 - armr.fiq_r[2] = armr.r[10];
1.264 - armr.fiq_r[3] = armr.r[11];
1.265 - armr.fiq_r[4] = armr.r[12];
1.266 - armr.fiq_r[5] = armr.r[13];
1.267 - armr.fiq_r[6] = armr.r[14];
1.268 - armr.fiq_r[7] = armr.spsr;
1.269 - armr.r[8] = armr.user_r[0];
1.270 - armr.r[9] = armr.user_r[1];
1.271 - armr.r[10] = armr.user_r[2];
1.272 - armr.r[11] = armr.user_r[3];
1.273 - armr.r[12] = armr.user_r[4];
1.275 + armr.fiq_r[0] = armr.r[8];
1.276 + armr.fiq_r[1] = armr.r[9];
1.277 + armr.fiq_r[2] = armr.r[10];
1.278 + armr.fiq_r[3] = armr.r[11];
1.279 + armr.fiq_r[4] = armr.r[12];
1.280 + armr.fiq_r[5] = armr.r[13];
1.281 + armr.fiq_r[6] = armr.r[14];
1.282 + armr.fiq_r[7] = armr.spsr;
1.283 + armr.r[8] = armr.user_r[0];
1.284 + armr.r[9] = armr.user_r[1];
1.285 + armr.r[10] = armr.user_r[2];
1.286 + armr.r[11] = armr.user_r[3];
1.287 + armr.r[12] = armr.user_r[4];
1.292 switch( targetMode ) {
1.295 - armr.r[13] = armr.user_r[5];
1.296 - armr.r[14] = armr.user_r[6];
1.298 + armr.r[13] = armr.user_r[5];
1.299 + armr.r[14] = armr.user_r[6];
1.302 - armr.r[13] = armr.svc_r[0];
1.303 - armr.r[14] = armr.svc_r[1];
1.304 - armr.spsr = armr.svc_r[2];
1.306 + armr.r[13] = armr.svc_r[0];
1.307 + armr.r[14] = armr.svc_r[1];
1.308 + armr.spsr = armr.svc_r[2];
1.311 - armr.r[13] = armr.abt_r[0];
1.312 - armr.r[14] = armr.abt_r[1];
1.313 - armr.spsr = armr.abt_r[2];
1.315 + armr.r[13] = armr.abt_r[0];
1.316 + armr.r[14] = armr.abt_r[1];
1.317 + armr.spsr = armr.abt_r[2];
1.320 - armr.r[13] = armr.und_r[0];
1.321 - armr.r[14] = armr.und_r[1];
1.322 - armr.spsr = armr.und_r[2];
1.324 + armr.r[13] = armr.und_r[0];
1.325 + armr.r[14] = armr.und_r[1];
1.326 + armr.spsr = armr.und_r[2];
1.329 - armr.r[13] = armr.irq_r[0];
1.330 - armr.r[14] = armr.irq_r[1];
1.331 - armr.spsr = armr.irq_r[2];
1.333 + armr.r[13] = armr.irq_r[0];
1.334 + armr.r[14] = armr.irq_r[1];
1.335 + armr.spsr = armr.irq_r[2];
1.338 - armr.user_r[0] = armr.r[8];
1.339 - armr.user_r[1] = armr.r[9];
1.340 - armr.user_r[2] = armr.r[10];
1.341 - armr.user_r[3] = armr.r[11];
1.342 - armr.user_r[4] = armr.r[12];
1.343 - armr.r[8] = armr.fiq_r[0];
1.344 - armr.r[9] = armr.fiq_r[1];
1.345 - armr.r[10] = armr.fiq_r[2];
1.346 - armr.r[11] = armr.fiq_r[3];
1.347 - armr.r[12] = armr.fiq_r[4];
1.348 - armr.r[13] = armr.fiq_r[5];
1.349 - armr.r[14] = armr.fiq_r[6];
1.350 - armr.spsr = armr.fiq_r[7];
1.352 + armr.user_r[0] = armr.r[8];
1.353 + armr.user_r[1] = armr.r[9];
1.354 + armr.user_r[2] = armr.r[10];
1.355 + armr.user_r[3] = armr.r[11];
1.356 + armr.user_r[4] = armr.r[12];
1.357 + armr.r[8] = armr.fiq_r[0];
1.358 + armr.r[9] = armr.fiq_r[1];
1.359 + armr.r[10] = armr.fiq_r[2];
1.360 + armr.r[11] = armr.fiq_r[3];
1.361 + armr.r[12] = armr.fiq_r[4];
1.362 + armr.r[13] = armr.fiq_r[5];
1.363 + armr.r[14] = armr.fiq_r[6];
1.364 + armr.spsr = armr.fiq_r[7];
1.369 @@ -418,54 +418,54 @@
1.371 static uint32_t arm_get_shift_operand( uint32_t ir )
1.373 - uint32_t operand, tmp;
1.374 - if( IFLAG(ir) == 0 ) {
1.375 - operand = RM(ir);
1.376 - switch(SHIFT(ir)) {
1.377 - case 0: /* (Rm << imm) */
1.378 - operand = operand << SHIFTIMM(ir);
1.380 - case 1: /* (Rm << Rs) */
1.381 - tmp = RS(ir)&0xFF;
1.382 - if( tmp > 31 ) operand = 0;
1.383 - else operand = operand << tmp;
1.385 - case 2: /* (Rm >> imm) */
1.386 - operand = operand >> SHIFTIMM(ir);
1.388 - case 3: /* (Rm >> Rs) */
1.389 - tmp = RS(ir) & 0xFF;
1.390 - if( tmp > 31 ) operand = 0;
1.391 - else operand = operand >> ir;
1.393 - case 4: /* (Rm >>> imm) */
1.394 - tmp = SHIFTIMM(ir);
1.395 - if( tmp == 0 ) operand = ((int32_t)operand) >> 31;
1.396 - else operand = ((int32_t)operand) >> tmp;
1.398 - case 5: /* (Rm >>> Rs) */
1.399 - tmp = RS(ir) & 0xFF;
1.400 - if( tmp > 31 ) operand = ((int32_t)operand) >> 31;
1.401 - else operand = ((int32_t)operand) >> tmp;
1.404 - tmp = SHIFTIMM(ir);
1.405 - if( tmp == 0 ) /* RRX aka rotate with carry */
1.406 - operand = (operand >> 1) | (armr.c<<31);
1.408 - operand = ROTATE_RIGHT_LONG(operand,tmp);
1.411 - tmp = RS(ir)&0x1F;
1.412 - operand = ROTATE_RIGHT_LONG(operand,tmp);
1.416 - operand = IMM8(ir);
1.417 - tmp = IMMROT(ir);
1.418 - operand = ROTATE_RIGHT_LONG(operand, tmp);
1.421 + uint32_t operand, tmp;
1.422 + if( IFLAG(ir) == 0 ) {
1.423 + operand = RM(ir);
1.424 + switch(SHIFT(ir)) {
1.425 + case 0: /* (Rm << imm) */
1.426 + operand = operand << SHIFTIMM(ir);
1.428 + case 1: /* (Rm << Rs) */
1.429 + tmp = RS(ir)&0xFF;
1.430 + if( tmp > 31 ) operand = 0;
1.431 + else operand = operand << tmp;
1.433 + case 2: /* (Rm >> imm) */
1.434 + operand = operand >> SHIFTIMM(ir);
1.436 + case 3: /* (Rm >> Rs) */
1.437 + tmp = RS(ir) & 0xFF;
1.438 + if( tmp > 31 ) operand = 0;
1.439 + else operand = operand >> ir;
1.441 + case 4: /* (Rm >>> imm) */
1.442 + tmp = SHIFTIMM(ir);
1.443 + if( tmp == 0 ) operand = ((int32_t)operand) >> 31;
1.444 + else operand = ((int32_t)operand) >> tmp;
1.446 + case 5: /* (Rm >>> Rs) */
1.447 + tmp = RS(ir) & 0xFF;
1.448 + if( tmp > 31 ) operand = ((int32_t)operand) >> 31;
1.449 + else operand = ((int32_t)operand) >> tmp;
1.452 + tmp = SHIFTIMM(ir);
1.453 + if( tmp == 0 ) /* RRX aka rotate with carry */
1.454 + operand = (operand >> 1) | (armr.c<<31);
1.456 + operand = ROTATE_RIGHT_LONG(operand,tmp);
1.459 + tmp = RS(ir)&0x1F;
1.460 + operand = ROTATE_RIGHT_LONG(operand,tmp);
1.464 + operand = IMM8(ir);
1.465 + tmp = IMMROT(ir);
1.466 + operand = ROTATE_RIGHT_LONG(operand, tmp);
1.472 @@ -475,115 +475,115 @@
1.474 static uint32_t arm_get_shift_operand_s( uint32_t ir )
1.476 - uint32_t operand, tmp;
1.477 - if( IFLAG(ir) == 0 ) {
1.478 - operand = RM(ir);
1.479 - switch(SHIFT(ir)) {
1.480 - case 0: /* (Rm << imm) */
1.481 - tmp = SHIFTIMM(ir);
1.482 - if( tmp == 0 ) { /* Rm */
1.483 - armr.shift_c = armr.c;
1.484 - } else { /* Rm << imm */
1.485 - armr.shift_c = (operand >> (32-tmp)) & 0x01;
1.486 - operand = operand << tmp;
1.489 - case 1: /* (Rm << Rs) */
1.490 - tmp = RS(ir)&0xFF;
1.492 - armr.shift_c = armr.c;
1.495 - armr.shift_c = (operand >> (32-tmp)) & 0x01;
1.496 - else armr.shift_c = 0;
1.498 - operand = operand << tmp;
1.499 - else operand = 0;
1.502 - case 2: /* (Rm >> imm) */
1.503 - tmp = SHIFTIMM(ir);
1.505 - armr.shift_c = operand >> 31;
1.508 - armr.shift_c = (operand >> (tmp-1)) & 0x01;
1.509 - operand = RM(ir) >> tmp;
1.512 - case 3: /* (Rm >> Rs) */
1.513 - tmp = RS(ir) & 0xFF;
1.515 - armr.shift_c = armr.c;
1.518 - armr.shift_c = (operand >> (tmp-1))&0x01;
1.519 - else armr.shift_c = 0;
1.521 - operand = operand >> tmp;
1.522 - else operand = 0;
1.525 - case 4: /* (Rm >>> imm) */
1.526 - tmp = SHIFTIMM(ir);
1.528 - armr.shift_c = operand >> 31;
1.529 - operand = -armr.shift_c;
1.531 - armr.shift_c = (operand >> (tmp-1)) & 0x01;
1.532 - operand = ((int32_t)operand) >> tmp;
1.535 - case 5: /* (Rm >>> Rs) */
1.536 - tmp = RS(ir) & 0xFF;
1.538 - armr.shift_c = armr.c;
1.541 - armr.shift_c = (operand >> (tmp-1))&0x01;
1.542 - operand = ((int32_t)operand) >> tmp;
1.544 - armr.shift_c = operand >> 31;
1.545 - operand = ((int32_t)operand) >> 31;
1.550 - tmp = SHIFTIMM(ir);
1.551 - if( tmp == 0 ) { /* RRX aka rotate with carry */
1.552 - armr.shift_c = operand&0x01;
1.553 - operand = (operand >> 1) | (armr.c<<31);
1.555 - armr.shift_c = operand>>(tmp-1);
1.556 - operand = ROTATE_RIGHT_LONG(operand,tmp);
1.560 - tmp = RS(ir)&0xFF;
1.562 - armr.shift_c = armr.c;
1.566 - armr.shift_c = operand>>31;
1.568 - armr.shift_c = (operand>>(tmp-1))&0x1;
1.569 - operand = ROTATE_RIGHT_LONG(operand,tmp);
1.575 - operand = IMM8(ir);
1.576 - tmp = IMMROT(ir);
1.578 - armr.shift_c = armr.c;
1.580 - operand = ROTATE_RIGHT_LONG(operand, tmp);
1.581 - armr.shift_c = operand>>31;
1.585 + uint32_t operand, tmp;
1.586 + if( IFLAG(ir) == 0 ) {
1.587 + operand = RM(ir);
1.588 + switch(SHIFT(ir)) {
1.589 + case 0: /* (Rm << imm) */
1.590 + tmp = SHIFTIMM(ir);
1.591 + if( tmp == 0 ) { /* Rm */
1.592 + armr.shift_c = armr.c;
1.593 + } else { /* Rm << imm */
1.594 + armr.shift_c = (operand >> (32-tmp)) & 0x01;
1.595 + operand = operand << tmp;
1.598 + case 1: /* (Rm << Rs) */
1.599 + tmp = RS(ir)&0xFF;
1.601 + armr.shift_c = armr.c;
1.604 + armr.shift_c = (operand >> (32-tmp)) & 0x01;
1.605 + else armr.shift_c = 0;
1.607 + operand = operand << tmp;
1.608 + else operand = 0;
1.611 + case 2: /* (Rm >> imm) */
1.612 + tmp = SHIFTIMM(ir);
1.614 + armr.shift_c = operand >> 31;
1.617 + armr.shift_c = (operand >> (tmp-1)) & 0x01;
1.618 + operand = RM(ir) >> tmp;
1.621 + case 3: /* (Rm >> Rs) */
1.622 + tmp = RS(ir) & 0xFF;
1.624 + armr.shift_c = armr.c;
1.627 + armr.shift_c = (operand >> (tmp-1))&0x01;
1.628 + else armr.shift_c = 0;
1.630 + operand = operand >> tmp;
1.631 + else operand = 0;
1.634 + case 4: /* (Rm >>> imm) */
1.635 + tmp = SHIFTIMM(ir);
1.637 + armr.shift_c = operand >> 31;
1.638 + operand = -armr.shift_c;
1.640 + armr.shift_c = (operand >> (tmp-1)) & 0x01;
1.641 + operand = ((int32_t)operand) >> tmp;
1.644 + case 5: /* (Rm >>> Rs) */
1.645 + tmp = RS(ir) & 0xFF;
1.647 + armr.shift_c = armr.c;
1.650 + armr.shift_c = (operand >> (tmp-1))&0x01;
1.651 + operand = ((int32_t)operand) >> tmp;
1.653 + armr.shift_c = operand >> 31;
1.654 + operand = ((int32_t)operand) >> 31;
1.659 + tmp = SHIFTIMM(ir);
1.660 + if( tmp == 0 ) { /* RRX aka rotate with carry */
1.661 + armr.shift_c = operand&0x01;
1.662 + operand = (operand >> 1) | (armr.c<<31);
1.664 + armr.shift_c = operand>>(tmp-1);
1.665 + operand = ROTATE_RIGHT_LONG(operand,tmp);
1.669 + tmp = RS(ir)&0xFF;
1.671 + armr.shift_c = armr.c;
1.675 + armr.shift_c = operand>>31;
1.677 + armr.shift_c = (operand>>(tmp-1))&0x1;
1.678 + operand = ROTATE_RIGHT_LONG(operand,tmp);
1.684 + operand = IMM8(ir);
1.685 + tmp = IMMROT(ir);
1.687 + armr.shift_c = armr.c;
1.689 + operand = ROTATE_RIGHT_LONG(operand, tmp);
1.690 + armr.shift_c = operand>>31;
1.697 @@ -595,31 +595,31 @@
1.699 static uint32_t arm_get_address_index( uint32_t ir )
1.701 - uint32_t operand = RM(ir);
1.704 - switch(SHIFT(ir)) {
1.705 - case 0: /* (Rm << imm) */
1.706 - operand = operand << SHIFTIMM(ir);
1.708 - case 2: /* (Rm >> imm) */
1.709 - operand = operand >> SHIFTIMM(ir);
1.711 - case 4: /* (Rm >>> imm) */
1.712 - tmp = SHIFTIMM(ir);
1.713 - if( tmp == 0 ) operand = ((int32_t)operand) >> 31;
1.714 - else operand = ((int32_t)operand) >> tmp;
1.717 - tmp = SHIFTIMM(ir);
1.718 - if( tmp == 0 ) /* RRX aka rotate with carry */
1.719 - operand = (operand >> 1) | (armr.c<<31);
1.721 - operand = ROTATE_RIGHT_LONG(operand,tmp);
1.723 - default: UNIMP(ir);
1.726 + uint32_t operand = RM(ir);
1.729 + switch(SHIFT(ir)) {
1.730 + case 0: /* (Rm << imm) */
1.731 + operand = operand << SHIFTIMM(ir);
1.733 + case 2: /* (Rm >> imm) */
1.734 + operand = operand >> SHIFTIMM(ir);
1.736 + case 4: /* (Rm >>> imm) */
1.737 + tmp = SHIFTIMM(ir);
1.738 + if( tmp == 0 ) operand = ((int32_t)operand) >> 31;
1.739 + else operand = ((int32_t)operand) >> tmp;
1.742 + tmp = SHIFTIMM(ir);
1.743 + if( tmp == 0 ) /* RRX aka rotate with carry */
1.744 + operand = (operand >> 1) | (armr.c<<31);
1.746 + operand = ROTATE_RIGHT_LONG(operand,tmp);
1.748 + default: UNIMP(ir);
1.754 @@ -631,60 +631,60 @@
1.756 static uint32_t arm_get_address_operand( uint32_t ir )
1.761 - switch( (ir>>21)&0x1D ) {
1.762 - case 0: /* Rn -= imm offset (post-indexed) [5.2.8 A5-28] */
1.765 - LRN(ir) = addr - IMM12(ir);
1.767 - case 4: /* Rn += imm offsett (post-indexed) [5.2.8 A5-28] */
1.770 - LRN(ir) = addr + IMM12(ir);
1.772 - case 8: /* Rn - imm offset [5.2.2 A5-20] */
1.773 - addr = RN(ir) - IMM12(ir);
1.775 - case 9: /* Rn -= imm offset (pre-indexed) [5.2.5 A5-24] */
1.776 - addr = RN(ir) - IMM12(ir);
1.779 - case 12: /* Rn + imm offset [5.2.2 A5-20] */
1.780 - addr = RN(ir) + IMM12(ir);
1.782 - case 13: /* Rn += imm offset [5.2.5 A5-24 ] */
1.783 - addr = RN(ir) + IMM12(ir);
1.786 - case 16: /* Rn -= Rm (post-indexed) [5.2.10 A5-32 ] */
1.789 - LRN(ir) = addr - arm_get_address_index(ir);
1.791 - case 20: /* Rn += Rm (post-indexed) [5.2.10 A5-32 ] */
1.794 - LRN(ir) = addr - arm_get_address_index(ir);
1.796 - case 24: /* Rn - Rm [5.2.4 A5-23] */
1.797 - addr = RN(ir) - arm_get_address_index(ir);
1.799 - case 25: /* RN -= Rm (pre-indexed) [5.2.7 A5-26] */
1.800 - addr = RN(ir) - arm_get_address_index(ir);
1.803 - case 28: /* Rn + Rm [5.2.4 A5-23] */
1.804 - addr = RN(ir) + arm_get_address_index(ir);
1.806 - case 29: /* RN += Rm (pre-indexed) [5.2.7 A5-26] */
1.807 - addr = RN(ir) + arm_get_address_index(ir);
1.815 + switch( (ir>>21)&0x1D ) {
1.816 + case 0: /* Rn -= imm offset (post-indexed) [5.2.8 A5-28] */
1.819 + LRN(ir) = addr - IMM12(ir);
1.821 + case 4: /* Rn += imm offsett (post-indexed) [5.2.8 A5-28] */
1.824 + LRN(ir) = addr + IMM12(ir);
1.826 + case 8: /* Rn - imm offset [5.2.2 A5-20] */
1.827 + addr = RN(ir) - IMM12(ir);
1.829 + case 9: /* Rn -= imm offset (pre-indexed) [5.2.5 A5-24] */
1.830 + addr = RN(ir) - IMM12(ir);
1.833 + case 12: /* Rn + imm offset [5.2.2 A5-20] */
1.834 + addr = RN(ir) + IMM12(ir);
1.836 + case 13: /* Rn += imm offset [5.2.5 A5-24 ] */
1.837 + addr = RN(ir) + IMM12(ir);
1.840 + case 16: /* Rn -= Rm (post-indexed) [5.2.10 A5-32 ] */
1.843 + LRN(ir) = addr - arm_get_address_index(ir);
1.845 + case 20: /* Rn += Rm (post-indexed) [5.2.10 A5-32 ] */
1.848 + LRN(ir) = addr - arm_get_address_index(ir);
1.850 + case 24: /* Rn - Rm [5.2.4 A5-23] */
1.851 + addr = RN(ir) - arm_get_address_index(ir);
1.853 + case 25: /* RN -= Rm (pre-indexed) [5.2.7 A5-26] */
1.854 + addr = RN(ir) - arm_get_address_index(ir);
1.857 + case 28: /* Rn + Rm [5.2.4 A5-23] */
1.858 + addr = RN(ir) + arm_get_address_index(ir);
1.860 + case 29: /* RN += Rm (pre-indexed) [5.2.7 A5-26] */
1.861 + addr = RN(ir) + arm_get_address_index(ir);
1.868 gboolean arm_execute_instruction( void )
1.869 @@ -696,11 +696,11 @@
1.871 tmp = armr.int_pending & (~armr.cpsr);
1.873 - if( tmp & CPSR_F ) {
1.874 - arm_raise_exception( EXC_FAST_IRQ );
1.876 - arm_raise_exception( EXC_IRQ );
1.878 + if( tmp & CPSR_F ) {
1.879 + arm_raise_exception( EXC_FAST_IRQ );
1.881 + arm_raise_exception( EXC_IRQ );
1.885 ir = MEM_READ_LONG(PC);
1.886 @@ -713,673 +713,673 @@
1.888 switch( COND(ir) ) {
1.899 case 2: /* CS/HS */
1.904 case 3: /* CC/LO */
1.930 - cond = armr.c && !armr.z;
1.932 + cond = armr.c && !armr.z;
1.935 - cond = (!armr.c) || armr.z;
1.937 + cond = (!armr.c) || armr.z;
1.940 - cond = (armr.n == armr.v);
1.942 + cond = (armr.n == armr.v);
1.945 - cond = (armr.n != armr.v);
1.947 + cond = (armr.n != armr.v);
1.950 - cond = (!armr.z) && (armr.n == armr.v);
1.952 + cond = (!armr.z) && (armr.n == armr.v);
1.955 - cond = armr.z || (armr.n != armr.v);
1.957 + cond = armr.z || (armr.n != armr.v);
1.964 case 15: /* (NV) */
1.974 - * Condition passed, now for the actual instructions...
1.976 - switch( GRP(ir) ) {
1.978 - if( (ir & 0x0D900000) == 0x01000000 ) {
1.979 - /* Instructions that aren't actual data processing even though
1.980 - * they sit in the DP instruction block.
1.982 - switch( ir & 0x0FF000F0 ) {
1.983 - case 0x01200010: /* BX Rd */
1.984 - armr.t = ir & 0x01;
1.985 - armr.r[15] = RM(ir) & 0xFFFFFFFE;
1.987 - case 0x01000000: /* MRS Rd, CPSR */
1.988 - LRD(ir) = arm_get_cpsr();
1.990 - case 0x01400000: /* MRS Rd, SPSR */
1.991 - LRD(ir) = armr.spsr;
1.993 - case 0x01200000: /* MSR CPSR, Rd */
1.994 - arm_set_cpsr( RM(ir), ir );
1.996 - case 0x01600000: /* MSR SPSR, Rd */
1.997 - arm_set_spsr( RM(ir), ir );
1.999 - case 0x03200000: /* MSR CPSR, imm */
1.1000 - arm_set_cpsr( ROTIMM12(ir), ir );
1.1002 - case 0x03600000: /* MSR SPSR, imm */
1.1003 - arm_set_spsr( ROTIMM12(ir), ir );
1.1008 - } else if( (ir & 0x0E000090) == 0x00000090 ) {
1.1009 - /* Neither are these */
1.1010 - switch( (ir>>5)&0x03 ) {
1.1012 - /* Arithmetic extension area */
1.1015 - LRN(ir) = RM(ir) * RS(ir);
1.1018 - tmp = RM(ir) * RS(ir);
1.1024 - LRN(ir) = RM(ir) * RS(ir) + RD(ir);
1.1027 - tmp = RM(ir) * RS(ir) + RD(ir);
1.1035 - case 11: /* UMLALS */
1.1037 - case 13: /* SMULLS */
1.1039 - case 15: /* SMLALS */
1.1043 - tmp = arm_read_long( RN(ir) );
1.1044 - switch( RN(ir) & 0x03 ) {
1.1046 - tmp = ROTATE_RIGHT_LONG(tmp, 8);
1.1049 - tmp = ROTATE_RIGHT_LONG(tmp, 16);
1.1052 - tmp = ROTATE_RIGHT_LONG(tmp, 24);
1.1055 - arm_write_long( RN(ir), RM(ir) );
1.1059 - tmp = arm_read_byte( RN(ir) );
1.1060 - arm_write_byte( RN(ir), RM(ir) );
1.1091 - /* Data processing */
1.1093 + * Condition passed, now for the actual instructions...
1.1097 + if( (ir & 0x0D900000) == 0x01000000 ) {
1.1098 + /* Instructions that aren't actual data processing even though
1.1099 + * they sit in the DP instruction block.
1.1101 + switch( ir & 0x0FF000F0 ) {
1.1102 + case 0x01200010: /* BX Rd */
1.1104 + armr.r[15] = RM(ir) & 0xFFFFFFFE;
1.1106 + case 0x01000000: /* MRS Rd, CPSR */
1.1107 + LRD(ir) = arm_get_cpsr();
1.1109 + case 0x01400000: /* MRS Rd, SPSR */
1.1112 + case 0x01200000: /* MSR CPSR, Rd */
1.1113 + arm_set_cpsr( RM(ir), ir );
1.1115 + case 0x01600000: /* MSR SPSR, Rd */
1.1116 + arm_set_spsr( RM(ir), ir );
1.1118 + case 0x03200000: /* MSR CPSR, imm */
1.1119 + arm_set_cpsr( ROTIMM12(ir), ir );
1.1121 + case 0x03600000: /* MSR SPSR, imm */
1.1122 + arm_set_spsr( ROTIMM12(ir), ir );
1.1127 + } else if( (ir & 0x0E000090) == 0x00000090 ) {
1.1128 + /* Neither are these */
1.1129 + switch( (ir>>5)&0x03 ) {
1.1131 + /* Arithmetic extension area */
1.1134 + LRN(ir) = RM(ir) * RS(ir);
1.1137 + tmp = RM(ir) * RS(ir);
1.1143 + LRN(ir) = RM(ir) * RS(ir) + RD(ir);
1.1146 + tmp = RM(ir) * RS(ir) + RD(ir);
1.1154 + case 11: /* UMLALS */
1.1156 + case 13: /* SMULLS */
1.1158 + case 15: /* SMLALS */
1.1162 + tmp = arm_read_long( RN(ir) );
1.1163 + switch( RN(ir) & 0x03 ) {
1.1165 + tmp = ROTATE_RIGHT_LONG(tmp, 8);
1.1168 + tmp = ROTATE_RIGHT_LONG(tmp, 16);
1.1171 + tmp = ROTATE_RIGHT_LONG(tmp, 24);
1.1174 + arm_write_long( RN(ir), RM(ir) );
1.1178 + tmp = arm_read_byte( RN(ir) );
1.1179 + arm_write_byte( RN(ir), RM(ir) );
1.1210 + /* Data processing */
1.1213 - case 0: /* AND Rd, Rn, operand */
1.1214 - LRD(ir) = RN(ir) & arm_get_shift_operand(ir);
1.1216 - case 1: /* ANDS Rd, Rn, operand */
1.1217 - operand = arm_get_shift_operand_s(ir) & RN(ir);
1.1219 - if( RDn(ir) == 15 ) {
1.1222 - armr.n = operand>>31;
1.1223 - armr.z = (operand == 0);
1.1224 - armr.c = armr.shift_c;
1.1227 - case 2: /* EOR Rd, Rn, operand */
1.1228 - LRD(ir) = RN(ir) ^ arm_get_shift_operand(ir);
1.1230 - case 3: /* EORS Rd, Rn, operand */
1.1231 - operand = arm_get_shift_operand_s(ir) ^ RN(ir);
1.1233 - if( RDn(ir) == 15 ) {
1.1236 - armr.n = operand>>31;
1.1237 - armr.z = (operand == 0);
1.1238 - armr.c = armr.shift_c;
1.1241 - case 4: /* SUB Rd, Rn, operand */
1.1242 - LRD(ir) = RN(ir) - arm_get_shift_operand(ir);
1.1244 - case 5: /* SUBS Rd, Rn, operand */
1.1246 - operand2 = arm_get_shift_operand(ir);
1.1247 - tmp = operand - operand2;
1.1249 - if( RDn(ir) == 15 ) {
1.1254 - armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.1255 - armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.1258 - case 6: /* RSB Rd, operand, Rn */
1.1259 - LRD(ir) = arm_get_shift_operand(ir) - RN(ir);
1.1261 - case 7: /* RSBS Rd, operand, Rn */
1.1262 - operand = arm_get_shift_operand(ir);
1.1264 - tmp = operand - operand2;
1.1266 - if( RDn(ir) == 15 ) {
1.1271 - armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.1272 - armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.1275 - case 8: /* ADD Rd, Rn, operand */
1.1276 - LRD(ir) = RN(ir) + arm_get_shift_operand(ir);
1.1278 - case 9: /* ADDS Rd, Rn, operand */
1.1279 - operand = arm_get_shift_operand(ir);
1.1281 - tmp = operand + operand2;
1.1283 - if( RDn(ir) == 15 ) {
1.1288 - armr.c = IS_CARRY(tmp,operand,operand2);
1.1289 - armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
1.1293 - LRD(ir) = RN(ir) + arm_get_shift_operand(ir) +
1.1297 - operand = arm_get_shift_operand(ir);
1.1299 - tmp = operand + operand2;
1.1300 - tmp2 = tmp + armr.c ? 1 : 0;
1.1302 - if( RDn(ir) == 15 ) {
1.1306 - armr.z = (tmp == 0 );
1.1307 - armr.c = IS_CARRY(tmp,operand,operand2) ||
1.1309 - armr.v = IS_ADDOVERFLOW(tmp,operand, operand2) ||
1.1310 - ((tmp&0x80000000) != (tmp2&0x80000000));
1.1314 - LRD(ir) = RN(ir) - arm_get_shift_operand(ir) -
1.1319 - operand2 = arm_get_shift_operand(ir);
1.1320 - tmp = operand - operand2;
1.1321 - tmp2 = tmp - (armr.c ? 0 : 1);
1.1322 - if( RDn(ir) == 15 ) {
1.1326 - armr.z = (tmp == 0 );
1.1327 - armr.c = IS_NOTBORROW(tmp,operand,operand2) &&
1.1329 - armr.v = IS_SUBOVERFLOW(tmp,operand,operand2) ||
1.1330 - ((tmp&0x80000000) != (tmp2&0x80000000));
1.1334 - LRD(ir) = arm_get_shift_operand(ir) - RN(ir) -
1.1338 - operand = arm_get_shift_operand(ir);
1.1340 - tmp = operand - operand2;
1.1341 - tmp2 = tmp - (armr.c ? 0 : 1);
1.1342 - if( RDn(ir) == 15 ) {
1.1346 - armr.z = (tmp == 0 );
1.1347 - armr.c = IS_NOTBORROW(tmp,operand,operand2) &&
1.1349 - armr.v = IS_SUBOVERFLOW(tmp,operand,operand2) ||
1.1350 - ((tmp&0x80000000) != (tmp2&0x80000000));
1.1353 - case 17: /* TST Rn, operand */
1.1354 - operand = arm_get_shift_operand_s(ir) & RN(ir);
1.1355 - armr.n = operand>>31;
1.1356 - armr.z = (operand == 0);
1.1357 - armr.c = armr.shift_c;
1.1359 - case 19: /* TEQ Rn, operand */
1.1360 - operand = arm_get_shift_operand_s(ir) ^ RN(ir);
1.1361 - armr.n = operand>>31;
1.1362 - armr.z = (operand == 0);
1.1363 - armr.c = armr.shift_c;
1.1365 - case 21: /* CMP Rn, operand */
1.1367 - operand2 = arm_get_shift_operand(ir);
1.1368 - tmp = operand - operand2;
1.1371 - armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.1372 - armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.1374 - case 23: /* CMN Rn, operand */
1.1376 - operand2 = arm_get_shift_operand(ir);
1.1377 - tmp = operand + operand2;
1.1380 - armr.c = IS_CARRY(tmp,operand,operand2);
1.1381 - armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
1.1383 - case 24: /* ORR Rd, Rn, operand */
1.1384 - LRD(ir) = RN(ir) | arm_get_shift_operand(ir);
1.1386 - case 25: /* ORRS Rd, Rn, operand */
1.1387 - operand = arm_get_shift_operand_s(ir) | RN(ir);
1.1389 - if( RDn(ir) == 15 ) {
1.1392 - armr.n = operand>>31;
1.1393 - armr.z = (operand == 0);
1.1394 - armr.c = armr.shift_c;
1.1397 - case 26: /* MOV Rd, operand */
1.1398 - LRD(ir) = arm_get_shift_operand(ir);
1.1400 - case 27: /* MOVS Rd, operand */
1.1401 - operand = arm_get_shift_operand_s(ir);
1.1403 - if( RDn(ir) == 15 ) {
1.1406 - armr.n = operand>>31;
1.1407 - armr.z = (operand == 0);
1.1408 - armr.c = armr.shift_c;
1.1411 - case 28: /* BIC Rd, Rn, operand */
1.1412 - LRD(ir) = RN(ir) & (~arm_get_shift_operand(ir));
1.1414 - case 29: /* BICS Rd, Rn, operand */
1.1415 - operand = RN(ir) & (~arm_get_shift_operand_s(ir));
1.1417 - if( RDn(ir) == 15 ) {
1.1420 - armr.n = operand>>31;
1.1421 - armr.z = (operand == 0);
1.1422 - armr.c = armr.shift_c;
1.1425 - case 30: /* MVN Rd, operand */
1.1426 - LRD(ir) = ~arm_get_shift_operand(ir);
1.1428 - case 31: /* MVNS Rd, operand */
1.1429 - operand = ~arm_get_shift_operand_s(ir);
1.1431 - if( RDn(ir) == 15 ) {
1.1434 - armr.n = operand>>31;
1.1435 - armr.z = (operand == 0);
1.1436 - armr.c = armr.shift_c;
1.1444 - case 1: /* Load/store */
1.1445 - operand = arm_get_address_operand(ir);
1.1446 - switch( (ir>>20)&0x17 ) {
1.1447 - case 0: case 16: case 18: /* STR Rd, address */
1.1448 - arm_write_long( operand, RD(ir) );
1.1450 - case 1: case 17: case 19: /* LDR Rd, address */
1.1451 - LRD(ir) = arm_read_long(operand);
1.1453 - case 2: /* STRT Rd, address */
1.1454 - arm_write_long_user( operand, RD(ir) );
1.1456 - case 3: /* LDRT Rd, address */
1.1457 - LRD(ir) = arm_read_long_user( operand );
1.1459 - case 4: case 20: case 22: /* STRB Rd, address */
1.1460 - arm_write_byte( operand, RD(ir) );
1.1462 - case 5: case 21: case 23: /* LDRB Rd, address */
1.1463 - LRD(ir) = arm_read_byte( operand );
1.1465 - case 6: /* STRBT Rd, address */
1.1466 - arm_write_byte_user( operand, RD(ir) );
1.1468 - case 7: /* LDRBT Rd, address */
1.1469 - LRD(ir) = arm_read_byte_user( operand );
1.1473 - case 2: /* Load/store multiple, branch*/
1.1474 - if( (ir & 0x02000000) == 0x02000000 ) { /* B[L] imm24 */
1.1475 - operand = (SIGNEXT24(ir&0x00FFFFFF) << 2);
1.1476 - if( (ir & 0x01000000) == 0x01000000 ) {
1.1477 - armr.r[14] = pc; /* BL */
1.1479 - armr.r[15] = pc + 4 + operand;
1.1480 - } else { /* Load/store multiple */
1.1481 - gboolean needRestore = FALSE;
1.1484 - switch( (ir & 0x01D00000) >> 20 ) {
1.1487 - arm_write_long( operand, armr.r[15]+4 );
1.1490 - for( i=14; i>= 0; i-- ) {
1.1491 - if( (ir & (1<<i)) ) {
1.1492 - arm_write_long( operand, armr.r[i] );
1.1498 - for( i=15; i>= 0; i-- ) {
1.1499 - if( (ir & (1<<i)) ) {
1.1500 - armr.r[i] = arm_read_long( operand );
1.1505 - case 4: /* STMDA (S) */
1.1507 - arm_write_long( operand, armr.r[15]+4 );
1.1510 - for( i=14; i>= 0; i-- ) {
1.1511 - if( (ir & (1<<i)) ) {
1.1512 - arm_write_long( operand, USER_R(i) );
1.1517 - case 5: /* LDMDA (S) */
1.1518 - if( (ir&0x00008000) ) { /* Load PC */
1.1519 - for( i=15; i>= 0; i-- ) {
1.1520 - if( (ir & (1<<i)) ) {
1.1521 - armr.r[i] = arm_read_long( operand );
1.1527 - for( i=15; i>= 0; i-- ) {
1.1528 - if( (ir & (1<<i)) ) {
1.1529 - USER_R(i) = arm_read_long( operand );
1.1536 - for( i=0; i< 15; i++ ) {
1.1537 - if( (ir & (1<<i)) ) {
1.1538 - arm_write_long( operand, armr.r[i] );
1.1543 - arm_write_long( operand, armr.r[15]+4 );
1.1548 - for( i=0; i< 16; i++ ) {
1.1549 - if( (ir & (1<<i)) ) {
1.1550 - armr.r[i] = arm_read_long( operand );
1.1555 - case 12: /* STMIA (S) */
1.1556 - for( i=0; i< 15; i++ ) {
1.1557 - if( (ir & (1<<i)) ) {
1.1558 - arm_write_long( operand, USER_R(i) );
1.1563 - arm_write_long( operand, armr.r[15]+4 );
1.1567 - case 13: /* LDMIA (S) */
1.1568 - if( (ir&0x00008000) ) { /* Load PC */
1.1569 - for( i=0; i < 16; i++ ) {
1.1570 - if( (ir & (1<<i)) ) {
1.1571 - armr.r[i] = arm_read_long( operand );
1.1577 - for( i=0; i < 16; i++ ) {
1.1578 - if( (ir & (1<<i)) ) {
1.1579 - USER_R(i) = arm_read_long( operand );
1.1588 - arm_write_long( operand, armr.r[15]+4 );
1.1590 - for( i=14; i>= 0; i-- ) {
1.1591 - if( (ir & (1<<i)) ) {
1.1593 - arm_write_long( operand, armr.r[i] );
1.1598 - for( i=15; i>= 0; i-- ) {
1.1599 - if( (ir & (1<<i)) ) {
1.1601 - armr.r[i] = arm_read_long( operand );
1.1605 - case 20: /* STMDB (S) */
1.1608 - arm_write_long( operand, armr.r[15]+4 );
1.1610 - for( i=14; i>= 0; i-- ) {
1.1611 - if( (ir & (1<<i)) ) {
1.1613 - arm_write_long( operand, USER_R(i) );
1.1617 - case 21: /* LDMDB (S) */
1.1618 - if( (ir&0x00008000) ) { /* Load PC */
1.1619 - for( i=15; i>= 0; i-- ) {
1.1620 - if( (ir & (1<<i)) ) {
1.1622 - armr.r[i] = arm_read_long( operand );
1.1627 - for( i=15; i>= 0; i-- ) {
1.1628 - if( (ir & (1<<i)) ) {
1.1630 - USER_R(i) = arm_read_long( operand );
1.1636 - for( i=0; i< 15; i++ ) {
1.1637 - if( (ir & (1<<i)) ) {
1.1639 - arm_write_long( operand, armr.r[i] );
1.1644 - arm_write_long( operand, armr.r[15]+4 );
1.1648 - for( i=0; i< 16; i++ ) {
1.1649 - if( (ir & (1<<i)) ) {
1.1651 - armr.r[i] = arm_read_long( operand );
1.1655 - case 28: /* STMIB (S) */
1.1656 - for( i=0; i< 15; i++ ) {
1.1657 - if( (ir & (1<<i)) ) {
1.1659 - arm_write_long( operand, USER_R(i) );
1.1664 - arm_write_long( operand, armr.r[15]+4 );
1.1667 - case 29: /* LDMIB (S) */
1.1668 - if( (ir&0x00008000) ) { /* Load PC */
1.1669 - for( i=0; i < 16; i++ ) {
1.1670 - if( (ir & (1<<i)) ) {
1.1672 - armr.r[i] = arm_read_long( operand );
1.1677 - for( i=0; i < 16; i++ ) {
1.1678 - if( (ir & (1<<i)) ) {
1.1680 - USER_R(i) = arm_read_long( operand );
1.1694 - if( (ir & 0x0F000000) == 0x0F000000 ) { /* SWI */
1.1695 - arm_raise_exception( EXC_SOFTWARE );
1.1702 + case 0: /* AND Rd, Rn, operand */
1.1703 + LRD(ir) = RN(ir) & arm_get_shift_operand(ir);
1.1705 + case 1: /* ANDS Rd, Rn, operand */
1.1706 + operand = arm_get_shift_operand_s(ir) & RN(ir);
1.1708 + if( RDn(ir) == 15 ) {
1.1711 + armr.n = operand>>31;
1.1712 + armr.z = (operand == 0);
1.1713 + armr.c = armr.shift_c;
1.1716 + case 2: /* EOR Rd, Rn, operand */
1.1717 + LRD(ir) = RN(ir) ^ arm_get_shift_operand(ir);
1.1719 + case 3: /* EORS Rd, Rn, operand */
1.1720 + operand = arm_get_shift_operand_s(ir) ^ RN(ir);
1.1722 + if( RDn(ir) == 15 ) {
1.1725 + armr.n = operand>>31;
1.1726 + armr.z = (operand == 0);
1.1727 + armr.c = armr.shift_c;
1.1730 + case 4: /* SUB Rd, Rn, operand */
1.1731 + LRD(ir) = RN(ir) - arm_get_shift_operand(ir);
1.1733 + case 5: /* SUBS Rd, Rn, operand */
1.1735 + operand2 = arm_get_shift_operand(ir);
1.1736 + tmp = operand - operand2;
1.1738 + if( RDn(ir) == 15 ) {
1.1743 + armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.1744 + armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.1747 + case 6: /* RSB Rd, operand, Rn */
1.1748 + LRD(ir) = arm_get_shift_operand(ir) - RN(ir);
1.1750 + case 7: /* RSBS Rd, operand, Rn */
1.1751 + operand = arm_get_shift_operand(ir);
1.1753 + tmp = operand - operand2;
1.1755 + if( RDn(ir) == 15 ) {
1.1760 + armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.1761 + armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.1764 + case 8: /* ADD Rd, Rn, operand */
1.1765 + LRD(ir) = RN(ir) + arm_get_shift_operand(ir);
1.1767 + case 9: /* ADDS Rd, Rn, operand */
1.1768 + operand = arm_get_shift_operand(ir);
1.1770 + tmp = operand + operand2;
1.1772 + if( RDn(ir) == 15 ) {
1.1777 + armr.c = IS_CARRY(tmp,operand,operand2);
1.1778 + armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
1.1782 + LRD(ir) = RN(ir) + arm_get_shift_operand(ir) +
1.1786 + operand = arm_get_shift_operand(ir);
1.1788 + tmp = operand + operand2;
1.1789 + tmp2 = tmp + armr.c ? 1 : 0;
1.1791 + if( RDn(ir) == 15 ) {
1.1795 + armr.z = (tmp == 0 );
1.1796 + armr.c = IS_CARRY(tmp,operand,operand2) ||
1.1798 + armr.v = IS_ADDOVERFLOW(tmp,operand, operand2) ||
1.1799 + ((tmp&0x80000000) != (tmp2&0x80000000));
1.1803 + LRD(ir) = RN(ir) - arm_get_shift_operand(ir) -
1.1808 + operand2 = arm_get_shift_operand(ir);
1.1809 + tmp = operand - operand2;
1.1810 + tmp2 = tmp - (armr.c ? 0 : 1);
1.1811 + if( RDn(ir) == 15 ) {
1.1815 + armr.z = (tmp == 0 );
1.1816 + armr.c = IS_NOTBORROW(tmp,operand,operand2) &&
1.1818 + armr.v = IS_SUBOVERFLOW(tmp,operand,operand2) ||
1.1819 + ((tmp&0x80000000) != (tmp2&0x80000000));
1.1823 + LRD(ir) = arm_get_shift_operand(ir) - RN(ir) -
1.1827 + operand = arm_get_shift_operand(ir);
1.1829 + tmp = operand - operand2;
1.1830 + tmp2 = tmp - (armr.c ? 0 : 1);
1.1831 + if( RDn(ir) == 15 ) {
1.1835 + armr.z = (tmp == 0 );
1.1836 + armr.c = IS_NOTBORROW(tmp,operand,operand2) &&
1.1838 + armr.v = IS_SUBOVERFLOW(tmp,operand,operand2) ||
1.1839 + ((tmp&0x80000000) != (tmp2&0x80000000));
1.1842 + case 17: /* TST Rn, operand */
1.1843 + operand = arm_get_shift_operand_s(ir) & RN(ir);
1.1844 + armr.n = operand>>31;
1.1845 + armr.z = (operand == 0);
1.1846 + armr.c = armr.shift_c;
1.1848 + case 19: /* TEQ Rn, operand */
1.1849 + operand = arm_get_shift_operand_s(ir) ^ RN(ir);
1.1850 + armr.n = operand>>31;
1.1851 + armr.z = (operand == 0);
1.1852 + armr.c = armr.shift_c;
1.1854 + case 21: /* CMP Rn, operand */
1.1856 + operand2 = arm_get_shift_operand(ir);
1.1857 + tmp = operand - operand2;
1.1860 + armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.1861 + armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.1863 + case 23: /* CMN Rn, operand */
1.1865 + operand2 = arm_get_shift_operand(ir);
1.1866 + tmp = operand + operand2;
1.1869 + armr.c = IS_CARRY(tmp,operand,operand2);
1.1870 + armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
1.1872 + case 24: /* ORR Rd, Rn, operand */
1.1873 + LRD(ir) = RN(ir) | arm_get_shift_operand(ir);
1.1875 + case 25: /* ORRS Rd, Rn, operand */
1.1876 + operand = arm_get_shift_operand_s(ir) | RN(ir);
1.1878 + if( RDn(ir) == 15 ) {
1.1881 + armr.n = operand>>31;
1.1882 + armr.z = (operand == 0);
1.1883 + armr.c = armr.shift_c;
1.1886 + case 26: /* MOV Rd, operand */
1.1887 + LRD(ir) = arm_get_shift_operand(ir);
1.1889 + case 27: /* MOVS Rd, operand */
1.1890 + operand = arm_get_shift_operand_s(ir);
1.1892 + if( RDn(ir) == 15 ) {
1.1895 + armr.n = operand>>31;
1.1896 + armr.z = (operand == 0);
1.1897 + armr.c = armr.shift_c;
1.1900 + case 28: /* BIC Rd, Rn, operand */
1.1901 + LRD(ir) = RN(ir) & (~arm_get_shift_operand(ir));
1.1903 + case 29: /* BICS Rd, Rn, operand */
1.1904 + operand = RN(ir) & (~arm_get_shift_operand_s(ir));
1.1906 + if( RDn(ir) == 15 ) {
1.1909 + armr.n = operand>>31;
1.1910 + armr.z = (operand == 0);
1.1911 + armr.c = armr.shift_c;
1.1914 + case 30: /* MVN Rd, operand */
1.1915 + LRD(ir) = ~arm_get_shift_operand(ir);
1.1917 + case 31: /* MVNS Rd, operand */
1.1918 + operand = ~arm_get_shift_operand_s(ir);
1.1920 + if( RDn(ir) == 15 ) {
1.1923 + armr.n = operand>>31;
1.1924 + armr.z = (operand == 0);
1.1925 + armr.c = armr.shift_c;
1.1933 + case 1: /* Load/store */
1.1934 + operand = arm_get_address_operand(ir);
1.1935 + switch( (ir>>20)&0x17 ) {
1.1936 + case 0: case 16: case 18: /* STR Rd, address */
1.1937 + arm_write_long( operand, RD(ir) );
1.1939 + case 1: case 17: case 19: /* LDR Rd, address */
1.1940 + LRD(ir) = arm_read_long(operand);
1.1942 + case 2: /* STRT Rd, address */
1.1943 + arm_write_long_user( operand, RD(ir) );
1.1945 + case 3: /* LDRT Rd, address */
1.1946 + LRD(ir) = arm_read_long_user( operand );
1.1948 + case 4: case 20: case 22: /* STRB Rd, address */
1.1949 + arm_write_byte( operand, RD(ir) );
1.1951 + case 5: case 21: case 23: /* LDRB Rd, address */
1.1952 + LRD(ir) = arm_read_byte( operand );
1.1954 + case 6: /* STRBT Rd, address */
1.1955 + arm_write_byte_user( operand, RD(ir) );
1.1957 + case 7: /* LDRBT Rd, address */
1.1958 + LRD(ir) = arm_read_byte_user( operand );
1.1962 + case 2: /* Load/store multiple, branch*/
1.1963 + if( (ir & 0x02000000) == 0x02000000 ) { /* B[L] imm24 */
1.1964 + operand = (SIGNEXT24(ir&0x00FFFFFF) << 2);
1.1965 + if( (ir & 0x01000000) == 0x01000000 ) {
1.1966 + armr.r[14] = pc; /* BL */
1.1968 + armr.r[15] = pc + 4 + operand;
1.1969 + } else { /* Load/store multiple */
1.1970 + gboolean needRestore = FALSE;
1.1973 + switch( (ir & 0x01D00000) >> 20 ) {
1.1976 + arm_write_long( operand, armr.r[15]+4 );
1.1979 + for( i=14; i>= 0; i-- ) {
1.1980 + if( (ir & (1<<i)) ) {
1.1981 + arm_write_long( operand, armr.r[i] );
1.1987 + for( i=15; i>= 0; i-- ) {
1.1988 + if( (ir & (1<<i)) ) {
1.1989 + armr.r[i] = arm_read_long( operand );
1.1994 + case 4: /* STMDA (S) */
1.1996 + arm_write_long( operand, armr.r[15]+4 );
1.1999 + for( i=14; i>= 0; i-- ) {
1.2000 + if( (ir & (1<<i)) ) {
1.2001 + arm_write_long( operand, USER_R(i) );
1.2006 + case 5: /* LDMDA (S) */
1.2007 + if( (ir&0x00008000) ) { /* Load PC */
1.2008 + for( i=15; i>= 0; i-- ) {
1.2009 + if( (ir & (1<<i)) ) {
1.2010 + armr.r[i] = arm_read_long( operand );
1.2016 + for( i=15; i>= 0; i-- ) {
1.2017 + if( (ir & (1<<i)) ) {
1.2018 + USER_R(i) = arm_read_long( operand );
1.2025 + for( i=0; i< 15; i++ ) {
1.2026 + if( (ir & (1<<i)) ) {
1.2027 + arm_write_long( operand, armr.r[i] );
1.2032 + arm_write_long( operand, armr.r[15]+4 );
1.2037 + for( i=0; i< 16; i++ ) {
1.2038 + if( (ir & (1<<i)) ) {
1.2039 + armr.r[i] = arm_read_long( operand );
1.2044 + case 12: /* STMIA (S) */
1.2045 + for( i=0; i< 15; i++ ) {
1.2046 + if( (ir & (1<<i)) ) {
1.2047 + arm_write_long( operand, USER_R(i) );
1.2052 + arm_write_long( operand, armr.r[15]+4 );
1.2056 + case 13: /* LDMIA (S) */
1.2057 + if( (ir&0x00008000) ) { /* Load PC */
1.2058 + for( i=0; i < 16; i++ ) {
1.2059 + if( (ir & (1<<i)) ) {
1.2060 + armr.r[i] = arm_read_long( operand );
1.2066 + for( i=0; i < 16; i++ ) {
1.2067 + if( (ir & (1<<i)) ) {
1.2068 + USER_R(i) = arm_read_long( operand );
1.2077 + arm_write_long( operand, armr.r[15]+4 );
1.2079 + for( i=14; i>= 0; i-- ) {
1.2080 + if( (ir & (1<<i)) ) {
1.2082 + arm_write_long( operand, armr.r[i] );
1.2087 + for( i=15; i>= 0; i-- ) {
1.2088 + if( (ir & (1<<i)) ) {
1.2090 + armr.r[i] = arm_read_long( operand );
1.2094 + case 20: /* STMDB (S) */
1.2097 + arm_write_long( operand, armr.r[15]+4 );
1.2099 + for( i=14; i>= 0; i-- ) {
1.2100 + if( (ir & (1<<i)) ) {
1.2102 + arm_write_long( operand, USER_R(i) );
1.2106 + case 21: /* LDMDB (S) */
1.2107 + if( (ir&0x00008000) ) { /* Load PC */
1.2108 + for( i=15; i>= 0; i-- ) {
1.2109 + if( (ir & (1<<i)) ) {
1.2111 + armr.r[i] = arm_read_long( operand );
1.2116 + for( i=15; i>= 0; i-- ) {
1.2117 + if( (ir & (1<<i)) ) {
1.2119 + USER_R(i) = arm_read_long( operand );
1.2125 + for( i=0; i< 15; i++ ) {
1.2126 + if( (ir & (1<<i)) ) {
1.2128 + arm_write_long( operand, armr.r[i] );
1.2133 + arm_write_long( operand, armr.r[15]+4 );
1.2137 + for( i=0; i< 16; i++ ) {
1.2138 + if( (ir & (1<<i)) ) {
1.2140 + armr.r[i] = arm_read_long( operand );
1.2144 + case 28: /* STMIB (S) */
1.2145 + for( i=0; i< 15; i++ ) {
1.2146 + if( (ir & (1<<i)) ) {
1.2148 + arm_write_long( operand, USER_R(i) );
1.2153 + arm_write_long( operand, armr.r[15]+4 );
1.2156 + case 29: /* LDMIB (S) */
1.2157 + if( (ir&0x00008000) ) { /* Load PC */
1.2158 + for( i=0; i < 16; i++ ) {
1.2159 + if( (ir & (1<<i)) ) {
1.2161 + armr.r[i] = arm_read_long( operand );
1.2166 + for( i=0; i < 16; i++ ) {
1.2167 + if( (ir & (1<<i)) ) {
1.2169 + USER_R(i) = arm_read_long( operand );
1.2183 + if( (ir & 0x0F000000) == 0x0F000000 ) { /* SWI */
1.2184 + arm_raise_exception( EXC_SOFTWARE );
1.2193 if( armr.r[15] >= 0x00200000 ) {
1.2194 - armr.running = FALSE;
1.2195 - WARN( "ARM Halted: BRANCH to invalid address %08X at %08X", armr.r[15], pc );
1.2197 + armr.running = FALSE;
1.2198 + WARN( "ARM Halted: BRANCH to invalid address %08X at %08X", armr.r[15], pc );