Search
lxdream.org :: lxdream :: r5:d85c2e81ce2d
lxdream 0.9.1
released Jun 29
Download Now
changeset5:d85c2e81ce2d
parent4:7d6f596ce577
child6:6e3663e58565
authornkeynes
dateSat Oct 02 05:49:23 2004 +0000 (15 years ago)
More work on the arm core
src/aica/armcore.c
src/aica/armcore.h
1.1 --- a/src/aica/armcore.c Sat Oct 02 05:49:12 2004 +0000
1.2 +++ b/src/aica/armcore.c Sat Oct 02 05:49:23 2004 +0000
1.3 @@ -3,7 +3,8 @@
1.4
1.5 struct arm_registers armr;
1.6
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.10
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.16
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.24
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 + else
1.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 processing
1.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, and
1.226 + * ignores the I flag (WTF do the load/store instructions use the I flag to
1.227 + * mean the _exact opposite_ of what it means for the data processing
1.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 + else
1.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.323
1.324 -#define COND(ir) (ir>>28)
1.325 + pc += 4;
1.326 + PC = pc;
1.327
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 + operand2
1.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.651
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 +0000
2.2 +++ b/src/aica/armcore.h Sat Oct 02 05:49:23 2004 +0000
2.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.6
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.12
2.13 #define CPSR_N 0x80000000 /* Negative flag */
2.14 @@ -42,6 +46,6 @@
2.15
2.16 extern struct arm_registers armr;
2.17
2.18 -
2.19 +#define CARRY_FLAG (armr.cpsr&CPSR_C)
2.20
2.21 #endif /* !dream_armcore_H */
.