revision 5:d85c2e81ce2d
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 5:d85c2e81ce2d |
parent | 4:7d6f596ce577 |
child | 6:6e3663e58565 |
author | nkeynes |
date | Sat Oct 02 05:49:23 2004 +0000 (19 years ago) |
More work on the arm core
1.1 --- a/src/aica/armcore.c Sat Oct 02 05:49:12 2004 +00001.2 +++ b/src/aica/armcore.c Sat Oct 02 05:49:23 2004 +00001.3 @@ -3,7 +3,8 @@1.5 struct arm_registers armr;1.7 -/* NB: The arm (one assumes) has a different memory map, but for the meantime... */1.8 +/* NB: The arm has a different memory map, but for the meantime... */1.9 +/* Page references are as per ARM DDI 0100E (June 2000) */1.11 #define MEM_READ_BYTE( addr ) mem_read_byte(addr)1.12 #define MEM_READ_WORD( addr ) mem_read_word(addr)1.13 @@ -12,20 +13,635 @@1.14 #define MEM_WRITE_WORD( addr, val ) mem_write_word(addr, val)1.15 #define MEM_WRITE_LONG( addr, val ) mem_write_long(addr, val)1.17 +1.18 +#define IS_NOTBORROW( result, op1, op2 ) (op2 > op1 ? 0 : 1)1.19 +#define IS_CARRY( result, op1, op2 ) (result < op1 ? 1 : 0)1.20 +#define IS_SUBOVERFLOW( result, op1, op2 ) (((op1^op2) & (result^op1)) >> 31)1.21 +#define IS_ADDOVERFLOW( result, op1, op2 ) (((op1&op2) & (result^op1)) >> 31)1.22 +1.23 #define PC armr.r[15];1.25 +/* Instruction fields */1.26 +#define COND(ir) (ir>>28)1.27 +#define GRP(ir) ((ir>>26)&0x03)1.28 +#define OPCODE(ir) ((ir>>20)&0x1F)1.29 +#define IFLAG(ir) (ir&0x02000000)1.30 +#define SFLAG(ir) (ir&0x00100000)1.31 +#define PFLAG(ir) (ir&0x01000000)1.32 +#define UFLAG(ir) (ir&0x00800000)1.33 +#define BFLAG(ir) (ir&0x00400000)1.34 +#define WFLAG(ir) (IR&0x00200000)1.35 +#define LFLAG(ir) SFLAG(ir)1.36 +#define RN(ir) (armr.r[((ir>>16)&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))1.37 +#define RD(ir) (armr.r[((ir>>12)&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))1.38 +#define RDn(ir) ((ir>>12)&0x0F)1.39 +#define RS(ir) (armr.r[((ir>>8)&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))1.40 +#define RM(ir) (armr.r[(ir&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))1.41 +#define LRN(ir) armr.r[((ir>>16)&0x0F)]1.42 +#define LRD(ir) armr.r[((ir>>12)&0x0F)]1.43 +#define LRS(ir) armr.r[((ir>>8)&0x0F)]1.44 +#define LRM(ir) armr.r[(ir&0x0F)]1.45 +1.46 +#define IMM8(ir) (ir&0xFF)1.47 +#define IMM12(ir) (ir&0xFFF)1.48 +#define SHIFTIMM(ir) ((ir>>7)0x1F)1.49 +#define IMMROT(ir) ((ir>>7)&1E)1.50 +#define SHIFT(ir) ((ir>>4)&0x07)1.51 +#define DISP24(ir) ((ir&0x00FFFFFF))1.52 +1.53 +static uint32_t arm_get_shift_operand( uint32_t ir )1.54 +{1.55 + uint32_t operand, tmp;1.56 + if( IFLAG(ir) == 0 ) {1.57 + operand = RM(ir);1.58 + switch(SHIFT(ir)) {1.59 + case 0: /* (Rm << imm) */1.60 + operand = operand << SHIFTIMM(ir);1.61 + break;1.62 + case 1: /* (Rm << Rs) */1.63 + tmp = RS(ir)&0xFF;1.64 + if( tmp > 31 ) operand = 0;1.65 + else operand = operand << tmp;1.66 + break;1.67 + case 2: /* (Rm >> imm) */1.68 + operand = operand >> SHIFTIMM(ir);1.69 + break;1.70 + case 3: /* (Rm >> Rs) */1.71 + tmp = RS(ir) & 0xFF;1.72 + if( tmp > 31 ) operand = 0;1.73 + else operand = operand >> ir;1.74 + break;1.75 + case 4: /* (Rm >>> imm) */1.76 + tmp = SHIFTIMM(ir);1.77 + if( tmp == 0 ) operand = ((int32_t)operand) >> 31;1.78 + else operand = ((int32_t)operand) >> tmp;1.79 + break;1.80 + case 5: /* (Rm >>> Rs) */1.81 + tmp = RS(ir) & 0xFF;1.82 + if( tmp > 31 ) operand = ((int32_t)operand) >> 31;1.83 + else operand = ((int32_t)operand) >> tmp;1.84 + break;1.85 + case 6:1.86 + tmp = SHIFTIMM(ir);1.87 + if( tmp == 0 ) /* RRX aka rotate with carry */1.88 + operand = (operand >> 1) | (arm4.c<<31);1.89 + else1.90 + operand = ROTATE_RIGHT_LONG(operand,tmp);1.91 + break;1.92 + case 7:1.93 + tmp = RS(ir)&0x1F;1.94 + operand = ROTATE_RIGHT_LONG(operand,tmp);1.95 + break;1.96 + }1.97 + } else {1.98 + operand = IMM8(ir);1.99 + tmp = IMMROT(ir);1.100 + operand = ROTATE_RIGHT_LONG(operand, tmp);1.101 + }1.102 + return operand;1.103 +}1.104 +1.105 +/**1.106 + * Compute the "shift operand" of the instruction for the data processing1.107 + * instructions. This variant also sets armr.shift_c (carry result for shifter)1.108 + * Reason for the variants is that most cases don't actually need the shift_c.1.109 + */1.110 +static uint32_t arm_get_shift_operand_s( uint32_t ir )1.111 +{1.112 + uint32_t operand, tmp;1.113 + if( IFLAG(ir) == 0 ) {1.114 + operand = RM(ir);1.115 + switch(SHIFT(ir)) {1.116 + case 0: /* (Rm << imm) */1.117 + tmp = SHIFTIMM(ir);1.118 + if( tmp == 0 ) { /* Rm */1.119 + armr.shift_c = armr.c;1.120 + } else { /* Rm << imm */1.121 + armr.shift_c = (operand >> (32-tmp)) & 0x01;1.122 + operand = operand << tmp;1.123 + }1.124 + break;1.125 + case 1: /* (Rm << Rs) */1.126 + tmp = RS(ir)&0xFF;1.127 + if( tmp == 0 ) {1.128 + armr.shift_c = armr.c;1.129 + } else {1.130 + if( tmp <= 32 )1.131 + armr.shift_c = (operand >> (32-tmp)) & 0x01;1.132 + else armr.shift_c = 0;1.133 + if( tmp < 32 )1.134 + operand = operand << tmp;1.135 + else operand = 0;1.136 + }1.137 + break;1.138 + case 2: /* (Rm >> imm) */1.139 + tmp = SHIFTIMM(ir);1.140 + if( tmp == 0 ) {1.141 + armr.shift_c = operand >> 31;1.142 + operand = 0;1.143 + } else {1.144 + armr.shift_c = (operand >> (tmp-1)) & 0x01;1.145 + operand = RM(ir) >> tmp;1.146 + }1.147 + break;1.148 + case 3: /* (Rm >> Rs) */1.149 + tmp = RS(ir) & 0xFF;1.150 + if( tmp == 0 ) {1.151 + armr.shift_c = armr.c;1.152 + } else {1.153 + if( tmp <= 32 )1.154 + armr.shift_c = (operand >> (tmp-1))&0x01;1.155 + else armr.shift_c = 0;1.156 + if( tmp < 32 )1.157 + operand = operand >> tmp;1.158 + else operand = 0;1.159 + }1.160 + break;1.161 + case 4: /* (Rm >>> imm) */1.162 + tmp = SHIFTIMM(ir);1.163 + if( tmp == 0 ) {1.164 + armr.shift_c = operand >> 31;1.165 + operand = -armr.shift_c;1.166 + } else {1.167 + armr.shift_c = (operand >> (tmp-1)) & 0x01;1.168 + operand = ((int32_t)operand) >> tmp;1.169 + }1.170 + break;1.171 + case 5: /* (Rm >>> Rs) */1.172 + tmp = RS(ir) & 0xFF;1.173 + if( tmp == 0 ) {1.174 + armr.shift_c = armr.c;1.175 + } else {1.176 + if( tmp < 32 ) {1.177 + armr.shift_c = (operand >> (tmp-1))&0x01;1.178 + operand = ((int32_t)operand) >> tmp;1.179 + } else {1.180 + armr.shift_c = operand >> 31;1.181 + operand = ((int32_t)operand) >> 31;1.182 + }1.183 + }1.184 + break;1.185 + case 6:1.186 + tmp = SHIFTIMM(ir);1.187 + if( tmp == 0 ) { /* RRX aka rotate with carry */1.188 + armr.shift_c = operand&0x01;1.189 + operand = (operand >> 1) | (arm4.c<<31);1.190 + } else {1.191 + armr.shift_c = operand>>(tmp-1);1.192 + operand = ROTATE_RIGHT_LONG(operand,tmp);1.193 + }1.194 + break;1.195 + case 7:1.196 + tmp = RS(ir)&0xFF;1.197 + if( tmp == 0 ) {1.198 + armr.shift_c = armr.c;1.199 + } else {1.200 + tmp &= 0x1F;1.201 + if( tmp == 0 ) {1.202 + armr.shift_c = operand>>31;1.203 + } else {1.204 + armr.shift_c = (operand>>(tmp-1))&0x1;1.205 + operand = ROTATE_RIGHT_LONG(operand,tmp);1.206 + }1.207 + }1.208 + break;1.209 + }1.210 + } else {1.211 + operand = IMM8(ir);1.212 + tmp = IMMROT(ir);1.213 + if( tmp == 0 ) {1.214 + armr.shift_c = armr.c;1.215 + } else {1.216 + operand = ROTATE_RIGHT_LONG(operand, tmp);1.217 + armr.shift_c = operand>>31;1.218 + }1.219 + }1.220 + return operand;1.221 +}1.222 +1.223 +/**1.224 + * Another variant of the shifter code for index-based memory addressing.1.225 + * Distinguished by the fact that it doesn't support register shifts, and1.226 + * ignores the I flag (WTF do the load/store instructions use the I flag to1.227 + * mean the _exact opposite_ of what it means for the data processing1.228 + * instructions ???)1.229 + */1.230 +static uint32_t arm_get_address_index( uint32_t ir )1.231 +{1.232 + uint32_t operand = RM(ir);1.233 + switch(SHIFT(ir)) {1.234 + case 0: /* (Rm << imm) */1.235 + operand = operand << SHIFTIMM(ir);1.236 + break;1.237 + case 2: /* (Rm >> imm) */1.238 + operand = operand >> SHIFTIMM(ir);1.239 + break;1.240 + case 4: /* (Rm >>> imm) */1.241 + tmp = SHIFTIMM(ir);1.242 + if( tmp == 0 ) operand = ((int32_t)operand) >> 31;1.243 + else operand = ((int32_t)operand) >> tmp;1.244 + break;1.245 + case 6:1.246 + tmp = SHIFTIMM(ir);1.247 + if( tmp == 0 ) /* RRX aka rotate with carry */1.248 + operand = (operand >> 1) | (arm4.c<<31);1.249 + else1.250 + operand = ROTATE_RIGHT_LONG(operand,tmp);1.251 + break;1.252 + default: UNIMP(ir);1.253 + }1.254 + return operand;1.255 +}1.256 +1.257 +static uint32_t arm_get_address_operand( uint32_t ir )1.258 +{1.259 + uint32_t addr;1.260 +1.261 + /* I P U . W */1.262 + switch( (ir>>21)&0x1D ) {1.263 + case 0: /* Rn -= imm offset (post-indexed) [5.2.8 A5-28] */1.264 + case 1:1.265 + addr = RN(ir);1.266 + RN(ir) = addr - IMM12(ir);1.267 + break;1.268 + case 4: /* Rn += imm offsett (post-indexed) [5.2.8 A5-28] */1.269 + case 5:1.270 + addr = RN(ir);1.271 + RN(ir) = addr + IMM12(ir);1.272 + break;1.273 + case 8: /* Rn - imm offset [5.2.2 A5-20] */1.274 + addr = RN(ir) - IMM12(ir);1.275 + break;1.276 + case 9: /* Rn -= imm offset (pre-indexed) [5.2.5 A5-24] */1.277 + addr = RN(ir) - IMM12(ir);1.278 + RN(ir) = addr;1.279 + break;1.280 + case 12: /* Rn + imm offset [5.2.2 A5-20] */1.281 + addr = RN(ir) + IMM12(ir);1.282 + break;1.283 + case 13: /* Rn += imm offset [5.2.5 A5-24 ] */1.284 + addr = RN(ir) + IMM12(ir);1.285 + RN(ir) = addr;1.286 + break;1.287 + case 16: /* Rn -= Rm (post-indexed) [5.2.10 A5-32 ] */1.288 + case 17:1.289 + addr = RN(ir);1.290 + RN(ir) = addr - arm_get_address_index(ir);1.291 + break;1.292 + case 20: /* Rn += Rm (post-indexed) [5.2.10 A5-32 ] */1.293 + case 21:1.294 + addr = RN(ir);1.295 + RN(ir) = addr - arm_get_address_index(ir);1.296 + break;1.297 + case 24: /* Rn - Rm [5.2.4 A5-23] */1.298 + addr = RN(ir) - arm_get_address_index(ir);1.299 + break;1.300 + case 25: /* RN -= Rm (pre-indexed) [5.2.7 A5-26] */1.301 + addr = RN(ir) - arm_get_address_index(ir);1.302 + RN(ir) = addr;1.303 + break;1.304 + case 28: /* Rn + Rm [5.2.4 A5-23] */1.305 + addr = RN(ir) + arm_get_address_index(ir);1.306 + break;1.307 + case 29: /* RN += Rm (pre-indexed) [5.2.7 A5-26] */1.308 + addr = RN(ir) + arm_get_address_index(ir);1.309 + RN(ir) = addr;1.310 + break;1.311 + default:1.312 + UNIMP(ir); /* Unreachable */1.313 + }1.314 + return addr;1.315 +}1.316 +1.317 void arm_execute_instruction( void )1.318 {1.319 - uint32_t ir = MEM_READ_LONG(PC);1.320 + uint32_t pc = PC;1.321 + uint32_t ir = MEM_READ_LONG(PC);1.322 + uint32_t operand, operand2, tmp, armr.shift_c;1.324 -#define COND(ir) (ir>>28)1.325 + pc += 4;1.326 + PC = pc;1.328 -1.329 + switch( COND(ir) ) {1.330 + case 0: /* EQ */1.331 + cond = armr.z;1.332 + break;1.333 + case 1: /* NE */1.334 + cond = !armr.z;1.335 + break;1.336 + case 2: /* CS/HS */1.337 + cond = armr.c;1.338 + break;1.339 + case 3: /* CC/LO */1.340 + cond = !armr.c;1.341 + break;1.342 + case 4: /* MI */1.343 + cond = armr.n;1.344 + break;1.345 + case 5: /* PL */1.346 + cond = !armr.n;1.347 + break;1.348 + case 6: /* VS */1.349 + cond = armr.v;1.350 + break;1.351 + case 7: /* VC */1.352 + cond = !armr.v;1.353 + break;1.354 + case 8: /* HI */1.355 + cond = armr.c && !armr.z;1.356 + break;1.357 + case 9: /* LS */1.358 + cond = (!armr.c) || armr.z;1.359 + break;1.360 + case 10: /* GE */1.361 + cond = (armr.n == armr.v);1.362 + break;1.363 + case 11: /* LT */1.364 + cond = (armr.n != armr.v);1.365 + break;1.366 + case 12: /* GT */1.367 + cond = (!armr.z) && (armr.n == armr.v);1.368 + break;1.369 + case 13: /* LE */1.370 + cond = armr.z || (armr.n != armr.v);1.371 + break;1.372 + case 14: /* AL */1.373 + cond = 1;1.374 + break;1.375 + case 15: /* (NV) */1.376 + cond = 0;1.377 + UNDEF(ir);1.378 + }1.379 +1.380 + switch( GRP(ir) ) {1.381 + case 0:1.382 + if( (ir & 0x0D900000) == 0x01000000 ) {1.383 + /* Instructions that aren't actual data processing */1.384 + switch( ir & 0x0FF000F0 ) {1.385 + case 0x01200010: /* BX */1.386 + break;1.387 + case 0x01000000: /* MRS Rd, CPSR */1.388 + break;1.389 + case 0x01400000: /* MRS Rd, SPSR */1.390 + break;1.391 + case 0x01200000: /* MSR CPSR, Rd */1.392 + break;1.393 + case 0x01600000: /* MSR SPSR, Rd */1.394 + break;1.395 + case 0x03200000: /* MSR CPSR, imm */1.396 + break;1.397 + case 0x03600000: /* MSR SPSR, imm */1.398 + break;1.399 + default:1.400 + UNIMP();1.401 + }1.402 + } else if( (ir & 0x0E000090) == 0x00000090 ) {1.403 + /* Neither are these */1.404 + switch( (ir>>5)&0x03 ) {1.405 + case 0:1.406 + /* Arithmetic extension area */1.407 + switch(OPCODE(ir)) {1.408 + case 0: /* MUL */1.409 + break;1.410 + case 1: /* MULS */1.411 + break;1.412 + case 2: /* MLA */1.413 + break;1.414 + case 3: /* MLAS */1.415 + break;1.416 + case 8: /* UMULL */1.417 + break;1.418 + case 9: /* UMULLS */1.419 + break;1.420 + case 10: /* UMLAL */1.421 + break;1.422 + case 11: /* UMLALS */1.423 + break;1.424 + case 12: /* SMULL */1.425 + break;1.426 + case 13: /* SMULLS */1.427 + break;1.428 + case 14: /* SMLAL */1.429 + break;1.430 + case 15: /* SMLALS */1.431 + break;1.432 + case 16: /* SWP */1.433 + break;1.434 + case 20: /* SWPB */1.435 + break;1.436 + default:1.437 + UNIMP(ir);1.438 + }1.439 + break;1.440 + case 1:1.441 + if( LFLAG(ir) ) {1.442 + /* LDRH */1.443 + } else {1.444 + /* STRH */1.445 + }1.446 + break;1.447 + case 2:1.448 + if( LFLAG(ir) ) {1.449 + /* LDRSB */1.450 + } else {1.451 + UNIMP(ir);1.452 + }1.453 + break;1.454 + case 3:1.455 + if( LFLAG(ir) ) {1.456 + /* LDRSH */1.457 + } else {1.458 + UNIMP(ir);1.459 + }1.460 + break;1.461 + }1.462 + } else {1.463 + /* Data processing */1.464 +1.465 + switch(OPCODE(ir)) {1.466 + case 0: /* AND Rd, Rn, operand */1.467 + RD(ir) = RN(ir) & arm_get_shift_operand(ir);1.468 + break;1.469 + case 1: /* ANDS Rd, Rn, operand */1.470 + operand = arm_get_shift_operand_s(ir) & RN(ir);1.471 + RD(ir) = operand;1.472 + if( RDn(ir) == 15 ) {1.473 + arm_restore_cpsr();1.474 + } else {1.475 + armr.n = operand>>31;1.476 + armr.z = (operand == 0);1.477 + armr.c = armr.shift_c;1.478 + }1.479 + break;1.480 + case 2: /* EOR Rd, Rn, operand */1.481 + RD(ir) = RN(ir) ^ arm_get_shift_operand(ir);1.482 + break;1.483 + case 3: /* EORS Rd, Rn, operand */1.484 + operand = arm_get_shift_operand_s(ir) ^ RN(ir);1.485 + RD(ir) = operand;1.486 + if( RDn(ir) == 15 ) {1.487 + arm_restore_cpsr();1.488 + } else {1.489 + armr.n = operand>>31;1.490 + armr.z = (operand == 0);1.491 + armr.c = armr.shift_c;1.492 + }1.493 + break;1.494 + case 4: /* SUB Rd, Rn, operand */1.495 + RD(ir) = RN(ir) - arm_get_shift_operand(ir);1.496 + break;1.497 + case 5: /* SUBS Rd, Rn, operand */1.498 + operand = RN(ir);1.499 + operand2 = arm_get_shift_operand(ir)1.500 + tmp = operand - operand2;1.501 + RD(ir) = tmp;1.502 + if( RDn(ir) == 15 ) {1.503 + arm_restore_cpsr();1.504 + } else {1.505 + armr.n = tmp>>31;1.506 + armr.z = (tmp == 0);1.507 + armr.c = IS_NOTBORROW(tmp,operand,operand2);1.508 + armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);1.509 + }1.510 + break;1.511 + case 6: /* RSB Rd, operand, Rn */1.512 + RD(ir) = arm_get_shift_operand(ir) - RN(ir);1.513 + break;1.514 + case 7: /* RSBS Rd, operand, Rn */1.515 + operand = arm_get_shift_operand(ir);1.516 + operand2 = RN(ir);1.517 + tmp = operand - operand2;1.518 + RD(ir) = tmp;1.519 + if( RDn(ir) == 15 ) {1.520 + arm_restore_cpsr();1.521 + } else {1.522 + armr.n = tmp>>31;1.523 + armr.z = (tmp == 0);1.524 + armr.c = IS_NOTBORROW(tmp,operand,operand2);1.525 + armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);1.526 + }1.527 + break;1.528 + case 8: /* ADD Rd, Rn, operand */1.529 + RD(ir) = RN(ir) + arm_get_shift_operand(ir);1.530 + break;1.531 + case 9: /* ADDS Rd, Rn, operand */1.532 + operand = arm_get_shift_operand(ir);1.533 + operand2 = RN(ir);1.534 + tmp = operand + operand21.535 + RD(ir) = tmp;1.536 + if( RDn(ir) == 15 ) {1.537 + arm_restore_cpsr();1.538 + } else {1.539 + armr.n = tmp>>31;1.540 + armr.z = (tmp == 0);1.541 + armr.c = IS_CARRY(tmp,operand,operand2);1.542 + armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);1.543 + }1.544 + break;1.545 + case 10: /* ADC */1.546 + case 11: /* ADCS */1.547 + case 12: /* SBC */1.548 + case 13: /* SBCS */1.549 + case 14: /* RSC */1.550 + case 15: /* RSCS */1.551 + break;1.552 + case 17: /* TST Rn, operand */1.553 + operand = arm_get_shift_operand_s(ir) & RN(ir);1.554 + armr.n = operand>>31;1.555 + armr.z = (operand == 0);1.556 + armr.c = armr.shift_c;1.557 + break;1.558 + case 19: /* TEQ Rn, operand */1.559 + operand = arm_get_shift_operand_s(ir) ^ RN(ir);1.560 + armr.n = operand>>31;1.561 + armr.z = (operand == 0);1.562 + armr.c = armr.shift_c;1.563 + break;1.564 + case 21: /* CMP Rn, operand */1.565 + operand = RN(ir);1.566 + operand2 = arm_get_shift_operand(ir)1.567 + tmp = operand - operand2;1.568 + armr.n = tmp>>31;1.569 + armr.z = (tmp == 0);1.570 + armr.c = IS_NOTBORROW(tmp,operand,operand2);1.571 + armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);1.572 + break;1.573 + case 23: /* CMN Rn, operand */1.574 + operand = RN(ir);1.575 + operand2 = arm_get_shift_operand(ir)1.576 + tmp = operand + operand2;1.577 + armr.n = tmp>>31;1.578 + armr.z = (tmp == 0);1.579 + armr.c = IS_CARRY(tmp,operand,operand2);1.580 + armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);1.581 + break;1.582 + case 24: /* ORR Rd, Rn, operand */1.583 + RD(ir) = RN(ir) | arm_get_shift_operand(ir);1.584 + break;1.585 + case 25: /* ORRS Rd, Rn, operand */1.586 + operand = arm_get_shift_operand_s(ir) | RN(ir);1.587 + RD(ir) = operand;1.588 + if( RDn(ir) == 15 ) {1.589 + arm_restore_cpsr();1.590 + } else {1.591 + armr.n = operand>>31;1.592 + armr.z = (operand == 0);1.593 + armr.c = armr.shift_c;1.594 + }1.595 + break;1.596 + case 26: /* MOV Rd, operand */1.597 + RD(ir) = arm_get_shift_operand(ir);1.598 + break;1.599 + case 27: /* MOVS Rd, operand */1.600 + operand = arm_get_shift_operand_s(ir);1.601 + RD(ir) = operand;1.602 + if( RDn(ir) == 15 ) {1.603 + arm_restore_cpsr();1.604 + } else {1.605 + armr.n = operand>>31;1.606 + armr.z = (operand == 0);1.607 + armr.c = armr.shift_c;1.608 + }1.609 + break;1.610 + case 28: /* BIC Rd, Rn, operand */1.611 + RD(ir) = RN(ir) & (~arm_get_shift_operand(ir));1.612 + break;1.613 + case 29: /* BICS Rd, Rn, operand */1.614 + operand = RN(ir) & (~arm_get_shift_operand_s(ir));1.615 + RD(ir) = operand;1.616 + if( RDn(ir) == 15 ) {1.617 + arm_restore_cpsr();1.618 + } else {1.619 + armr.n = operand>>31;1.620 + armr.z = (operand == 0);1.621 + armr.c = armr.shift_c;1.622 + }1.623 + break;1.624 + case 30: /* MVN Rd, operand */1.625 + RD(ir) = ~arm_get_shift_operand(ir);1.626 + break;1.627 + case 31: /* MVNS Rd, operand */1.628 + operand = ~arm_get_shift_operand_s(ir);1.629 + RD(ir) = operand;1.630 + if( RDn(ir) == 15 ) {1.631 + arm_restore_cpsr();1.632 + } else {1.633 + armr.n = operand>>31;1.634 + armr.z = (operand == 0);1.635 + armr.c = armr.shift_c;1.636 + }1.637 + break;1.638 + default:1.639 + UNIMP(ir);1.640 + }1.641 + }1.642 + break;1.643 + case 1: /* Load/store */1.644 + break;1.645 + case 2: /* Load/store multiple, branch*/1.646 + break;1.647 + case 3: /* Copro */1.648 + break;1.649 + }1.650 }1.652 -void arm_execute_thumb_instruction( void )1.653 -{1.654 -1.655 -1.656 -1.657 -}
2.1 --- a/src/aica/armcore.h Sat Oct 02 05:49:12 2004 +00002.2 +++ b/src/aica/armcore.h Sat Oct 02 05:49:23 2004 +00002.3 @@ -21,6 +21,10 @@2.4 uint32_t svc_r[2]; /* SVC bank 13..14 */2.5 uint32_t user_r[7]; /* User/System bank 8..14 */2.7 + uint32_t c,n,z,v,t;2.8 +2.9 + /* "fake" registers */2.10 + uint32_t shift_c; /* used for temporary storage of shifter results */2.11 };2.13 #define CPSR_N 0x80000000 /* Negative flag */2.14 @@ -42,6 +46,6 @@2.16 extern struct arm_registers armr;2.18 -2.19 +#define CARRY_FLAG (armr.cpsr&CPSR_C)2.21 #endif /* !dream_armcore_H */
.