Mercurial > vba-clojure
diff src/gba/arm-new.h @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/gba/arm-new.h Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,7453 @@ 1.4 +#ifdef BKPT_SUPPORT 1.5 +#define CONSOLE_OUTPUT(a, b) \ 1.6 + extern void (*dbgOutput)(char *, u32); \ 1.7 + if ((opcode == 0xe0000000) && (reg[0].I == 0xC0DED00D)) { \ 1.8 + dbgOutput((a), (b)); \ 1.9 + } 1.10 +#else 1.11 +#define CONSOLE_OUTPUT(a, b) 1.12 +#endif 1.13 + 1.14 +#define OP_AND \ 1.15 + reg[dest].I = reg[(opcode >> 16) & 15].I & value; \ 1.16 + CONSOLE_OUTPUT(NULL, reg[2].I); 1.17 + 1.18 +#define OP_ANDS \ 1.19 + reg[dest].I = reg[(opcode >> 16) & 15].I & value; \ 1.20 + \ 1.21 + N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \ 1.22 + Z_FLAG = (reg[dest].I) ? false : true; \ 1.23 + C_FLAG = C_OUT; 1.24 + 1.25 +#define OP_EOR \ 1.26 + reg[dest].I = reg[(opcode >> 16) & 15].I ^ value; 1.27 + 1.28 +#define OP_EORS \ 1.29 + reg[dest].I = reg[(opcode >> 16) & 15].I ^ value; \ 1.30 + \ 1.31 + N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \ 1.32 + Z_FLAG = (reg[dest].I) ? false : true; \ 1.33 + C_FLAG = C_OUT; 1.34 +#ifdef C_CORE 1.35 +#define NEG(i) ((i) >> 31) 1.36 +#define POS(i) ((~(i)) >> 31) 1.37 +#define ADDCARRY(a, b, c) \ 1.38 + C_FLAG = ((NEG(a) & NEG(b)) | \ 1.39 + (NEG(a) & POS(c)) | \ 1.40 + (NEG(b) & POS(c))) ? true : false; 1.41 +#define ADDOVERFLOW(a, b, c) \ 1.42 + V_FLAG = ((NEG(a) & NEG(b) & POS(c)) | \ 1.43 + (POS(a) & POS(b) & NEG(c))) ? true : false; 1.44 +#define SUBCARRY(a, b, c) \ 1.45 + C_FLAG = ((NEG(a) & POS(b)) | \ 1.46 + (NEG(a) & POS(c)) | \ 1.47 + (POS(b) & POS(c))) ? true : false; 1.48 +#define SUBOVERFLOW(a, b, c) \ 1.49 + V_FLAG = ((NEG(a) & POS(b) & POS(c)) | \ 1.50 + (POS(a) & NEG(b) & NEG(c))) ? true : false; 1.51 +#define OP_SUB \ 1.52 + { \ 1.53 + reg[dest].I = reg[base].I - value; \ 1.54 + } 1.55 +#define OP_SUBS \ 1.56 + { \ 1.57 + u32 lhs = reg[base].I; \ 1.58 + u32 rhs = value; \ 1.59 + u32 res = lhs - rhs; \ 1.60 + reg[dest].I = res; \ 1.61 + Z_FLAG = (res == 0) ? true : false; \ 1.62 + N_FLAG = NEG(res) ? true : false; \ 1.63 + SUBCARRY(lhs, rhs, res); \ 1.64 + SUBOVERFLOW(lhs, rhs, res); \ 1.65 + } 1.66 +#define OP_RSB \ 1.67 + { \ 1.68 + reg[dest].I = value - reg[base].I; \ 1.69 + } 1.70 +#define OP_RSBS \ 1.71 + { \ 1.72 + u32 lhs = reg[base].I; \ 1.73 + u32 rhs = value; \ 1.74 + u32 res = rhs - lhs; \ 1.75 + reg[dest].I = res; \ 1.76 + Z_FLAG = (res == 0) ? true : false; \ 1.77 + N_FLAG = NEG(res) ? true : false; \ 1.78 + SUBCARRY(rhs, lhs, res); \ 1.79 + SUBOVERFLOW(rhs, lhs, res); \ 1.80 + } 1.81 +#define OP_ADD \ 1.82 + { \ 1.83 + reg[dest].I = reg[base].I + value; \ 1.84 + } 1.85 +#define OP_ADDS \ 1.86 + { \ 1.87 + u32 lhs = reg[base].I; \ 1.88 + u32 rhs = value; \ 1.89 + u32 res = lhs + rhs; \ 1.90 + reg[dest].I = res; \ 1.91 + Z_FLAG = (res == 0) ? true : false; \ 1.92 + N_FLAG = NEG(res) ? true : false; \ 1.93 + ADDCARRY(lhs, rhs, res); \ 1.94 + ADDOVERFLOW(lhs, rhs, res); \ 1.95 + } 1.96 +#define OP_ADC \ 1.97 + { \ 1.98 + reg[dest].I = reg[base].I + value + (u32)C_FLAG; \ 1.99 + } 1.100 +#define OP_ADCS \ 1.101 + { \ 1.102 + u32 lhs = reg[base].I; \ 1.103 + u32 rhs = value; \ 1.104 + u32 res = lhs + rhs + (u32)C_FLAG; \ 1.105 + reg[dest].I = res; \ 1.106 + Z_FLAG = (res == 0) ? true : false; \ 1.107 + N_FLAG = NEG(res) ? true : false; \ 1.108 + ADDCARRY(lhs, rhs, res); \ 1.109 + ADDOVERFLOW(lhs, rhs, res); \ 1.110 + } 1.111 +#define OP_SBC \ 1.112 + { \ 1.113 + reg[dest].I = reg[base].I - value - !((u32)C_FLAG); \ 1.114 + } 1.115 +#define OP_SBCS \ 1.116 + { \ 1.117 + u32 lhs = reg[base].I; \ 1.118 + u32 rhs = value; \ 1.119 + u32 res = lhs - rhs - !((u32)C_FLAG); \ 1.120 + reg[dest].I = res; \ 1.121 + Z_FLAG = (res == 0) ? true : false; \ 1.122 + N_FLAG = NEG(res) ? true : false; \ 1.123 + SUBCARRY(lhs, rhs, res); \ 1.124 + SUBOVERFLOW(lhs, rhs, res); \ 1.125 + } 1.126 +#define OP_RSC \ 1.127 + { \ 1.128 + reg[dest].I = value - reg[base].I - !((u32)C_FLAG); \ 1.129 + } 1.130 +#define OP_RSCS \ 1.131 + { \ 1.132 + u32 lhs = reg[base].I; \ 1.133 + u32 rhs = value; \ 1.134 + u32 res = rhs - lhs - !((u32)C_FLAG); \ 1.135 + reg[dest].I = res; \ 1.136 + Z_FLAG = (res == 0) ? true : false; \ 1.137 + N_FLAG = NEG(res) ? true : false; \ 1.138 + SUBCARRY(rhs, lhs, res); \ 1.139 + SUBOVERFLOW(rhs, lhs, res); \ 1.140 + } 1.141 +#define OP_CMP \ 1.142 + { \ 1.143 + u32 lhs = reg[base].I; \ 1.144 + u32 rhs = value; \ 1.145 + u32 res = lhs - rhs; \ 1.146 + Z_FLAG = (res == 0) ? true : false; \ 1.147 + N_FLAG = NEG(res) ? true : false; \ 1.148 + SUBCARRY(lhs, rhs, res); \ 1.149 + SUBOVERFLOW(lhs, rhs, res); \ 1.150 + } 1.151 +#define OP_CMN \ 1.152 + { \ 1.153 + u32 lhs = reg[base].I; \ 1.154 + u32 rhs = value; \ 1.155 + u32 res = lhs + rhs; \ 1.156 + Z_FLAG = (res == 0) ? true : false; \ 1.157 + N_FLAG = NEG(res) ? true : false; \ 1.158 + ADDCARRY(lhs, rhs, res); \ 1.159 + ADDOVERFLOW(lhs, rhs, res); \ 1.160 + } 1.161 + 1.162 +#define LOGICAL_LSL_REG \ 1.163 + { \ 1.164 + u32 v = reg[opcode & 0x0f].I; \ 1.165 + C_OUT = (v >> (32 - shift)) & 1 ? true : false; \ 1.166 + value = v << shift; \ 1.167 + } 1.168 +#define LOGICAL_LSR_REG \ 1.169 + { \ 1.170 + u32 v = reg[opcode & 0x0f].I; \ 1.171 + C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ 1.172 + value = v >> shift; \ 1.173 + } 1.174 +#define LOGICAL_ASR_REG \ 1.175 + { \ 1.176 + u32 v = reg[opcode & 0x0f].I; \ 1.177 + C_OUT = ((s32)v >> (int)(shift - 1)) & 1 ? true : false; \ 1.178 + value = (s32)v >> (int)shift; \ 1.179 + } 1.180 +#define LOGICAL_ROR_REG \ 1.181 + { \ 1.182 + u32 v = reg[opcode & 0x0f].I; \ 1.183 + C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ 1.184 + value = ((v << (32 - shift)) | \ 1.185 + (v >> shift)); \ 1.186 + } 1.187 +#define LOGICAL_RRX_REG \ 1.188 + { \ 1.189 + u32 v = reg[opcode & 0x0f].I; \ 1.190 + shift = (int)C_FLAG; \ 1.191 + C_OUT = (v & 1) ? true : false; \ 1.192 + value = ((v >> 1) | \ 1.193 + (shift << 31)); \ 1.194 + } 1.195 +#define LOGICAL_ROR_IMM \ 1.196 + { \ 1.197 + u32 v = opcode & 0xff; \ 1.198 + C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ 1.199 + value = ((v << (32 - shift)) | \ 1.200 + (v >> shift)); \ 1.201 + } 1.202 +#define ARITHMETIC_LSL_REG \ 1.203 + { \ 1.204 + u32 v = reg[opcode & 0x0f].I; \ 1.205 + value = v << shift; \ 1.206 + } 1.207 +#define ARITHMETIC_LSR_REG \ 1.208 + { \ 1.209 + u32 v = reg[opcode & 0x0f].I; \ 1.210 + value = v >> shift; \ 1.211 + } 1.212 +#define ARITHMETIC_ASR_REG \ 1.213 + { \ 1.214 + u32 v = reg[opcode & 0x0f].I; \ 1.215 + value = (s32)v >> (int)shift; \ 1.216 + } 1.217 +#define ARITHMETIC_ROR_REG \ 1.218 + { \ 1.219 + u32 v = reg[opcode & 0x0f].I; \ 1.220 + value = ((v << (32 - shift)) | \ 1.221 + (v >> shift)); \ 1.222 + } 1.223 +#define ARITHMETIC_RRX_REG \ 1.224 + { \ 1.225 + u32 v = reg[opcode & 0x0f].I; \ 1.226 + shift = (int)C_FLAG; \ 1.227 + value = ((v >> 1) | \ 1.228 + (shift << 31)); \ 1.229 + } 1.230 +#define ARITHMETIC_ROR_IMM \ 1.231 + { \ 1.232 + u32 v = opcode & 0xff; \ 1.233 + value = ((v << (32 - shift)) | \ 1.234 + (v >> shift)); \ 1.235 + } 1.236 +#define ROR_IMM_MSR \ 1.237 + { \ 1.238 + u32 v = opcode & 0xff; \ 1.239 + value = ((v << (32 - shift)) | \ 1.240 + (v >> shift)); \ 1.241 + } 1.242 +#define ROR_VALUE \ 1.243 + { \ 1.244 + value = ((value << (32 - shift)) | \ 1.245 + (value >> shift)); \ 1.246 + } 1.247 +#define RCR_VALUE \ 1.248 + { \ 1.249 + shift = (int)C_FLAG; \ 1.250 + value = ((value >> 1) | \ 1.251 + (shift << 31)); \ 1.252 + } 1.253 +#else 1.254 +#ifdef __GNUC__ 1.255 + #ifdef __POWERPC__ 1.256 + #define OP_SUB \ 1.257 + { \ 1.258 + reg[dest].I = reg[base].I - value; \ 1.259 + } 1.260 + #define OP_SUBS \ 1.261 + { \ 1.262 + register int Flags; \ 1.263 + register int Result; \ 1.264 + asm volatile ("subco. %0, %2, %3\n" \ 1.265 + "mcrxr cr1\n" \ 1.266 + "mfcr %1\n" \ 1.267 + : "=r" (Result), \ 1.268 + "=r" (Flags) \ 1.269 + : "r" (reg[base].I), \ 1.270 + "r" (value) \ 1.271 + ); \ 1.272 + reg[dest].I = Result; \ 1.273 + Z_FLAG = (Flags >> 29) & 1; \ 1.274 + N_FLAG = (Flags >> 31) & 1; \ 1.275 + C_FLAG = (Flags >> 25) & 1; \ 1.276 + V_FLAG = (Flags >> 26) & 1; \ 1.277 + } 1.278 + #define OP_RSB \ 1.279 + { \ 1.280 + reg[dest].I = value - reg[base].I; \ 1.281 + } 1.282 + #define OP_RSBS \ 1.283 + { \ 1.284 + register int Flags; \ 1.285 + register int Result; \ 1.286 + asm volatile ("subfco. %0, %2, %3\n" \ 1.287 + "mcrxr cr1\n" \ 1.288 + "mfcr %1\n" \ 1.289 + : "=r" (Result), \ 1.290 + "=r" (Flags) \ 1.291 + : "r" (reg[base].I), \ 1.292 + "r" (value) \ 1.293 + ); \ 1.294 + reg[dest].I = Result; \ 1.295 + Z_FLAG = (Flags >> 29) & 1; \ 1.296 + N_FLAG = (Flags >> 31) & 1; \ 1.297 + C_FLAG = (Flags >> 25) & 1; \ 1.298 + V_FLAG = (Flags >> 26) & 1; \ 1.299 + } 1.300 + #define OP_ADD \ 1.301 + { \ 1.302 + reg[dest].I = reg[base].I + value; \ 1.303 + } 1.304 + 1.305 + #define OP_ADDS \ 1.306 + { \ 1.307 + register int Flags; \ 1.308 + register int Result; \ 1.309 + asm volatile ("addco. %0, %2, %3\n" \ 1.310 + "mcrxr cr1\n" \ 1.311 + "mfcr %1\n" \ 1.312 + : "=r" (Result), \ 1.313 + "=r" (Flags) \ 1.314 + : "r" (reg[base].I), \ 1.315 + "r" (value) \ 1.316 + ); \ 1.317 + reg[dest].I = Result; \ 1.318 + Z_FLAG = (Flags >> 29) & 1; \ 1.319 + N_FLAG = (Flags >> 31) & 1; \ 1.320 + C_FLAG = (Flags >> 25) & 1; \ 1.321 + V_FLAG = (Flags >> 26) & 1; \ 1.322 + } 1.323 + #define OP_ADC \ 1.324 + { \ 1.325 + reg[dest].I = reg[base].I + value + (u32)C_FLAG; \ 1.326 + } 1.327 + #define OP_ADCS \ 1.328 + { \ 1.329 + register int Flags; \ 1.330 + register int Result; \ 1.331 + asm volatile ("mtspr xer, %4\n" \ 1.332 + "addeo. %0, %2, %3\n" \ 1.333 + "mcrxr cr1\n" \ 1.334 + "mfcr %1\n" \ 1.335 + : "=r" (Result), \ 1.336 + "=r" (Flags) \ 1.337 + : "r" (reg[base].I), \ 1.338 + "r" (value), \ 1.339 + "r" (C_FLAG << 29) \ 1.340 + ); \ 1.341 + reg[dest].I = Result; \ 1.342 + Z_FLAG = (Flags >> 29) & 1; \ 1.343 + N_FLAG = (Flags >> 31) & 1; \ 1.344 + C_FLAG = (Flags >> 25) & 1; \ 1.345 + V_FLAG = (Flags >> 26) & 1; \ 1.346 + } 1.347 + #define OP_SBC \ 1.348 + { \ 1.349 + reg[dest].I = reg[base].I - value - (C_FLAG ^ 1); \ 1.350 + } 1.351 + #define OP_SBCS \ 1.352 + { \ 1.353 + register int Flags; \ 1.354 + register int Result; \ 1.355 + asm volatile ("mtspr xer, %4\n" \ 1.356 + "subfeo. %0, %3, %2\n" \ 1.357 + "mcrxr cr1\n" \ 1.358 + "mfcr %1\n" \ 1.359 + : "=r" (Result), \ 1.360 + "=r" (Flags) \ 1.361 + : "r" (reg[base].I), \ 1.362 + "r" (value), \ 1.363 + "r" (C_FLAG << 29) \ 1.364 + ); \ 1.365 + reg[dest].I = Result; \ 1.366 + Z_FLAG = (Flags >> 29) & 1; \ 1.367 + N_FLAG = (Flags >> 31) & 1; \ 1.368 + C_FLAG = (Flags >> 25) & 1; \ 1.369 + V_FLAG = (Flags >> 26) & 1; \ 1.370 + } 1.371 + #define OP_RSC \ 1.372 + { \ 1.373 + reg[dest].I = value - reg[base].I - (C_FLAG ^ 1); \ 1.374 + } 1.375 + #define OP_RSCS \ 1.376 + { \ 1.377 + register int Flags; \ 1.378 + register int Result; \ 1.379 + asm volatile ("mtspr xer, %4\n" \ 1.380 + "subfeo. %0, %2, %3\n" \ 1.381 + "mcrxr cr1\n" \ 1.382 + "mfcr %1\n" \ 1.383 + : "=r" (Result), \ 1.384 + "=r" (Flags) \ 1.385 + : "r" (reg[base].I), \ 1.386 + "r" (value), \ 1.387 + "r" (C_FLAG << 29) \ 1.388 + ); \ 1.389 + reg[dest].I = Result; \ 1.390 + Z_FLAG = (Flags >> 29) & 1; \ 1.391 + N_FLAG = (Flags >> 31) & 1; \ 1.392 + C_FLAG = (Flags >> 25) & 1; \ 1.393 + V_FLAG = (Flags >> 26) & 1; \ 1.394 + } 1.395 + #define OP_CMP \ 1.396 + { \ 1.397 + register int Flags; \ 1.398 + register int Result; \ 1.399 + asm volatile ("subco. %0, %2, %3\n" \ 1.400 + "mcrxr cr1\n" \ 1.401 + "mfcr %1\n" \ 1.402 + : "=r" (Result), \ 1.403 + "=r" (Flags) \ 1.404 + : "r" (reg[base].I), \ 1.405 + "r" (value) \ 1.406 + ); \ 1.407 + Z_FLAG = (Flags >> 29) & 1; \ 1.408 + N_FLAG = (Flags >> 31) & 1; \ 1.409 + C_FLAG = (Flags >> 25) & 1; \ 1.410 + V_FLAG = (Flags >> 26) & 1; \ 1.411 + } 1.412 + #define OP_CMN \ 1.413 + { \ 1.414 + register int Flags; \ 1.415 + register int Result; \ 1.416 + asm volatile ("addco. %0, %2, %3\n" \ 1.417 + "mcrxr cr1\n" \ 1.418 + "mfcr %1\n" \ 1.419 + : "=r" (Result), \ 1.420 + "=r" (Flags) \ 1.421 + : "r" (reg[base].I), \ 1.422 + "r" (value) \ 1.423 + ); \ 1.424 + Z_FLAG = (Flags >> 29) & 1; \ 1.425 + N_FLAG = (Flags >> 31) & 1; \ 1.426 + C_FLAG = (Flags >> 25) & 1; \ 1.427 + V_FLAG = (Flags >> 26) & 1; \ 1.428 + } 1.429 + 1.430 + #define LOGICAL_LSL_REG \ 1.431 + { \ 1.432 + u32 v = reg[opcode & 0x0f].I; \ 1.433 + C_OUT = (v >> (32 - shift)) & 1 ? true : false; \ 1.434 + value = v << shift; \ 1.435 + } 1.436 + #define LOGICAL_LSR_REG \ 1.437 + { \ 1.438 + u32 v = reg[opcode & 0x0f].I; \ 1.439 + C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ 1.440 + value = v >> shift; \ 1.441 + } 1.442 + #define LOGICAL_ASR_REG \ 1.443 + { \ 1.444 + u32 v = reg[opcode & 0x0f].I; \ 1.445 + C_OUT = ((s32)v >> (int)(shift - 1)) & 1 ? true : false; \ 1.446 + value = (s32)v >> (int)shift; \ 1.447 + } 1.448 + #define LOGICAL_ROR_REG \ 1.449 + { \ 1.450 + u32 v = reg[opcode & 0x0f].I; \ 1.451 + C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ 1.452 + value = ((v << (32 - shift)) | \ 1.453 + (v >> shift)); \ 1.454 + } 1.455 + #define LOGICAL_RRX_REG \ 1.456 + { \ 1.457 + u32 v = reg[opcode & 0x0f].I; \ 1.458 + shift = (int)C_FLAG; \ 1.459 + C_OUT = (v & 1) ? true : false; \ 1.460 + value = ((v >> 1) | \ 1.461 + (shift << 31)); \ 1.462 + } 1.463 + #define LOGICAL_ROR_IMM \ 1.464 + { \ 1.465 + u32 v = opcode & 0xff; \ 1.466 + C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ 1.467 + value = ((v << (32 - shift)) | \ 1.468 + (v >> shift)); \ 1.469 + } 1.470 + #define ARITHMETIC_LSL_REG \ 1.471 + { \ 1.472 + u32 v = reg[opcode & 0x0f].I; \ 1.473 + value = v << shift; \ 1.474 + } 1.475 + #define ARITHMETIC_LSR_REG \ 1.476 + { \ 1.477 + u32 v = reg[opcode & 0x0f].I; \ 1.478 + value = v >> shift; \ 1.479 + } 1.480 + #define ARITHMETIC_ASR_REG \ 1.481 + { \ 1.482 + u32 v = reg[opcode & 0x0f].I; \ 1.483 + value = (s32)v >> (int)shift; \ 1.484 + } 1.485 + #define ARITHMETIC_ROR_REG \ 1.486 + { \ 1.487 + u32 v = reg[opcode & 0x0f].I; \ 1.488 + value = ((v << (32 - shift)) | \ 1.489 + (v >> shift)); \ 1.490 + } 1.491 + #define ARITHMETIC_RRX_REG \ 1.492 + { \ 1.493 + u32 v = reg[opcode & 0x0f].I; \ 1.494 + shift = (int)C_FLAG; \ 1.495 + value = ((v >> 1) | \ 1.496 + (shift << 31)); \ 1.497 + } 1.498 + #define ARITHMETIC_ROR_IMM \ 1.499 + { \ 1.500 + u32 v = opcode & 0xff; \ 1.501 + value = ((v << (32 - shift)) | \ 1.502 + (v >> shift)); \ 1.503 + } 1.504 + #define ROR_IMM_MSR \ 1.505 + { \ 1.506 + u32 v = opcode & 0xff; \ 1.507 + value = ((v << (32 - shift)) | \ 1.508 + (v >> shift)); \ 1.509 + } 1.510 + #define ROR_VALUE \ 1.511 + { \ 1.512 + value = ((value << (32 - shift)) | \ 1.513 + (value >> shift)); \ 1.514 + } 1.515 + #define RCR_VALUE \ 1.516 + { \ 1.517 + shift = (int)C_FLAG; \ 1.518 + value = ((value >> 1) | \ 1.519 + (shift << 31)); \ 1.520 + } 1.521 +#else 1.522 +#define OP_SUB \ 1.523 + asm ("sub %1, %%ebx;" \ 1.524 + : "=b" (reg[dest].I) \ 1.525 + : "r" (value), "b" (reg[base].I)); 1.526 + 1.527 +#define OP_SUBS \ 1.528 + asm ("sub %1, %%ebx;" \ 1.529 + "setsb N_FLAG;" \ 1.530 + "setzb Z_FLAG;" \ 1.531 + "setncb C_FLAG;" \ 1.532 + "setob V_FLAG;" \ 1.533 + : "=b" (reg[dest].I) \ 1.534 + : "r" (value), "b" (reg[base].I)); 1.535 + 1.536 +#define OP_RSB \ 1.537 + asm ("sub %1, %%ebx;" \ 1.538 + : "=b" (reg[dest].I) \ 1.539 + : "r" (reg[base].I), "b" (value)); 1.540 + 1.541 +#define OP_RSBS \ 1.542 + asm ("sub %1, %%ebx;" \ 1.543 + "setsb N_FLAG;" \ 1.544 + "setzb Z_FLAG;" \ 1.545 + "setncb C_FLAG;" \ 1.546 + "setob V_FLAG;" \ 1.547 + : "=b" (reg[dest].I) \ 1.548 + : "r" (reg[base].I), "b" (value)); 1.549 + 1.550 +#define OP_ADD \ 1.551 + asm ("add %1, %%ebx;" \ 1.552 + : "=b" (reg[dest].I) \ 1.553 + : "r" (value), "b" (reg[base].I)); 1.554 + 1.555 +#define OP_ADDS \ 1.556 + asm ("add %1, %%ebx;" \ 1.557 + "setsb N_FLAG;" \ 1.558 + "setzb Z_FLAG;" \ 1.559 + "setcb C_FLAG;" \ 1.560 + "setob V_FLAG;" \ 1.561 + : "=b" (reg[dest].I) \ 1.562 + : "r" (value), "b" (reg[base].I)); 1.563 + 1.564 +#define OP_ADC \ 1.565 + asm ("bt $0, C_FLAG;" \ 1.566 + "adc %1, %%ebx;" \ 1.567 + : "=b" (reg[dest].I) \ 1.568 + : "r" (value), "b" (reg[base].I)); 1.569 + 1.570 +#define OP_ADCS \ 1.571 + asm ("bt $0, C_FLAG;" \ 1.572 + "adc %1, %%ebx;" \ 1.573 + "setsb N_FLAG;" \ 1.574 + "setzb Z_FLAG;" \ 1.575 + "setcb C_FLAG;" \ 1.576 + "setob V_FLAG;" \ 1.577 + : "=b" (reg[dest].I) \ 1.578 + : "r" (value), "b" (reg[base].I)); 1.579 + 1.580 +#define OP_SBC \ 1.581 + asm ("bt $0, C_FLAG;" \ 1.582 + "cmc;" \ 1.583 + "sbb %1, %%ebx;" \ 1.584 + : "=b" (reg[dest].I) \ 1.585 + : "r" (value), "b" (reg[base].I)); 1.586 + 1.587 +#define OP_SBCS \ 1.588 + asm ("bt $0, C_FLAG;" \ 1.589 + "cmc;" \ 1.590 + "sbb %1, %%ebx;" \ 1.591 + "setsb N_FLAG;" \ 1.592 + "setzb Z_FLAG;" \ 1.593 + "setncb C_FLAG;" \ 1.594 + "setob V_FLAG;" \ 1.595 + : "=b" (reg[dest].I) \ 1.596 + : "r" (value), "b" (reg[base].I)); 1.597 +#define OP_RSC \ 1.598 + asm ("bt $0, C_FLAG;" \ 1.599 + "cmc;" \ 1.600 + "sbb %1, %%ebx;" \ 1.601 + : "=b" (reg[dest].I) \ 1.602 + : "r" (reg[base].I), "b" (value)); 1.603 + 1.604 +#define OP_RSCS \ 1.605 + asm ("bt $0, C_FLAG;" \ 1.606 + "cmc;" \ 1.607 + "sbb %1, %%ebx;" \ 1.608 + "setsb N_FLAG;" \ 1.609 + "setzb Z_FLAG;" \ 1.610 + "setncb C_FLAG;" \ 1.611 + "setob V_FLAG;" \ 1.612 + : "=b" (reg[dest].I) \ 1.613 + : "r" (reg[base].I), "b" (value)); 1.614 +#define OP_CMP \ 1.615 + asm ("sub %0, %1;" \ 1.616 + "setsb N_FLAG;" \ 1.617 + "setzb Z_FLAG;" \ 1.618 + "setncb C_FLAG;" \ 1.619 + "setob V_FLAG;" \ 1.620 + : \ 1.621 + : "r" (value), "r" (reg[base].I)); 1.622 + 1.623 +#define OP_CMN \ 1.624 + asm ("add %0, %1;" \ 1.625 + "setsb N_FLAG;" \ 1.626 + "setzb Z_FLAG;" \ 1.627 + "setcb C_FLAG;" \ 1.628 + "setob V_FLAG;" \ 1.629 + : \ 1.630 + : "r" (value), "r" (reg[base].I)); 1.631 +#define LOGICAL_LSL_REG \ 1.632 + asm ("shl %%cl, %%eax;" \ 1.633 + "setcb %%cl;" \ 1.634 + : "=a" (value), "=c" (C_OUT) \ 1.635 + : "a" (reg[opcode & 0x0f].I), "c" (shift)); 1.636 + 1.637 +#define LOGICAL_LSR_REG \ 1.638 + asm ("shr %%cl, %%eax;" \ 1.639 + "setcb %%cl;" \ 1.640 + : "=a" (value), "=c" (C_OUT) \ 1.641 + : "a" (reg[opcode & 0x0f].I), "c" (shift)); 1.642 + 1.643 +#define LOGICAL_ASR_REG \ 1.644 + asm ("sar %%cl, %%eax;" \ 1.645 + "setcb %%cl;" \ 1.646 + : "=a" (value), "=c" (C_OUT) \ 1.647 + : "a" (reg[opcode & 0x0f].I), "c" (shift)); 1.648 + 1.649 +#define LOGICAL_ROR_REG \ 1.650 + asm ("ror %%cl, %%eax;" \ 1.651 + "setcb %%cl;" \ 1.652 + : "=a" (value), "=c" (C_OUT) \ 1.653 + : "a" (reg[opcode & 0x0f].I), "c" (shift)); 1.654 + 1.655 +#define LOGICAL_RRX_REG \ 1.656 + asm ("bt $0, C_FLAG;" \ 1.657 + "rcr $1, %%eax;" \ 1.658 + "setcb %%cl;" \ 1.659 + : "=a" (value), "=c" (C_OUT) \ 1.660 + : "a" (reg[opcode & 0x0f].I)); 1.661 + 1.662 +#define LOGICAL_ROR_IMM \ 1.663 + asm ("ror %%cl, %%eax;" \ 1.664 + "setcb %%cl;" \ 1.665 + : "=a" (value), "=c" (C_OUT) \ 1.666 + : "a" (opcode & 0xff), "c" (shift)); 1.667 +#define ARITHMETIC_LSL_REG \ 1.668 + asm ("\ 1.669 + shl %%cl, %%eax;" \ 1.670 + : "=a" (value) \ 1.671 + : "a" (reg[opcode & 0x0f].I), "c" (shift)); 1.672 + 1.673 +#define ARITHMETIC_LSR_REG \ 1.674 + asm ("\ 1.675 + shr %%cl, %%eax;" \ 1.676 + : "=a" (value) \ 1.677 + : "a" (reg[opcode & 0x0f].I), "c" (shift)); 1.678 + 1.679 +#define ARITHMETIC_ASR_REG \ 1.680 + asm ("\ 1.681 + sar %%cl, %%eax;" \ 1.682 + : "=a" (value) \ 1.683 + : "a" (reg[opcode & 0x0f].I), "c" (shift)); 1.684 + 1.685 +#define ARITHMETIC_ROR_REG \ 1.686 + asm ("\ 1.687 + ror %%cl, %%eax;" \ 1.688 + : "=a" (value) \ 1.689 + : "a" (reg[opcode & 0x0f].I), "c" (shift)); 1.690 + 1.691 +#define ARITHMETIC_RRX_REG \ 1.692 + asm ("\ 1.693 + bt $0, C_FLAG;\ 1.694 + rcr $1, %%eax;" \ 1.695 + : "=a" (value) \ 1.696 + : "a" (reg[opcode & 0x0f].I)); 1.697 + 1.698 +#define ARITHMETIC_ROR_IMM \ 1.699 + asm ("\ 1.700 + ror %%cl, %%eax;" \ 1.701 + : "=a" (value) \ 1.702 + : "a" (opcode & 0xff), "c" (shift)); 1.703 +#define ROR_IMM_MSR \ 1.704 + asm ("ror %%cl, %%eax;" \ 1.705 + : "=a" (value) \ 1.706 + : "a" (opcode & 0xFF), "c" (shift)); 1.707 +#define ROR_VALUE \ 1.708 + asm ("ror %%cl, %0" \ 1.709 + : "=r" (value) \ 1.710 + : "r" (value), "c" (shift)); 1.711 +#define RCR_VALUE \ 1.712 + asm ("bt $0, C_FLAG;" \ 1.713 + "rcr $1, %0" \ 1.714 + : "=r" (value) \ 1.715 + : "r" (value)); 1.716 +#endif 1.717 +#else 1.718 +#define OP_SUB \ 1.719 + { \ 1.720 + __asm mov ebx, base \ 1.721 + __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \ 1.722 + __asm sub ebx, value \ 1.723 + __asm mov eax, dest \ 1.724 + __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \ 1.725 + } 1.726 + 1.727 +#define OP_SUBS \ 1.728 + { \ 1.729 + __asm mov ebx, base \ 1.730 + __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \ 1.731 + __asm sub ebx, value \ 1.732 + __asm mov eax, dest \ 1.733 + __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \ 1.734 + __asm sets byte ptr N_FLAG \ 1.735 + __asm setz byte ptr Z_FLAG \ 1.736 + __asm setnc byte ptr C_FLAG \ 1.737 + __asm seto byte ptr V_FLAG \ 1.738 + } 1.739 + 1.740 +#define OP_RSB \ 1.741 + { \ 1.742 + __asm mov ebx, base \ 1.743 + __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \ 1.744 + __asm mov eax, value \ 1.745 + __asm sub eax, ebx \ 1.746 + __asm mov ebx, dest \ 1.747 + __asm mov dword ptr [OFFSET reg + 4 * ebx], eax \ 1.748 + } 1.749 + 1.750 +#define OP_RSBS \ 1.751 + { \ 1.752 + __asm mov ebx, base \ 1.753 + __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \ 1.754 + __asm mov eax, value \ 1.755 + __asm sub eax, ebx \ 1.756 + __asm mov ebx, dest \ 1.757 + __asm mov dword ptr [OFFSET reg + 4 * ebx], eax \ 1.758 + __asm sets byte ptr N_FLAG \ 1.759 + __asm setz byte ptr Z_FLAG \ 1.760 + __asm setnc byte ptr C_FLAG \ 1.761 + __asm seto byte ptr V_FLAG \ 1.762 + } 1.763 + 1.764 +#define OP_ADD \ 1.765 + { \ 1.766 + __asm mov ebx, base \ 1.767 + __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \ 1.768 + __asm add ebx, value \ 1.769 + __asm mov eax, dest \ 1.770 + __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \ 1.771 + } 1.772 + 1.773 +#define OP_ADDS \ 1.774 + { \ 1.775 + __asm mov ebx, base \ 1.776 + __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \ 1.777 + __asm add ebx, value \ 1.778 + __asm mov eax, dest \ 1.779 + __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \ 1.780 + __asm sets byte ptr N_FLAG \ 1.781 + __asm setz byte ptr Z_FLAG \ 1.782 + __asm setc byte ptr C_FLAG \ 1.783 + __asm seto byte ptr V_FLAG \ 1.784 + } 1.785 + 1.786 +#define OP_ADC \ 1.787 + { \ 1.788 + __asm mov ebx, base \ 1.789 + __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \ 1.790 + __asm bt word ptr C_FLAG, 0 \ 1.791 + __asm adc ebx, value \ 1.792 + __asm mov eax, dest \ 1.793 + __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \ 1.794 + } 1.795 + 1.796 +#define OP_ADCS \ 1.797 + { \ 1.798 + __asm mov ebx, base \ 1.799 + __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \ 1.800 + __asm bt word ptr C_FLAG, 0 \ 1.801 + __asm adc ebx, value \ 1.802 + __asm mov eax, dest \ 1.803 + __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \ 1.804 + __asm sets byte ptr N_FLAG \ 1.805 + __asm setz byte ptr Z_FLAG \ 1.806 + __asm setc byte ptr C_FLAG \ 1.807 + __asm seto byte ptr V_FLAG \ 1.808 + } 1.809 + 1.810 +#define OP_SBC \ 1.811 + { \ 1.812 + __asm mov ebx, base \ 1.813 + __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \ 1.814 + __asm mov eax, value \ 1.815 + __asm bt word ptr C_FLAG, 0 \ 1.816 + __asm cmc \ 1.817 + __asm sbb ebx, eax \ 1.818 + __asm mov eax, dest \ 1.819 + __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \ 1.820 + } 1.821 + 1.822 +#define OP_SBCS \ 1.823 + { \ 1.824 + __asm mov ebx, base \ 1.825 + __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \ 1.826 + __asm mov eax, value \ 1.827 + __asm bt word ptr C_FLAG, 0 \ 1.828 + __asm cmc \ 1.829 + __asm sbb ebx, eax \ 1.830 + __asm mov eax, dest \ 1.831 + __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \ 1.832 + __asm sets byte ptr N_FLAG \ 1.833 + __asm setz byte ptr Z_FLAG \ 1.834 + __asm setnc byte ptr C_FLAG \ 1.835 + __asm seto byte ptr V_FLAG \ 1.836 + } 1.837 +#define OP_RSC \ 1.838 + { \ 1.839 + __asm mov ebx, value \ 1.840 + __asm mov eax, base \ 1.841 + __asm mov eax, dword ptr[OFFSET reg + 4 * eax] \ 1.842 + __asm bt word ptr C_FLAG, 0 \ 1.843 + __asm cmc \ 1.844 + __asm sbb ebx, eax \ 1.845 + __asm mov eax, dest \ 1.846 + __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \ 1.847 + } 1.848 + 1.849 +#define OP_RSCS \ 1.850 + { \ 1.851 + __asm mov ebx, value \ 1.852 + __asm mov eax, base \ 1.853 + __asm mov eax, dword ptr[OFFSET reg + 4 * eax] \ 1.854 + __asm bt word ptr C_FLAG, 0 \ 1.855 + __asm cmc \ 1.856 + __asm sbb ebx, eax \ 1.857 + __asm mov eax, dest \ 1.858 + __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \ 1.859 + __asm sets byte ptr N_FLAG \ 1.860 + __asm setz byte ptr Z_FLAG \ 1.861 + __asm setnc byte ptr C_FLAG \ 1.862 + __asm seto byte ptr V_FLAG \ 1.863 + } 1.864 +#define OP_CMP \ 1.865 + { \ 1.866 + __asm mov eax, base \ 1.867 + __asm mov ebx, dword ptr [OFFSET reg + 4 * eax] \ 1.868 + __asm sub ebx, value \ 1.869 + __asm sets byte ptr N_FLAG \ 1.870 + __asm setz byte ptr Z_FLAG \ 1.871 + __asm setnc byte ptr C_FLAG \ 1.872 + __asm seto byte ptr V_FLAG \ 1.873 + } 1.874 + 1.875 +#define OP_CMN \ 1.876 + { \ 1.877 + __asm mov eax, base \ 1.878 + __asm mov ebx, dword ptr [OFFSET reg + 4 * eax] \ 1.879 + __asm add ebx, value \ 1.880 + __asm sets byte ptr N_FLAG \ 1.881 + __asm setz byte ptr Z_FLAG \ 1.882 + __asm setc byte ptr C_FLAG \ 1.883 + __asm seto byte ptr V_FLAG \ 1.884 + } 1.885 +#define LOGICAL_LSL_REG \ 1.886 + __asm mov eax, opcode \ 1.887 + __asm and eax, 0x0f \ 1.888 + __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \ 1.889 + __asm mov cl, byte ptr shift \ 1.890 + __asm shl eax, cl \ 1.891 + __asm mov value, eax \ 1.892 + __asm setc byte ptr C_OUT 1.893 + 1.894 +#define LOGICAL_LSR_REG \ 1.895 + __asm mov eax, opcode \ 1.896 + __asm and eax, 0x0f \ 1.897 + __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \ 1.898 + __asm mov cl, byte ptr shift \ 1.899 + __asm shr eax, cl \ 1.900 + __asm mov value, eax \ 1.901 + __asm setc byte ptr C_OUT 1.902 + 1.903 +#define LOGICAL_ASR_REG \ 1.904 + __asm mov eax, opcode \ 1.905 + __asm and eax, 0x0f \ 1.906 + __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \ 1.907 + __asm mov cl, byte ptr shift \ 1.908 + __asm sar eax, cl \ 1.909 + __asm mov value, eax \ 1.910 + __asm setc byte ptr C_OUT 1.911 + 1.912 +#define LOGICAL_ROR_REG \ 1.913 + __asm mov eax, opcode \ 1.914 + __asm and eax, 0x0F \ 1.915 + __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \ 1.916 + __asm mov cl, byte ptr shift \ 1.917 + __asm ror eax, cl \ 1.918 + __asm mov value, eax \ 1.919 + __asm setc byte ptr C_OUT 1.920 + 1.921 +#define LOGICAL_RRX_REG \ 1.922 + __asm mov eax, opcode \ 1.923 + __asm and eax, 0x0F \ 1.924 + __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \ 1.925 + __asm bt word ptr C_OUT, 0 \ 1.926 + __asm rcr eax, 1 \ 1.927 + __asm mov value, eax \ 1.928 + __asm setc byte ptr C_OUT 1.929 + 1.930 +#define LOGICAL_ROR_IMM \ 1.931 + __asm mov eax, opcode \ 1.932 + __asm and eax, 0xff \ 1.933 + __asm mov cl, byte ptr shift \ 1.934 + __asm ror eax, cl \ 1.935 + __asm mov value, eax \ 1.936 + __asm setc byte ptr C_OUT 1.937 +#define ARITHMETIC_LSL_REG \ 1.938 + __asm mov eax, opcode \ 1.939 + __asm and eax, 0x0f \ 1.940 + __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \ 1.941 + __asm mov cl, byte ptr shift \ 1.942 + __asm shl eax, cl \ 1.943 + __asm mov value, eax 1.944 + 1.945 +#define ARITHMETIC_LSR_REG \ 1.946 + __asm mov eax, opcode \ 1.947 + __asm and eax, 0x0f \ 1.948 + __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \ 1.949 + __asm mov cl, byte ptr shift \ 1.950 + __asm shr eax, cl \ 1.951 + __asm mov value, eax 1.952 + 1.953 +#define ARITHMETIC_ASR_REG \ 1.954 + __asm mov eax, opcode \ 1.955 + __asm and eax, 0x0f \ 1.956 + __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \ 1.957 + __asm mov cl, byte ptr shift \ 1.958 + __asm sar eax, cl \ 1.959 + __asm mov value, eax 1.960 + 1.961 +#define ARITHMETIC_ROR_REG \ 1.962 + __asm mov eax, opcode \ 1.963 + __asm and eax, 0x0F \ 1.964 + __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \ 1.965 + __asm mov cl, byte ptr shift \ 1.966 + __asm ror eax, cl \ 1.967 + __asm mov value, eax 1.968 + 1.969 +#define ARITHMETIC_RRX_REG \ 1.970 + __asm mov eax, opcode \ 1.971 + __asm and eax, 0x0F \ 1.972 + __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \ 1.973 + __asm bt word ptr C_FLAG, 0 \ 1.974 + __asm rcr eax, 1 \ 1.975 + __asm mov value, eax 1.976 + 1.977 +#define ARITHMETIC_ROR_IMM \ 1.978 + __asm mov eax, opcode \ 1.979 + __asm and eax, 0xff \ 1.980 + __asm mov cl, byte ptr shift \ 1.981 + __asm ror eax, cl \ 1.982 + __asm mov value, eax 1.983 +#define ROR_IMM_MSR \ 1.984 + { \ 1.985 + __asm mov eax, opcode \ 1.986 + __asm and eax, 0xff \ 1.987 + __asm mov cl, byte ptr shift \ 1.988 + __asm ror eax, CL \ 1.989 + __asm mov value, eax \ 1.990 + } 1.991 +#define ROR_VALUE \ 1.992 + { \ 1.993 + __asm mov cl, byte ptr shift \ 1.994 + __asm ror dword ptr value, cl \ 1.995 + } 1.996 +#define RCR_VALUE \ 1.997 + { \ 1.998 + __asm mov cl, byte ptr shift \ 1.999 + __asm bt word ptr C_FLAG, 0 \ 1.1000 + __asm rcr dword ptr value, 1 \ 1.1001 + } 1.1002 +#endif 1.1003 +#endif 1.1004 + 1.1005 +#define OP_TST \ 1.1006 + u32 res = reg[base].I & value; \ 1.1007 + N_FLAG = (res & 0x80000000) ? true : false; \ 1.1008 + Z_FLAG = (res) ? false : true; \ 1.1009 + C_FLAG = C_OUT; 1.1010 + 1.1011 +#define OP_TEQ \ 1.1012 + u32 res = reg[base].I ^ value; \ 1.1013 + N_FLAG = (res & 0x80000000) ? true : false; \ 1.1014 + Z_FLAG = (res) ? false : true; \ 1.1015 + C_FLAG = C_OUT; 1.1016 + 1.1017 +#define OP_ORR \ 1.1018 + reg[dest].I = reg[base].I | value; 1.1019 + 1.1020 +#define OP_ORRS \ 1.1021 + reg[dest].I = reg[base].I | value; \ 1.1022 + N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \ 1.1023 + Z_FLAG = (reg[dest].I) ? false : true; \ 1.1024 + C_FLAG = C_OUT; 1.1025 + 1.1026 +#define OP_MOV \ 1.1027 + reg[dest].I = value; 1.1028 + 1.1029 +#define OP_MOVS \ 1.1030 + reg[dest].I = value; \ 1.1031 + N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \ 1.1032 + Z_FLAG = (reg[dest].I) ? false : true; \ 1.1033 + C_FLAG = C_OUT; 1.1034 + 1.1035 +#define OP_BIC \ 1.1036 + reg[dest].I = reg[base].I & (~value); 1.1037 + 1.1038 +#define OP_BICS \ 1.1039 + reg[dest].I = reg[base].I & (~value); \ 1.1040 + N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \ 1.1041 + Z_FLAG = (reg[dest].I) ? false : true; \ 1.1042 + C_FLAG = C_OUT; 1.1043 + 1.1044 +#define OP_MVN \ 1.1045 + reg[dest].I = ~value; 1.1046 + 1.1047 +#define OP_MVNS \ 1.1048 + reg[dest].I = ~value; \ 1.1049 + N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \ 1.1050 + Z_FLAG = (reg[dest].I) ? false : true; \ 1.1051 + C_FLAG = C_OUT; 1.1052 + 1.1053 +#define CASE_16(BASE) \ 1.1054 +case BASE: \ 1.1055 +case BASE + 1: \ 1.1056 +case BASE + 2: \ 1.1057 +case BASE + 3: \ 1.1058 +case BASE + 4: \ 1.1059 +case BASE + 5: \ 1.1060 +case BASE + 6: \ 1.1061 +case BASE + 7: \ 1.1062 +case BASE + 8: \ 1.1063 +case BASE + 9: \ 1.1064 +case BASE + 10: \ 1.1065 +case BASE + 11: \ 1.1066 +case BASE + 12: \ 1.1067 +case BASE + 13: \ 1.1068 +case BASE + 14: \ 1.1069 +case BASE + 15: 1.1070 + 1.1071 +#define CASE_256(BASE) \ 1.1072 + CASE_16(BASE) \ 1.1073 + CASE_16(BASE + 0x10) \ 1.1074 + CASE_16(BASE + 0x20) \ 1.1075 + CASE_16(BASE + 0x30) \ 1.1076 + CASE_16(BASE + 0x40) \ 1.1077 + CASE_16(BASE + 0x50) \ 1.1078 + CASE_16(BASE + 0x60) \ 1.1079 + CASE_16(BASE + 0x70) \ 1.1080 + CASE_16(BASE + 0x80) \ 1.1081 + CASE_16(BASE + 0x90) \ 1.1082 + CASE_16(BASE + 0xa0) \ 1.1083 + CASE_16(BASE + 0xb0) \ 1.1084 + CASE_16(BASE + 0xc0) \ 1.1085 + CASE_16(BASE + 0xd0) \ 1.1086 + CASE_16(BASE + 0xe0) \ 1.1087 + CASE_16(BASE + 0xf0) 1.1088 + 1.1089 +#define LOGICAL_DATA_OPCODE(OPCODE, OPCODE2, BASE) \ 1.1090 +case BASE: \ 1.1091 +case BASE + 8: \ 1.1092 +{ \ 1.1093 + /* OP Rd,Rb,Rm LSL # */ \ 1.1094 + int base = (opcode >> 16) & 0x0F; \ 1.1095 + int shift = (opcode >> 7) & 0x1F; \ 1.1096 + int dest = (opcode >> 12) & 15; \ 1.1097 + bool C_OUT = C_FLAG; \ 1.1098 + u32 value; \ 1.1099 + \ 1.1100 + if (shift) { \ 1.1101 + LOGICAL_LSL_REG \ 1.1102 + } else { \ 1.1103 + value = reg[opcode & 0x0F].I; \ 1.1104 + } \ 1.1105 + if (dest == 15) { \ 1.1106 + OPCODE2 \ 1.1107 + /* todo */ \ 1.1108 + if (opcode & 0x00100000) { \ 1.1109 + clockTicks++; \ 1.1110 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1111 + } \ 1.1112 + if (armState) { \ 1.1113 + reg[15].I &= 0xFFFFFFFC; \ 1.1114 + armNextPC = reg[15].I; \ 1.1115 + reg[15].I += 4; \ 1.1116 + } else { \ 1.1117 + reg[15].I &= 0xFFFFFFFE; \ 1.1118 + armNextPC = reg[15].I; \ 1.1119 + reg[15].I += 2; \ 1.1120 + } \ 1.1121 + } else { \ 1.1122 + OPCODE \ 1.1123 + } \ 1.1124 +} \ 1.1125 +break; \ 1.1126 +case BASE + 2: \ 1.1127 +case BASE + 10: \ 1.1128 +{ \ 1.1129 + /* OP Rd,Rb,Rm LSR # */ \ 1.1130 + int base = (opcode >> 16) & 0x0F; \ 1.1131 + int shift = (opcode >> 7) & 0x1F; \ 1.1132 + int dest = (opcode >> 12) & 15; \ 1.1133 + bool C_OUT = C_FLAG; \ 1.1134 + u32 value; \ 1.1135 + if (shift) { \ 1.1136 + LOGICAL_LSR_REG \ 1.1137 + } else { \ 1.1138 + value = 0; \ 1.1139 + C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false; \ 1.1140 + } \ 1.1141 + \ 1.1142 + if (dest == 15) { \ 1.1143 + OPCODE2 \ 1.1144 + /* todo */ \ 1.1145 + if (opcode & 0x00100000) { \ 1.1146 + clockTicks++; \ 1.1147 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1148 + } \ 1.1149 + if (armState) { \ 1.1150 + reg[15].I &= 0xFFFFFFFC; \ 1.1151 + armNextPC = reg[15].I; \ 1.1152 + reg[15].I += 4; \ 1.1153 + } else { \ 1.1154 + reg[15].I &= 0xFFFFFFFE; \ 1.1155 + armNextPC = reg[15].I; \ 1.1156 + reg[15].I += 2; \ 1.1157 + } \ 1.1158 + } else { \ 1.1159 + OPCODE \ 1.1160 + } \ 1.1161 +} \ 1.1162 +break; \ 1.1163 +case BASE + 4: \ 1.1164 +case BASE + 12: \ 1.1165 +{ \ 1.1166 + /* OP Rd,Rb,Rm ASR # */ \ 1.1167 + int base = (opcode >> 16) & 0x0F; \ 1.1168 + int shift = (opcode >> 7) & 0x1F; \ 1.1169 + int dest = (opcode >> 12) & 15; \ 1.1170 + bool C_OUT = C_FLAG; \ 1.1171 + u32 value; \ 1.1172 + if (shift) { \ 1.1173 + LOGICAL_ASR_REG \ 1.1174 + } else { \ 1.1175 + if (reg[opcode & 0x0F].I & 0x80000000) { \ 1.1176 + value = 0xFFFFFFFF; \ 1.1177 + C_OUT = true; \ 1.1178 + } else { \ 1.1179 + value = 0; \ 1.1180 + C_OUT = false; \ 1.1181 + } \ 1.1182 + } \ 1.1183 + \ 1.1184 + if (dest == 15) { \ 1.1185 + OPCODE2 \ 1.1186 + /* todo */ \ 1.1187 + if (opcode & 0x00100000) { \ 1.1188 + clockTicks++; \ 1.1189 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1190 + } \ 1.1191 + if (armState) { \ 1.1192 + reg[15].I &= 0xFFFFFFFC; \ 1.1193 + armNextPC = reg[15].I; \ 1.1194 + reg[15].I += 4; \ 1.1195 + } else { \ 1.1196 + reg[15].I &= 0xFFFFFFFE; \ 1.1197 + armNextPC = reg[15].I; \ 1.1198 + reg[15].I += 2; \ 1.1199 + } \ 1.1200 + } else { \ 1.1201 + OPCODE \ 1.1202 + } \ 1.1203 +} \ 1.1204 +break; \ 1.1205 +case BASE + 6: \ 1.1206 +case BASE + 14: \ 1.1207 +{ \ 1.1208 + /* OP Rd,Rb,Rm ROR # */ \ 1.1209 + int base = (opcode >> 16) & 0x0F; \ 1.1210 + int shift = (opcode >> 7) & 0x1F; \ 1.1211 + int dest = (opcode >> 12) & 15; \ 1.1212 + bool C_OUT = C_FLAG; \ 1.1213 + u32 value; \ 1.1214 + if (shift) { \ 1.1215 + LOGICAL_ROR_REG \ 1.1216 + } else { \ 1.1217 + LOGICAL_RRX_REG \ 1.1218 + } \ 1.1219 + if (dest == 15) { \ 1.1220 + OPCODE2 \ 1.1221 + /* todo */ \ 1.1222 + if (opcode & 0x00100000) { \ 1.1223 + clockTicks++; \ 1.1224 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1225 + } \ 1.1226 + if (armState) { \ 1.1227 + reg[15].I &= 0xFFFFFFFC; \ 1.1228 + armNextPC = reg[15].I; \ 1.1229 + reg[15].I += 4; \ 1.1230 + } else { \ 1.1231 + reg[15].I &= 0xFFFFFFFE; \ 1.1232 + armNextPC = reg[15].I; \ 1.1233 + reg[15].I += 2; \ 1.1234 + } \ 1.1235 + } else { \ 1.1236 + OPCODE \ 1.1237 + } \ 1.1238 +} \ 1.1239 +break; \ 1.1240 +case BASE + 1: \ 1.1241 +{ \ 1.1242 + /* OP Rd,Rb,Rm LSL Rs */ \ 1.1243 + clockTicks++; \ 1.1244 + int base = (opcode >> 16) & 0x0F; \ 1.1245 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.1246 + int dest = (opcode >> 12) & 15; \ 1.1247 + bool C_OUT = C_FLAG; \ 1.1248 + u32 value; \ 1.1249 + if (shift) { \ 1.1250 + if (shift == 32) { \ 1.1251 + value = 0; \ 1.1252 + C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false); \ 1.1253 + } else if (shift < 32) { \ 1.1254 + LOGICAL_LSL_REG \ 1.1255 + } else { \ 1.1256 + value = 0; \ 1.1257 + C_OUT = false; \ 1.1258 + } \ 1.1259 + } else { \ 1.1260 + value = reg[opcode & 0x0F].I; \ 1.1261 + } \ 1.1262 + if (dest == 15) { \ 1.1263 + OPCODE2 \ 1.1264 + /* todo */ \ 1.1265 + if (opcode & 0x00100000) { \ 1.1266 + clockTicks++; \ 1.1267 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1268 + } \ 1.1269 + if (armState) { \ 1.1270 + reg[15].I &= 0xFFFFFFFC; \ 1.1271 + armNextPC = reg[15].I; \ 1.1272 + reg[15].I += 4; \ 1.1273 + } else { \ 1.1274 + reg[15].I &= 0xFFFFFFFE; \ 1.1275 + armNextPC = reg[15].I; \ 1.1276 + reg[15].I += 2; \ 1.1277 + } \ 1.1278 + } else { \ 1.1279 + OPCODE \ 1.1280 + } \ 1.1281 +} \ 1.1282 +break; \ 1.1283 +case BASE + 3: \ 1.1284 +{ \ 1.1285 + /* OP Rd,Rb,Rm LSR Rs */ \ 1.1286 + clockTicks++; \ 1.1287 + int base = (opcode >> 16) & 0x0F; \ 1.1288 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.1289 + int dest = (opcode >> 12) & 15; \ 1.1290 + bool C_OUT = C_FLAG; \ 1.1291 + u32 value; \ 1.1292 + if (shift) { \ 1.1293 + if (shift == 32) { \ 1.1294 + value = 0; \ 1.1295 + C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false); \ 1.1296 + } else if (shift < 32) { \ 1.1297 + LOGICAL_LSR_REG \ 1.1298 + } else { \ 1.1299 + value = 0; \ 1.1300 + C_OUT = false; \ 1.1301 + } \ 1.1302 + } else { \ 1.1303 + value = reg[opcode & 0x0F].I; \ 1.1304 + } \ 1.1305 + if (dest == 15) { \ 1.1306 + OPCODE2 \ 1.1307 + /* todo */ \ 1.1308 + if (opcode & 0x00100000) { \ 1.1309 + clockTicks++; \ 1.1310 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1311 + } \ 1.1312 + if (armState) { \ 1.1313 + reg[15].I &= 0xFFFFFFFC; \ 1.1314 + armNextPC = reg[15].I; \ 1.1315 + reg[15].I += 4; \ 1.1316 + } else { \ 1.1317 + reg[15].I &= 0xFFFFFFFE; \ 1.1318 + armNextPC = reg[15].I; \ 1.1319 + reg[15].I += 2; \ 1.1320 + } \ 1.1321 + } else { \ 1.1322 + OPCODE \ 1.1323 + } \ 1.1324 +} \ 1.1325 +break; \ 1.1326 +case BASE + 5: \ 1.1327 +{ \ 1.1328 + /* OP Rd,Rb,Rm ASR Rs */ \ 1.1329 + clockTicks++; \ 1.1330 + int base = (opcode >> 16) & 0x0F; \ 1.1331 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.1332 + int dest = (opcode >> 12) & 15; \ 1.1333 + bool C_OUT = C_FLAG; \ 1.1334 + u32 value; \ 1.1335 + if (shift < 32) { \ 1.1336 + if (shift) { \ 1.1337 + LOGICAL_ASR_REG \ 1.1338 + } else { \ 1.1339 + value = reg[opcode & 0x0F].I; \ 1.1340 + } \ 1.1341 + } else { \ 1.1342 + if (reg[opcode & 0x0F].I & 0x80000000) { \ 1.1343 + value = 0xFFFFFFFF; \ 1.1344 + C_OUT = true; \ 1.1345 + } else { \ 1.1346 + value = 0; \ 1.1347 + C_OUT = false; \ 1.1348 + } \ 1.1349 + } \ 1.1350 + if (dest == 15) { \ 1.1351 + OPCODE2 \ 1.1352 + /* todo */ \ 1.1353 + if (opcode & 0x00100000) { \ 1.1354 + clockTicks++; \ 1.1355 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1356 + } \ 1.1357 + if (armState) { \ 1.1358 + reg[15].I &= 0xFFFFFFFC; \ 1.1359 + armNextPC = reg[15].I; \ 1.1360 + reg[15].I += 4; \ 1.1361 + } else { \ 1.1362 + reg[15].I &= 0xFFFFFFFE; \ 1.1363 + armNextPC = reg[15].I; \ 1.1364 + reg[15].I += 2; \ 1.1365 + } \ 1.1366 + } else { \ 1.1367 + OPCODE \ 1.1368 + } \ 1.1369 +} \ 1.1370 +break; \ 1.1371 +case BASE + 7: \ 1.1372 +{ \ 1.1373 + /* OP Rd,Rb,Rm ROR Rs */ \ 1.1374 + clockTicks++; \ 1.1375 + int base = (opcode >> 16) & 0x0F; \ 1.1376 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.1377 + int dest = (opcode >> 12) & 15; \ 1.1378 + bool C_OUT = C_FLAG; \ 1.1379 + u32 value; \ 1.1380 + if (shift) { \ 1.1381 + shift &= 0x1f; \ 1.1382 + if (shift) { \ 1.1383 + LOGICAL_ROR_REG \ 1.1384 + } else { \ 1.1385 + value = reg[opcode & 0x0F].I; \ 1.1386 + C_OUT = (value & 0x80000000 ? true : false); \ 1.1387 + } \ 1.1388 + } else { \ 1.1389 + value = reg[opcode & 0x0F].I; \ 1.1390 + C_OUT = (value & 0x80000000 ? true : false); \ 1.1391 + } \ 1.1392 + if (dest == 15) { \ 1.1393 + OPCODE2 \ 1.1394 + /* todo */ \ 1.1395 + if (opcode & 0x00100000) { \ 1.1396 + clockTicks++; \ 1.1397 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1398 + } \ 1.1399 + if (armState) { \ 1.1400 + reg[15].I &= 0xFFFFFFFC; \ 1.1401 + armNextPC = reg[15].I; \ 1.1402 + reg[15].I += 4; \ 1.1403 + } else { \ 1.1404 + reg[15].I &= 0xFFFFFFFE; \ 1.1405 + armNextPC = reg[15].I; \ 1.1406 + reg[15].I += 2; \ 1.1407 + } \ 1.1408 + } else { \ 1.1409 + OPCODE \ 1.1410 + } \ 1.1411 +} \ 1.1412 +break; \ 1.1413 +case BASE + 0x200: \ 1.1414 +case BASE + 0x201: \ 1.1415 +case BASE + 0x202: \ 1.1416 +case BASE + 0x203: \ 1.1417 +case BASE + 0x204: \ 1.1418 +case BASE + 0x205: \ 1.1419 +case BASE + 0x206: \ 1.1420 +case BASE + 0x207: \ 1.1421 +case BASE + 0x208: \ 1.1422 +case BASE + 0x209: \ 1.1423 +case BASE + 0x20a: \ 1.1424 +case BASE + 0x20b: \ 1.1425 +case BASE + 0x20c: \ 1.1426 +case BASE + 0x20d: \ 1.1427 +case BASE + 0x20e: \ 1.1428 +case BASE + 0x20f: \ 1.1429 +{ \ 1.1430 + int shift = (opcode & 0xF00) >> 7; \ 1.1431 + int base = (opcode >> 16) & 0x0F; \ 1.1432 + int dest = (opcode >> 12) & 0x0F; \ 1.1433 + bool C_OUT = C_FLAG; \ 1.1434 + u32 value; \ 1.1435 + if (shift) { \ 1.1436 + LOGICAL_ROR_IMM \ 1.1437 + } else { \ 1.1438 + value = opcode & 0xff; \ 1.1439 + } \ 1.1440 + if (dest == 15) { \ 1.1441 + OPCODE2 \ 1.1442 + /* todo */ \ 1.1443 + if (opcode & 0x00100000) { \ 1.1444 + clockTicks++; \ 1.1445 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1446 + } \ 1.1447 + if (armState) { \ 1.1448 + reg[15].I &= 0xFFFFFFFC; \ 1.1449 + armNextPC = reg[15].I; \ 1.1450 + reg[15].I += 4; \ 1.1451 + } else { \ 1.1452 + reg[15].I &= 0xFFFFFFFE; \ 1.1453 + armNextPC = reg[15].I; \ 1.1454 + reg[15].I += 2; \ 1.1455 + } \ 1.1456 + } else { \ 1.1457 + OPCODE \ 1.1458 + } \ 1.1459 +} \ 1.1460 +break; 1.1461 + 1.1462 +#define LOGICAL_DATA_OPCODE_WITHOUT_base(OPCODE, OPCODE2, BASE) \ 1.1463 +case BASE: \ 1.1464 +case BASE + 8: \ 1.1465 +{ \ 1.1466 + /* OP Rd,Rb,Rm LSL # */ \ 1.1467 + int shift = (opcode >> 7) & 0x1F; \ 1.1468 + int dest = (opcode >> 12) & 15; \ 1.1469 + bool C_OUT = C_FLAG; \ 1.1470 + u32 value; \ 1.1471 + \ 1.1472 + if (shift) { \ 1.1473 + LOGICAL_LSL_REG \ 1.1474 + } else { \ 1.1475 + value = reg[opcode & 0x0F].I; \ 1.1476 + } \ 1.1477 + if (dest == 15) { \ 1.1478 + OPCODE2 \ 1.1479 + /* todo */ \ 1.1480 + if (opcode & 0x00100000) { \ 1.1481 + clockTicks++; \ 1.1482 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1483 + } \ 1.1484 + if (armState) { \ 1.1485 + reg[15].I &= 0xFFFFFFFC; \ 1.1486 + armNextPC = reg[15].I; \ 1.1487 + reg[15].I += 4; \ 1.1488 + } else { \ 1.1489 + reg[15].I &= 0xFFFFFFFE; \ 1.1490 + armNextPC = reg[15].I; \ 1.1491 + reg[15].I += 2; \ 1.1492 + } \ 1.1493 + } else { \ 1.1494 + OPCODE \ 1.1495 + } \ 1.1496 +} \ 1.1497 +break; \ 1.1498 +case BASE + 2: \ 1.1499 +case BASE + 10: \ 1.1500 +{ \ 1.1501 + /* OP Rd,Rb,Rm LSR # */ \ 1.1502 + int shift = (opcode >> 7) & 0x1F; \ 1.1503 + int dest = (opcode >> 12) & 15; \ 1.1504 + bool C_OUT = C_FLAG; \ 1.1505 + u32 value; \ 1.1506 + if (shift) { \ 1.1507 + LOGICAL_LSR_REG \ 1.1508 + } else { \ 1.1509 + value = 0; \ 1.1510 + C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false; \ 1.1511 + } \ 1.1512 + \ 1.1513 + if (dest == 15) { \ 1.1514 + OPCODE2 \ 1.1515 + /* todo */ \ 1.1516 + if (opcode & 0x00100000) { \ 1.1517 + clockTicks++; \ 1.1518 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1519 + } \ 1.1520 + if (armState) { \ 1.1521 + reg[15].I &= 0xFFFFFFFC; \ 1.1522 + armNextPC = reg[15].I; \ 1.1523 + reg[15].I += 4; \ 1.1524 + } else { \ 1.1525 + reg[15].I &= 0xFFFFFFFE; \ 1.1526 + armNextPC = reg[15].I; \ 1.1527 + reg[15].I += 2; \ 1.1528 + } \ 1.1529 + } else { \ 1.1530 + OPCODE \ 1.1531 + } \ 1.1532 +} \ 1.1533 +break; \ 1.1534 +case BASE + 4: \ 1.1535 +case BASE + 12: \ 1.1536 +{ \ 1.1537 + /* OP Rd,Rb,Rm ASR # */ \ 1.1538 + int shift = (opcode >> 7) & 0x1F; \ 1.1539 + int dest = (opcode >> 12) & 15; \ 1.1540 + bool C_OUT = C_FLAG; \ 1.1541 + u32 value; \ 1.1542 + if (shift) { \ 1.1543 + LOGICAL_ASR_REG \ 1.1544 + } else { \ 1.1545 + if (reg[opcode & 0x0F].I & 0x80000000) { \ 1.1546 + value = 0xFFFFFFFF; \ 1.1547 + C_OUT = true; \ 1.1548 + } else { \ 1.1549 + value = 0; \ 1.1550 + C_OUT = false; \ 1.1551 + } \ 1.1552 + } \ 1.1553 + \ 1.1554 + if (dest == 15) { \ 1.1555 + OPCODE2 \ 1.1556 + /* todo */ \ 1.1557 + if (opcode & 0x00100000) { \ 1.1558 + clockTicks++; \ 1.1559 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1560 + } \ 1.1561 + if (armState) { \ 1.1562 + reg[15].I &= 0xFFFFFFFC; \ 1.1563 + armNextPC = reg[15].I; \ 1.1564 + reg[15].I += 4; \ 1.1565 + } else { \ 1.1566 + reg[15].I &= 0xFFFFFFFE; \ 1.1567 + armNextPC = reg[15].I; \ 1.1568 + reg[15].I += 2; \ 1.1569 + } \ 1.1570 + } else { \ 1.1571 + OPCODE \ 1.1572 + } \ 1.1573 +} \ 1.1574 +break; \ 1.1575 +case BASE + 6: \ 1.1576 +case BASE + 14: \ 1.1577 +{ \ 1.1578 + /* OP Rd,Rb,Rm ROR # */ \ 1.1579 + int shift = (opcode >> 7) & 0x1F; \ 1.1580 + int dest = (opcode >> 12) & 15; \ 1.1581 + bool C_OUT = C_FLAG; \ 1.1582 + u32 value; \ 1.1583 + if (shift) { \ 1.1584 + LOGICAL_ROR_REG \ 1.1585 + } else { \ 1.1586 + LOGICAL_RRX_REG \ 1.1587 + } \ 1.1588 + if (dest == 15) { \ 1.1589 + OPCODE2 \ 1.1590 + /* todo */ \ 1.1591 + if (opcode & 0x00100000) { \ 1.1592 + clockTicks++; \ 1.1593 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1594 + } \ 1.1595 + if (armState) { \ 1.1596 + reg[15].I &= 0xFFFFFFFC; \ 1.1597 + armNextPC = reg[15].I; \ 1.1598 + reg[15].I += 4; \ 1.1599 + } else { \ 1.1600 + reg[15].I &= 0xFFFFFFFE; \ 1.1601 + armNextPC = reg[15].I; \ 1.1602 + reg[15].I += 2; \ 1.1603 + } \ 1.1604 + } else { \ 1.1605 + OPCODE \ 1.1606 + } \ 1.1607 +} \ 1.1608 +break; \ 1.1609 +case BASE + 1: \ 1.1610 +{ \ 1.1611 + /* OP Rd,Rb,Rm LSL Rs */ \ 1.1612 + clockTicks++; \ 1.1613 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.1614 + int dest = (opcode >> 12) & 15; \ 1.1615 + bool C_OUT = C_FLAG; \ 1.1616 + u32 value; \ 1.1617 + if (shift) { \ 1.1618 + if (shift == 32) { \ 1.1619 + value = 0; \ 1.1620 + C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false); \ 1.1621 + } else if (shift < 32) { \ 1.1622 + LOGICAL_LSL_REG \ 1.1623 + } else { \ 1.1624 + value = 0; \ 1.1625 + C_OUT = false; \ 1.1626 + } \ 1.1627 + } else { \ 1.1628 + value = reg[opcode & 0x0F].I; \ 1.1629 + } \ 1.1630 + if (dest == 15) { \ 1.1631 + OPCODE2 \ 1.1632 + /* todo */ \ 1.1633 + if (opcode & 0x00100000) { \ 1.1634 + clockTicks++; \ 1.1635 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1636 + } \ 1.1637 + if (armState) { \ 1.1638 + reg[15].I &= 0xFFFFFFFC; \ 1.1639 + armNextPC = reg[15].I; \ 1.1640 + reg[15].I += 4; \ 1.1641 + } else { \ 1.1642 + reg[15].I &= 0xFFFFFFFE; \ 1.1643 + armNextPC = reg[15].I; \ 1.1644 + reg[15].I += 2; \ 1.1645 + } \ 1.1646 + } else { \ 1.1647 + OPCODE \ 1.1648 + } \ 1.1649 +} \ 1.1650 +break; \ 1.1651 +case BASE + 3: \ 1.1652 +{ \ 1.1653 + /* OP Rd,Rb,Rm LSR Rs */ \ 1.1654 + clockTicks++; \ 1.1655 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.1656 + int dest = (opcode >> 12) & 15; \ 1.1657 + bool C_OUT = C_FLAG; \ 1.1658 + u32 value; \ 1.1659 + if (shift) { \ 1.1660 + if (shift == 32) { \ 1.1661 + value = 0; \ 1.1662 + C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false); \ 1.1663 + } else if (shift < 32) { \ 1.1664 + LOGICAL_LSR_REG \ 1.1665 + } else { \ 1.1666 + value = 0; \ 1.1667 + C_OUT = false; \ 1.1668 + } \ 1.1669 + } else { \ 1.1670 + value = reg[opcode & 0x0F].I; \ 1.1671 + } \ 1.1672 + if (dest == 15) { \ 1.1673 + OPCODE2 \ 1.1674 + /* todo */ \ 1.1675 + if (opcode & 0x00100000) { \ 1.1676 + clockTicks++; \ 1.1677 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1678 + } \ 1.1679 + if (armState) { \ 1.1680 + reg[15].I &= 0xFFFFFFFC; \ 1.1681 + armNextPC = reg[15].I; \ 1.1682 + reg[15].I += 4; \ 1.1683 + } else { \ 1.1684 + reg[15].I &= 0xFFFFFFFE; \ 1.1685 + armNextPC = reg[15].I; \ 1.1686 + reg[15].I += 2; \ 1.1687 + } \ 1.1688 + } else { \ 1.1689 + OPCODE \ 1.1690 + } \ 1.1691 +} \ 1.1692 +break; \ 1.1693 +case BASE + 5: \ 1.1694 +{ \ 1.1695 + /* OP Rd,Rb,Rm ASR Rs */ \ 1.1696 + clockTicks++; \ 1.1697 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.1698 + int dest = (opcode >> 12) & 15; \ 1.1699 + bool C_OUT = C_FLAG; \ 1.1700 + u32 value; \ 1.1701 + if (shift < 32) { \ 1.1702 + if (shift) { \ 1.1703 + LOGICAL_ASR_REG \ 1.1704 + } else { \ 1.1705 + value = reg[opcode & 0x0F].I; \ 1.1706 + } \ 1.1707 + } else { \ 1.1708 + if (reg[opcode & 0x0F].I & 0x80000000) { \ 1.1709 + value = 0xFFFFFFFF; \ 1.1710 + C_OUT = true; \ 1.1711 + } else { \ 1.1712 + value = 0; \ 1.1713 + C_OUT = false; \ 1.1714 + } \ 1.1715 + } \ 1.1716 + if (dest == 15) { \ 1.1717 + OPCODE2 \ 1.1718 + /* todo */ \ 1.1719 + if (opcode & 0x00100000) { \ 1.1720 + clockTicks++; \ 1.1721 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1722 + } \ 1.1723 + if (armState) { \ 1.1724 + reg[15].I &= 0xFFFFFFFC; \ 1.1725 + armNextPC = reg[15].I; \ 1.1726 + reg[15].I += 4; \ 1.1727 + } else { \ 1.1728 + reg[15].I &= 0xFFFFFFFE; \ 1.1729 + armNextPC = reg[15].I; \ 1.1730 + reg[15].I += 2; \ 1.1731 + } \ 1.1732 + } else { \ 1.1733 + OPCODE \ 1.1734 + } \ 1.1735 +} \ 1.1736 +break; \ 1.1737 +case BASE + 7: \ 1.1738 +{ \ 1.1739 + /* OP Rd,Rb,Rm ROR Rs */ \ 1.1740 + clockTicks++; \ 1.1741 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.1742 + int dest = (opcode >> 12) & 15; \ 1.1743 + bool C_OUT = C_FLAG; \ 1.1744 + u32 value; \ 1.1745 + if (shift) { \ 1.1746 + shift &= 0x1f; \ 1.1747 + if (shift) { \ 1.1748 + LOGICAL_ROR_REG \ 1.1749 + } else { \ 1.1750 + value = reg[opcode & 0x0F].I; \ 1.1751 + C_OUT = (value & 0x80000000 ? true : false); \ 1.1752 + } \ 1.1753 + } else { \ 1.1754 + value = reg[opcode & 0x0F].I; \ 1.1755 + C_OUT = (value & 0x80000000 ? true : false); \ 1.1756 + } \ 1.1757 + if (dest == 15) { \ 1.1758 + OPCODE2 \ 1.1759 + /* todo */ \ 1.1760 + if (opcode & 0x00100000) { \ 1.1761 + clockTicks++; \ 1.1762 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1763 + } \ 1.1764 + if (armState) { \ 1.1765 + reg[15].I &= 0xFFFFFFFC; \ 1.1766 + armNextPC = reg[15].I; \ 1.1767 + reg[15].I += 4; \ 1.1768 + } else { \ 1.1769 + reg[15].I &= 0xFFFFFFFE; \ 1.1770 + armNextPC = reg[15].I; \ 1.1771 + reg[15].I += 2; \ 1.1772 + } \ 1.1773 + } else { \ 1.1774 + OPCODE \ 1.1775 + } \ 1.1776 +} \ 1.1777 +break; \ 1.1778 +case BASE + 0x200: \ 1.1779 +case BASE + 0x201: \ 1.1780 +case BASE + 0x202: \ 1.1781 +case BASE + 0x203: \ 1.1782 +case BASE + 0x204: \ 1.1783 +case BASE + 0x205: \ 1.1784 +case BASE + 0x206: \ 1.1785 +case BASE + 0x207: \ 1.1786 +case BASE + 0x208: \ 1.1787 +case BASE + 0x209: \ 1.1788 +case BASE + 0x20a: \ 1.1789 +case BASE + 0x20b: \ 1.1790 +case BASE + 0x20c: \ 1.1791 +case BASE + 0x20d: \ 1.1792 +case BASE + 0x20e: \ 1.1793 +case BASE + 0x20f: \ 1.1794 +{ \ 1.1795 + int shift = (opcode & 0xF00) >> 7; \ 1.1796 + int dest = (opcode >> 12) & 0x0F; \ 1.1797 + bool C_OUT = C_FLAG; \ 1.1798 + u32 value; \ 1.1799 + if (shift) { \ 1.1800 + LOGICAL_ROR_IMM \ 1.1801 + } else { \ 1.1802 + value = opcode & 0xff; \ 1.1803 + } \ 1.1804 + if (dest == 15) { \ 1.1805 + OPCODE2 \ 1.1806 + /* todo */ \ 1.1807 + if (opcode & 0x00100000) { \ 1.1808 + clockTicks++; \ 1.1809 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1810 + } \ 1.1811 + if (armState) { \ 1.1812 + reg[15].I &= 0xFFFFFFFC; \ 1.1813 + armNextPC = reg[15].I; \ 1.1814 + reg[15].I += 4; \ 1.1815 + } else { \ 1.1816 + reg[15].I &= 0xFFFFFFFE; \ 1.1817 + armNextPC = reg[15].I; \ 1.1818 + reg[15].I += 2; \ 1.1819 + } \ 1.1820 + } else { \ 1.1821 + OPCODE \ 1.1822 + } \ 1.1823 +} \ 1.1824 +break; 1.1825 + 1.1826 +#define ARITHMETIC_DATA_OPCODE(OPCODE, OPCODE2, BASE) \ 1.1827 +case BASE: \ 1.1828 +case BASE + 8: \ 1.1829 +{ \ 1.1830 + /* OP Rd,Rb,Rm LSL # */ \ 1.1831 + int base = (opcode >> 16) & 0x0F; \ 1.1832 + int shift = (opcode >> 7) & 0x1F; \ 1.1833 + int dest = (opcode >> 12) & 15; \ 1.1834 + u32 value; \ 1.1835 + if (shift) { \ 1.1836 + ARITHMETIC_LSL_REG \ 1.1837 + } else { \ 1.1838 + value = reg[opcode & 0x0F].I; \ 1.1839 + } \ 1.1840 + if (dest == 15) { \ 1.1841 + OPCODE2 \ 1.1842 + /* todo */ \ 1.1843 + if (opcode & 0x00100000) { \ 1.1844 + clockTicks++; \ 1.1845 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1846 + } \ 1.1847 + if (armState) { \ 1.1848 + reg[15].I &= 0xFFFFFFFC; \ 1.1849 + armNextPC = reg[15].I; \ 1.1850 + reg[15].I += 4; \ 1.1851 + } else { \ 1.1852 + reg[15].I &= 0xFFFFFFFE; \ 1.1853 + armNextPC = reg[15].I; \ 1.1854 + reg[15].I += 2; \ 1.1855 + } \ 1.1856 + } else { \ 1.1857 + OPCODE \ 1.1858 + } \ 1.1859 +} \ 1.1860 +break; \ 1.1861 +case BASE + 2: \ 1.1862 +case BASE + 10: \ 1.1863 +{ \ 1.1864 + /* OP Rd,Rb,Rm LSR # */ \ 1.1865 + int base = (opcode >> 16) & 0x0F; \ 1.1866 + int shift = (opcode >> 7) & 0x1F; \ 1.1867 + int dest = (opcode >> 12) & 15; \ 1.1868 + u32 value; \ 1.1869 + if (shift) { \ 1.1870 + ARITHMETIC_LSR_REG \ 1.1871 + } else { \ 1.1872 + value = 0; \ 1.1873 + } \ 1.1874 + if (dest == 15) { \ 1.1875 + OPCODE2 \ 1.1876 + /* todo */ \ 1.1877 + if (opcode & 0x00100000) { \ 1.1878 + clockTicks++; \ 1.1879 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1880 + } \ 1.1881 + if (armState) { \ 1.1882 + reg[15].I &= 0xFFFFFFFC; \ 1.1883 + armNextPC = reg[15].I; \ 1.1884 + reg[15].I += 4; \ 1.1885 + } else { \ 1.1886 + reg[15].I &= 0xFFFFFFFE; \ 1.1887 + armNextPC = reg[15].I; \ 1.1888 + reg[15].I += 2; \ 1.1889 + } \ 1.1890 + } else { \ 1.1891 + OPCODE \ 1.1892 + } \ 1.1893 +} \ 1.1894 +break; \ 1.1895 +case BASE + 4: \ 1.1896 +case BASE + 12: \ 1.1897 +{ \ 1.1898 + /* OP Rd,Rb,Rm ASR # */ \ 1.1899 + int base = (opcode >> 16) & 0x0F; \ 1.1900 + int shift = (opcode >> 7) & 0x1F; \ 1.1901 + int dest = (opcode >> 12) & 15; \ 1.1902 + u32 value; \ 1.1903 + if (shift) { \ 1.1904 + ARITHMETIC_ASR_REG \ 1.1905 + } else { \ 1.1906 + if (reg[opcode & 0x0F].I & 0x80000000) { \ 1.1907 + value = 0xFFFFFFFF; \ 1.1908 + } else value = 0; \ 1.1909 + } \ 1.1910 + if (dest == 15) { \ 1.1911 + OPCODE2 \ 1.1912 + /* todo */ \ 1.1913 + if (opcode & 0x00100000) { \ 1.1914 + clockTicks++; \ 1.1915 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1916 + } \ 1.1917 + if (armState) { \ 1.1918 + reg[15].I &= 0xFFFFFFFC; \ 1.1919 + armNextPC = reg[15].I; \ 1.1920 + reg[15].I += 4; \ 1.1921 + } else { \ 1.1922 + reg[15].I &= 0xFFFFFFFE; \ 1.1923 + armNextPC = reg[15].I; \ 1.1924 + reg[15].I += 2; \ 1.1925 + } \ 1.1926 + } else { \ 1.1927 + OPCODE \ 1.1928 + } \ 1.1929 +} \ 1.1930 +break; \ 1.1931 +case BASE + 6: \ 1.1932 +case BASE + 14: \ 1.1933 +{ \ 1.1934 + /* OP Rd,Rb,Rm ROR # */ \ 1.1935 + int base = (opcode >> 16) & 0x0F; \ 1.1936 + int shift = (opcode >> 7) & 0x1F; \ 1.1937 + int dest = (opcode >> 12) & 15; \ 1.1938 + u32 value; \ 1.1939 + if (shift) { \ 1.1940 + ARITHMETIC_ROR_REG \ 1.1941 + } else { \ 1.1942 + ARITHMETIC_RRX_REG \ 1.1943 + } \ 1.1944 + if (dest == 15) { \ 1.1945 + OPCODE2 \ 1.1946 + /* todo */ \ 1.1947 + if (opcode & 0x00100000) { \ 1.1948 + clockTicks++; \ 1.1949 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1950 + } \ 1.1951 + if (armState) { \ 1.1952 + reg[15].I &= 0xFFFFFFFC; \ 1.1953 + armNextPC = reg[15].I; \ 1.1954 + reg[15].I += 4; \ 1.1955 + } else { \ 1.1956 + reg[15].I &= 0xFFFFFFFE; \ 1.1957 + armNextPC = reg[15].I; \ 1.1958 + reg[15].I += 2; \ 1.1959 + } \ 1.1960 + } else { \ 1.1961 + OPCODE \ 1.1962 + } \ 1.1963 +} \ 1.1964 +break; \ 1.1965 +case BASE + 1: \ 1.1966 +{ \ 1.1967 + /* OP Rd,Rb,Rm LSL Rs */ \ 1.1968 + clockTicks++; \ 1.1969 + int base = (opcode >> 16) & 0x0F; \ 1.1970 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.1971 + int dest = (opcode >> 12) & 15; \ 1.1972 + u32 value; \ 1.1973 + if (shift) { \ 1.1974 + if (shift == 32) { \ 1.1975 + value = 0; \ 1.1976 + } else if (shift < 32) { \ 1.1977 + ARITHMETIC_LSL_REG \ 1.1978 + } else value = 0; \ 1.1979 + } else { \ 1.1980 + value = reg[opcode & 0x0F].I; \ 1.1981 + } \ 1.1982 + if (dest == 15) { \ 1.1983 + OPCODE2 \ 1.1984 + /* todo */ \ 1.1985 + if (opcode & 0x00100000) { \ 1.1986 + clockTicks++; \ 1.1987 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.1988 + } \ 1.1989 + if (armState) { \ 1.1990 + reg[15].I &= 0xFFFFFFFC; \ 1.1991 + armNextPC = reg[15].I; \ 1.1992 + reg[15].I += 4; \ 1.1993 + } else { \ 1.1994 + reg[15].I &= 0xFFFFFFFE; \ 1.1995 + armNextPC = reg[15].I; \ 1.1996 + reg[15].I += 2; \ 1.1997 + } \ 1.1998 + } else { \ 1.1999 + OPCODE \ 1.2000 + } \ 1.2001 +} \ 1.2002 +break; \ 1.2003 +case BASE + 3: \ 1.2004 +{ \ 1.2005 + /* OP Rd,Rb,Rm LSR Rs */ \ 1.2006 + clockTicks++; \ 1.2007 + int base = (opcode >> 16) & 0x0F; \ 1.2008 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.2009 + int dest = (opcode >> 12) & 15; \ 1.2010 + u32 value; \ 1.2011 + if (shift) { \ 1.2012 + if (shift == 32) { \ 1.2013 + value = 0; \ 1.2014 + } else if (shift < 32) { \ 1.2015 + ARITHMETIC_LSR_REG \ 1.2016 + } else value = 0; \ 1.2017 + } else { \ 1.2018 + value = reg[opcode & 0x0F].I; \ 1.2019 + } \ 1.2020 + if (dest == 15) { \ 1.2021 + OPCODE2 \ 1.2022 + /* todo */ \ 1.2023 + if (opcode & 0x00100000) { \ 1.2024 + clockTicks++; \ 1.2025 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.2026 + } \ 1.2027 + if (armState) { \ 1.2028 + reg[15].I &= 0xFFFFFFFC; \ 1.2029 + armNextPC = reg[15].I; \ 1.2030 + reg[15].I += 4; \ 1.2031 + } else { \ 1.2032 + reg[15].I &= 0xFFFFFFFE; \ 1.2033 + armNextPC = reg[15].I; \ 1.2034 + reg[15].I += 2; \ 1.2035 + } \ 1.2036 + } else { \ 1.2037 + OPCODE \ 1.2038 + } \ 1.2039 +} \ 1.2040 +break; \ 1.2041 +case BASE + 5: \ 1.2042 +{ \ 1.2043 + /* OP Rd,Rb,Rm ASR Rs */ \ 1.2044 + clockTicks++; \ 1.2045 + int base = (opcode >> 16) & 0x0F; \ 1.2046 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.2047 + int dest = (opcode >> 12) & 15; \ 1.2048 + u32 value; \ 1.2049 + if (shift < 32) { \ 1.2050 + if (shift) { \ 1.2051 + ARITHMETIC_ASR_REG \ 1.2052 + } else { \ 1.2053 + value = reg[opcode & 0x0F].I; \ 1.2054 + } \ 1.2055 + } else { \ 1.2056 + if (reg[opcode & 0x0F].I & 0x80000000) { \ 1.2057 + value = 0xFFFFFFFF; \ 1.2058 + } else value = 0; \ 1.2059 + } \ 1.2060 + if (dest == 15) { \ 1.2061 + OPCODE2 \ 1.2062 + /* todo */ \ 1.2063 + if (opcode & 0x00100000) { \ 1.2064 + clockTicks++; \ 1.2065 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.2066 + } \ 1.2067 + if (armState) { \ 1.2068 + reg[15].I &= 0xFFFFFFFC; \ 1.2069 + armNextPC = reg[15].I; \ 1.2070 + reg[15].I += 4; \ 1.2071 + } else { \ 1.2072 + reg[15].I &= 0xFFFFFFFE; \ 1.2073 + armNextPC = reg[15].I; \ 1.2074 + reg[15].I += 2; \ 1.2075 + } \ 1.2076 + } else { \ 1.2077 + OPCODE \ 1.2078 + } \ 1.2079 +} \ 1.2080 +break; \ 1.2081 +case BASE + 7: \ 1.2082 +{ \ 1.2083 + /* OP Rd,Rb,Rm ROR Rs */ \ 1.2084 + clockTicks++; \ 1.2085 + int base = (opcode >> 16) & 0x0F; \ 1.2086 + int shift = reg[(opcode >> 8) & 15].B.B0; \ 1.2087 + int dest = (opcode >> 12) & 15; \ 1.2088 + u32 value; \ 1.2089 + if (shift) { \ 1.2090 + shift &= 0x1f; \ 1.2091 + if (shift) { \ 1.2092 + ARITHMETIC_ROR_REG \ 1.2093 + } else { \ 1.2094 + value = reg[opcode & 0x0F].I; \ 1.2095 + } \ 1.2096 + } else { \ 1.2097 + value = reg[opcode & 0x0F].I; \ 1.2098 + } \ 1.2099 + if (dest == 15) { \ 1.2100 + OPCODE2 \ 1.2101 + /* todo */ \ 1.2102 + if (opcode & 0x00100000) { \ 1.2103 + clockTicks++; \ 1.2104 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.2105 + } \ 1.2106 + if (armState) { \ 1.2107 + reg[15].I &= 0xFFFFFFFC; \ 1.2108 + armNextPC = reg[15].I; \ 1.2109 + reg[15].I += 4; \ 1.2110 + } else { \ 1.2111 + reg[15].I &= 0xFFFFFFFE; \ 1.2112 + armNextPC = reg[15].I; \ 1.2113 + reg[15].I += 2; \ 1.2114 + } \ 1.2115 + } else { \ 1.2116 + OPCODE \ 1.2117 + } \ 1.2118 +} \ 1.2119 +break; \ 1.2120 +case BASE + 0x200: \ 1.2121 +case BASE + 0x201: \ 1.2122 +case BASE + 0x202: \ 1.2123 +case BASE + 0x203: \ 1.2124 +case BASE + 0x204: \ 1.2125 +case BASE + 0x205: \ 1.2126 +case BASE + 0x206: \ 1.2127 +case BASE + 0x207: \ 1.2128 +case BASE + 0x208: \ 1.2129 +case BASE + 0x209: \ 1.2130 +case BASE + 0x20a: \ 1.2131 +case BASE + 0x20b: \ 1.2132 +case BASE + 0x20c: \ 1.2133 +case BASE + 0x20d: \ 1.2134 +case BASE + 0x20e: \ 1.2135 +case BASE + 0x20f: \ 1.2136 +{ \ 1.2137 + int shift = (opcode & 0xF00) >> 7; \ 1.2138 + int base = (opcode >> 16) & 0x0F; \ 1.2139 + int dest = (opcode >> 12) & 0x0F; \ 1.2140 + u32 value; \ 1.2141 + { \ 1.2142 + ARITHMETIC_ROR_IMM \ 1.2143 + } \ 1.2144 + if (dest == 15) { \ 1.2145 + OPCODE2 \ 1.2146 + /* todo */ \ 1.2147 + if (opcode & 0x00100000) { \ 1.2148 + clockTicks++; \ 1.2149 + CPUSwitchMode(reg[17].I & 0x1f, false); \ 1.2150 + } \ 1.2151 + if (armState) { \ 1.2152 + reg[15].I &= 0xFFFFFFFC; \ 1.2153 + armNextPC = reg[15].I; \ 1.2154 + reg[15].I += 4; \ 1.2155 + } else { \ 1.2156 + reg[15].I &= 0xFFFFFFFE; \ 1.2157 + armNextPC = reg[15].I; \ 1.2158 + reg[15].I += 2; \ 1.2159 + } \ 1.2160 + } else { \ 1.2161 + OPCODE \ 1.2162 + } \ 1.2163 +} \ 1.2164 +break; 1.2165 + 1.2166 +u32 opcode = CPUReadMemoryQuick(armNextPC); 1.2167 + 1.2168 +clockTicks = memoryWaitFetch32[(armNextPC >> 24) & 15]; 1.2169 + 1.2170 +#ifndef FINAL_VERSION 1.2171 +if (armNextPC == stop) 1.2172 +{ 1.2173 + armNextPC++; 1.2174 +} 1.2175 +#endif 1.2176 + 1.2177 +armNextPC = reg[15].I; 1.2178 +reg[15].I += 4; 1.2179 +int cond = opcode >> 28; 1.2180 +// suggested optimization for frequent cases 1.2181 +bool cond_res; 1.2182 +if (cond == 0x0e) 1.2183 +{ 1.2184 + cond_res = true; 1.2185 +} 1.2186 +else 1.2187 +{ 1.2188 + switch (cond) 1.2189 + { 1.2190 + case 0x00: // EQ 1.2191 + cond_res = Z_FLAG; 1.2192 + break; 1.2193 + case 0x01: // NE 1.2194 + cond_res = !Z_FLAG; 1.2195 + break; 1.2196 + case 0x02: // CS 1.2197 + cond_res = C_FLAG; 1.2198 + break; 1.2199 + case 0x03: // CC 1.2200 + cond_res = !C_FLAG; 1.2201 + break; 1.2202 + case 0x04: // MI 1.2203 + cond_res = N_FLAG; 1.2204 + break; 1.2205 + case 0x05: // PL 1.2206 + cond_res = !N_FLAG; 1.2207 + break; 1.2208 + case 0x06: // VS 1.2209 + cond_res = V_FLAG; 1.2210 + break; 1.2211 + case 0x07: // VC 1.2212 + cond_res = !V_FLAG; 1.2213 + break; 1.2214 + case 0x08: // HI 1.2215 + cond_res = C_FLAG && !Z_FLAG; 1.2216 + break; 1.2217 + case 0x09: // LS 1.2218 + cond_res = !C_FLAG || Z_FLAG; 1.2219 + break; 1.2220 + case 0x0A: // GE 1.2221 + cond_res = N_FLAG == V_FLAG; 1.2222 + break; 1.2223 + case 0x0B: // LT 1.2224 + cond_res = N_FLAG != V_FLAG; 1.2225 + break; 1.2226 + case 0x0C: // GT 1.2227 + cond_res = !Z_FLAG && (N_FLAG == V_FLAG); 1.2228 + break; 1.2229 + case 0x0D: // LE 1.2230 + cond_res = Z_FLAG || (N_FLAG != V_FLAG); 1.2231 + break; 1.2232 + case 0x0E: 1.2233 + cond_res = true; 1.2234 + break; 1.2235 + case 0x0F: 1.2236 + default: 1.2237 + // ??? 1.2238 + cond_res = false; 1.2239 + break; 1.2240 + } 1.2241 +} 1.2242 + 1.2243 +if (cond_res) 1.2244 +{ 1.2245 + switch (((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x0F)) 1.2246 + { 1.2247 + LOGICAL_DATA_OPCODE_WITHOUT_base(OP_AND, OP_AND, 0x000); 1.2248 + LOGICAL_DATA_OPCODE_WITHOUT_base(OP_ANDS, OP_AND, 0x010); 1.2249 + case 0x009: 1.2250 + { 1.2251 + // MUL Rd, Rm, Rs 1.2252 + int dest = (opcode >> 16) & 0x0F; 1.2253 + int mult = (opcode & 0x0F); 1.2254 + u32 rs = reg[(opcode >> 8) & 0x0F].I; 1.2255 + reg[dest].I = reg[mult].I * rs; 1.2256 + if (((s32)rs) < 0) 1.2257 + rs = ~rs; 1.2258 + if ((rs & 0xFFFFFF00) == 0) 1.2259 + clockTicks += 2; 1.2260 + else if ((rs & 0xFFFF0000) == 0) 1.2261 + clockTicks += 3; 1.2262 + else if ((rs & 0xFF000000) == 0) 1.2263 + clockTicks += 4; 1.2264 + else 1.2265 + clockTicks += 5; 1.2266 + } 1.2267 + break; 1.2268 + case 0x019: 1.2269 + { 1.2270 + // MULS Rd, Rm, Rs 1.2271 + int dest = (opcode >> 16) & 0x0F; 1.2272 + int mult = (opcode & 0x0F); 1.2273 + u32 rs = reg[(opcode >> 8) & 0x0F].I; 1.2274 + reg[dest].I = reg[mult].I * rs; 1.2275 + N_FLAG = (reg[dest].I & 0x80000000) ? true : false; 1.2276 + Z_FLAG = (reg[dest].I) ? false : true; 1.2277 + if (((s32)rs) < 0) 1.2278 + rs = ~rs; 1.2279 + if ((rs & 0xFFFFFF00) == 0) 1.2280 + clockTicks += 2; 1.2281 + else if ((rs & 0xFFFF0000) == 0) 1.2282 + clockTicks += 3; 1.2283 + else if ((rs & 0xFF000000) == 0) 1.2284 + clockTicks += 4; 1.2285 + else 1.2286 + clockTicks += 5; 1.2287 + } 1.2288 + break; 1.2289 + case 0x00b: 1.2290 + case 0x02b: 1.2291 + { 1.2292 + // STRH Rd, [Rn], -Rm 1.2293 + int base = (opcode >> 16) & 0x0F; 1.2294 + int dest = (opcode >> 12) & 0x0F; 1.2295 + u32 address = reg[base].I; 1.2296 + int offset = reg[opcode & 0x0F].I; 1.2297 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2298 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2299 + address -= offset; 1.2300 + reg[base].I = address; 1.2301 + } 1.2302 + break; 1.2303 + case 0x04b: 1.2304 + case 0x06b: 1.2305 + { 1.2306 + // STRH Rd, [Rn], #-offset 1.2307 + int base = (opcode >> 16) & 0x0F; 1.2308 + int dest = (opcode >> 12) & 0x0F; 1.2309 + u32 address = reg[base].I; 1.2310 + int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 1.2311 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2312 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2313 + address -= offset; 1.2314 + reg[base].I = address; 1.2315 + } 1.2316 + break; 1.2317 + case 0x08b: 1.2318 + case 0x0ab: 1.2319 + { 1.2320 + // STRH Rd, [Rn], Rm 1.2321 + int base = (opcode >> 16) & 0x0F; 1.2322 + int dest = (opcode >> 12) & 0x0F; 1.2323 + u32 address = reg[base].I; 1.2324 + int offset = reg[opcode & 0x0F].I; 1.2325 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2326 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2327 + address += offset; 1.2328 + reg[base].I = address; 1.2329 + } 1.2330 + break; 1.2331 + case 0x0cb: 1.2332 + case 0x0eb: 1.2333 + { 1.2334 + // STRH Rd, [Rn], #offset 1.2335 + int base = (opcode >> 16) & 0x0F; 1.2336 + int dest = (opcode >> 12) & 0x0F; 1.2337 + u32 address = reg[base].I; 1.2338 + int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 1.2339 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2340 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2341 + address += offset; 1.2342 + reg[base].I = address; 1.2343 + } 1.2344 + break; 1.2345 + case 0x10b: 1.2346 + { 1.2347 + // STRH Rd, [Rn, -Rm] 1.2348 + int base = (opcode >> 16) & 0x0F; 1.2349 + int dest = (opcode >> 12) & 0x0F; 1.2350 + u32 address = reg[base].I - reg[opcode & 0x0F].I; 1.2351 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2352 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2353 + } 1.2354 + break; 1.2355 + case 0x12b: 1.2356 + { 1.2357 + // STRH Rd, [Rn, -Rm]! 1.2358 + int base = (opcode >> 16) & 0x0F; 1.2359 + int dest = (opcode >> 12) & 0x0F; 1.2360 + u32 address = reg[base].I - reg[opcode & 0x0F].I; 1.2361 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2362 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2363 + reg[base].I = address; 1.2364 + } 1.2365 + break; 1.2366 + case 0x14b: 1.2367 + { 1.2368 + // STRH Rd, [Rn, -#offset] 1.2369 + int base = (opcode >> 16) & 0x0F; 1.2370 + int dest = (opcode >> 12) & 0x0F; 1.2371 + u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2372 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2373 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2374 + } 1.2375 + break; 1.2376 + case 0x16b: 1.2377 + { 1.2378 + // STRH Rd, [Rn, -#offset]! 1.2379 + int base = (opcode >> 16) & 0x0F; 1.2380 + int dest = (opcode >> 12) & 0x0F; 1.2381 + u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2382 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2383 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2384 + reg[base].I = address; 1.2385 + } 1.2386 + break; 1.2387 + case 0x18b: 1.2388 + { 1.2389 + // STRH Rd, [Rn, Rm] 1.2390 + int base = (opcode >> 16) & 0x0F; 1.2391 + int dest = (opcode >> 12) & 0x0F; 1.2392 + u32 address = reg[base].I + reg[opcode & 0x0F].I; 1.2393 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2394 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2395 + } 1.2396 + break; 1.2397 + case 0x1ab: 1.2398 + { 1.2399 + // STRH Rd, [Rn, Rm]! 1.2400 + int base = (opcode >> 16) & 0x0F; 1.2401 + int dest = (opcode >> 12) & 0x0F; 1.2402 + u32 address = reg[base].I + reg[opcode & 0x0F].I; 1.2403 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2404 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2405 + reg[base].I = address; 1.2406 + } 1.2407 + break; 1.2408 + case 0x1cb: 1.2409 + { 1.2410 + // STRH Rd, [Rn, #offset] 1.2411 + int base = (opcode >> 16) & 0x0F; 1.2412 + int dest = (opcode >> 12) & 0x0F; 1.2413 + u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2414 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2415 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2416 + } 1.2417 + break; 1.2418 + case 0x1eb: 1.2419 + { 1.2420 + // STRH Rd, [Rn, #offset]! 1.2421 + int base = (opcode >> 16) & 0x0F; 1.2422 + int dest = (opcode >> 12) & 0x0F; 1.2423 + u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2424 + clockTicks += 4 + CPUUpdateTicksAccess16(address); 1.2425 + CPUWriteHalfWord(address, reg[dest].W.W0); 1.2426 + reg[base].I = address; 1.2427 + } 1.2428 + break; 1.2429 + case 0x01b: 1.2430 + case 0x03b: 1.2431 + { 1.2432 + // LDRH Rd, [Rn], -Rm 1.2433 + int base = (opcode >> 16) & 0x0F; 1.2434 + int dest = (opcode >> 12) & 0x0F; 1.2435 + u32 address = reg[base].I; 1.2436 + int offset = reg[opcode & 0x0F].I; 1.2437 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2438 + reg[dest].I = CPUReadHalfWord(address); 1.2439 + if (dest != base) 1.2440 + { 1.2441 + address -= offset; 1.2442 + reg[base].I = address; 1.2443 + } 1.2444 + } 1.2445 + break; 1.2446 + case 0x05b: 1.2447 + case 0x07b: 1.2448 + { 1.2449 + // LDRH Rd, [Rn], #-offset 1.2450 + int base = (opcode >> 16) & 0x0F; 1.2451 + int dest = (opcode >> 12) & 0x0F; 1.2452 + u32 address = reg[base].I; 1.2453 + int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 1.2454 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2455 + reg[dest].I = CPUReadHalfWord(address); 1.2456 + if (dest != base) 1.2457 + { 1.2458 + address -= offset; 1.2459 + reg[base].I = address; 1.2460 + } 1.2461 + } 1.2462 + break; 1.2463 + case 0x09b: 1.2464 + case 0x0bb: 1.2465 + { 1.2466 + // LDRH Rd, [Rn], Rm 1.2467 + int base = (opcode >> 16) & 0x0F; 1.2468 + int dest = (opcode >> 12) & 0x0F; 1.2469 + u32 address = reg[base].I; 1.2470 + int offset = reg[opcode & 0x0F].I; 1.2471 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2472 + reg[dest].I = CPUReadHalfWord(address); 1.2473 + if (dest != base) 1.2474 + { 1.2475 + address += offset; 1.2476 + reg[base].I = address; 1.2477 + } 1.2478 + } 1.2479 + break; 1.2480 + case 0x0db: 1.2481 + case 0x0fb: 1.2482 + { 1.2483 + // LDRH Rd, [Rn], #offset 1.2484 + int base = (opcode >> 16) & 0x0F; 1.2485 + int dest = (opcode >> 12) & 0x0F; 1.2486 + u32 address = reg[base].I; 1.2487 + int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 1.2488 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2489 + reg[dest].I = CPUReadHalfWord(address); 1.2490 + if (dest != base) 1.2491 + { 1.2492 + address += offset; 1.2493 + reg[base].I = address; 1.2494 + } 1.2495 + } 1.2496 + break; 1.2497 + case 0x11b: 1.2498 + { 1.2499 + // LDRH Rd, [Rn, -Rm] 1.2500 + int base = (opcode >> 16) & 0x0F; 1.2501 + int dest = (opcode >> 12) & 0x0F; 1.2502 + u32 address = reg[base].I - reg[opcode & 0x0F].I; 1.2503 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2504 + reg[dest].I = CPUReadHalfWord(address); 1.2505 + } 1.2506 + break; 1.2507 + case 0x13b: 1.2508 + { 1.2509 + // LDRH Rd, [Rn, -Rm]! 1.2510 + int base = (opcode >> 16) & 0x0F; 1.2511 + int dest = (opcode >> 12) & 0x0F; 1.2512 + u32 address = reg[base].I - reg[opcode & 0x0F].I; 1.2513 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2514 + reg[dest].I = CPUReadHalfWord(address); 1.2515 + if (dest != base) 1.2516 + reg[base].I = address; 1.2517 + } 1.2518 + break; 1.2519 + case 0x15b: 1.2520 + { 1.2521 + // LDRH Rd, [Rn, -#offset] 1.2522 + int base = (opcode >> 16) & 0x0F; 1.2523 + int dest = (opcode >> 12) & 0x0F; 1.2524 + u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2525 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2526 + reg[dest].I = CPUReadHalfWord(address); 1.2527 + } 1.2528 + break; 1.2529 + case 0x17b: 1.2530 + { 1.2531 + // LDRH Rd, [Rn, -#offset]! 1.2532 + int base = (opcode >> 16) & 0x0F; 1.2533 + int dest = (opcode >> 12) & 0x0F; 1.2534 + u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2535 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2536 + reg[dest].I = CPUReadHalfWord(address); 1.2537 + if (dest != base) 1.2538 + reg[base].I = address; 1.2539 + } 1.2540 + break; 1.2541 + case 0x19b: 1.2542 + { 1.2543 + // LDRH Rd, [Rn, Rm] 1.2544 + int base = (opcode >> 16) & 0x0F; 1.2545 + int dest = (opcode >> 12) & 0x0F; 1.2546 + u32 address = reg[base].I + reg[opcode & 0x0F].I; 1.2547 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2548 + reg[dest].I = CPUReadHalfWord(address); 1.2549 + } 1.2550 + break; 1.2551 + case 0x1bb: 1.2552 + { 1.2553 + // LDRH Rd, [Rn, Rm]! 1.2554 + int base = (opcode >> 16) & 0x0F; 1.2555 + int dest = (opcode >> 12) & 0x0F; 1.2556 + u32 address = reg[base].I + reg[opcode & 0x0F].I; 1.2557 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2558 + reg[dest].I = CPUReadHalfWord(address); 1.2559 + if (dest != base) 1.2560 + reg[base].I = address; 1.2561 + } 1.2562 + break; 1.2563 + case 0x1db: 1.2564 + { 1.2565 + // LDRH Rd, [Rn, #offset] 1.2566 + int base = (opcode >> 16) & 0x0F; 1.2567 + int dest = (opcode >> 12) & 0x0F; 1.2568 + u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2569 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2570 + reg[dest].I = CPUReadHalfWord(address); 1.2571 + } 1.2572 + break; 1.2573 + case 0x1fb: 1.2574 + { 1.2575 + // LDRH Rd, [Rn, #offset]! 1.2576 + int base = (opcode >> 16) & 0x0F; 1.2577 + int dest = (opcode >> 12) & 0x0F; 1.2578 + u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2579 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2580 + reg[dest].I = CPUReadHalfWord(address); 1.2581 + if (dest != base) 1.2582 + reg[base].I = address; 1.2583 + } 1.2584 + break; 1.2585 + case 0x01d: 1.2586 + case 0x03d: 1.2587 + { 1.2588 + // LDRSB Rd, [Rn], -Rm 1.2589 + int base = (opcode >> 16) & 0x0F; 1.2590 + int dest = (opcode >> 12) & 0x0F; 1.2591 + u32 address = reg[base].I; 1.2592 + int offset = reg[opcode & 0x0F].I; 1.2593 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2594 + reg[dest].I = (s8)CPUReadByte(address); 1.2595 + if (dest != base) 1.2596 + { 1.2597 + address -= offset; 1.2598 + reg[base].I = address; 1.2599 + } 1.2600 + } 1.2601 + break; 1.2602 + case 0x05d: 1.2603 + case 0x07d: 1.2604 + { 1.2605 + // LDRSB Rd, [Rn], #-offset 1.2606 + int base = (opcode >> 16) & 0x0F; 1.2607 + int dest = (opcode >> 12) & 0x0F; 1.2608 + u32 address = reg[base].I; 1.2609 + int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 1.2610 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2611 + reg[dest].I = (s8)CPUReadByte(address); 1.2612 + if (dest != base) 1.2613 + { 1.2614 + address -= offset; 1.2615 + reg[base].I = address; 1.2616 + } 1.2617 + } 1.2618 + break; 1.2619 + case 0x09d: 1.2620 + case 0x0bd: 1.2621 + { 1.2622 + // LDRSB Rd, [Rn], Rm 1.2623 + int base = (opcode >> 16) & 0x0F; 1.2624 + int dest = (opcode >> 12) & 0x0F; 1.2625 + u32 address = reg[base].I; 1.2626 + int offset = reg[opcode & 0x0F].I; 1.2627 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2628 + reg[dest].I = (s8)CPUReadByte(address); 1.2629 + if (dest != base) 1.2630 + { 1.2631 + address += offset; 1.2632 + reg[base].I = address; 1.2633 + } 1.2634 + } 1.2635 + break; 1.2636 + case 0x0dd: 1.2637 + case 0x0fd: 1.2638 + { 1.2639 + // LDRSB Rd, [Rn], #offset 1.2640 + int base = (opcode >> 16) & 0x0F; 1.2641 + int dest = (opcode >> 12) & 0x0F; 1.2642 + u32 address = reg[base].I; 1.2643 + int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 1.2644 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2645 + reg[dest].I = (s8)CPUReadByte(address); 1.2646 + if (dest != base) 1.2647 + { 1.2648 + address += offset; 1.2649 + reg[base].I = address; 1.2650 + } 1.2651 + } 1.2652 + break; 1.2653 + case 0x11d: 1.2654 + { 1.2655 + // LDRSB Rd, [Rn, -Rm] 1.2656 + int base = (opcode >> 16) & 0x0F; 1.2657 + int dest = (opcode >> 12) & 0x0F; 1.2658 + u32 address = reg[base].I - reg[opcode & 0x0F].I; 1.2659 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2660 + reg[dest].I = (s8)CPUReadByte(address); 1.2661 + } 1.2662 + break; 1.2663 + case 0x13d: 1.2664 + { 1.2665 + // LDRSB Rd, [Rn, -Rm]! 1.2666 + int base = (opcode >> 16) & 0x0F; 1.2667 + int dest = (opcode >> 12) & 0x0F; 1.2668 + u32 address = reg[base].I - reg[opcode & 0x0F].I; 1.2669 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2670 + reg[dest].I = (s8)CPUReadByte(address); 1.2671 + if (dest != base) 1.2672 + reg[base].I = address; 1.2673 + } 1.2674 + break; 1.2675 + case 0x15d: 1.2676 + { 1.2677 + // LDRSB Rd, [Rn, -#offset] 1.2678 + int base = (opcode >> 16) & 0x0F; 1.2679 + int dest = (opcode >> 12) & 0x0F; 1.2680 + u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2681 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2682 + reg[dest].I = (s8)CPUReadByte(address); 1.2683 + } 1.2684 + break; 1.2685 + case 0x17d: 1.2686 + { 1.2687 + // LDRSB Rd, [Rn, -#offset]! 1.2688 + int base = (opcode >> 16) & 0x0F; 1.2689 + int dest = (opcode >> 12) & 0x0F; 1.2690 + u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2691 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2692 + reg[dest].I = (s8)CPUReadByte(address); 1.2693 + if (dest != base) 1.2694 + reg[base].I = address; 1.2695 + } 1.2696 + break; 1.2697 + case 0x19d: 1.2698 + { 1.2699 + // LDRSB Rd, [Rn, Rm] 1.2700 + int base = (opcode >> 16) & 0x0F; 1.2701 + int dest = (opcode >> 12) & 0x0F; 1.2702 + u32 address = reg[base].I + reg[opcode & 0x0F].I; 1.2703 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2704 + reg[dest].I = (s8)CPUReadByte(address); 1.2705 + } 1.2706 + break; 1.2707 + case 0x1bd: 1.2708 + { 1.2709 + // LDRSB Rd, [Rn, Rm]! 1.2710 + int base = (opcode >> 16) & 0x0F; 1.2711 + int dest = (opcode >> 12) & 0x0F; 1.2712 + u32 address = reg[base].I + reg[opcode & 0x0F].I; 1.2713 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2714 + reg[dest].I = (s8)CPUReadByte(address); 1.2715 + if (dest != base) 1.2716 + reg[base].I = address; 1.2717 + } 1.2718 + break; 1.2719 + case 0x1dd: 1.2720 + { 1.2721 + // LDRSB Rd, [Rn, #offset] 1.2722 + int base = (opcode >> 16) & 0x0F; 1.2723 + int dest = (opcode >> 12) & 0x0F; 1.2724 + u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2725 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2726 + reg[dest].I = (s8)CPUReadByte(address); 1.2727 + } 1.2728 + break; 1.2729 + case 0x1fd: 1.2730 + { 1.2731 + // LDRSB Rd, [Rn, #offset]! 1.2732 + int base = (opcode >> 16) & 0x0F; 1.2733 + int dest = (opcode >> 12) & 0x0F; 1.2734 + u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2735 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2736 + reg[dest].I = (s8)CPUReadByte(address); 1.2737 + if (dest != base) 1.2738 + reg[base].I = address; 1.2739 + } 1.2740 + break; 1.2741 + case 0x01f: 1.2742 + case 0x03f: 1.2743 + { 1.2744 + // LDRSH Rd, [Rn], -Rm 1.2745 + int base = (opcode >> 16) & 0x0F; 1.2746 + int dest = (opcode >> 12) & 0x0F; 1.2747 + u32 address = reg[base].I; 1.2748 + int offset = reg[opcode & 0x0F].I; 1.2749 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2750 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2751 + if (dest != base) 1.2752 + { 1.2753 + address -= offset; 1.2754 + reg[base].I = address; 1.2755 + } 1.2756 + } 1.2757 + break; 1.2758 + case 0x05f: 1.2759 + case 0x07f: 1.2760 + { 1.2761 + // LDRSH Rd, [Rn], #-offset 1.2762 + int base = (opcode >> 16) & 0x0F; 1.2763 + int dest = (opcode >> 12) & 0x0F; 1.2764 + u32 address = reg[base].I; 1.2765 + int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 1.2766 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2767 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2768 + if (dest != base) 1.2769 + { 1.2770 + address -= offset; 1.2771 + reg[base].I = address; 1.2772 + } 1.2773 + } 1.2774 + break; 1.2775 + case 0x09f: 1.2776 + case 0x0bf: 1.2777 + { 1.2778 + // LDRSH Rd, [Rn], Rm 1.2779 + int base = (opcode >> 16) & 0x0F; 1.2780 + int dest = (opcode >> 12) & 0x0F; 1.2781 + u32 address = reg[base].I; 1.2782 + int offset = reg[opcode & 0x0F].I; 1.2783 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2784 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2785 + if (dest != base) 1.2786 + { 1.2787 + address += offset; 1.2788 + reg[base].I = address; 1.2789 + } 1.2790 + } 1.2791 + break; 1.2792 + case 0x0df: 1.2793 + case 0x0ff: 1.2794 + { 1.2795 + // LDRSH Rd, [Rn], #offset 1.2796 + int base = (opcode >> 16) & 0x0F; 1.2797 + int dest = (opcode >> 12) & 0x0F; 1.2798 + u32 address = reg[base].I; 1.2799 + int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 1.2800 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2801 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2802 + if (dest != base) 1.2803 + { 1.2804 + address += offset; 1.2805 + reg[base].I = address; 1.2806 + } 1.2807 + } 1.2808 + break; 1.2809 + case 0x11f: 1.2810 + { 1.2811 + // LDRSH Rd, [Rn, -Rm] 1.2812 + int base = (opcode >> 16) & 0x0F; 1.2813 + int dest = (opcode >> 12) & 0x0F; 1.2814 + u32 address = reg[base].I - reg[opcode & 0x0F].I; 1.2815 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2816 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2817 + } 1.2818 + break; 1.2819 + case 0x13f: 1.2820 + { 1.2821 + // LDRSH Rd, [Rn, -Rm]! 1.2822 + int base = (opcode >> 16) & 0x0F; 1.2823 + int dest = (opcode >> 12) & 0x0F; 1.2824 + u32 address = reg[base].I - reg[opcode & 0x0F].I; 1.2825 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2826 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2827 + if (dest != base) 1.2828 + reg[base].I = address; 1.2829 + } 1.2830 + break; 1.2831 + case 0x15f: 1.2832 + { 1.2833 + // LDRSH Rd, [Rn, -#offset] 1.2834 + int base = (opcode >> 16) & 0x0F; 1.2835 + int dest = (opcode >> 12) & 0x0F; 1.2836 + u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2837 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2838 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2839 + } 1.2840 + break; 1.2841 + case 0x17f: 1.2842 + { 1.2843 + // LDRSH Rd, [Rn, -#offset]! 1.2844 + int base = (opcode >> 16) & 0x0F; 1.2845 + int dest = (opcode >> 12) & 0x0F; 1.2846 + u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2847 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2848 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2849 + if (dest != base) 1.2850 + reg[base].I = address; 1.2851 + } 1.2852 + break; 1.2853 + case 0x19f: 1.2854 + { 1.2855 + // LDRSH Rd, [Rn, Rm] 1.2856 + int base = (opcode >> 16) & 0x0F; 1.2857 + int dest = (opcode >> 12) & 0x0F; 1.2858 + u32 address = reg[base].I + reg[opcode & 0x0F].I; 1.2859 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2860 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2861 + } 1.2862 + break; 1.2863 + case 0x1bf: 1.2864 + { 1.2865 + // LDRSH Rd, [Rn, Rm]! 1.2866 + int base = (opcode >> 16) & 0x0F; 1.2867 + int dest = (opcode >> 12) & 0x0F; 1.2868 + u32 address = reg[base].I + reg[opcode & 0x0F].I; 1.2869 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2870 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2871 + if (dest != base) 1.2872 + reg[base].I = address; 1.2873 + } 1.2874 + break; 1.2875 + case 0x1df: 1.2876 + { 1.2877 + // LDRSH Rd, [Rn, #offset] 1.2878 + int base = (opcode >> 16) & 0x0F; 1.2879 + int dest = (opcode >> 12) & 0x0F; 1.2880 + u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2881 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2882 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2883 + } 1.2884 + break; 1.2885 + case 0x1ff: 1.2886 + { 1.2887 + // LDRSH Rd, [Rn, #offset]! 1.2888 + int base = (opcode >> 16) & 0x0F; 1.2889 + int dest = (opcode >> 12) & 0x0F; 1.2890 + u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); 1.2891 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.2892 + reg[dest].I = (s16)CPUReadHalfWordSigned(address); 1.2893 + if (dest != base) 1.2894 + reg[base].I = address; 1.2895 + } 1.2896 + break; 1.2897 + LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EOR, OP_EOR, 0x020); 1.2898 + LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EORS, OP_EOR, 0x030); 1.2899 + case 0x029: 1.2900 + { 1.2901 + // MLA Rd, Rm, Rs, Rn 1.2902 + int dest = (opcode >> 16) & 0x0F; 1.2903 + int mult = (opcode & 0x0F); 1.2904 + u32 rs = reg[(opcode >> 8) & 0x0F].I; 1.2905 + reg[dest].I = reg[mult].I * rs + reg[(opcode >> 12) & 0x0f].I; 1.2906 + if (((s32)rs) < 0) 1.2907 + rs = ~rs; 1.2908 + if ((rs & 0xFFFFFF00) == 0) 1.2909 + clockTicks += 3; 1.2910 + else if ((rs & 0xFFFF0000) == 0) 1.2911 + clockTicks += 4; 1.2912 + else if ((rs & 0xFF000000) == 0) 1.2913 + clockTicks += 5; 1.2914 + else 1.2915 + clockTicks += 6; 1.2916 + } 1.2917 + break; 1.2918 + case 0x039: 1.2919 + { 1.2920 + // MLAS Rd, Rm, Rs, Rn 1.2921 + int dest = (opcode >> 16) & 0x0F; 1.2922 + int mult = (opcode & 0x0F); 1.2923 + u32 rs = reg[(opcode >> 8) & 0x0F].I; 1.2924 + reg[dest].I = reg[mult].I * rs + reg[(opcode >> 12) & 0x0f].I; 1.2925 + N_FLAG = (reg[dest].I & 0x80000000) ? true : false; 1.2926 + Z_FLAG = (reg[dest].I) ? false : true; 1.2927 + if (((s32)rs) < 0) 1.2928 + rs = ~rs; 1.2929 + if ((rs & 0xFFFFFF00) == 0) 1.2930 + clockTicks += 3; 1.2931 + else if ((rs & 0xFFFF0000) == 0) 1.2932 + clockTicks += 4; 1.2933 + else if ((rs & 0xFF000000) == 0) 1.2934 + clockTicks += 5; 1.2935 + else 1.2936 + clockTicks += 6; 1.2937 + } 1.2938 + break; 1.2939 + ARITHMETIC_DATA_OPCODE(OP_SUB, OP_SUB, 0x040); 1.2940 + ARITHMETIC_DATA_OPCODE(OP_SUBS, OP_SUB, 0x050); 1.2941 + ARITHMETIC_DATA_OPCODE(OP_RSB, OP_RSB, 0x060); 1.2942 + ARITHMETIC_DATA_OPCODE(OP_RSBS, OP_RSB, 0x070); 1.2943 + ARITHMETIC_DATA_OPCODE(OP_ADD, OP_ADD, 0x080); 1.2944 + ARITHMETIC_DATA_OPCODE(OP_ADDS, OP_ADD, 0x090); 1.2945 + case 0x089: 1.2946 + { 1.2947 + // UMULL RdLo, RdHi, Rn, Rs 1.2948 + u32 umult = reg[(opcode & 0x0F)].I; 1.2949 + u32 usource = reg[(opcode >> 8) & 0x0F].I; 1.2950 + int destLo = (opcode >> 12) & 0x0F; 1.2951 + int destHi = (opcode >> 16) & 0x0F; 1.2952 + u64 uTemp = ((u64)umult) * ((u64)usource); 1.2953 + reg[destLo].I = (u32)(uTemp & 0xFFFFFFFF); 1.2954 + reg[destHi].I = (u32)(uTemp >> 32); 1.2955 + if ((usource & 0xFFFFFF00) == 0) 1.2956 + clockTicks += 2; 1.2957 + else if ((usource & 0xFFFF0000) == 0) 1.2958 + clockTicks += 3; 1.2959 + else if ((usource & 0xFF000000) == 0) 1.2960 + clockTicks += 4; 1.2961 + else 1.2962 + clockTicks += 5; 1.2963 + } 1.2964 + break; 1.2965 + case 0x099: 1.2966 + { 1.2967 + // UMULLS RdLo, RdHi, Rn, Rs 1.2968 + u32 umult = reg[(opcode & 0x0F)].I; 1.2969 + u32 usource = reg[(opcode >> 8) & 0x0F].I; 1.2970 + int destLo = (opcode >> 12) & 0x0F; 1.2971 + int destHi = (opcode >> 16) & 0x0F; 1.2972 + u64 uTemp = ((u64)umult) * ((u64)usource); 1.2973 + reg[destLo].I = (u32)(uTemp & 0xFFFFFFFF); 1.2974 + reg[destHi].I = (u32)(uTemp >> 32); 1.2975 + Z_FLAG = (uTemp) ? false : true; 1.2976 + N_FLAG = (reg[destHi].I & 0x80000000) ? true : false; 1.2977 + if ((usource & 0xFFFFFF00) == 0) 1.2978 + clockTicks += 2; 1.2979 + else if ((usource & 0xFFFF0000) == 0) 1.2980 + clockTicks += 3; 1.2981 + else if ((usource & 0xFF000000) == 0) 1.2982 + clockTicks += 4; 1.2983 + else 1.2984 + clockTicks += 5; 1.2985 + } 1.2986 + break; 1.2987 + ARITHMETIC_DATA_OPCODE(OP_ADC, OP_ADC, 0x0a0); 1.2988 + ARITHMETIC_DATA_OPCODE(OP_ADCS, OP_ADC, 0x0b0); 1.2989 + case 0x0a9: 1.2990 + { 1.2991 + // UMLAL RdLo, RdHi, Rn, Rs 1.2992 + u32 umult = reg[(opcode & 0x0F)].I; 1.2993 + u32 usource = reg[(opcode >> 8) & 0x0F].I; 1.2994 + int destLo = (opcode >> 12) & 0x0F; 1.2995 + int destHi = (opcode >> 16) & 0x0F; 1.2996 + u64 uTemp = (u64)reg[destHi].I; 1.2997 + uTemp <<= 32; 1.2998 + uTemp |= (u64)reg[destLo].I; 1.2999 + uTemp += ((u64)umult) * ((u64)usource); 1.3000 + reg[destLo].I = (u32)(uTemp & 0xFFFFFFFF); 1.3001 + reg[destHi].I = (u32)(uTemp >> 32); 1.3002 + if ((usource & 0xFFFFFF00) == 0) 1.3003 + clockTicks += 3; 1.3004 + else if ((usource & 0xFFFF0000) == 0) 1.3005 + clockTicks += 4; 1.3006 + else if ((usource & 0xFF000000) == 0) 1.3007 + clockTicks += 5; 1.3008 + else 1.3009 + clockTicks += 6; 1.3010 + } 1.3011 + break; 1.3012 + case 0x0b9: 1.3013 + { 1.3014 + // UMLALS RdLo, RdHi, Rn, Rs 1.3015 + u32 umult = reg[(opcode & 0x0F)].I; 1.3016 + u32 usource = reg[(opcode >> 8) & 0x0F].I; 1.3017 + int destLo = (opcode >> 12) & 0x0F; 1.3018 + int destHi = (opcode >> 16) & 0x0F; 1.3019 + u64 uTemp = (u64)reg[destHi].I; 1.3020 + uTemp <<= 32; 1.3021 + uTemp |= (u64)reg[destLo].I; 1.3022 + uTemp += ((u64)umult) * ((u64)usource); 1.3023 + reg[destLo].I = (u32)(uTemp & 0xFFFFFFFF); 1.3024 + reg[destHi].I = (u32)(uTemp >> 32); 1.3025 + Z_FLAG = (uTemp) ? false : true; 1.3026 + N_FLAG = (reg[destHi].I & 0x80000000) ? true : false; 1.3027 + if ((usource & 0xFFFFFF00) == 0) 1.3028 + clockTicks += 3; 1.3029 + else if ((usource & 0xFFFF0000) == 0) 1.3030 + clockTicks += 4; 1.3031 + else if ((usource & 0xFF000000) == 0) 1.3032 + clockTicks += 5; 1.3033 + else 1.3034 + clockTicks += 6; 1.3035 + } 1.3036 + break; 1.3037 + ARITHMETIC_DATA_OPCODE(OP_SBC, OP_SBC, 0x0c0); 1.3038 + ARITHMETIC_DATA_OPCODE(OP_SBCS, OP_SBC, 0x0d0); 1.3039 + case 0x0c9: 1.3040 + { 1.3041 + // SMULL RdLo, RdHi, Rm, Rs 1.3042 + int destLo = (opcode >> 12) & 0x0F; 1.3043 + int destHi = (opcode >> 16) & 0x0F; 1.3044 + u32 rs = reg[(opcode >> 8) & 0x0F].I; 1.3045 + s64 m = (s32)reg[(opcode & 0x0F)].I; 1.3046 + s64 s = (s32)rs; 1.3047 + s64 sTemp = m * s; 1.3048 + reg[destLo].I = (u32)(sTemp & 0xFFFFFFFF); 1.3049 + reg[destHi].I = (u32)(sTemp >> 32); 1.3050 + if (((s32)rs) < 0) 1.3051 + rs = ~rs; 1.3052 + if ((rs & 0xFFFFFF00) == 0) 1.3053 + clockTicks += 2; 1.3054 + else if ((rs & 0xFFFF0000) == 0) 1.3055 + clockTicks += 3; 1.3056 + else if ((rs & 0xFF000000) == 0) 1.3057 + clockTicks += 4; 1.3058 + else 1.3059 + clockTicks += 5; 1.3060 + } 1.3061 + break; 1.3062 + case 0x0d9: 1.3063 + { 1.3064 + // SMULLS RdLo, RdHi, Rm, Rs 1.3065 + int destLo = (opcode >> 12) & 0x0F; 1.3066 + int destHi = (opcode >> 16) & 0x0F; 1.3067 + u32 rs = reg[(opcode >> 8) & 0x0F].I; 1.3068 + s64 m = (s32)reg[(opcode & 0x0F)].I; 1.3069 + s64 s = (s32)rs; 1.3070 + s64 sTemp = m * s; 1.3071 + reg[destLo].I = (u32)(sTemp & 0xFFFFFFFF); 1.3072 + reg[destHi].I = (u32)(sTemp >> 32); 1.3073 + Z_FLAG = (sTemp) ? false : true; 1.3074 + N_FLAG = (sTemp < 0) ? true : false; 1.3075 + if (((s32)rs) < 0) 1.3076 + rs = ~rs; 1.3077 + if ((rs & 0xFFFFFF00) == 0) 1.3078 + clockTicks += 2; 1.3079 + else if ((rs & 0xFFFF0000) == 0) 1.3080 + clockTicks += 3; 1.3081 + else if ((rs & 0xFF000000) == 0) 1.3082 + clockTicks += 4; 1.3083 + else 1.3084 + clockTicks += 5; 1.3085 + } 1.3086 + break; 1.3087 + ARITHMETIC_DATA_OPCODE(OP_RSC, OP_RSC, 0x0e0); 1.3088 + ARITHMETIC_DATA_OPCODE(OP_RSCS, OP_RSC, 0x0f0); 1.3089 + case 0x0e9: 1.3090 + { 1.3091 + // SMLAL RdLo, RdHi, Rm, Rs 1.3092 + int destLo = (opcode >> 12) & 0x0F; 1.3093 + int destHi = (opcode >> 16) & 0x0F; 1.3094 + u32 rs = reg[(opcode >> 8) & 0x0F].I; 1.3095 + s64 m = (s32)reg[(opcode & 0x0F)].I; 1.3096 + s64 s = (s32)rs; 1.3097 + s64 sTemp = (u64)reg[destHi].I; 1.3098 + sTemp <<= 32; 1.3099 + sTemp |= (u64)reg[destLo].I; 1.3100 + sTemp += m * s; 1.3101 + reg[destLo].I = (u32)(sTemp & 0xFFFFFFFF); 1.3102 + reg[destHi].I = (u32)(sTemp >> 32); 1.3103 + if (((s32)rs) < 0) 1.3104 + rs = ~rs; 1.3105 + if ((rs & 0xFFFFFF00) == 0) 1.3106 + clockTicks += 3; 1.3107 + else if ((rs & 0xFFFF0000) == 0) 1.3108 + clockTicks += 4; 1.3109 + else if ((rs & 0xFF000000) == 0) 1.3110 + clockTicks += 5; 1.3111 + else 1.3112 + clockTicks += 6; 1.3113 + } 1.3114 + break; 1.3115 + case 0x0f9: 1.3116 + { 1.3117 + // SMLALS RdLo, RdHi, Rm, Rs 1.3118 + int destLo = (opcode >> 12) & 0x0F; 1.3119 + int destHi = (opcode >> 16) & 0x0F; 1.3120 + u32 rs = reg[(opcode >> 8) & 0x0F].I; 1.3121 + s64 m = (s32)reg[(opcode & 0x0F)].I; 1.3122 + s64 s = (s32)rs; 1.3123 + s64 sTemp = (u64)reg[destHi].I; 1.3124 + sTemp <<= 32; 1.3125 + sTemp |= (u64)reg[destLo].I; 1.3126 + sTemp += m * s; 1.3127 + reg[destLo].I = (u32)(sTemp & 0xFFFFFFFF); 1.3128 + reg[destHi].I = (u32)(sTemp >> 32); 1.3129 + Z_FLAG = (sTemp) ? false : true; 1.3130 + N_FLAG = (sTemp < 0) ? true : false; 1.3131 + if (((s32)rs) < 0) 1.3132 + rs = ~rs; 1.3133 + if ((rs & 0xFFFFFF00) == 0) 1.3134 + clockTicks += 3; 1.3135 + else if ((rs & 0xFFFF0000) == 0) 1.3136 + clockTicks += 4; 1.3137 + else if ((rs & 0xFF000000) == 0) 1.3138 + clockTicks += 5; 1.3139 + else 1.3140 + clockTicks += 6; 1.3141 + } 1.3142 + break; 1.3143 + LOGICAL_DATA_OPCODE(OP_TST, OP_TST, 0x110); 1.3144 + case 0x100: 1.3145 + // MRS Rd, CPSR 1.3146 + // TODO: check if right instruction.... 1.3147 + CPUUpdateCPSR(); 1.3148 + reg[(opcode >> 12) & 0x0F].I = reg[16].I; 1.3149 + break; 1.3150 + case 0x109: 1.3151 + { 1.3152 + // SWP Rd, Rm, [Rn] 1.3153 + u32 address = reg[(opcode >> 16) & 15].I; 1.3154 + u32 temp = CPUReadMemory(address); 1.3155 + CPUWriteMemory(address, reg[opcode & 15].I); 1.3156 + reg[(opcode >> 12) & 15].I = temp; 1.3157 + } 1.3158 + break; 1.3159 + LOGICAL_DATA_OPCODE(OP_TEQ, OP_TEQ, 0x130); 1.3160 + case 0x120: 1.3161 + { 1.3162 + // MSR CPSR_fields, Rm 1.3163 + CPUUpdateCPSR(); 1.3164 + u32 value = reg[opcode & 15].I; 1.3165 + u32 newValue = reg[16].I; 1.3166 + if (armMode > 0x10) 1.3167 + { 1.3168 + if (opcode & 0x00010000) 1.3169 + newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF); 1.3170 + if (opcode & 0x00020000) 1.3171 + newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00); 1.3172 + if (opcode & 0x00040000) 1.3173 + newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000); 1.3174 + } 1.3175 + if (opcode & 0x00080000) 1.3176 + newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000); 1.3177 + newValue |= 0x10; 1.3178 + CPUSwitchMode(newValue & 0x1f, false); 1.3179 + reg[16].I = newValue; 1.3180 + CPUUpdateFlags(); 1.3181 + } 1.3182 + break; 1.3183 + case 0x121: 1.3184 + { 1.3185 + // BX Rm 1.3186 + // TODO: check if right instruction... 1.3187 + clockTicks += 3; 1.3188 + int base = opcode & 0x0F; 1.3189 + armState = reg[base].I & 1 ? false : true; 1.3190 + if (armState) 1.3191 + { 1.3192 + reg[15].I = reg[base].I & 0xFFFFFFFC; 1.3193 + armNextPC = reg[15].I; 1.3194 + reg[15].I += 4; 1.3195 + } 1.3196 + else 1.3197 + { 1.3198 + reg[15].I = reg[base].I & 0xFFFFFFFE; 1.3199 + armNextPC = reg[15].I; 1.3200 + reg[15].I += 2; 1.3201 + } 1.3202 + } 1.3203 + break; 1.3204 + ARITHMETIC_DATA_OPCODE(OP_CMP, OP_CMP, 0x150); 1.3205 + case 0x140: 1.3206 + // MRS Rd, SPSR 1.3207 + // TODO: check if right instruction... 1.3208 + reg[(opcode >> 12) & 0x0F].I = reg[17].I; 1.3209 + break; 1.3210 + case 0x149: 1.3211 + { 1.3212 + // SWPB Rd, Rm, [Rn] 1.3213 + u32 address = reg[(opcode >> 16) & 15].I; 1.3214 + u32 temp = CPUReadByte(address); 1.3215 + CPUWriteByte(address, reg[opcode & 15].B.B0); 1.3216 + reg[(opcode >> 12) & 15].I = temp; 1.3217 + } 1.3218 + break; 1.3219 + ARITHMETIC_DATA_OPCODE(OP_CMN, OP_CMN, 0x170); 1.3220 + case 0x160: 1.3221 + { 1.3222 + // MSR SPSR_fields, Rm 1.3223 + u32 value = reg[opcode & 15].I; 1.3224 + if (armMode > 0x10 && armMode < 0x1f) 1.3225 + { 1.3226 + if (opcode & 0x00010000) 1.3227 + reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF); 1.3228 + if (opcode & 0x00020000) 1.3229 + reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00); 1.3230 + if (opcode & 0x00040000) 1.3231 + reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000); 1.3232 + if (opcode & 0x00080000) 1.3233 + reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000); 1.3234 + } 1.3235 + } 1.3236 + break; 1.3237 + LOGICAL_DATA_OPCODE(OP_ORR, OP_ORR, 0x180); 1.3238 + LOGICAL_DATA_OPCODE(OP_ORRS, OP_ORR, 0x190); 1.3239 + LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOV, OP_MOV, 0x1a0); 1.3240 + LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOVS, OP_MOV, 0x1b0); 1.3241 + LOGICAL_DATA_OPCODE(OP_BIC, OP_BIC, 0x1c0); 1.3242 + LOGICAL_DATA_OPCODE(OP_BICS, OP_BIC, 0x1d0); 1.3243 + LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVN, OP_MVN, 0x1e0); 1.3244 + LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVNS, OP_MVN, 0x1f0); 1.3245 +#ifdef BKPT_SUPPORT 1.3246 + case 0x127: 1.3247 + case 0x7ff: // for GDB support 1.3248 + extern void (*dbgSignal)(int, int); 1.3249 + reg[15].I -= 4; 1.3250 + armNextPC -= 4; 1.3251 + dbgSignal(5, (opcode & 0x0f) | ((opcode >> 4) & 0xfff0)); 1.3252 + return; 1.3253 +#endif 1.3254 + case 0x320: 1.3255 + case 0x321: 1.3256 + case 0x322: 1.3257 + case 0x323: 1.3258 + case 0x324: 1.3259 + case 0x325: 1.3260 + case 0x326: 1.3261 + case 0x327: 1.3262 + case 0x328: 1.3263 + case 0x329: 1.3264 + case 0x32a: 1.3265 + case 0x32b: 1.3266 + case 0x32c: 1.3267 + case 0x32d: 1.3268 + case 0x32e: 1.3269 + case 0x32f: 1.3270 + { 1.3271 + // MSR CPSR_fields, # 1.3272 + CPUUpdateCPSR(); 1.3273 + u32 value = opcode & 0xFF; 1.3274 + int shift = (opcode & 0xF00) >> 7; 1.3275 + if (shift) 1.3276 + { 1.3277 + ROR_IMM_MSR; 1.3278 + } 1.3279 + u32 newValue = reg[16].I; 1.3280 + if (armMode > 0x10) 1.3281 + { 1.3282 + if (opcode & 0x00010000) 1.3283 + newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF); 1.3284 + if (opcode & 0x00020000) 1.3285 + newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00); 1.3286 + if (opcode & 0x00040000) 1.3287 + newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000); 1.3288 + } 1.3289 + if (opcode & 0x00080000) 1.3290 + newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000); 1.3291 + 1.3292 + newValue |= 0x10; 1.3293 + 1.3294 + CPUSwitchMode(newValue & 0x1f, false); 1.3295 + reg[16].I = newValue; 1.3296 + CPUUpdateFlags(); 1.3297 + } 1.3298 + break; 1.3299 + case 0x360: 1.3300 + case 0x361: 1.3301 + case 0x362: 1.3302 + case 0x363: 1.3303 + case 0x364: 1.3304 + case 0x365: 1.3305 + case 0x366: 1.3306 + case 0x367: 1.3307 + case 0x368: 1.3308 + case 0x369: 1.3309 + case 0x36a: 1.3310 + case 0x36b: 1.3311 + case 0x36c: 1.3312 + case 0x36d: 1.3313 + case 0x36e: 1.3314 + case 0x36f: 1.3315 + { 1.3316 + // MSR SPSR_fields, # 1.3317 + if (armMode > 0x10 && armMode < 0x1f) 1.3318 + { 1.3319 + u32 value = opcode & 0xFF; 1.3320 + int shift = (opcode & 0xF00) >> 7; 1.3321 + if (shift) 1.3322 + { 1.3323 + ROR_IMM_MSR; 1.3324 + } 1.3325 + if (opcode & 0x00010000) 1.3326 + reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF); 1.3327 + if (opcode & 0x00020000) 1.3328 + reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00); 1.3329 + if (opcode & 0x00040000) 1.3330 + reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000); 1.3331 + if (opcode & 0x00080000) 1.3332 + reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000); 1.3333 + } 1.3334 + } 1.3335 + break; 1.3336 + CASE_16(0x400) 1.3337 + // T versions shouldn't be different on GBA 1.3338 + CASE_16(0x420) 1.3339 + { 1.3340 + // STR Rd, [Rn], -# 1.3341 + int offset = opcode & 0xFFF; 1.3342 + int dest = (opcode >> 12) & 15; 1.3343 + int base = (opcode >> 16) & 15; 1.3344 + u32 address = reg[base].I; 1.3345 + CPUWriteMemory(address, reg[dest].I); 1.3346 + reg[base].I = address - offset; 1.3347 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3348 + } 1.3349 + break; 1.3350 + CASE_16(0x480) 1.3351 + // T versions shouldn't be different on GBA 1.3352 + CASE_16(0x4a0) 1.3353 + { 1.3354 + // STR Rd, [Rn], # 1.3355 + int offset = opcode & 0xFFF; 1.3356 + int dest = (opcode >> 12) & 15; 1.3357 + int base = (opcode >> 16) & 15; 1.3358 + u32 address = reg[base].I; 1.3359 + CPUWriteMemory(address, reg[dest].I); 1.3360 + reg[base].I = address + offset; 1.3361 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3362 + } 1.3363 + break; 1.3364 + CASE_16(0x500) 1.3365 + { 1.3366 + // STR Rd, [Rn, -#] 1.3367 + int offset = opcode & 0xFFF; 1.3368 + int dest = (opcode >> 12) & 15; 1.3369 + int base = (opcode >> 16) & 15; 1.3370 + u32 address = reg[base].I - offset; 1.3371 + CPUWriteMemory(address, reg[dest].I); 1.3372 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3373 + } 1.3374 + break; 1.3375 + CASE_16(0x520) 1.3376 + { 1.3377 + // STR Rd, [Rn, -#]! 1.3378 + int offset = opcode & 0xFFF; 1.3379 + int dest = (opcode >> 12) & 15; 1.3380 + int base = (opcode >> 16) & 15; 1.3381 + u32 address = reg[base].I - offset; 1.3382 + reg[base].I = address; 1.3383 + CPUWriteMemory(address, reg[dest].I); 1.3384 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3385 + } 1.3386 + break; 1.3387 + CASE_16(0x580) 1.3388 + { 1.3389 + // STR Rd, [Rn, #] 1.3390 + int offset = opcode & 0xFFF; 1.3391 + int dest = (opcode >> 12) & 15; 1.3392 + int base = (opcode >> 16) & 15; 1.3393 + u32 address = reg[base].I + offset; 1.3394 + CPUWriteMemory(address, reg[dest].I); 1.3395 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3396 + } 1.3397 + break; 1.3398 + CASE_16(0x5a0) 1.3399 + { 1.3400 + // STR Rd, [Rn, #]! 1.3401 + int offset = opcode & 0xFFF; 1.3402 + int dest = (opcode >> 12) & 15; 1.3403 + int base = (opcode >> 16) & 15; 1.3404 + u32 address = reg[base].I + offset; 1.3405 + reg[base].I = address; 1.3406 + CPUWriteMemory(address, reg[dest].I); 1.3407 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3408 + } 1.3409 + break; 1.3410 + CASE_16(0x410) 1.3411 + { 1.3412 + // LDR Rd, [Rn], -# 1.3413 + int offset = opcode & 0xFFF; 1.3414 + int dest = (opcode >> 12) & 15; 1.3415 + int base = (opcode >> 16) & 15; 1.3416 + u32 address = reg[base].I; 1.3417 + reg[dest].I = CPUReadMemory(address); 1.3418 + if (dest != base) 1.3419 + reg[base].I -= offset; 1.3420 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.3421 + if (dest == 15) 1.3422 + { 1.3423 + clockTicks += 2; 1.3424 + reg[15].I &= 0xFFFFFFFC; 1.3425 + armNextPC = reg[15].I; 1.3426 + reg[15].I += 4; 1.3427 + } 1.3428 + } 1.3429 + break; 1.3430 + CASE_16(0x430) 1.3431 + { 1.3432 + // LDRT Rd, [Rn], -# 1.3433 + int offset = opcode & 0xFFF; 1.3434 + int dest = (opcode >> 12) & 15; 1.3435 + int base = (opcode >> 16) & 15; 1.3436 + u32 address = reg[base].I; 1.3437 + reg[dest].I = CPUReadMemory(address); 1.3438 + if (dest != base) 1.3439 + reg[base].I -= offset; 1.3440 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.3441 + } 1.3442 + break; 1.3443 + CASE_16(0x490) 1.3444 + { 1.3445 + // LDR Rd, [Rn], # 1.3446 + int offset = opcode & 0xFFF; 1.3447 + int dest = (opcode >> 12) & 15; 1.3448 + int base = (opcode >> 16) & 15; 1.3449 + u32 address = reg[base].I; 1.3450 + reg[dest].I = CPUReadMemory(address); 1.3451 + if (dest != base) 1.3452 + reg[base].I += offset; 1.3453 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.3454 + if (dest == 15) 1.3455 + { 1.3456 + clockTicks += 2; 1.3457 + reg[15].I &= 0xFFFFFFFC; 1.3458 + armNextPC = reg[15].I; 1.3459 + reg[15].I += 4; 1.3460 + } 1.3461 + } 1.3462 + break; 1.3463 + CASE_16(0x4b0) 1.3464 + { 1.3465 + // LDRT Rd, [Rn], # 1.3466 + int offset = opcode & 0xFFF; 1.3467 + int dest = (opcode >> 12) & 15; 1.3468 + int base = (opcode >> 16) & 15; 1.3469 + u32 address = reg[base].I; 1.3470 + reg[dest].I = CPUReadMemory(address); 1.3471 + if (dest != base) 1.3472 + reg[base].I += offset; 1.3473 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.3474 + } 1.3475 + break; 1.3476 + CASE_16(0x510) 1.3477 + { 1.3478 + // LDR Rd, [Rn, -#] 1.3479 + int offset = opcode & 0xFFF; 1.3480 + int dest = (opcode >> 12) & 15; 1.3481 + int base = (opcode >> 16) & 15; 1.3482 + u32 address = reg[base].I - offset; 1.3483 + reg[dest].I = CPUReadMemory(address); 1.3484 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.3485 + if (dest == 15) 1.3486 + { 1.3487 + clockTicks += 2; 1.3488 + reg[15].I &= 0xFFFFFFFC; 1.3489 + armNextPC = reg[15].I; 1.3490 + reg[15].I += 4; 1.3491 + } 1.3492 + } 1.3493 + break; 1.3494 + CASE_16(0x530) 1.3495 + { 1.3496 + // LDR Rd, [Rn, -#]! 1.3497 + int offset = opcode & 0xFFF; 1.3498 + int dest = (opcode >> 12) & 15; 1.3499 + int base = (opcode >> 16) & 15; 1.3500 + u32 address = reg[base].I - offset; 1.3501 + reg[dest].I = CPUReadMemory(address); 1.3502 + if (dest != base) 1.3503 + reg[base].I = address; 1.3504 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.3505 + if (dest == 15) 1.3506 + { 1.3507 + clockTicks += 2; 1.3508 + reg[15].I &= 0xFFFFFFFC; 1.3509 + armNextPC = reg[15].I; 1.3510 + reg[15].I += 4; 1.3511 + } 1.3512 + } 1.3513 + break; 1.3514 + CASE_16(0x590) 1.3515 + { 1.3516 + // LDR Rd, [Rn, #] 1.3517 + int offset = opcode & 0xFFF; 1.3518 + int dest = (opcode >> 12) & 15; 1.3519 + int base = (opcode >> 16) & 15; 1.3520 + u32 address = reg[base].I + offset; 1.3521 + reg[dest].I = CPUReadMemory(address); 1.3522 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.3523 + if (dest == 15) 1.3524 + { 1.3525 + clockTicks += 2; 1.3526 + reg[15].I &= 0xFFFFFFFC; 1.3527 + armNextPC = reg[15].I; 1.3528 + reg[15].I += 4; 1.3529 + } 1.3530 + } 1.3531 + break; 1.3532 + CASE_16(0x5b0) 1.3533 + { 1.3534 + // LDR Rd, [Rn, #]! 1.3535 + int offset = opcode & 0xFFF; 1.3536 + int dest = (opcode >> 12) & 15; 1.3537 + int base = (opcode >> 16) & 15; 1.3538 + u32 address = reg[base].I + offset; 1.3539 + reg[dest].I = CPUReadMemory(address); 1.3540 + if (dest != base) 1.3541 + reg[base].I = address; 1.3542 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.3543 + if (dest == 15) 1.3544 + { 1.3545 + clockTicks += 2; 1.3546 + reg[15].I &= 0xFFFFFFFC; 1.3547 + armNextPC = reg[15].I; 1.3548 + reg[15].I += 4; 1.3549 + } 1.3550 + } 1.3551 + break; 1.3552 + CASE_16(0x440) 1.3553 + // T versions shouldn't be different on GBA 1.3554 + CASE_16(0x460) 1.3555 + { 1.3556 + // STRB Rd, [Rn], -# 1.3557 + int offset = opcode & 0xFFF; 1.3558 + int dest = (opcode >> 12) & 15; 1.3559 + int base = (opcode >> 16) & 15; 1.3560 + u32 address = reg[base].I; 1.3561 + CPUWriteByte(address, reg[dest].B.B0); 1.3562 + reg[base].I = address - offset; 1.3563 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.3564 + } 1.3565 + break; 1.3566 + CASE_16(0x4c0) 1.3567 + // T versions shouldn't be different on GBA 1.3568 + CASE_16(0x4e0) 1.3569 + // STRB Rd, [Rn], # 1.3570 + { 1.3571 + int offset = opcode & 0xFFF; 1.3572 + int dest = (opcode >> 12) & 15; 1.3573 + int base = (opcode >> 16) & 15; 1.3574 + u32 address = reg[base].I; 1.3575 + CPUWriteByte(address, reg[dest].B.B0); 1.3576 + reg[base].I = address + offset; 1.3577 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.3578 + } 1.3579 + break; 1.3580 + CASE_16(0x540) 1.3581 + { 1.3582 + // STRB Rd, [Rn, -#] 1.3583 + int offset = opcode & 0xFFF; 1.3584 + int dest = (opcode >> 12) & 15; 1.3585 + int base = (opcode >> 16) & 15; 1.3586 + u32 address = reg[base].I - offset; 1.3587 + CPUWriteByte(address, reg[dest].B.B0); 1.3588 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.3589 + } 1.3590 + break; 1.3591 + CASE_16(0x560) 1.3592 + { 1.3593 + // STRB Rd, [Rn, -#]! 1.3594 + int offset = opcode & 0xFFF; 1.3595 + int dest = (opcode >> 12) & 15; 1.3596 + int base = (opcode >> 16) & 15; 1.3597 + u32 address = reg[base].I - offset; 1.3598 + reg[base].I = address; 1.3599 + CPUWriteByte(address, reg[dest].B.B0); 1.3600 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.3601 + } 1.3602 + break; 1.3603 + CASE_16(0x5c0) 1.3604 + { 1.3605 + // STRB Rd, [Rn, #] 1.3606 + int offset = opcode & 0xFFF; 1.3607 + int dest = (opcode >> 12) & 15; 1.3608 + int base = (opcode >> 16) & 15; 1.3609 + u32 address = reg[base].I + offset; 1.3610 + CPUWriteByte(address, reg[dest].B.B0); 1.3611 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.3612 + } 1.3613 + break; 1.3614 + CASE_16(0x5e0) 1.3615 + { 1.3616 + // STRB Rd, [Rn, #]! 1.3617 + int offset = opcode & 0xFFF; 1.3618 + int dest = (opcode >> 12) & 15; 1.3619 + int base = (opcode >> 16) & 15; 1.3620 + u32 address = reg[base].I + offset; 1.3621 + reg[base].I = address; 1.3622 + CPUWriteByte(address, reg[dest].I); 1.3623 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.3624 + } 1.3625 + break; 1.3626 + CASE_16(0x450) 1.3627 + // T versions shouldn't be different 1.3628 + CASE_16(0x470) 1.3629 + { 1.3630 + // LDRB Rd, [Rn], -# 1.3631 + int offset = opcode & 0xFFF; 1.3632 + int dest = (opcode >> 12) & 15; 1.3633 + int base = (opcode >> 16) & 15; 1.3634 + u32 address = reg[base].I; 1.3635 + reg[dest].I = CPUReadByte(address); 1.3636 + if (dest != base) 1.3637 + reg[base].I -= offset; 1.3638 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.3639 + } 1.3640 + break; 1.3641 + CASE_16(0x4d0) 1.3642 + CASE_16(0x4f0) // T versions should not be different 1.3643 + { 1.3644 + // LDRB Rd, [Rn], # 1.3645 + int offset = opcode & 0xFFF; 1.3646 + int dest = (opcode >> 12) & 15; 1.3647 + int base = (opcode >> 16) & 15; 1.3648 + u32 address = reg[base].I; 1.3649 + reg[dest].I = CPUReadByte(address); 1.3650 + if (dest != base) 1.3651 + reg[base].I += offset; 1.3652 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.3653 + } 1.3654 + break; 1.3655 + CASE_16(0x550) 1.3656 + { 1.3657 + // LDRB Rd, [Rn, -#] 1.3658 + int offset = opcode & 0xFFF; 1.3659 + int dest = (opcode >> 12) & 15; 1.3660 + int base = (opcode >> 16) & 15; 1.3661 + u32 address = reg[base].I - offset; 1.3662 + reg[dest].I = CPUReadByte(address); 1.3663 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.3664 + } 1.3665 + break; 1.3666 + CASE_16(0x570) 1.3667 + { 1.3668 + // LDRB Rd, [Rn, -#]! 1.3669 + int offset = opcode & 0xFFF; 1.3670 + int dest = (opcode >> 12) & 15; 1.3671 + int base = (opcode >> 16) & 15; 1.3672 + u32 address = reg[base].I - offset; 1.3673 + reg[dest].I = CPUReadByte(address); 1.3674 + if (dest != base) 1.3675 + reg[base].I = address; 1.3676 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.3677 + } 1.3678 + break; 1.3679 + CASE_16(0x5d0) 1.3680 + { 1.3681 + // LDRB Rd, [Rn, #] 1.3682 + int offset = opcode & 0xFFF; 1.3683 + int dest = (opcode >> 12) & 15; 1.3684 + int base = (opcode >> 16) & 15; 1.3685 + u32 address = reg[base].I + offset; 1.3686 + reg[dest].I = CPUReadByte(address); 1.3687 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.3688 + } 1.3689 + break; 1.3690 + CASE_16(0x5f0) 1.3691 + { 1.3692 + // LDRB Rd, [Rn, #]! 1.3693 + int offset = opcode & 0xFFF; 1.3694 + int dest = (opcode >> 12) & 15; 1.3695 + int base = (opcode >> 16) & 15; 1.3696 + u32 address = reg[base].I + offset; 1.3697 + reg[dest].I = CPUReadByte(address); 1.3698 + if (dest != base) 1.3699 + reg[base].I = address; 1.3700 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.3701 + } 1.3702 + break; 1.3703 + case 0x600: 1.3704 + case 0x608: 1.3705 + // T versions are the same 1.3706 + case 0x620: 1.3707 + case 0x628: 1.3708 + { 1.3709 + // STR Rd, [Rn], -Rm, LSL # 1.3710 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.3711 + int dest = (opcode >> 12) & 15; 1.3712 + int base = (opcode >> 16) & 15; 1.3713 + u32 address = reg[base].I; 1.3714 + CPUWriteMemory(address, reg[dest].I); 1.3715 + reg[base].I = address - offset; 1.3716 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3717 + } 1.3718 + break; 1.3719 + case 0x602: 1.3720 + case 0x60a: 1.3721 + // T versions are the same 1.3722 + case 0x622: 1.3723 + case 0x62a: 1.3724 + { 1.3725 + // STR Rd, [Rn], -Rm, LSR # 1.3726 + int shift = (opcode >> 7) & 31; 1.3727 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.3728 + int dest = (opcode >> 12) & 15; 1.3729 + int base = (opcode >> 16) & 15; 1.3730 + u32 address = reg[base].I; 1.3731 + CPUWriteMemory(address, reg[dest].I); 1.3732 + reg[base].I = address - offset; 1.3733 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3734 + } 1.3735 + break; 1.3736 + case 0x604: 1.3737 + case 0x60c: 1.3738 + // T versions are the same 1.3739 + case 0x624: 1.3740 + case 0x62c: 1.3741 + { 1.3742 + // STR Rd, [Rn], -Rm, ASR # 1.3743 + int shift = (opcode >> 7) & 31; 1.3744 + int offset; 1.3745 + if (shift) 1.3746 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.3747 + else if (reg[opcode & 15].I & 0x80000000) 1.3748 + offset = 0xFFFFFFFF; 1.3749 + else 1.3750 + offset = 0; 1.3751 + int dest = (opcode >> 12) & 15; 1.3752 + int base = (opcode >> 16) & 15; 1.3753 + u32 address = reg[base].I; 1.3754 + CPUWriteMemory(address, reg[dest].I); 1.3755 + reg[base].I = address - offset; 1.3756 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3757 + } 1.3758 + break; 1.3759 + case 0x606: 1.3760 + case 0x60e: 1.3761 + // T versions are the same 1.3762 + case 0x626: 1.3763 + case 0x62e: 1.3764 + { 1.3765 + // STR Rd, [Rn], -Rm, ROR # 1.3766 + int shift = (opcode >> 7) & 31; 1.3767 + u32 value = reg[opcode & 15].I; 1.3768 + if (shift) 1.3769 + { 1.3770 + ROR_VALUE; 1.3771 + } 1.3772 + else 1.3773 + { 1.3774 + RCR_VALUE; 1.3775 + } 1.3776 + int dest = (opcode >> 12) & 15; 1.3777 + int base = (opcode >> 16) & 15; 1.3778 + u32 address = reg[base].I; 1.3779 + CPUWriteMemory(address, reg[dest].I); 1.3780 + reg[base].I = address - value; 1.3781 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3782 + } 1.3783 + break; 1.3784 + case 0x680: 1.3785 + case 0x688: 1.3786 + // T versions are the same 1.3787 + case 0x6a0: 1.3788 + case 0x6a8: 1.3789 + { 1.3790 + // STR Rd, [Rn], Rm, LSL # 1.3791 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.3792 + int dest = (opcode >> 12) & 15; 1.3793 + int base = (opcode >> 16) & 15; 1.3794 + u32 address = reg[base].I; 1.3795 + CPUWriteMemory(address, reg[dest].I); 1.3796 + reg[base].I = address + offset; 1.3797 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3798 + } 1.3799 + break; 1.3800 + case 0x682: 1.3801 + case 0x68a: 1.3802 + // T versions are the same 1.3803 + case 0x6a2: 1.3804 + case 0x6aa: 1.3805 + { 1.3806 + // STR Rd, [Rn], Rm, LSR # 1.3807 + int shift = (opcode >> 7) & 31; 1.3808 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.3809 + int dest = (opcode >> 12) & 15; 1.3810 + int base = (opcode >> 16) & 15; 1.3811 + u32 address = reg[base].I; 1.3812 + CPUWriteMemory(address, reg[dest].I); 1.3813 + reg[base].I = address + offset; 1.3814 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3815 + } 1.3816 + break; 1.3817 + case 0x684: 1.3818 + case 0x68c: 1.3819 + // T versions are the same 1.3820 + case 0x6a4: 1.3821 + case 0x6ac: 1.3822 + { 1.3823 + // STR Rd, [Rn], Rm, ASR # 1.3824 + int shift = (opcode >> 7) & 31; 1.3825 + int offset; 1.3826 + if (shift) 1.3827 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.3828 + else if (reg[opcode & 15].I & 0x80000000) 1.3829 + offset = 0xFFFFFFFF; 1.3830 + else 1.3831 + offset = 0; 1.3832 + int dest = (opcode >> 12) & 15; 1.3833 + int base = (opcode >> 16) & 15; 1.3834 + u32 address = reg[base].I; 1.3835 + CPUWriteMemory(address, reg[dest].I); 1.3836 + reg[base].I = address + offset; 1.3837 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3838 + } 1.3839 + break; 1.3840 + case 0x686: 1.3841 + case 0x68e: 1.3842 + // T versions are the same 1.3843 + case 0x6a6: 1.3844 + case 0x6ae: 1.3845 + { 1.3846 + // STR Rd, [Rn], Rm, ROR # 1.3847 + int shift = (opcode >> 7) & 31; 1.3848 + u32 value = reg[opcode & 15].I; 1.3849 + if (shift) 1.3850 + { 1.3851 + ROR_VALUE; 1.3852 + } 1.3853 + else 1.3854 + { 1.3855 + RCR_VALUE; 1.3856 + } 1.3857 + int dest = (opcode >> 12) & 15; 1.3858 + int base = (opcode >> 16) & 15; 1.3859 + u32 address = reg[base].I; 1.3860 + CPUWriteMemory(address, reg[dest].I); 1.3861 + reg[base].I = address + value; 1.3862 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3863 + } 1.3864 + break; 1.3865 + case 0x700: 1.3866 + case 0x708: 1.3867 + { 1.3868 + // STR Rd, [Rn, -Rm, LSL #] 1.3869 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.3870 + int dest = (opcode >> 12) & 15; 1.3871 + int base = (opcode >> 16) & 15; 1.3872 + u32 address = reg[base].I - offset; 1.3873 + CPUWriteMemory(address, reg[dest].I); 1.3874 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3875 + } 1.3876 + break; 1.3877 + case 0x702: 1.3878 + case 0x70a: 1.3879 + { 1.3880 + // STR Rd, [Rn, -Rm, LSR #] 1.3881 + int shift = (opcode >> 7) & 31; 1.3882 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.3883 + int dest = (opcode >> 12) & 15; 1.3884 + int base = (opcode >> 16) & 15; 1.3885 + u32 address = reg[base].I - offset; 1.3886 + CPUWriteMemory(address, reg[dest].I); 1.3887 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3888 + } 1.3889 + break; 1.3890 + case 0x704: 1.3891 + case 0x70c: 1.3892 + { 1.3893 + // STR Rd, [Rn, -Rm, ASR #] 1.3894 + int shift = (opcode >> 7) & 31; 1.3895 + int offset; 1.3896 + if (shift) 1.3897 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.3898 + else if (reg[opcode & 15].I & 0x80000000) 1.3899 + offset = 0xFFFFFFFF; 1.3900 + else 1.3901 + offset = 0; 1.3902 + int dest = (opcode >> 12) & 15; 1.3903 + int base = (opcode >> 16) & 15; 1.3904 + u32 address = reg[base].I - offset; 1.3905 + CPUWriteMemory(address, reg[dest].I); 1.3906 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3907 + } 1.3908 + break; 1.3909 + case 0x706: 1.3910 + case 0x70e: 1.3911 + { 1.3912 + // STR Rd, [Rn, -Rm, ROR #] 1.3913 + int shift = (opcode >> 7) & 31; 1.3914 + u32 value = reg[opcode & 15].I; 1.3915 + if (shift) 1.3916 + { 1.3917 + ROR_VALUE; 1.3918 + } 1.3919 + else 1.3920 + { 1.3921 + RCR_VALUE; 1.3922 + } 1.3923 + int dest = (opcode >> 12) & 15; 1.3924 + int base = (opcode >> 16) & 15; 1.3925 + u32 address = reg[base].I - value; 1.3926 + CPUWriteMemory(address, reg[dest].I); 1.3927 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3928 + } 1.3929 + break; 1.3930 + case 0x720: 1.3931 + case 0x728: 1.3932 + { 1.3933 + // STR Rd, [Rn, -Rm, LSL #]! 1.3934 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.3935 + int dest = (opcode >> 12) & 15; 1.3936 + int base = (opcode >> 16) & 15; 1.3937 + u32 address = reg[base].I - offset; 1.3938 + reg[base].I = address; 1.3939 + CPUWriteMemory(address, reg[dest].I); 1.3940 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3941 + } 1.3942 + break; 1.3943 + case 0x722: 1.3944 + case 0x72a: 1.3945 + { 1.3946 + // STR Rd, [Rn, -Rm, LSR #]! 1.3947 + int shift = (opcode >> 7) & 31; 1.3948 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.3949 + int dest = (opcode >> 12) & 15; 1.3950 + int base = (opcode >> 16) & 15; 1.3951 + u32 address = reg[base].I - offset; 1.3952 + reg[base].I = address; 1.3953 + CPUWriteMemory(address, reg[dest].I); 1.3954 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3955 + } 1.3956 + break; 1.3957 + case 0x724: 1.3958 + case 0x72c: 1.3959 + { 1.3960 + // STR Rd, [Rn, -Rm, ASR #]! 1.3961 + int shift = (opcode >> 7) & 31; 1.3962 + int offset; 1.3963 + if (shift) 1.3964 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.3965 + else if (reg[opcode & 15].I & 0x80000000) 1.3966 + offset = 0xFFFFFFFF; 1.3967 + else 1.3968 + offset = 0; 1.3969 + int dest = (opcode >> 12) & 15; 1.3970 + int base = (opcode >> 16) & 15; 1.3971 + u32 address = reg[base].I - offset; 1.3972 + reg[base].I = address; 1.3973 + CPUWriteMemory(address, reg[dest].I); 1.3974 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3975 + } 1.3976 + break; 1.3977 + case 0x726: 1.3978 + case 0x72e: 1.3979 + { 1.3980 + // STR Rd, [Rn, -Rm, ROR #]! 1.3981 + int shift = (opcode >> 7) & 31; 1.3982 + u32 value = reg[opcode & 15].I; 1.3983 + if (shift) 1.3984 + { 1.3985 + ROR_VALUE; 1.3986 + } 1.3987 + else 1.3988 + { 1.3989 + RCR_VALUE; 1.3990 + } 1.3991 + int dest = (opcode >> 12) & 15; 1.3992 + int base = (opcode >> 16) & 15; 1.3993 + u32 address = reg[base].I - value; 1.3994 + reg[base].I = address; 1.3995 + CPUWriteMemory(address, reg[dest].I); 1.3996 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.3997 + } 1.3998 + break; 1.3999 + case 0x780: 1.4000 + case 0x788: 1.4001 + { 1.4002 + // STR Rd, [Rn, Rm, LSL #] 1.4003 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4004 + int dest = (opcode >> 12) & 15; 1.4005 + int base = (opcode >> 16) & 15; 1.4006 + u32 address = reg[base].I + offset; 1.4007 + CPUWriteMemory(address, reg[dest].I); 1.4008 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.4009 + } 1.4010 + break; 1.4011 + case 0x782: 1.4012 + case 0x78a: 1.4013 + { 1.4014 + // STR Rd, [Rn, Rm, LSR #] 1.4015 + int shift = (opcode >> 7) & 31; 1.4016 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4017 + int dest = (opcode >> 12) & 15; 1.4018 + int base = (opcode >> 16) & 15; 1.4019 + u32 address = reg[base].I + offset; 1.4020 + CPUWriteMemory(address, reg[dest].I); 1.4021 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.4022 + } 1.4023 + break; 1.4024 + case 0x784: 1.4025 + case 0x78c: 1.4026 + { 1.4027 + // STR Rd, [Rn, Rm, ASR #] 1.4028 + int shift = (opcode >> 7) & 31; 1.4029 + int offset; 1.4030 + if (shift) 1.4031 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.4032 + else if (reg[opcode & 15].I & 0x80000000) 1.4033 + offset = 0xFFFFFFFF; 1.4034 + else 1.4035 + offset = 0; 1.4036 + int dest = (opcode >> 12) & 15; 1.4037 + int base = (opcode >> 16) & 15; 1.4038 + u32 address = reg[base].I + offset; 1.4039 + CPUWriteMemory(address, reg[dest].I); 1.4040 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.4041 + } 1.4042 + break; 1.4043 + case 0x786: 1.4044 + case 0x78e: 1.4045 + { 1.4046 + // STR Rd, [Rn, Rm, ROR #] 1.4047 + int shift = (opcode >> 7) & 31; 1.4048 + u32 value = reg[opcode & 15].I; 1.4049 + if (shift) 1.4050 + { 1.4051 + ROR_VALUE; 1.4052 + } 1.4053 + else 1.4054 + { 1.4055 + RCR_VALUE; 1.4056 + } 1.4057 + int dest = (opcode >> 12) & 15; 1.4058 + int base = (opcode >> 16) & 15; 1.4059 + u32 address = reg[base].I + value; 1.4060 + CPUWriteMemory(address, reg[dest].I); 1.4061 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.4062 + } 1.4063 + break; 1.4064 + case 0x7a0: 1.4065 + case 0x7a8: 1.4066 + { 1.4067 + // STR Rd, [Rn, Rm, LSL #]! 1.4068 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4069 + int dest = (opcode >> 12) & 15; 1.4070 + int base = (opcode >> 16) & 15; 1.4071 + u32 address = reg[base].I + offset; 1.4072 + reg[base].I = address; 1.4073 + CPUWriteMemory(address, reg[dest].I); 1.4074 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.4075 + } 1.4076 + break; 1.4077 + case 0x7a2: 1.4078 + case 0x7aa: 1.4079 + { 1.4080 + // STR Rd, [Rn, Rm, LSR #]! 1.4081 + int shift = (opcode >> 7) & 31; 1.4082 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4083 + int dest = (opcode >> 12) & 15; 1.4084 + int base = (opcode >> 16) & 15; 1.4085 + u32 address = reg[base].I + offset; 1.4086 + reg[base].I = address; 1.4087 + CPUWriteMemory(address, reg[dest].I); 1.4088 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.4089 + } 1.4090 + break; 1.4091 + case 0x7a4: 1.4092 + case 0x7ac: 1.4093 + { 1.4094 + // STR Rd, [Rn, Rm, ASR #]! 1.4095 + int shift = (opcode >> 7) & 31; 1.4096 + int offset; 1.4097 + if (shift) 1.4098 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.4099 + else if (reg[opcode & 15].I & 0x80000000) 1.4100 + offset = 0xFFFFFFFF; 1.4101 + else 1.4102 + offset = 0; 1.4103 + int dest = (opcode >> 12) & 15; 1.4104 + int base = (opcode >> 16) & 15; 1.4105 + u32 address = reg[base].I + offset; 1.4106 + reg[base].I = address; 1.4107 + CPUWriteMemory(address, reg[dest].I); 1.4108 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.4109 + } 1.4110 + break; 1.4111 + case 0x7a6: 1.4112 + case 0x7ae: 1.4113 + { 1.4114 + // STR Rd, [Rn, Rm, ROR #]! 1.4115 + int shift = (opcode >> 7) & 31; 1.4116 + u32 value = reg[opcode & 15].I; 1.4117 + if (shift) 1.4118 + { 1.4119 + ROR_VALUE; 1.4120 + } 1.4121 + else 1.4122 + { 1.4123 + RCR_VALUE; 1.4124 + } 1.4125 + int dest = (opcode >> 12) & 15; 1.4126 + int base = (opcode >> 16) & 15; 1.4127 + u32 address = reg[base].I + value; 1.4128 + reg[base].I = address; 1.4129 + CPUWriteMemory(address, reg[dest].I); 1.4130 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.4131 + } 1.4132 + break; 1.4133 + case 0x610: 1.4134 + case 0x618: 1.4135 + // T versions are the same 1.4136 + case 0x630: 1.4137 + case 0x638: 1.4138 + { 1.4139 + // LDR Rd, [Rn], -Rm, LSL # 1.4140 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4141 + int dest = (opcode >> 12) & 15; 1.4142 + int base = (opcode >> 16) & 15; 1.4143 + u32 address = reg[base].I; 1.4144 + reg[dest].I = CPUReadMemory(address); 1.4145 + if (dest != base) 1.4146 + reg[base].I = address - offset; 1.4147 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4148 + if (dest == 15) 1.4149 + { 1.4150 + clockTicks += 2; 1.4151 + reg[15].I &= 0xFFFFFFFC; 1.4152 + armNextPC = reg[15].I; 1.4153 + reg[15].I += 4; 1.4154 + } 1.4155 + } 1.4156 + break; 1.4157 + case 0x612: 1.4158 + case 0x61a: 1.4159 + // T versions are the same 1.4160 + case 0x632: 1.4161 + case 0x63a: 1.4162 + { 1.4163 + // LDR Rd, [Rn], -Rm, LSR # 1.4164 + int shift = (opcode >> 7) & 31; 1.4165 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4166 + int dest = (opcode >> 12) & 15; 1.4167 + int base = (opcode >> 16) & 15; 1.4168 + u32 address = reg[base].I; 1.4169 + reg[dest].I = CPUReadMemory(address); 1.4170 + if (dest != base) 1.4171 + reg[base].I = address - offset; 1.4172 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4173 + if (dest == 15) 1.4174 + { 1.4175 + clockTicks += 2; 1.4176 + reg[15].I &= 0xFFFFFFFC; 1.4177 + armNextPC = reg[15].I; 1.4178 + reg[15].I += 4; 1.4179 + } 1.4180 + } 1.4181 + break; 1.4182 + case 0x614: 1.4183 + case 0x61c: 1.4184 + // T versions are the same 1.4185 + case 0x634: 1.4186 + case 0x63c: 1.4187 + { 1.4188 + // LDR Rd, [Rn], -Rm, ASR # 1.4189 + int shift = (opcode >> 7) & 31; 1.4190 + int offset; 1.4191 + if (shift) 1.4192 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.4193 + else if (reg[opcode & 15].I & 0x80000000) 1.4194 + offset = 0xFFFFFFFF; 1.4195 + else 1.4196 + offset = 0; 1.4197 + int dest = (opcode >> 12) & 15; 1.4198 + int base = (opcode >> 16) & 15; 1.4199 + u32 address = reg[base].I; 1.4200 + reg[dest].I = CPUReadMemory(address); 1.4201 + if (dest != base) 1.4202 + reg[base].I = address - offset; 1.4203 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4204 + if (dest == 15) 1.4205 + { 1.4206 + clockTicks += 2; 1.4207 + reg[15].I &= 0xFFFFFFFC; 1.4208 + armNextPC = reg[15].I; 1.4209 + reg[15].I += 4; 1.4210 + } 1.4211 + } 1.4212 + break; 1.4213 + case 0x616: 1.4214 + case 0x61e: 1.4215 + // T versions are the same 1.4216 + case 0x636: 1.4217 + case 0x63e: 1.4218 + { 1.4219 + // LDR Rd, [Rn], -Rm, ROR # 1.4220 + int shift = (opcode >> 7) & 31; 1.4221 + u32 value = reg[opcode & 15].I; 1.4222 + if (shift) 1.4223 + { 1.4224 + ROR_VALUE; 1.4225 + } 1.4226 + else 1.4227 + { 1.4228 + RCR_VALUE; 1.4229 + } 1.4230 + int dest = (opcode >> 12) & 15; 1.4231 + int base = (opcode >> 16) & 15; 1.4232 + u32 address = reg[base].I; 1.4233 + reg[dest].I = CPUReadMemory(address); 1.4234 + if (dest != base) 1.4235 + reg[base].I = address - value; 1.4236 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4237 + if (dest == 15) 1.4238 + { 1.4239 + clockTicks += 2; 1.4240 + reg[15].I &= 0xFFFFFFFC; 1.4241 + armNextPC = reg[15].I; 1.4242 + reg[15].I += 4; 1.4243 + } 1.4244 + } 1.4245 + break; 1.4246 + case 0x690: 1.4247 + case 0x698: 1.4248 + // T versions are the same 1.4249 + case 0x6b0: 1.4250 + case 0x6b8: 1.4251 + { 1.4252 + // LDR Rd, [Rn], Rm, LSL # 1.4253 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4254 + int dest = (opcode >> 12) & 15; 1.4255 + int base = (opcode >> 16) & 15; 1.4256 + u32 address = reg[base].I; 1.4257 + reg[dest].I = CPUReadMemory(address); 1.4258 + if (dest != base) 1.4259 + reg[base].I = address + offset; 1.4260 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4261 + if (dest == 15) 1.4262 + { 1.4263 + clockTicks += 2; 1.4264 + reg[15].I &= 0xFFFFFFFC; 1.4265 + armNextPC = reg[15].I; 1.4266 + reg[15].I += 4; 1.4267 + } 1.4268 + } 1.4269 + break; 1.4270 + case 0x692: 1.4271 + case 0x69a: 1.4272 + // T versions are the same 1.4273 + case 0x6b2: 1.4274 + case 0x6ba: 1.4275 + { 1.4276 + // LDR Rd, [Rn], Rm, LSR # 1.4277 + int shift = (opcode >> 7) & 31; 1.4278 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4279 + int dest = (opcode >> 12) & 15; 1.4280 + int base = (opcode >> 16) & 15; 1.4281 + u32 address = reg[base].I; 1.4282 + reg[dest].I = CPUReadMemory(address); 1.4283 + if (dest != base) 1.4284 + reg[base].I = address + offset; 1.4285 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4286 + if (dest == 15) 1.4287 + { 1.4288 + clockTicks += 2; 1.4289 + reg[15].I &= 0xFFFFFFFC; 1.4290 + armNextPC = reg[15].I; 1.4291 + reg[15].I += 4; 1.4292 + } 1.4293 + } 1.4294 + break; 1.4295 + case 0x694: 1.4296 + case 0x69c: 1.4297 + // T versions are the same 1.4298 + case 0x6b4: 1.4299 + case 0x6bc: 1.4300 + { 1.4301 + // LDR Rd, [Rn], Rm, ASR # 1.4302 + int shift = (opcode >> 7) & 31; 1.4303 + int offset; 1.4304 + if (shift) 1.4305 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.4306 + else if (reg[opcode & 15].I & 0x80000000) 1.4307 + offset = 0xFFFFFFFF; 1.4308 + else 1.4309 + offset = 0; 1.4310 + int dest = (opcode >> 12) & 15; 1.4311 + int base = (opcode >> 16) & 15; 1.4312 + u32 address = reg[base].I; 1.4313 + reg[dest].I = CPUReadMemory(address); 1.4314 + if (dest != base) 1.4315 + reg[base].I = address + offset; 1.4316 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4317 + if (dest == 15) 1.4318 + { 1.4319 + clockTicks += 2; 1.4320 + reg[15].I &= 0xFFFFFFFC; 1.4321 + armNextPC = reg[15].I; 1.4322 + reg[15].I += 4; 1.4323 + } 1.4324 + } 1.4325 + break; 1.4326 + case 0x696: 1.4327 + case 0x69e: 1.4328 + // T versions are the same 1.4329 + case 0x6b6: 1.4330 + case 0x6be: 1.4331 + { 1.4332 + // LDR Rd, [Rn], Rm, ROR # 1.4333 + int shift = (opcode >> 7) & 31; 1.4334 + u32 value = reg[opcode & 15].I; 1.4335 + if (shift) 1.4336 + { 1.4337 + ROR_VALUE; 1.4338 + } 1.4339 + else 1.4340 + { 1.4341 + RCR_VALUE; 1.4342 + } 1.4343 + int dest = (opcode >> 12) & 15; 1.4344 + int base = (opcode >> 16) & 15; 1.4345 + u32 address = reg[base].I; 1.4346 + reg[dest].I = CPUReadMemory(address); 1.4347 + if (dest != base) 1.4348 + reg[base].I = address + value; 1.4349 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4350 + if (dest == 15) 1.4351 + { 1.4352 + clockTicks += 2; 1.4353 + reg[15].I &= 0xFFFFFFFC; 1.4354 + armNextPC = reg[15].I; 1.4355 + reg[15].I += 4; 1.4356 + } 1.4357 + } 1.4358 + break; 1.4359 + case 0x710: 1.4360 + case 0x718: 1.4361 + { 1.4362 + // LDR Rd, [Rn, -Rm, LSL #] 1.4363 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4364 + int dest = (opcode >> 12) & 15; 1.4365 + int base = (opcode >> 16) & 15; 1.4366 + u32 address = reg[base].I - offset; 1.4367 + reg[dest].I = CPUReadMemory(address); 1.4368 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4369 + if (dest == 15) 1.4370 + { 1.4371 + clockTicks += 2; 1.4372 + reg[15].I &= 0xFFFFFFFC; 1.4373 + armNextPC = reg[15].I; 1.4374 + reg[15].I += 4; 1.4375 + } 1.4376 + } 1.4377 + break; 1.4378 + case 0x712: 1.4379 + case 0x71a: 1.4380 + { 1.4381 + // LDR Rd, [Rn, -Rm, LSR #] 1.4382 + int shift = (opcode >> 7) & 31; 1.4383 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4384 + int dest = (opcode >> 12) & 15; 1.4385 + int base = (opcode >> 16) & 15; 1.4386 + u32 address = reg[base].I - offset; 1.4387 + reg[dest].I = CPUReadMemory(address); 1.4388 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4389 + if (dest == 15) 1.4390 + { 1.4391 + clockTicks += 2; 1.4392 + reg[15].I &= 0xFFFFFFFC; 1.4393 + armNextPC = reg[15].I; 1.4394 + reg[15].I += 4; 1.4395 + } 1.4396 + } 1.4397 + break; 1.4398 + case 0x714: 1.4399 + case 0x71c: 1.4400 + { 1.4401 + // LDR Rd, [Rn, -Rm, ASR #] 1.4402 + int shift = (opcode >> 7) & 31; 1.4403 + int offset; 1.4404 + if (shift) 1.4405 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.4406 + else if (reg[opcode & 15].I & 0x80000000) 1.4407 + offset = 0xFFFFFFFF; 1.4408 + else 1.4409 + offset = 0; 1.4410 + int dest = (opcode >> 12) & 15; 1.4411 + int base = (opcode >> 16) & 15; 1.4412 + u32 address = reg[base].I - offset; 1.4413 + reg[dest].I = CPUReadMemory(address); 1.4414 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4415 + if (dest == 15) 1.4416 + { 1.4417 + clockTicks += 2; 1.4418 + reg[15].I &= 0xFFFFFFFC; 1.4419 + armNextPC = reg[15].I; 1.4420 + reg[15].I += 4; 1.4421 + } 1.4422 + } 1.4423 + break; 1.4424 + case 0x716: 1.4425 + case 0x71e: 1.4426 + { 1.4427 + // LDR Rd, [Rn, -Rm, ROR #] 1.4428 + int shift = (opcode >> 7) & 31; 1.4429 + u32 value = reg[opcode & 15].I; 1.4430 + if (shift) 1.4431 + { 1.4432 + ROR_VALUE; 1.4433 + } 1.4434 + else 1.4435 + { 1.4436 + RCR_VALUE; 1.4437 + } 1.4438 + int dest = (opcode >> 12) & 15; 1.4439 + int base = (opcode >> 16) & 15; 1.4440 + u32 address = reg[base].I - value; 1.4441 + reg[dest].I = CPUReadMemory(address); 1.4442 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4443 + if (dest == 15) 1.4444 + { 1.4445 + clockTicks += 2; 1.4446 + reg[15].I &= 0xFFFFFFFC; 1.4447 + armNextPC = reg[15].I; 1.4448 + reg[15].I += 4; 1.4449 + } 1.4450 + } 1.4451 + break; 1.4452 + case 0x730: 1.4453 + case 0x738: 1.4454 + { 1.4455 + // LDR Rd, [Rn, -Rm, LSL #]! 1.4456 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4457 + int dest = (opcode >> 12) & 15; 1.4458 + int base = (opcode >> 16) & 15; 1.4459 + u32 address = reg[base].I - offset; 1.4460 + reg[dest].I = CPUReadMemory(address); 1.4461 + if (dest != base) 1.4462 + reg[base].I = address; 1.4463 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4464 + if (dest == 15) 1.4465 + { 1.4466 + clockTicks += 2; 1.4467 + reg[15].I &= 0xFFFFFFFC; 1.4468 + armNextPC = reg[15].I; 1.4469 + reg[15].I += 4; 1.4470 + } 1.4471 + } 1.4472 + break; 1.4473 + case 0x732: 1.4474 + case 0x73a: 1.4475 + { 1.4476 + // LDR Rd, [Rn, -Rm, LSR #]! 1.4477 + int shift = (opcode >> 7) & 31; 1.4478 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4479 + int dest = (opcode >> 12) & 15; 1.4480 + int base = (opcode >> 16) & 15; 1.4481 + u32 address = reg[base].I - offset; 1.4482 + reg[dest].I = CPUReadMemory(address); 1.4483 + if (dest != base) 1.4484 + reg[base].I = address; 1.4485 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4486 + if (dest == 15) 1.4487 + { 1.4488 + clockTicks += 2; 1.4489 + reg[15].I &= 0xFFFFFFFC; 1.4490 + armNextPC = reg[15].I; 1.4491 + reg[15].I += 4; 1.4492 + } 1.4493 + } 1.4494 + break; 1.4495 + case 0x734: 1.4496 + case 0x73c: 1.4497 + { 1.4498 + // LDR Rd, [Rn, -Rm, ASR #]! 1.4499 + int shift = (opcode >> 7) & 31; 1.4500 + int offset; 1.4501 + if (shift) 1.4502 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.4503 + else if (reg[opcode & 15].I & 0x80000000) 1.4504 + offset = 0xFFFFFFFF; 1.4505 + else 1.4506 + offset = 0; 1.4507 + int dest = (opcode >> 12) & 15; 1.4508 + int base = (opcode >> 16) & 15; 1.4509 + u32 address = reg[base].I - offset; 1.4510 + reg[dest].I = CPUReadMemory(address); 1.4511 + if (dest != base) 1.4512 + reg[base].I = address; 1.4513 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4514 + if (dest == 15) 1.4515 + { 1.4516 + clockTicks += 2; 1.4517 + reg[15].I &= 0xFFFFFFFC; 1.4518 + armNextPC = reg[15].I; 1.4519 + reg[15].I += 4; 1.4520 + } 1.4521 + } 1.4522 + break; 1.4523 + case 0x736: 1.4524 + case 0x73e: 1.4525 + { 1.4526 + // LDR Rd, [Rn, -Rm, ROR #]! 1.4527 + int shift = (opcode >> 7) & 31; 1.4528 + u32 value = reg[opcode & 15].I; 1.4529 + if (shift) 1.4530 + { 1.4531 + ROR_VALUE; 1.4532 + } 1.4533 + else 1.4534 + { 1.4535 + RCR_VALUE; 1.4536 + } 1.4537 + int dest = (opcode >> 12) & 15; 1.4538 + int base = (opcode >> 16) & 15; 1.4539 + u32 address = reg[base].I - value; 1.4540 + reg[dest].I = CPUReadMemory(address); 1.4541 + if (dest != base) 1.4542 + reg[base].I = address; 1.4543 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4544 + if (dest == 15) 1.4545 + { 1.4546 + clockTicks += 2; 1.4547 + reg[15].I &= 0xFFFFFFFC; 1.4548 + armNextPC = reg[15].I; 1.4549 + reg[15].I += 4; 1.4550 + } 1.4551 + } 1.4552 + break; 1.4553 + case 0x790: 1.4554 + case 0x798: 1.4555 + { 1.4556 + // LDR Rd, [Rn, Rm, LSL #] 1.4557 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4558 + int dest = (opcode >> 12) & 15; 1.4559 + int base = (opcode >> 16) & 15; 1.4560 + u32 address = reg[base].I + offset; 1.4561 + reg[dest].I = CPUReadMemory(address); 1.4562 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4563 + if (dest == 15) 1.4564 + { 1.4565 + clockTicks += 2; 1.4566 + reg[15].I &= 0xFFFFFFFC; 1.4567 + armNextPC = reg[15].I; 1.4568 + reg[15].I += 4; 1.4569 + } 1.4570 + } 1.4571 + break; 1.4572 + case 0x792: 1.4573 + case 0x79a: 1.4574 + { 1.4575 + // LDR Rd, [Rn, Rm, LSR #] 1.4576 + int shift = (opcode >> 7) & 31; 1.4577 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4578 + int dest = (opcode >> 12) & 15; 1.4579 + int base = (opcode >> 16) & 15; 1.4580 + u32 address = reg[base].I + offset; 1.4581 + reg[dest].I = CPUReadMemory(address); 1.4582 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4583 + if (dest == 15) 1.4584 + { 1.4585 + clockTicks += 2; 1.4586 + reg[15].I &= 0xFFFFFFFC; 1.4587 + armNextPC = reg[15].I; 1.4588 + reg[15].I += 4; 1.4589 + } 1.4590 + } 1.4591 + break; 1.4592 + case 0x794: 1.4593 + case 0x79c: 1.4594 + { 1.4595 + // LDR Rd, [Rn, Rm, ASR #] 1.4596 + int shift = (opcode >> 7) & 31; 1.4597 + int offset; 1.4598 + if (shift) 1.4599 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.4600 + else if (reg[opcode & 15].I & 0x80000000) 1.4601 + offset = 0xFFFFFFFF; 1.4602 + else 1.4603 + offset = 0; 1.4604 + int dest = (opcode >> 12) & 15; 1.4605 + int base = (opcode >> 16) & 15; 1.4606 + u32 address = reg[base].I + offset; 1.4607 + reg[dest].I = CPUReadMemory(address); 1.4608 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4609 + if (dest == 15) 1.4610 + { 1.4611 + clockTicks += 2; 1.4612 + reg[15].I &= 0xFFFFFFFC; 1.4613 + armNextPC = reg[15].I; 1.4614 + reg[15].I += 4; 1.4615 + } 1.4616 + } 1.4617 + break; 1.4618 + case 0x796: 1.4619 + case 0x79e: 1.4620 + { 1.4621 + // LDR Rd, [Rn, Rm, ROR #] 1.4622 + int shift = (opcode >> 7) & 31; 1.4623 + u32 value = reg[opcode & 15].I; 1.4624 + if (shift) 1.4625 + { 1.4626 + ROR_VALUE; 1.4627 + } 1.4628 + else 1.4629 + { 1.4630 + RCR_VALUE; 1.4631 + } 1.4632 + int dest = (opcode >> 12) & 15; 1.4633 + int base = (opcode >> 16) & 15; 1.4634 + u32 address = reg[base].I + value; 1.4635 + reg[dest].I = CPUReadMemory(address); 1.4636 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4637 + if (dest == 15) 1.4638 + { 1.4639 + clockTicks += 2; 1.4640 + reg[15].I &= 0xFFFFFFFC; 1.4641 + armNextPC = reg[15].I; 1.4642 + reg[15].I += 4; 1.4643 + } 1.4644 + } 1.4645 + break; 1.4646 + case 0x7b0: 1.4647 + case 0x7b8: 1.4648 + { 1.4649 + // LDR Rd, [Rn, Rm, LSL #]! 1.4650 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4651 + int dest = (opcode >> 12) & 15; 1.4652 + int base = (opcode >> 16) & 15; 1.4653 + u32 address = reg[base].I + offset; 1.4654 + reg[dest].I = CPUReadMemory(address); 1.4655 + if (dest != base) 1.4656 + reg[base].I = address; 1.4657 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4658 + if (dest == 15) 1.4659 + { 1.4660 + clockTicks += 2; 1.4661 + reg[15].I &= 0xFFFFFFFC; 1.4662 + armNextPC = reg[15].I; 1.4663 + reg[15].I += 4; 1.4664 + } 1.4665 + } 1.4666 + break; 1.4667 + case 0x7b2: 1.4668 + case 0x7ba: 1.4669 + { 1.4670 + // LDR Rd, [Rn, Rm, LSR #]! 1.4671 + int shift = (opcode >> 7) & 31; 1.4672 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4673 + int dest = (opcode >> 12) & 15; 1.4674 + int base = (opcode >> 16) & 15; 1.4675 + u32 address = reg[base].I + offset; 1.4676 + reg[dest].I = CPUReadMemory(address); 1.4677 + if (dest != base) 1.4678 + reg[base].I = address; 1.4679 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4680 + if (dest == 15) 1.4681 + { 1.4682 + clockTicks += 2; 1.4683 + reg[15].I &= 0xFFFFFFFC; 1.4684 + armNextPC = reg[15].I; 1.4685 + reg[15].I += 4; 1.4686 + } 1.4687 + } 1.4688 + break; 1.4689 + case 0x7b4: 1.4690 + case 0x7bc: 1.4691 + { 1.4692 + // LDR Rd, [Rn, Rm, ASR #]! 1.4693 + int shift = (opcode >> 7) & 31; 1.4694 + int offset; 1.4695 + if (shift) 1.4696 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.4697 + else if (reg[opcode & 15].I & 0x80000000) 1.4698 + offset = 0xFFFFFFFF; 1.4699 + else 1.4700 + offset = 0; 1.4701 + int dest = (opcode >> 12) & 15; 1.4702 + int base = (opcode >> 16) & 15; 1.4703 + u32 address = reg[base].I + offset; 1.4704 + reg[dest].I = CPUReadMemory(address); 1.4705 + if (dest != base) 1.4706 + reg[base].I = address; 1.4707 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4708 + if (dest == 15) 1.4709 + { 1.4710 + clockTicks += 2; 1.4711 + reg[15].I &= 0xFFFFFFFC; 1.4712 + armNextPC = reg[15].I; 1.4713 + reg[15].I += 4; 1.4714 + } 1.4715 + } 1.4716 + break; 1.4717 + case 0x7b6: 1.4718 + case 0x7be: 1.4719 + { 1.4720 + // LDR Rd, [Rn, Rm, ROR #]! 1.4721 + int shift = (opcode >> 7) & 31; 1.4722 + u32 value = reg[opcode & 15].I; 1.4723 + if (shift) 1.4724 + { 1.4725 + ROR_VALUE; 1.4726 + } 1.4727 + else 1.4728 + { 1.4729 + RCR_VALUE; 1.4730 + } 1.4731 + int dest = (opcode >> 12) & 15; 1.4732 + int base = (opcode >> 16) & 15; 1.4733 + u32 address = reg[base].I + value; 1.4734 + reg[dest].I = CPUReadMemory(address); 1.4735 + if (dest != base) 1.4736 + reg[base].I = address; 1.4737 + clockTicks += 3 + CPUUpdateTicksAccess32(address); 1.4738 + if (dest == 15) 1.4739 + { 1.4740 + clockTicks += 2; 1.4741 + reg[15].I &= 0xFFFFFFFC; 1.4742 + armNextPC = reg[15].I; 1.4743 + reg[15].I += 4; 1.4744 + } 1.4745 + } 1.4746 + break; 1.4747 + case 0x640: 1.4748 + case 0x648: 1.4749 + // T versions are the same 1.4750 + case 0x660: 1.4751 + case 0x668: 1.4752 + { 1.4753 + // STRB Rd, [Rn], -Rm, LSL # 1.4754 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4755 + int dest = (opcode >> 12) & 15; 1.4756 + int base = (opcode >> 16) & 15; 1.4757 + u32 address = reg[base].I; 1.4758 + CPUWriteByte(address, reg[dest].B.B0); 1.4759 + reg[base].I = address - offset; 1.4760 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4761 + } 1.4762 + break; 1.4763 + case 0x642: 1.4764 + case 0x64a: 1.4765 + // T versions are the same 1.4766 + case 0x662: 1.4767 + case 0x66a: 1.4768 + { 1.4769 + // STRB Rd, [Rn], -Rm, LSR # 1.4770 + int shift = (opcode >> 7) & 31; 1.4771 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4772 + int dest = (opcode >> 12) & 15; 1.4773 + int base = (opcode >> 16) & 15; 1.4774 + u32 address = reg[base].I; 1.4775 + CPUWriteByte(address, reg[dest].B.B0); 1.4776 + reg[base].I = address - offset; 1.4777 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4778 + } 1.4779 + break; 1.4780 + case 0x644: 1.4781 + case 0x64c: 1.4782 + // T versions are the same 1.4783 + case 0x664: 1.4784 + case 0x66c: 1.4785 + { 1.4786 + // STRB Rd, [Rn], -Rm, ASR # 1.4787 + int shift = (opcode >> 7) & 31; 1.4788 + int offset; 1.4789 + if (shift) 1.4790 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.4791 + else if (reg[opcode & 15].I & 0x80000000) 1.4792 + offset = 0xFFFFFFFF; 1.4793 + else 1.4794 + offset = 0; 1.4795 + int dest = (opcode >> 12) & 15; 1.4796 + int base = (opcode >> 16) & 15; 1.4797 + u32 address = reg[base].I; 1.4798 + CPUWriteByte(address, reg[dest].B.B0); 1.4799 + reg[base].I = address - offset; 1.4800 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4801 + } 1.4802 + break; 1.4803 + case 0x646: 1.4804 + case 0x64e: 1.4805 + // T versions are the same 1.4806 + case 0x666: 1.4807 + case 0x66e: 1.4808 + { 1.4809 + // STRB Rd, [Rn], -Rm, ROR # 1.4810 + int shift = (opcode >> 7) & 31; 1.4811 + u32 value = reg[opcode & 15].I; 1.4812 + if (shift) 1.4813 + { 1.4814 + ROR_VALUE; 1.4815 + } 1.4816 + else 1.4817 + { 1.4818 + RCR_VALUE; 1.4819 + } 1.4820 + int dest = (opcode >> 12) & 15; 1.4821 + int base = (opcode >> 16) & 15; 1.4822 + u32 address = reg[base].I; 1.4823 + CPUWriteByte(address, reg[dest].B.B0); 1.4824 + reg[base].I = address - value; 1.4825 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4826 + } 1.4827 + break; 1.4828 + case 0x6c0: 1.4829 + case 0x6c8: 1.4830 + // T versions are the same 1.4831 + case 0x6e0: 1.4832 + case 0x6e8: 1.4833 + { 1.4834 + // STRB Rd, [Rn], Rm, LSL # 1.4835 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4836 + int dest = (opcode >> 12) & 15; 1.4837 + int base = (opcode >> 16) & 15; 1.4838 + u32 address = reg[base].I; 1.4839 + CPUWriteByte(address, reg[dest].B.B0); 1.4840 + reg[base].I = address + offset; 1.4841 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4842 + } 1.4843 + break; 1.4844 + case 0x6c2: 1.4845 + case 0x6ca: 1.4846 + // T versions are the same 1.4847 + case 0x6e2: 1.4848 + case 0x6ea: 1.4849 + { 1.4850 + // STRB Rd, [Rn], Rm, LSR # 1.4851 + int shift = (opcode >> 7) & 31; 1.4852 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4853 + int dest = (opcode >> 12) & 15; 1.4854 + int base = (opcode >> 16) & 15; 1.4855 + u32 address = reg[base].I; 1.4856 + CPUWriteByte(address, reg[dest].B.B0); 1.4857 + reg[base].I = address + offset; 1.4858 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4859 + } 1.4860 + break; 1.4861 + case 0x6c4: 1.4862 + case 0x6cc: 1.4863 + // T versions are the same 1.4864 + case 0x6e4: 1.4865 + case 0x6ec: 1.4866 + { 1.4867 + // STR Rd, [Rn], Rm, ASR # 1.4868 + int shift = (opcode >> 7) & 31; 1.4869 + int offset; 1.4870 + if (shift) 1.4871 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.4872 + else if (reg[opcode & 15].I & 0x80000000) 1.4873 + offset = 0xFFFFFFFF; 1.4874 + else 1.4875 + offset = 0; 1.4876 + int dest = (opcode >> 12) & 15; 1.4877 + int base = (opcode >> 16) & 15; 1.4878 + u32 address = reg[base].I; 1.4879 + CPUWriteByte(address, reg[dest].B.B0); 1.4880 + reg[base].I = address + offset; 1.4881 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4882 + } 1.4883 + break; 1.4884 + case 0x6c6: 1.4885 + case 0x6ce: 1.4886 + // T versions are the same 1.4887 + case 0x6e6: 1.4888 + case 0x6ee: 1.4889 + { 1.4890 + // STRB Rd, [Rn], Rm, ROR # 1.4891 + int shift = (opcode >> 7) & 31; 1.4892 + u32 value = reg[opcode & 15].I; 1.4893 + if (shift) 1.4894 + { 1.4895 + ROR_VALUE; 1.4896 + } 1.4897 + else 1.4898 + { 1.4899 + RCR_VALUE; 1.4900 + } 1.4901 + int dest = (opcode >> 12) & 15; 1.4902 + int base = (opcode >> 16) & 15; 1.4903 + u32 address = reg[base].I; 1.4904 + CPUWriteByte(address, reg[dest].B.B0); 1.4905 + reg[base].I = address + value; 1.4906 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4907 + } 1.4908 + break; 1.4909 + case 0x740: 1.4910 + case 0x748: 1.4911 + { 1.4912 + // STRB Rd, [Rn, -Rm, LSL #] 1.4913 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4914 + int dest = (opcode >> 12) & 15; 1.4915 + int base = (opcode >> 16) & 15; 1.4916 + u32 address = reg[base].I - offset; 1.4917 + CPUWriteByte(address, reg[dest].B.B0); 1.4918 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4919 + } 1.4920 + break; 1.4921 + case 0x742: 1.4922 + case 0x74a: 1.4923 + { 1.4924 + // STRB Rd, [Rn, -Rm, LSR #] 1.4925 + int shift = (opcode >> 7) & 31; 1.4926 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4927 + int dest = (opcode >> 12) & 15; 1.4928 + int base = (opcode >> 16) & 15; 1.4929 + u32 address = reg[base].I - offset; 1.4930 + CPUWriteByte(address, reg[dest].B.B0); 1.4931 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4932 + } 1.4933 + break; 1.4934 + case 0x744: 1.4935 + case 0x74c: 1.4936 + { 1.4937 + // STRB Rd, [Rn, -Rm, ASR #] 1.4938 + int shift = (opcode >> 7) & 31; 1.4939 + int offset; 1.4940 + if (shift) 1.4941 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.4942 + else if (reg[opcode & 15].I & 0x80000000) 1.4943 + offset = 0xFFFFFFFF; 1.4944 + else 1.4945 + offset = 0; 1.4946 + int dest = (opcode >> 12) & 15; 1.4947 + int base = (opcode >> 16) & 15; 1.4948 + u32 address = reg[base].I - offset; 1.4949 + CPUWriteByte(address, reg[dest].B.B0); 1.4950 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4951 + } 1.4952 + break; 1.4953 + case 0x746: 1.4954 + case 0x74e: 1.4955 + { 1.4956 + // STRB Rd, [Rn, -Rm, ROR #] 1.4957 + int shift = (opcode >> 7) & 31; 1.4958 + u32 value = reg[opcode & 15].I; 1.4959 + if (shift) 1.4960 + { 1.4961 + ROR_VALUE; 1.4962 + } 1.4963 + else 1.4964 + { 1.4965 + RCR_VALUE; 1.4966 + } 1.4967 + int dest = (opcode >> 12) & 15; 1.4968 + int base = (opcode >> 16) & 15; 1.4969 + u32 address = reg[base].I - value; 1.4970 + CPUWriteByte(address, reg[dest].B.B0); 1.4971 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4972 + } 1.4973 + break; 1.4974 + case 0x760: 1.4975 + case 0x768: 1.4976 + { 1.4977 + // STRB Rd, [Rn, -Rm, LSL #]! 1.4978 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.4979 + int dest = (opcode >> 12) & 15; 1.4980 + int base = (opcode >> 16) & 15; 1.4981 + u32 address = reg[base].I - offset; 1.4982 + reg[base].I = address; 1.4983 + CPUWriteByte(address, reg[dest].B.B0); 1.4984 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4985 + } 1.4986 + break; 1.4987 + case 0x762: 1.4988 + case 0x76a: 1.4989 + { 1.4990 + // STRB Rd, [Rn, -Rm, LSR #]! 1.4991 + int shift = (opcode >> 7) & 31; 1.4992 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.4993 + int dest = (opcode >> 12) & 15; 1.4994 + int base = (opcode >> 16) & 15; 1.4995 + u32 address = reg[base].I - offset; 1.4996 + reg[base].I = address; 1.4997 + CPUWriteByte(address, reg[dest].B.B0); 1.4998 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.4999 + } 1.5000 + break; 1.5001 + case 0x764: 1.5002 + case 0x76c: 1.5003 + { 1.5004 + // STRB Rd, [Rn, -Rm, ASR #]! 1.5005 + int shift = (opcode >> 7) & 31; 1.5006 + int offset; 1.5007 + if (shift) 1.5008 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.5009 + else if (reg[opcode & 15].I & 0x80000000) 1.5010 + offset = 0xFFFFFFFF; 1.5011 + else 1.5012 + offset = 0; 1.5013 + int dest = (opcode >> 12) & 15; 1.5014 + int base = (opcode >> 16) & 15; 1.5015 + u32 address = reg[base].I - offset; 1.5016 + reg[base].I = address; 1.5017 + CPUWriteByte(address, reg[dest].B.B0); 1.5018 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.5019 + } 1.5020 + break; 1.5021 + case 0x766: 1.5022 + case 0x76e: 1.5023 + { 1.5024 + // STRB Rd, [Rn, -Rm, ROR #]! 1.5025 + int shift = (opcode >> 7) & 31; 1.5026 + u32 value = reg[opcode & 15].I; 1.5027 + if (shift) 1.5028 + { 1.5029 + ROR_VALUE; 1.5030 + } 1.5031 + else 1.5032 + { 1.5033 + RCR_VALUE; 1.5034 + } 1.5035 + int dest = (opcode >> 12) & 15; 1.5036 + int base = (opcode >> 16) & 15; 1.5037 + u32 address = reg[base].I - value; 1.5038 + reg[base].I = address; 1.5039 + CPUWriteByte(address, reg[dest].B.B0); 1.5040 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.5041 + } 1.5042 + break; 1.5043 + case 0x7c0: 1.5044 + case 0x7c8: 1.5045 + { 1.5046 + // STRB Rd, [Rn, Rm, LSL #] 1.5047 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.5048 + int dest = (opcode >> 12) & 15; 1.5049 + int base = (opcode >> 16) & 15; 1.5050 + u32 address = reg[base].I + offset; 1.5051 + CPUWriteByte(address, reg[dest].B.B0); 1.5052 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.5053 + } 1.5054 + break; 1.5055 + case 0x7c2: 1.5056 + case 0x7ca: 1.5057 + { 1.5058 + // STRB Rd, [Rn, Rm, LSR #] 1.5059 + int shift = (opcode >> 7) & 31; 1.5060 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.5061 + int dest = (opcode >> 12) & 15; 1.5062 + int base = (opcode >> 16) & 15; 1.5063 + u32 address = reg[base].I + offset; 1.5064 + CPUWriteByte(address, reg[dest].B.B0); 1.5065 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.5066 + } 1.5067 + break; 1.5068 + case 0x7c4: 1.5069 + case 0x7cc: 1.5070 + { 1.5071 + // STRB Rd, [Rn, Rm, ASR #] 1.5072 + int shift = (opcode >> 7) & 31; 1.5073 + int offset; 1.5074 + if (shift) 1.5075 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.5076 + else if (reg[opcode & 15].I & 0x80000000) 1.5077 + offset = 0xFFFFFFFF; 1.5078 + else 1.5079 + offset = 0; 1.5080 + int dest = (opcode >> 12) & 15; 1.5081 + int base = (opcode >> 16) & 15; 1.5082 + u32 address = reg[base].I + offset; 1.5083 + CPUWriteByte(address, reg[dest].B.B0); 1.5084 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.5085 + } 1.5086 + break; 1.5087 + case 0x7c6: 1.5088 + case 0x7ce: 1.5089 + { 1.5090 + // STRB Rd, [Rn, Rm, ROR #] 1.5091 + int shift = (opcode >> 7) & 31; 1.5092 + u32 value = reg[opcode & 15].I; 1.5093 + if (shift) 1.5094 + { 1.5095 + ROR_VALUE; 1.5096 + } 1.5097 + else 1.5098 + { 1.5099 + RCR_VALUE; 1.5100 + } 1.5101 + int dest = (opcode >> 12) & 15; 1.5102 + int base = (opcode >> 16) & 15; 1.5103 + u32 address = reg[base].I + value; 1.5104 + CPUWriteByte(address, reg[dest].B.B0); 1.5105 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.5106 + } 1.5107 + break; 1.5108 + case 0x7e0: 1.5109 + case 0x7e8: 1.5110 + { 1.5111 + // STRB Rd, [Rn, Rm, LSL #]! 1.5112 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.5113 + int dest = (opcode >> 12) & 15; 1.5114 + int base = (opcode >> 16) & 15; 1.5115 + u32 address = reg[base].I + offset; 1.5116 + reg[base].I = address; 1.5117 + CPUWriteByte(address, reg[dest].B.B0); 1.5118 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.5119 + } 1.5120 + break; 1.5121 + case 0x7e2: 1.5122 + case 0x7ea: 1.5123 + { 1.5124 + // STRB Rd, [Rn, Rm, LSR #]! 1.5125 + int shift = (opcode >> 7) & 31; 1.5126 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.5127 + int dest = (opcode >> 12) & 15; 1.5128 + int base = (opcode >> 16) & 15; 1.5129 + u32 address = reg[base].I + offset; 1.5130 + reg[base].I = address; 1.5131 + CPUWriteByte(address, reg[dest].B.B0); 1.5132 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.5133 + } 1.5134 + break; 1.5135 + case 0x7e4: 1.5136 + case 0x7ec: 1.5137 + { 1.5138 + // STRB Rd, [Rn, Rm, ASR #]! 1.5139 + int shift = (opcode >> 7) & 31; 1.5140 + int offset; 1.5141 + if (shift) 1.5142 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.5143 + else if (reg[opcode & 15].I & 0x80000000) 1.5144 + offset = 0xFFFFFFFF; 1.5145 + else 1.5146 + offset = 0; 1.5147 + int dest = (opcode >> 12) & 15; 1.5148 + int base = (opcode >> 16) & 15; 1.5149 + u32 address = reg[base].I + offset; 1.5150 + reg[base].I = address; 1.5151 + CPUWriteByte(address, reg[dest].B.B0); 1.5152 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.5153 + } 1.5154 + break; 1.5155 + case 0x7e6: 1.5156 + case 0x7ee: 1.5157 + { 1.5158 + // STRB Rd, [Rn, Rm, ROR #]! 1.5159 + int shift = (opcode >> 7) & 31; 1.5160 + u32 value = reg[opcode & 15].I; 1.5161 + if (shift) 1.5162 + { 1.5163 + ROR_VALUE; 1.5164 + } 1.5165 + else 1.5166 + { 1.5167 + RCR_VALUE; 1.5168 + } 1.5169 + int dest = (opcode >> 12) & 15; 1.5170 + int base = (opcode >> 16) & 15; 1.5171 + u32 address = reg[base].I + value; 1.5172 + reg[base].I = address; 1.5173 + CPUWriteByte(address, reg[dest].B.B0); 1.5174 + clockTicks += 2 + CPUUpdateTicksAccess16(address); 1.5175 + } 1.5176 + break; 1.5177 + case 0x650: 1.5178 + case 0x658: 1.5179 + // T versions are the same 1.5180 + case 0x670: 1.5181 + case 0x678: 1.5182 + { 1.5183 + // LDRB Rd, [Rn], -Rm, LSL # 1.5184 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.5185 + int dest = (opcode >> 12) & 15; 1.5186 + int base = (opcode >> 16) & 15; 1.5187 + u32 address = reg[base].I; 1.5188 + reg[dest].I = CPUReadByte(address); 1.5189 + if (dest != base) 1.5190 + reg[base].I = address - offset; 1.5191 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5192 + } 1.5193 + break; 1.5194 + case 0x652: 1.5195 + case 0x65a: 1.5196 + // T versions are the same 1.5197 + case 0x672: 1.5198 + case 0x67a: 1.5199 + { 1.5200 + // LDRB Rd, [Rn], -Rm, LSR # 1.5201 + int shift = (opcode >> 7) & 31; 1.5202 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.5203 + int dest = (opcode >> 12) & 15; 1.5204 + int base = (opcode >> 16) & 15; 1.5205 + u32 address = reg[base].I; 1.5206 + reg[dest].I = CPUReadByte(address); 1.5207 + if (dest != base) 1.5208 + reg[base].I = address - offset; 1.5209 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5210 + } 1.5211 + break; 1.5212 + case 0x654: 1.5213 + case 0x65c: 1.5214 + // T versions are the same 1.5215 + case 0x674: 1.5216 + case 0x67c: 1.5217 + { 1.5218 + // LDRB Rd, [Rn], -Rm, ASR # 1.5219 + int shift = (opcode >> 7) & 31; 1.5220 + int offset; 1.5221 + if (shift) 1.5222 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.5223 + else if (reg[opcode & 15].I & 0x80000000) 1.5224 + offset = 0xFFFFFFFF; 1.5225 + else 1.5226 + offset = 0; 1.5227 + int dest = (opcode >> 12) & 15; 1.5228 + int base = (opcode >> 16) & 15; 1.5229 + u32 address = reg[base].I; 1.5230 + reg[dest].I = CPUReadByte(address); 1.5231 + if (dest != base) 1.5232 + reg[base].I = address - offset; 1.5233 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5234 + } 1.5235 + break; 1.5236 + case 0x656: 1.5237 + case 0x65e: 1.5238 + // T versions are the same 1.5239 + case 0x676: 1.5240 + case 0x67e: 1.5241 + { 1.5242 + // LDRB Rd, [Rn], -Rm, ROR # 1.5243 + int shift = (opcode >> 7) & 31; 1.5244 + u32 value = reg[opcode & 15].I; 1.5245 + if (shift) 1.5246 + { 1.5247 + ROR_VALUE; 1.5248 + } 1.5249 + else 1.5250 + { 1.5251 + RCR_VALUE; 1.5252 + } 1.5253 + int dest = (opcode >> 12) & 15; 1.5254 + int base = (opcode >> 16) & 15; 1.5255 + u32 address = reg[base].I; 1.5256 + reg[dest].I = CPUReadByte(address); 1.5257 + if (dest != base) 1.5258 + reg[base].I = address - value; 1.5259 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5260 + } 1.5261 + break; 1.5262 + case 0x6d0: 1.5263 + case 0x6d8: 1.5264 + // T versions are the same 1.5265 + case 0x6f0: 1.5266 + case 0x6f8: 1.5267 + { 1.5268 + // LDRB Rd, [Rn], Rm, LSL # 1.5269 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.5270 + int dest = (opcode >> 12) & 15; 1.5271 + int base = (opcode >> 16) & 15; 1.5272 + u32 address = reg[base].I; 1.5273 + reg[dest].I = CPUReadByte(address); 1.5274 + if (dest != base) 1.5275 + reg[base].I = address + offset; 1.5276 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5277 + } 1.5278 + break; 1.5279 + case 0x6d2: 1.5280 + case 0x6da: 1.5281 + // T versions are the same 1.5282 + case 0x6f2: 1.5283 + case 0x6fa: 1.5284 + { 1.5285 + // LDRB Rd, [Rn], Rm, LSR # 1.5286 + int shift = (opcode >> 7) & 31; 1.5287 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.5288 + int dest = (opcode >> 12) & 15; 1.5289 + int base = (opcode >> 16) & 15; 1.5290 + u32 address = reg[base].I; 1.5291 + reg[dest].I = CPUReadByte(address); 1.5292 + if (dest != base) 1.5293 + reg[base].I = address + offset; 1.5294 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5295 + } 1.5296 + break; 1.5297 + case 0x6d4: 1.5298 + case 0x6dc: 1.5299 + // T versions are the same 1.5300 + case 0x6f4: 1.5301 + case 0x6fc: 1.5302 + { 1.5303 + // LDRB Rd, [Rn], Rm, ASR # 1.5304 + int shift = (opcode >> 7) & 31; 1.5305 + int offset; 1.5306 + if (shift) 1.5307 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.5308 + else if (reg[opcode & 15].I & 0x80000000) 1.5309 + offset = 0xFFFFFFFF; 1.5310 + else 1.5311 + offset = 0; 1.5312 + int dest = (opcode >> 12) & 15; 1.5313 + int base = (opcode >> 16) & 15; 1.5314 + u32 address = reg[base].I; 1.5315 + reg[dest].I = CPUReadByte(address); 1.5316 + if (dest != base) 1.5317 + reg[base].I = address + offset; 1.5318 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5319 + } 1.5320 + break; 1.5321 + case 0x6d6: 1.5322 + case 0x6de: 1.5323 + // T versions are the same 1.5324 + case 0x6f6: 1.5325 + case 0x6fe: 1.5326 + { 1.5327 + // LDRB Rd, [Rn], Rm, ROR # 1.5328 + int shift = (opcode >> 7) & 31; 1.5329 + u32 value = reg[opcode & 15].I; 1.5330 + if (shift) 1.5331 + { 1.5332 + ROR_VALUE; 1.5333 + } 1.5334 + else 1.5335 + { 1.5336 + RCR_VALUE; 1.5337 + } 1.5338 + int dest = (opcode >> 12) & 15; 1.5339 + int base = (opcode >> 16) & 15; 1.5340 + u32 address = reg[base].I; 1.5341 + reg[dest].I = CPUReadByte(address); 1.5342 + if (dest != base) 1.5343 + reg[base].I = address + value; 1.5344 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5345 + } 1.5346 + break; 1.5347 + case 0x750: 1.5348 + case 0x758: 1.5349 + { 1.5350 + // LDRB Rd, [Rn, -Rm, LSL #] 1.5351 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.5352 + int dest = (opcode >> 12) & 15; 1.5353 + int base = (opcode >> 16) & 15; 1.5354 + u32 address = reg[base].I - offset; 1.5355 + reg[dest].I = CPUReadByte(address); 1.5356 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5357 + } 1.5358 + break; 1.5359 + case 0x752: 1.5360 + case 0x75a: 1.5361 + { 1.5362 + // LDRB Rd, [Rn, -Rm, LSR #] 1.5363 + int shift = (opcode >> 7) & 31; 1.5364 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.5365 + int dest = (opcode >> 12) & 15; 1.5366 + int base = (opcode >> 16) & 15; 1.5367 + u32 address = reg[base].I - offset; 1.5368 + reg[dest].I = CPUReadByte(address); 1.5369 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5370 + } 1.5371 + break; 1.5372 + case 0x754: 1.5373 + case 0x75c: 1.5374 + { 1.5375 + // LDRB Rd, [Rn, -Rm, ASR #] 1.5376 + int shift = (opcode >> 7) & 31; 1.5377 + int offset; 1.5378 + if (shift) 1.5379 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.5380 + else if (reg[opcode & 15].I & 0x80000000) 1.5381 + offset = 0xFFFFFFFF; 1.5382 + else 1.5383 + offset = 0; 1.5384 + int dest = (opcode >> 12) & 15; 1.5385 + int base = (opcode >> 16) & 15; 1.5386 + u32 address = reg[base].I - offset; 1.5387 + reg[dest].I = CPUReadByte(address); 1.5388 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5389 + } 1.5390 + break; 1.5391 + case 0x756: 1.5392 + case 0x75e: 1.5393 + { 1.5394 + // LDRB Rd, [Rn, -Rm, ROR #] 1.5395 + int shift = (opcode >> 7) & 31; 1.5396 + u32 value = reg[opcode & 15].I; 1.5397 + if (shift) 1.5398 + { 1.5399 + ROR_VALUE; 1.5400 + } 1.5401 + else 1.5402 + { 1.5403 + RCR_VALUE; 1.5404 + } 1.5405 + int dest = (opcode >> 12) & 15; 1.5406 + int base = (opcode >> 16) & 15; 1.5407 + u32 address = reg[base].I - value; 1.5408 + reg[dest].I = CPUReadByte(address); 1.5409 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5410 + } 1.5411 + break; 1.5412 + case 0x770: 1.5413 + case 0x778: 1.5414 + { 1.5415 + // LDRB Rd, [Rn, -Rm, LSL #]! 1.5416 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.5417 + int dest = (opcode >> 12) & 15; 1.5418 + int base = (opcode >> 16) & 15; 1.5419 + u32 address = reg[base].I - offset; 1.5420 + reg[dest].I = CPUReadByte(address); 1.5421 + if (dest != base) 1.5422 + reg[base].I = address; 1.5423 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5424 + } 1.5425 + break; 1.5426 + case 0x772: 1.5427 + case 0x77a: 1.5428 + { 1.5429 + // LDRB Rd, [Rn, -Rm, LSR #]! 1.5430 + int shift = (opcode >> 7) & 31; 1.5431 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.5432 + int dest = (opcode >> 12) & 15; 1.5433 + int base = (opcode >> 16) & 15; 1.5434 + u32 address = reg[base].I - offset; 1.5435 + reg[dest].I = CPUReadByte(address); 1.5436 + if (dest != base) 1.5437 + reg[base].I = address; 1.5438 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5439 + } 1.5440 + break; 1.5441 + case 0x774: 1.5442 + case 0x77c: 1.5443 + { 1.5444 + // LDRB Rd, [Rn, -Rm, ASR #]! 1.5445 + int shift = (opcode >> 7) & 31; 1.5446 + int offset; 1.5447 + if (shift) 1.5448 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.5449 + else if (reg[opcode & 15].I & 0x80000000) 1.5450 + offset = 0xFFFFFFFF; 1.5451 + else 1.5452 + offset = 0; 1.5453 + int dest = (opcode >> 12) & 15; 1.5454 + int base = (opcode >> 16) & 15; 1.5455 + u32 address = reg[base].I - offset; 1.5456 + reg[dest].I = CPUReadByte(address); 1.5457 + if (dest != base) 1.5458 + reg[base].I = address; 1.5459 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5460 + } 1.5461 + break; 1.5462 + case 0x776: 1.5463 + case 0x77e: 1.5464 + { 1.5465 + // LDRB Rd, [Rn, -Rm, ROR #]! 1.5466 + int shift = (opcode >> 7) & 31; 1.5467 + u32 value = reg[opcode & 15].I; 1.5468 + if (shift) 1.5469 + { 1.5470 + ROR_VALUE; 1.5471 + } 1.5472 + else 1.5473 + { 1.5474 + RCR_VALUE; 1.5475 + } 1.5476 + int dest = (opcode >> 12) & 15; 1.5477 + int base = (opcode >> 16) & 15; 1.5478 + u32 address = reg[base].I - value; 1.5479 + reg[dest].I = CPUReadByte(address); 1.5480 + if (dest != base) 1.5481 + reg[base].I = address; 1.5482 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5483 + } 1.5484 + break; 1.5485 + case 0x7d0: 1.5486 + case 0x7d8: 1.5487 + { 1.5488 + // LDRB Rd, [Rn, Rm, LSL #] 1.5489 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.5490 + int dest = (opcode >> 12) & 15; 1.5491 + int base = (opcode >> 16) & 15; 1.5492 + u32 address = reg[base].I + offset; 1.5493 + reg[dest].I = CPUReadByte(address); 1.5494 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5495 + } 1.5496 + break; 1.5497 + case 0x7d2: 1.5498 + case 0x7da: 1.5499 + { 1.5500 + // LDRB Rd, [Rn, Rm, LSR #] 1.5501 + int shift = (opcode >> 7) & 31; 1.5502 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.5503 + int dest = (opcode >> 12) & 15; 1.5504 + int base = (opcode >> 16) & 15; 1.5505 + u32 address = reg[base].I + offset; 1.5506 + reg[dest].I = CPUReadByte(address); 1.5507 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5508 + } 1.5509 + break; 1.5510 + case 0x7d4: 1.5511 + case 0x7dc: 1.5512 + { 1.5513 + // LDRB Rd, [Rn, Rm, ASR #] 1.5514 + int shift = (opcode >> 7) & 31; 1.5515 + int offset; 1.5516 + if (shift) 1.5517 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.5518 + else if (reg[opcode & 15].I & 0x80000000) 1.5519 + offset = 0xFFFFFFFF; 1.5520 + else 1.5521 + offset = 0; 1.5522 + int dest = (opcode >> 12) & 15; 1.5523 + int base = (opcode >> 16) & 15; 1.5524 + u32 address = reg[base].I + offset; 1.5525 + reg[dest].I = CPUReadByte(address); 1.5526 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5527 + } 1.5528 + break; 1.5529 + case 0x7d6: 1.5530 + case 0x7de: 1.5531 + { 1.5532 + // LDRB Rd, [Rn, Rm, ROR #] 1.5533 + int shift = (opcode >> 7) & 31; 1.5534 + u32 value = reg[opcode & 15].I; 1.5535 + if (shift) 1.5536 + { 1.5537 + ROR_VALUE; 1.5538 + } 1.5539 + else 1.5540 + { 1.5541 + RCR_VALUE; 1.5542 + } 1.5543 + int dest = (opcode >> 12) & 15; 1.5544 + int base = (opcode >> 16) & 15; 1.5545 + u32 address = reg[base].I + value; 1.5546 + reg[dest].I = CPUReadByte(address); 1.5547 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5548 + } 1.5549 + break; 1.5550 + case 0x7f0: 1.5551 + case 0x7f8: 1.5552 + { 1.5553 + // LDRB Rd, [Rn, Rm, LSL #]! 1.5554 + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); 1.5555 + int dest = (opcode >> 12) & 15; 1.5556 + int base = (opcode >> 16) & 15; 1.5557 + u32 address = reg[base].I + offset; 1.5558 + reg[dest].I = CPUReadByte(address); 1.5559 + if (dest != base) 1.5560 + reg[base].I = address; 1.5561 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5562 + } 1.5563 + break; 1.5564 + case 0x7f2: 1.5565 + case 0x7fa: 1.5566 + { 1.5567 + // LDRB Rd, [Rn, Rm, LSR #]! 1.5568 + int shift = (opcode >> 7) & 31; 1.5569 + int offset = shift ? reg[opcode & 15].I >> shift : 0; 1.5570 + int dest = (opcode >> 12) & 15; 1.5571 + int base = (opcode >> 16) & 15; 1.5572 + u32 address = reg[base].I + offset; 1.5573 + reg[dest].I = CPUReadByte(address); 1.5574 + if (dest != base) 1.5575 + reg[base].I = address; 1.5576 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5577 + } 1.5578 + break; 1.5579 + case 0x7f4: 1.5580 + case 0x7fc: 1.5581 + { 1.5582 + // LDRB Rd, [Rn, Rm, ASR #]! 1.5583 + int shift = (opcode >> 7) & 31; 1.5584 + int offset; 1.5585 + if (shift) 1.5586 + offset = (int)((s32)reg[opcode & 15].I >> shift); 1.5587 + else if (reg[opcode & 15].I & 0x80000000) 1.5588 + offset = 0xFFFFFFFF; 1.5589 + else 1.5590 + offset = 0; 1.5591 + int dest = (opcode >> 12) & 15; 1.5592 + int base = (opcode >> 16) & 15; 1.5593 + u32 address = reg[base].I + offset; 1.5594 + reg[dest].I = CPUReadByte(address); 1.5595 + if (dest != base) 1.5596 + reg[base].I = address; 1.5597 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5598 + } 1.5599 + break; 1.5600 + case 0x7f6: 1.5601 + case 0x7fe: 1.5602 + { 1.5603 + // LDRB Rd, [Rn, Rm, ROR #]! 1.5604 + int shift = (opcode >> 7) & 31; 1.5605 + u32 value = reg[opcode & 15].I; 1.5606 + if (shift) 1.5607 + { 1.5608 + ROR_VALUE; 1.5609 + } 1.5610 + else 1.5611 + { 1.5612 + RCR_VALUE; 1.5613 + } 1.5614 + int dest = (opcode >> 12) & 15; 1.5615 + int base = (opcode >> 16) & 15; 1.5616 + u32 address = reg[base].I + value; 1.5617 + reg[dest].I = CPUReadByte(address); 1.5618 + if (dest != base) 1.5619 + reg[base].I = address; 1.5620 + clockTicks += 3 + CPUUpdateTicksAccess16(address); 1.5621 + } 1.5622 + break; 1.5623 +#define STMW_REG(val, num) \ 1.5624 + if (opcode & (val)) { \ 1.5625 + CPUWriteMemory(address, reg[(num)].I); \ 1.5626 + if (!offset) { \ 1.5627 + reg[base].I = temp; \ 1.5628 + clockTicks += 1 + CPUUpdateTicksAccess32(address); \ 1.5629 + offset = 1; \ 1.5630 + } else { \ 1.5631 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); \ 1.5632 + } \ 1.5633 + address += 4; \ 1.5634 + } 1.5635 +#define STM_REG(val, num) \ 1.5636 + if (opcode & (val)) { \ 1.5637 + CPUWriteMemory(address, reg[(num)].I); \ 1.5638 + if (!offset) { \ 1.5639 + clockTicks += 1 + CPUUpdateTicksAccess32(address); \ 1.5640 + offset = 1; \ 1.5641 + } else { \ 1.5642 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); \ 1.5643 + } \ 1.5644 + address += 4; \ 1.5645 + } 1.5646 + 1.5647 + CASE_16(0x800) 1.5648 + // STMDA Rn, {Rlist} 1.5649 + { 1.5650 + int base = (opcode & 0x000F0000) >> 16; 1.5651 + u32 temp = reg[base].I - 1.5652 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.5653 + u32 address = (temp + 4) & 0xFFFFFFFC; 1.5654 + clockTicks += 2; 1.5655 + int offset = 0; 1.5656 + STM_REG(1, 0); 1.5657 + STM_REG(2, 1); 1.5658 + STM_REG(4, 2); 1.5659 + STM_REG(8, 3); 1.5660 + STM_REG(16, 4); 1.5661 + STM_REG(32, 5); 1.5662 + STM_REG(64, 6); 1.5663 + STM_REG(128, 7); 1.5664 + STM_REG(256, 8); 1.5665 + STM_REG(512, 9); 1.5666 + STM_REG(1024, 10); 1.5667 + STM_REG(2048, 11); 1.5668 + STM_REG(4096, 12); 1.5669 + STM_REG(8192, 13); 1.5670 + STM_REG(16384, 14); 1.5671 + if (opcode & 32768) 1.5672 + { 1.5673 + CPUWriteMemory(address, reg[15].I + 4); 1.5674 + if (!offset) 1.5675 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.5676 + else 1.5677 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.5678 + } 1.5679 + } 1.5680 + break; 1.5681 + CASE_16(0x820) 1.5682 + { 1.5683 + // STMDA Rn!, {Rlist} 1.5684 + int base = (opcode & 0x000F0000) >> 16; 1.5685 + u32 temp = reg[base].I - 1.5686 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.5687 + u32 address = (temp + 4) & 0xFFFFFFFC; 1.5688 + clockTicks += 2; 1.5689 + int offset = 0; 1.5690 + 1.5691 + STMW_REG(1, 0); 1.5692 + STMW_REG(2, 1); 1.5693 + STMW_REG(4, 2); 1.5694 + STMW_REG(8, 3); 1.5695 + STMW_REG(16, 4); 1.5696 + STMW_REG(32, 5); 1.5697 + STMW_REG(64, 6); 1.5698 + STMW_REG(128, 7); 1.5699 + STMW_REG(256, 8); 1.5700 + STMW_REG(512, 9); 1.5701 + STMW_REG(1024, 10); 1.5702 + STMW_REG(2048, 11); 1.5703 + STMW_REG(4096, 12); 1.5704 + STMW_REG(8192, 13); 1.5705 + STMW_REG(16384, 14); 1.5706 + if (opcode & 32768) 1.5707 + { 1.5708 + CPUWriteMemory(address, reg[15].I + 4); 1.5709 + if (!offset) 1.5710 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.5711 + else 1.5712 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.5713 + reg[base].I = temp; 1.5714 + } 1.5715 + } 1.5716 + break; 1.5717 + CASE_16(0x840) 1.5718 + { 1.5719 + // STMDA Rn, {Rlist}^ 1.5720 + int base = (opcode & 0x000F0000) >> 16; 1.5721 + u32 temp = reg[base].I - 1.5722 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.5723 + u32 address = (temp + 4) & 0xFFFFFFFC; 1.5724 + clockTicks += 2; 1.5725 + int offset = 0; 1.5726 + 1.5727 + STM_REG(1, 0); 1.5728 + STM_REG(2, 1); 1.5729 + STM_REG(4, 2); 1.5730 + STM_REG(8, 3); 1.5731 + STM_REG(16, 4); 1.5732 + STM_REG(32, 5); 1.5733 + STM_REG(64, 6); 1.5734 + STM_REG(128, 7); 1.5735 + 1.5736 + if (armMode == 0x11) 1.5737 + { 1.5738 + STM_REG(256, R8_FIQ); 1.5739 + STM_REG(512, R9_FIQ); 1.5740 + STM_REG(1024, R10_FIQ); 1.5741 + STM_REG(2048, R11_FIQ); 1.5742 + STM_REG(4096, R12_FIQ); 1.5743 + } 1.5744 + else 1.5745 + { 1.5746 + STM_REG(256, 8); 1.5747 + STM_REG(512, 9); 1.5748 + STM_REG(1024, 10); 1.5749 + STM_REG(2048, 11); 1.5750 + STM_REG(4096, 12); 1.5751 + } 1.5752 + 1.5753 + if (armMode != 0x10 && armMode != 0x1f) 1.5754 + { 1.5755 + STM_REG(8192, R13_USR); 1.5756 + STM_REG(16384, R14_USR); 1.5757 + } 1.5758 + else 1.5759 + { 1.5760 + STM_REG(8192, 13); 1.5761 + STM_REG(16384, 14); 1.5762 + } 1.5763 + 1.5764 + if (opcode & 32768) 1.5765 + { 1.5766 + CPUWriteMemory(address, reg[15].I + 4); 1.5767 + if (!offset) 1.5768 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.5769 + else 1.5770 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.5771 + } 1.5772 + } 1.5773 + break; 1.5774 + CASE_16(0x860) 1.5775 + { 1.5776 + // STMDA Rn!, {Rlist}^ 1.5777 + int base = (opcode & 0x000F0000) >> 16; 1.5778 + u32 temp = reg[base].I - 1.5779 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.5780 + u32 address = (temp + 4) & 0xFFFFFFFC; 1.5781 + clockTicks += 2; 1.5782 + int offset = 0; 1.5783 + 1.5784 + STMW_REG(1, 0); 1.5785 + STMW_REG(2, 1); 1.5786 + STMW_REG(4, 2); 1.5787 + STMW_REG(8, 3); 1.5788 + STMW_REG(16, 4); 1.5789 + STMW_REG(32, 5); 1.5790 + STMW_REG(64, 6); 1.5791 + STMW_REG(128, 7); 1.5792 + 1.5793 + if (armMode == 0x11) 1.5794 + { 1.5795 + STMW_REG(256, R8_FIQ); 1.5796 + STMW_REG(512, R9_FIQ); 1.5797 + STMW_REG(1024, R10_FIQ); 1.5798 + STMW_REG(2048, R11_FIQ); 1.5799 + STMW_REG(4096, R12_FIQ); 1.5800 + } 1.5801 + else 1.5802 + { 1.5803 + STMW_REG(256, 8); 1.5804 + STMW_REG(512, 9); 1.5805 + STMW_REG(1024, 10); 1.5806 + STMW_REG(2048, 11); 1.5807 + STMW_REG(4096, 12); 1.5808 + } 1.5809 + 1.5810 + if (armMode != 0x10 && armMode != 0x1f) 1.5811 + { 1.5812 + STMW_REG(8192, R13_USR); 1.5813 + STMW_REG(16384, R14_USR); 1.5814 + } 1.5815 + else 1.5816 + { 1.5817 + STMW_REG(8192, 13); 1.5818 + STMW_REG(16384, 14); 1.5819 + } 1.5820 + 1.5821 + if (opcode & 32768) 1.5822 + { 1.5823 + CPUWriteMemory(address, reg[15].I + 4); 1.5824 + if (!offset) 1.5825 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.5826 + else 1.5827 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.5828 + reg[base].I = temp; 1.5829 + } 1.5830 + } 1.5831 + break; 1.5832 + 1.5833 + CASE_16(0x880) 1.5834 + { 1.5835 + // STMIA Rn, {Rlist} 1.5836 + int base = (opcode & 0x000F0000) >> 16; 1.5837 + u32 address = reg[base].I & 0xFFFFFFFC; 1.5838 + clockTicks += 2; 1.5839 + int offset = 0; 1.5840 + STM_REG(1, 0); 1.5841 + STM_REG(2, 1); 1.5842 + STM_REG(4, 2); 1.5843 + STM_REG(8, 3); 1.5844 + STM_REG(16, 4); 1.5845 + STM_REG(32, 5); 1.5846 + STM_REG(64, 6); 1.5847 + STM_REG(128, 7); 1.5848 + STM_REG(256, 8); 1.5849 + STM_REG(512, 9); 1.5850 + STM_REG(1024, 10); 1.5851 + STM_REG(2048, 11); 1.5852 + STM_REG(4096, 12); 1.5853 + STM_REG(8192, 13); 1.5854 + STM_REG(16384, 14); 1.5855 + if (opcode & 32768) 1.5856 + { 1.5857 + CPUWriteMemory(address, reg[15].I + 4); 1.5858 + if (!offset) 1.5859 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.5860 + else 1.5861 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.5862 + } 1.5863 + } 1.5864 + break; 1.5865 + CASE_16(0x8a0) 1.5866 + { 1.5867 + // STMIA Rn!, {Rlist} 1.5868 + int base = (opcode & 0x000F0000) >> 16; 1.5869 + u32 address = reg[base].I & 0xFFFFFFFC; 1.5870 + clockTicks += 2; 1.5871 + int offset = 0; 1.5872 + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] + 1.5873 + cpuBitsSet[(opcode >> 8) & 255]); 1.5874 + STMW_REG(1, 0); 1.5875 + STMW_REG(2, 1); 1.5876 + STMW_REG(4, 2); 1.5877 + STMW_REG(8, 3); 1.5878 + STMW_REG(16, 4); 1.5879 + STMW_REG(32, 5); 1.5880 + STMW_REG(64, 6); 1.5881 + STMW_REG(128, 7); 1.5882 + STMW_REG(256, 8); 1.5883 + STMW_REG(512, 9); 1.5884 + STMW_REG(1024, 10); 1.5885 + STMW_REG(2048, 11); 1.5886 + STMW_REG(4096, 12); 1.5887 + STMW_REG(8192, 13); 1.5888 + STMW_REG(16384, 14); 1.5889 + if (opcode & 32768) 1.5890 + { 1.5891 + CPUWriteMemory(address, reg[15].I + 4); 1.5892 + if (!offset) 1.5893 + { 1.5894 + reg[base].I = temp; 1.5895 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.5896 + } 1.5897 + else 1.5898 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.5899 + } 1.5900 + } 1.5901 + break; 1.5902 + CASE_16(0x8c0) 1.5903 + { 1.5904 + // STMIA Rn, {Rlist}^ 1.5905 + int base = (opcode & 0x000F0000) >> 16; 1.5906 + u32 address = reg[base].I & 0xFFFFFFFC; 1.5907 + clockTicks += 2; 1.5908 + int offset = 0; 1.5909 + STM_REG(1, 0); 1.5910 + STM_REG(2, 1); 1.5911 + STM_REG(4, 2); 1.5912 + STM_REG(8, 3); 1.5913 + STM_REG(16, 4); 1.5914 + STM_REG(32, 5); 1.5915 + STM_REG(64, 6); 1.5916 + STM_REG(128, 7); 1.5917 + if (armMode == 0x11) 1.5918 + { 1.5919 + STM_REG(256, R8_FIQ); 1.5920 + STM_REG(512, R9_FIQ); 1.5921 + STM_REG(1024, R10_FIQ); 1.5922 + STM_REG(2048, R11_FIQ); 1.5923 + STM_REG(4096, R12_FIQ); 1.5924 + } 1.5925 + else 1.5926 + { 1.5927 + STM_REG(256, 8); 1.5928 + STM_REG(512, 9); 1.5929 + STM_REG(1024, 10); 1.5930 + STM_REG(2048, 11); 1.5931 + STM_REG(4096, 12); 1.5932 + } 1.5933 + if (armMode != 0x10 && armMode != 0x1f) 1.5934 + { 1.5935 + STM_REG(8192, R13_USR); 1.5936 + STM_REG(16384, R14_USR); 1.5937 + } 1.5938 + else 1.5939 + { 1.5940 + STM_REG(8192, 13); 1.5941 + STM_REG(16384, 14); 1.5942 + } 1.5943 + if (opcode & 32768) 1.5944 + { 1.5945 + CPUWriteMemory(address, reg[15].I + 4); 1.5946 + if (!offset) 1.5947 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.5948 + else 1.5949 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.5950 + } 1.5951 + } 1.5952 + break; 1.5953 + CASE_16(0x8e0) 1.5954 + { 1.5955 + // STMIA Rn!, {Rlist}^ 1.5956 + int base = (opcode & 0x000F0000) >> 16; 1.5957 + u32 address = reg[base].I & 0xFFFFFFFC; 1.5958 + clockTicks += 2; 1.5959 + int offset = 0; 1.5960 + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] + 1.5961 + cpuBitsSet[(opcode >> 8) & 255]); 1.5962 + STMW_REG(1, 0); 1.5963 + STMW_REG(2, 1); 1.5964 + STMW_REG(4, 2); 1.5965 + STMW_REG(8, 3); 1.5966 + STMW_REG(16, 4); 1.5967 + STMW_REG(32, 5); 1.5968 + STMW_REG(64, 6); 1.5969 + STMW_REG(128, 7); 1.5970 + if (armMode == 0x11) 1.5971 + { 1.5972 + STMW_REG(256, R8_FIQ); 1.5973 + STMW_REG(512, R9_FIQ); 1.5974 + STMW_REG(1024, R10_FIQ); 1.5975 + STMW_REG(2048, R11_FIQ); 1.5976 + STMW_REG(4096, R12_FIQ); 1.5977 + } 1.5978 + else 1.5979 + { 1.5980 + STMW_REG(256, 8); 1.5981 + STMW_REG(512, 9); 1.5982 + STMW_REG(1024, 10); 1.5983 + STMW_REG(2048, 11); 1.5984 + STMW_REG(4096, 12); 1.5985 + } 1.5986 + if (armMode != 0x10 && armMode != 0x1f) 1.5987 + { 1.5988 + STMW_REG(8192, R13_USR); 1.5989 + STMW_REG(16384, R14_USR); 1.5990 + } 1.5991 + else 1.5992 + { 1.5993 + STMW_REG(8192, 13); 1.5994 + STMW_REG(16384, 14); 1.5995 + } 1.5996 + if (opcode & 32768) 1.5997 + { 1.5998 + CPUWriteMemory(address, reg[15].I + 4); 1.5999 + if (!offset) 1.6000 + { 1.6001 + reg[base].I = temp; 1.6002 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.6003 + } 1.6004 + else 1.6005 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.6006 + } 1.6007 + } 1.6008 + break; 1.6009 + 1.6010 + CASE_16(0x900) 1.6011 + { 1.6012 + // STMDB Rn, {Rlist} 1.6013 + int base = (opcode & 0x000F0000) >> 16; 1.6014 + u32 temp = reg[base].I - 1.6015 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6016 + u32 address = temp & 0xFFFFFFFC; 1.6017 + clockTicks += 2; 1.6018 + int offset = 0; 1.6019 + STM_REG(1, 0); 1.6020 + STM_REG(2, 1); 1.6021 + STM_REG(4, 2); 1.6022 + STM_REG(8, 3); 1.6023 + STM_REG(16, 4); 1.6024 + STM_REG(32, 5); 1.6025 + STM_REG(64, 6); 1.6026 + STM_REG(128, 7); 1.6027 + STM_REG(256, 8); 1.6028 + STM_REG(512, 9); 1.6029 + STM_REG(1024, 10); 1.6030 + STM_REG(2048, 11); 1.6031 + STM_REG(4096, 12); 1.6032 + STM_REG(8192, 13); 1.6033 + STM_REG(16384, 14); 1.6034 + if (opcode & 32768) 1.6035 + { 1.6036 + CPUWriteMemory(address, reg[15].I + 4); 1.6037 + if (!offset) 1.6038 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.6039 + else 1.6040 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.6041 + } 1.6042 + } 1.6043 + break; 1.6044 + CASE_16(0x920) 1.6045 + { 1.6046 + // STMDB Rn!, {Rlist} 1.6047 + int base = (opcode & 0x000F0000) >> 16; 1.6048 + u32 temp = reg[base].I - 1.6049 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6050 + u32 address = temp & 0xFFFFFFFC; 1.6051 + clockTicks += 2; 1.6052 + int offset = 0; 1.6053 + 1.6054 + STMW_REG(1, 0); 1.6055 + STMW_REG(2, 1); 1.6056 + STMW_REG(4, 2); 1.6057 + STMW_REG(8, 3); 1.6058 + STMW_REG(16, 4); 1.6059 + STMW_REG(32, 5); 1.6060 + STMW_REG(64, 6); 1.6061 + STMW_REG(128, 7); 1.6062 + STMW_REG(256, 8); 1.6063 + STMW_REG(512, 9); 1.6064 + STMW_REG(1024, 10); 1.6065 + STMW_REG(2048, 11); 1.6066 + STMW_REG(4096, 12); 1.6067 + STMW_REG(8192, 13); 1.6068 + STMW_REG(16384, 14); 1.6069 + if (opcode & 32768) 1.6070 + { 1.6071 + CPUWriteMemory(address, reg[15].I + 4); 1.6072 + if (!offset) 1.6073 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.6074 + else 1.6075 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.6076 + reg[base].I = temp; 1.6077 + } 1.6078 + } 1.6079 + break; 1.6080 + CASE_16(0x940) 1.6081 + { 1.6082 + // STMDB Rn, {Rlist}^ 1.6083 + int base = (opcode & 0x000F0000) >> 16; 1.6084 + u32 temp = reg[base].I - 1.6085 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6086 + u32 address = temp & 0xFFFFFFFC; 1.6087 + clockTicks += 2; 1.6088 + int offset = 0; 1.6089 + 1.6090 + STM_REG(1, 0); 1.6091 + STM_REG(2, 1); 1.6092 + STM_REG(4, 2); 1.6093 + STM_REG(8, 3); 1.6094 + STM_REG(16, 4); 1.6095 + STM_REG(32, 5); 1.6096 + STM_REG(64, 6); 1.6097 + STM_REG(128, 7); 1.6098 + 1.6099 + if (armMode == 0x11) 1.6100 + { 1.6101 + STM_REG(256, R8_FIQ); 1.6102 + STM_REG(512, R9_FIQ); 1.6103 + STM_REG(1024, R10_FIQ); 1.6104 + STM_REG(2048, R11_FIQ); 1.6105 + STM_REG(4096, R12_FIQ); 1.6106 + } 1.6107 + else 1.6108 + { 1.6109 + STM_REG(256, 8); 1.6110 + STM_REG(512, 9); 1.6111 + STM_REG(1024, 10); 1.6112 + STM_REG(2048, 11); 1.6113 + STM_REG(4096, 12); 1.6114 + } 1.6115 + 1.6116 + if (armMode != 0x10 && armMode != 0x1f) 1.6117 + { 1.6118 + STM_REG(8192, R13_USR); 1.6119 + STM_REG(16384, R14_USR); 1.6120 + } 1.6121 + else 1.6122 + { 1.6123 + STM_REG(8192, 13); 1.6124 + STM_REG(16384, 14); 1.6125 + } 1.6126 + 1.6127 + if (opcode & 32768) 1.6128 + { 1.6129 + CPUWriteMemory(address, reg[15].I + 4); 1.6130 + if (!offset) 1.6131 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.6132 + else 1.6133 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.6134 + } 1.6135 + } 1.6136 + break; 1.6137 + CASE_16(0x960) 1.6138 + { 1.6139 + // STMDB Rn!, {Rlist}^ 1.6140 + int base = (opcode & 0x000F0000) >> 16; 1.6141 + u32 temp = reg[base].I - 1.6142 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6143 + u32 address = temp & 0xFFFFFFFC; 1.6144 + clockTicks += 2; 1.6145 + int offset = 0; 1.6146 + 1.6147 + STMW_REG(1, 0); 1.6148 + STMW_REG(2, 1); 1.6149 + STMW_REG(4, 2); 1.6150 + STMW_REG(8, 3); 1.6151 + STMW_REG(16, 4); 1.6152 + STMW_REG(32, 5); 1.6153 + STMW_REG(64, 6); 1.6154 + STMW_REG(128, 7); 1.6155 + 1.6156 + if (armMode == 0x11) 1.6157 + { 1.6158 + STMW_REG(256, R8_FIQ); 1.6159 + STMW_REG(512, R9_FIQ); 1.6160 + STMW_REG(1024, R10_FIQ); 1.6161 + STMW_REG(2048, R11_FIQ); 1.6162 + STMW_REG(4096, R12_FIQ); 1.6163 + } 1.6164 + else 1.6165 + { 1.6166 + STMW_REG(256, 8); 1.6167 + STMW_REG(512, 9); 1.6168 + STMW_REG(1024, 10); 1.6169 + STMW_REG(2048, 11); 1.6170 + STMW_REG(4096, 12); 1.6171 + } 1.6172 + 1.6173 + if (armMode != 0x10 && armMode != 0x1f) 1.6174 + { 1.6175 + STMW_REG(8192, R13_USR); 1.6176 + STMW_REG(16384, R14_USR); 1.6177 + } 1.6178 + else 1.6179 + { 1.6180 + STMW_REG(8192, 13); 1.6181 + STMW_REG(16384, 14); 1.6182 + } 1.6183 + 1.6184 + if (opcode & 32768) 1.6185 + { 1.6186 + CPUWriteMemory(address, reg[15].I + 4); 1.6187 + if (!offset) 1.6188 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.6189 + else 1.6190 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.6191 + reg[base].I = temp; 1.6192 + } 1.6193 + } 1.6194 + break; 1.6195 + 1.6196 + CASE_16(0x980) 1.6197 + // STMIB Rn, {Rlist} 1.6198 + { 1.6199 + int base = (opcode & 0x000F0000) >> 16; 1.6200 + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; 1.6201 + clockTicks += 2; 1.6202 + int offset = 0; 1.6203 + STM_REG(1, 0); 1.6204 + STM_REG(2, 1); 1.6205 + STM_REG(4, 2); 1.6206 + STM_REG(8, 3); 1.6207 + STM_REG(16, 4); 1.6208 + STM_REG(32, 5); 1.6209 + STM_REG(64, 6); 1.6210 + STM_REG(128, 7); 1.6211 + STM_REG(256, 8); 1.6212 + STM_REG(512, 9); 1.6213 + STM_REG(1024, 10); 1.6214 + STM_REG(2048, 11); 1.6215 + STM_REG(4096, 12); 1.6216 + STM_REG(8192, 13); 1.6217 + STM_REG(16384, 14); 1.6218 + if (opcode & 32768) 1.6219 + { 1.6220 + CPUWriteMemory(address, reg[15].I + 4); 1.6221 + if (!offset) 1.6222 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.6223 + else 1.6224 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.6225 + } 1.6226 + } 1.6227 + break; 1.6228 + CASE_16(0x9a0) 1.6229 + { 1.6230 + // STMIB Rn!, {Rlist} 1.6231 + int base = (opcode & 0x000F0000) >> 16; 1.6232 + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; 1.6233 + clockTicks += 2; 1.6234 + int offset = 0; 1.6235 + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] + 1.6236 + cpuBitsSet[(opcode >> 8) & 255]); 1.6237 + STMW_REG(1, 0); 1.6238 + STMW_REG(2, 1); 1.6239 + STMW_REG(4, 2); 1.6240 + STMW_REG(8, 3); 1.6241 + STMW_REG(16, 4); 1.6242 + STMW_REG(32, 5); 1.6243 + STMW_REG(64, 6); 1.6244 + STMW_REG(128, 7); 1.6245 + STMW_REG(256, 8); 1.6246 + STMW_REG(512, 9); 1.6247 + STMW_REG(1024, 10); 1.6248 + STMW_REG(2048, 11); 1.6249 + STMW_REG(4096, 12); 1.6250 + STMW_REG(8192, 13); 1.6251 + STMW_REG(16384, 14); 1.6252 + if (opcode & 32768) 1.6253 + { 1.6254 + CPUWriteMemory(address, reg[15].I + 4); 1.6255 + if (!offset) 1.6256 + { 1.6257 + reg[base].I = temp; 1.6258 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.6259 + } 1.6260 + else 1.6261 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.6262 + } 1.6263 + } 1.6264 + break; 1.6265 + CASE_16(0x9c0) 1.6266 + { 1.6267 + // STMIB Rn, {Rlist}^ 1.6268 + int base = (opcode & 0x000F0000) >> 16; 1.6269 + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; 1.6270 + clockTicks += 2; 1.6271 + int offset = 0; 1.6272 + STM_REG(1, 0); 1.6273 + STM_REG(2, 1); 1.6274 + STM_REG(4, 2); 1.6275 + STM_REG(8, 3); 1.6276 + STM_REG(16, 4); 1.6277 + STM_REG(32, 5); 1.6278 + STM_REG(64, 6); 1.6279 + STM_REG(128, 7); 1.6280 + if (armMode == 0x11) 1.6281 + { 1.6282 + STM_REG(256, R8_FIQ); 1.6283 + STM_REG(512, R9_FIQ); 1.6284 + STM_REG(1024, R10_FIQ); 1.6285 + STM_REG(2048, R11_FIQ); 1.6286 + STM_REG(4096, R12_FIQ); 1.6287 + } 1.6288 + else 1.6289 + { 1.6290 + STM_REG(256, 8); 1.6291 + STM_REG(512, 9); 1.6292 + STM_REG(1024, 10); 1.6293 + STM_REG(2048, 11); 1.6294 + STM_REG(4096, 12); 1.6295 + } 1.6296 + if (armMode != 0x10 && armMode != 0x1f) 1.6297 + { 1.6298 + STM_REG(8192, R13_USR); 1.6299 + STM_REG(16384, R14_USR); 1.6300 + } 1.6301 + else 1.6302 + { 1.6303 + STM_REG(8192, 13); 1.6304 + STM_REG(16384, 14); 1.6305 + } 1.6306 + if (opcode & 32768) 1.6307 + { 1.6308 + CPUWriteMemory(address, reg[15].I + 4); 1.6309 + if (!offset) 1.6310 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.6311 + else 1.6312 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.6313 + } 1.6314 + } 1.6315 + break; 1.6316 + CASE_16(0x9e0) 1.6317 + { 1.6318 + // STMIB Rn!, {Rlist}^ 1.6319 + int base = (opcode & 0x000F0000) >> 16; 1.6320 + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; 1.6321 + clockTicks += 2; 1.6322 + int offset = 0; 1.6323 + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] + 1.6324 + cpuBitsSet[(opcode >> 8) & 255]); 1.6325 + STMW_REG(1, 0); 1.6326 + STMW_REG(2, 1); 1.6327 + STMW_REG(4, 2); 1.6328 + STMW_REG(8, 3); 1.6329 + STMW_REG(16, 4); 1.6330 + STMW_REG(32, 5); 1.6331 + STMW_REG(64, 6); 1.6332 + STMW_REG(128, 7); 1.6333 + if (armMode == 0x11) 1.6334 + { 1.6335 + STMW_REG(256, R8_FIQ); 1.6336 + STMW_REG(512, R9_FIQ); 1.6337 + STMW_REG(1024, R10_FIQ); 1.6338 + STMW_REG(2048, R11_FIQ); 1.6339 + STMW_REG(4096, R12_FIQ); 1.6340 + } 1.6341 + else 1.6342 + { 1.6343 + STMW_REG(256, 8); 1.6344 + STMW_REG(512, 9); 1.6345 + STMW_REG(1024, 10); 1.6346 + STMW_REG(2048, 11); 1.6347 + STMW_REG(4096, 12); 1.6348 + } 1.6349 + if (armMode != 0x10 && armMode != 0x1f) 1.6350 + { 1.6351 + STMW_REG(8192, R13_USR); 1.6352 + STMW_REG(16384, R14_USR); 1.6353 + } 1.6354 + else 1.6355 + { 1.6356 + STMW_REG(8192, 13); 1.6357 + STMW_REG(16384, 14); 1.6358 + } 1.6359 + if (opcode & 32768) 1.6360 + { 1.6361 + CPUWriteMemory(address, reg[15].I + 4); 1.6362 + if (!offset) 1.6363 + { 1.6364 + reg[base].I = temp; 1.6365 + clockTicks += 1 + CPUUpdateTicksAccess32(address); 1.6366 + } 1.6367 + else 1.6368 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 1.6369 + } 1.6370 + } 1.6371 + break; 1.6372 + 1.6373 +#define LDM_REG(val, num) \ 1.6374 + if (opcode & (val)) { \ 1.6375 + reg[(num)].I = CPUReadMemory(address); \ 1.6376 + if (offset) \ 1.6377 + clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); \ 1.6378 + else { \ 1.6379 + clockTicks += 1 + CPUUpdateTicksAccess32(address); \ 1.6380 + offset = 1; \ 1.6381 + } \ 1.6382 + address += 4; \ 1.6383 + } 1.6384 + 1.6385 + CASE_16(0x810) 1.6386 + { 1.6387 + // LDMDA Rn, {Rlist} 1.6388 + int base = (opcode & 0x000F0000) >> 16; 1.6389 + u32 temp = reg[base].I - 1.6390 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6391 + u32 address = (temp + 4) & 0xFFFFFFFC; 1.6392 + clockTicks += 2; 1.6393 + int offset = 0; 1.6394 + LDM_REG(1, 0); 1.6395 + LDM_REG(2, 1); 1.6396 + LDM_REG(4, 2); 1.6397 + LDM_REG(8, 3); 1.6398 + LDM_REG(16, 4); 1.6399 + LDM_REG(32, 5); 1.6400 + LDM_REG(64, 6); 1.6401 + LDM_REG(128, 7); 1.6402 + LDM_REG(256, 8); 1.6403 + LDM_REG(512, 9); 1.6404 + LDM_REG(1024, 10); 1.6405 + LDM_REG(2048, 11); 1.6406 + LDM_REG(4096, 12); 1.6407 + LDM_REG(8192, 13); 1.6408 + LDM_REG(16384, 14); 1.6409 + if (opcode & 32768) 1.6410 + { 1.6411 + reg[15].I = CPUReadMemory(address); 1.6412 + if (!offset) 1.6413 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.6414 + else 1.6415 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.6416 + armNextPC = reg[15].I; 1.6417 + reg[15].I += 4; 1.6418 + } 1.6419 + } 1.6420 + break; 1.6421 + CASE_16(0x830) 1.6422 + { 1.6423 + // LDMDA Rn!, {Rlist} 1.6424 + int base = (opcode & 0x000F0000) >> 16; 1.6425 + u32 temp = reg[base].I - 1.6426 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6427 + u32 address = (temp + 4) & 0xFFFFFFFC; 1.6428 + clockTicks += 2; 1.6429 + int offset = 0; 1.6430 + LDM_REG(1, 0); 1.6431 + LDM_REG(2, 1); 1.6432 + LDM_REG(4, 2); 1.6433 + LDM_REG(8, 3); 1.6434 + LDM_REG(16, 4); 1.6435 + LDM_REG(32, 5); 1.6436 + LDM_REG(64, 6); 1.6437 + LDM_REG(128, 7); 1.6438 + LDM_REG(256, 8); 1.6439 + LDM_REG(512, 9); 1.6440 + LDM_REG(1024, 10); 1.6441 + LDM_REG(2048, 11); 1.6442 + LDM_REG(4096, 12); 1.6443 + LDM_REG(8192, 13); 1.6444 + LDM_REG(16384, 14); 1.6445 + if (opcode & 32768) 1.6446 + { 1.6447 + reg[15].I = CPUReadMemory(address); 1.6448 + if (!offset) 1.6449 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.6450 + else 1.6451 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.6452 + armNextPC = reg[15].I; 1.6453 + reg[15].I += 4; 1.6454 + } 1.6455 + if (!(opcode & (1 << base))) 1.6456 + reg[base].I = temp; 1.6457 + } 1.6458 + break; 1.6459 + CASE_16(0x850) 1.6460 + { 1.6461 + // LDMDA Rn, {Rlist}^ 1.6462 + int base = (opcode & 0x000F0000) >> 16; 1.6463 + u32 temp = reg[base].I - 1.6464 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6465 + u32 address = (temp + 4) & 0xFFFFFFFC; 1.6466 + clockTicks += 2; 1.6467 + int offset = 0; 1.6468 + if (opcode & 0x8000) 1.6469 + { 1.6470 + LDM_REG(1, 0); 1.6471 + LDM_REG(2, 1); 1.6472 + LDM_REG(4, 2); 1.6473 + LDM_REG(8, 3); 1.6474 + LDM_REG(16, 4); 1.6475 + LDM_REG(32, 5); 1.6476 + LDM_REG(64, 6); 1.6477 + LDM_REG(128, 7); 1.6478 + LDM_REG(256, 8); 1.6479 + LDM_REG(512, 9); 1.6480 + LDM_REG(1024, 10); 1.6481 + LDM_REG(2048, 11); 1.6482 + LDM_REG(4096, 12); 1.6483 + LDM_REG(8192, 13); 1.6484 + LDM_REG(16384, 14); 1.6485 + 1.6486 + reg[15].I = CPUReadMemory(address); 1.6487 + if (!offset) 1.6488 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.6489 + else 1.6490 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.6491 + 1.6492 + CPUSwitchMode(reg[17].I & 0x1f, false); 1.6493 + if (armState) 1.6494 + { 1.6495 + armNextPC = reg[15].I & 0xFFFFFFFC; 1.6496 + reg[15].I = armNextPC + 4; 1.6497 + } 1.6498 + else 1.6499 + { 1.6500 + armNextPC = reg[15].I & 0xFFFFFFFE; 1.6501 + reg[15].I = armNextPC + 2; 1.6502 + } 1.6503 + } 1.6504 + else 1.6505 + { 1.6506 + LDM_REG(1, 0); 1.6507 + LDM_REG(2, 1); 1.6508 + LDM_REG(4, 2); 1.6509 + LDM_REG(8, 3); 1.6510 + LDM_REG(16, 4); 1.6511 + LDM_REG(32, 5); 1.6512 + LDM_REG(64, 6); 1.6513 + LDM_REG(128, 7); 1.6514 + 1.6515 + if (armMode == 0x11) 1.6516 + { 1.6517 + LDM_REG(256, R8_FIQ); 1.6518 + LDM_REG(512, R9_FIQ); 1.6519 + LDM_REG(1024, R10_FIQ); 1.6520 + LDM_REG(2048, R11_FIQ); 1.6521 + LDM_REG(4096, R12_FIQ); 1.6522 + } 1.6523 + else 1.6524 + { 1.6525 + LDM_REG(256, 8); 1.6526 + LDM_REG(512, 9); 1.6527 + LDM_REG(1024, 10); 1.6528 + LDM_REG(2048, 11); 1.6529 + LDM_REG(4096, 12); 1.6530 + } 1.6531 + 1.6532 + if (armMode != 0x10 && armMode != 0x1f) 1.6533 + { 1.6534 + LDM_REG(8192, R13_USR); 1.6535 + LDM_REG(16384, R14_USR); 1.6536 + } 1.6537 + else 1.6538 + { 1.6539 + LDM_REG(8192, 13); 1.6540 + LDM_REG(16384, 14); 1.6541 + } 1.6542 + } 1.6543 + } 1.6544 + break; 1.6545 + CASE_16(0x870) 1.6546 + { 1.6547 + // LDMDA Rn!, {Rlist}^ 1.6548 + int base = (opcode & 0x000F0000) >> 16; 1.6549 + u32 temp = reg[base].I - 1.6550 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6551 + u32 address = (temp + 4) & 0xFFFFFFFC; 1.6552 + clockTicks += 2; 1.6553 + int offset = 0; 1.6554 + if (opcode & 0x8000) 1.6555 + { 1.6556 + LDM_REG(1, 0); 1.6557 + LDM_REG(2, 1); 1.6558 + LDM_REG(4, 2); 1.6559 + LDM_REG(8, 3); 1.6560 + LDM_REG(16, 4); 1.6561 + LDM_REG(32, 5); 1.6562 + LDM_REG(64, 6); 1.6563 + LDM_REG(128, 7); 1.6564 + LDM_REG(256, 8); 1.6565 + LDM_REG(512, 9); 1.6566 + LDM_REG(1024, 10); 1.6567 + LDM_REG(2048, 11); 1.6568 + LDM_REG(4096, 12); 1.6569 + LDM_REG(8192, 13); 1.6570 + LDM_REG(16384, 14); 1.6571 + 1.6572 + reg[15].I = CPUReadMemory(address); 1.6573 + if (!offset) 1.6574 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.6575 + else 1.6576 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.6577 + 1.6578 + if (!(opcode & (1 << base))) 1.6579 + reg[base].I = temp; 1.6580 + 1.6581 + CPUSwitchMode(reg[17].I & 0x1f, false); 1.6582 + if (armState) 1.6583 + { 1.6584 + armNextPC = reg[15].I & 0xFFFFFFFC; 1.6585 + reg[15].I = armNextPC + 4; 1.6586 + } 1.6587 + else 1.6588 + { 1.6589 + armNextPC = reg[15].I & 0xFFFFFFFE; 1.6590 + reg[15].I = armNextPC + 2; 1.6591 + } 1.6592 + } 1.6593 + else 1.6594 + { 1.6595 + LDM_REG(1, 0); 1.6596 + LDM_REG(2, 1); 1.6597 + LDM_REG(4, 2); 1.6598 + LDM_REG(8, 3); 1.6599 + LDM_REG(16, 4); 1.6600 + LDM_REG(32, 5); 1.6601 + LDM_REG(64, 6); 1.6602 + LDM_REG(128, 7); 1.6603 + 1.6604 + if (armMode == 0x11) 1.6605 + { 1.6606 + LDM_REG(256, R8_FIQ); 1.6607 + LDM_REG(512, R9_FIQ); 1.6608 + LDM_REG(1024, R10_FIQ); 1.6609 + LDM_REG(2048, R11_FIQ); 1.6610 + LDM_REG(4096, R12_FIQ); 1.6611 + } 1.6612 + else 1.6613 + { 1.6614 + LDM_REG(256, 8); 1.6615 + LDM_REG(512, 9); 1.6616 + LDM_REG(1024, 10); 1.6617 + LDM_REG(2048, 11); 1.6618 + LDM_REG(4096, 12); 1.6619 + } 1.6620 + 1.6621 + if (armMode != 0x10 && armMode != 0x1f) 1.6622 + { 1.6623 + LDM_REG(8192, R13_USR); 1.6624 + LDM_REG(16384, R14_USR); 1.6625 + } 1.6626 + else 1.6627 + { 1.6628 + LDM_REG(8192, 13); 1.6629 + LDM_REG(16384, 14); 1.6630 + } 1.6631 + 1.6632 + if (!(opcode & (1 << base))) 1.6633 + reg[base].I = temp; 1.6634 + } 1.6635 + } 1.6636 + break; 1.6637 + 1.6638 + CASE_16(0x890) 1.6639 + { 1.6640 + // LDMIA Rn, {Rlist} 1.6641 + int base = (opcode & 0x000F0000) >> 16; 1.6642 + u32 address = reg[base].I & 0xFFFFFFFC; 1.6643 + clockTicks += 2; 1.6644 + int offset = 0; 1.6645 + LDM_REG(1, 0); 1.6646 + LDM_REG(2, 1); 1.6647 + LDM_REG(4, 2); 1.6648 + LDM_REG(8, 3); 1.6649 + LDM_REG(16, 4); 1.6650 + LDM_REG(32, 5); 1.6651 + LDM_REG(64, 6); 1.6652 + LDM_REG(128, 7); 1.6653 + LDM_REG(256, 8); 1.6654 + LDM_REG(512, 9); 1.6655 + LDM_REG(1024, 10); 1.6656 + LDM_REG(2048, 11); 1.6657 + LDM_REG(4096, 12); 1.6658 + LDM_REG(8192, 13); 1.6659 + LDM_REG(16384, 14); 1.6660 + if (opcode & 32768) 1.6661 + { 1.6662 + reg[15].I = CPUReadMemory(address); 1.6663 + if (!offset) 1.6664 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.6665 + else 1.6666 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.6667 + armNextPC = reg[15].I; 1.6668 + reg[15].I += 4; 1.6669 + } 1.6670 + } 1.6671 + break; 1.6672 + CASE_16(0x8b0) 1.6673 + { 1.6674 + // LDMIA Rn!, {Rlist} 1.6675 + int base = (opcode & 0x000F0000) >> 16; 1.6676 + u32 temp = reg[base].I + 1.6677 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6678 + u32 address = reg[base].I & 0xFFFFFFFC; 1.6679 + clockTicks += 2; 1.6680 + int offset = 0; 1.6681 + LDM_REG(1, 0); 1.6682 + LDM_REG(2, 1); 1.6683 + LDM_REG(4, 2); 1.6684 + LDM_REG(8, 3); 1.6685 + LDM_REG(16, 4); 1.6686 + LDM_REG(32, 5); 1.6687 + LDM_REG(64, 6); 1.6688 + LDM_REG(128, 7); 1.6689 + LDM_REG(256, 8); 1.6690 + LDM_REG(512, 9); 1.6691 + LDM_REG(1024, 10); 1.6692 + LDM_REG(2048, 11); 1.6693 + LDM_REG(4096, 12); 1.6694 + LDM_REG(8192, 13); 1.6695 + LDM_REG(16384, 14); 1.6696 + if (opcode & 32768) 1.6697 + { 1.6698 + reg[15].I = CPUReadMemory(address); 1.6699 + if (!offset) 1.6700 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.6701 + else 1.6702 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.6703 + armNextPC = reg[15].I; 1.6704 + reg[15].I += 4; 1.6705 + } 1.6706 + if (!(opcode & (1 << base))) 1.6707 + reg[base].I = temp; 1.6708 + } 1.6709 + break; 1.6710 + CASE_16(0x8d0) 1.6711 + { 1.6712 + // LDMIA Rn, {Rlist}^ 1.6713 + int base = (opcode & 0x000F0000) >> 16; 1.6714 + u32 address = reg[base].I & 0xFFFFFFFC; 1.6715 + clockTicks += 2; 1.6716 + int offset = 0; 1.6717 + if (opcode & 0x8000) 1.6718 + { 1.6719 + LDM_REG(1, 0); 1.6720 + LDM_REG(2, 1); 1.6721 + LDM_REG(4, 2); 1.6722 + LDM_REG(8, 3); 1.6723 + LDM_REG(16, 4); 1.6724 + LDM_REG(32, 5); 1.6725 + LDM_REG(64, 6); 1.6726 + LDM_REG(128, 7); 1.6727 + LDM_REG(256, 8); 1.6728 + LDM_REG(512, 9); 1.6729 + LDM_REG(1024, 10); 1.6730 + LDM_REG(2048, 11); 1.6731 + LDM_REG(4096, 12); 1.6732 + LDM_REG(8192, 13); 1.6733 + LDM_REG(16384, 14); 1.6734 + 1.6735 + reg[15].I = CPUReadMemory(address); 1.6736 + if (!offset) 1.6737 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.6738 + else 1.6739 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.6740 + 1.6741 + CPUSwitchMode(reg[17].I & 0x1f, false); 1.6742 + if (armState) 1.6743 + { 1.6744 + armNextPC = reg[15].I & 0xFFFFFFFC; 1.6745 + reg[15].I = armNextPC + 4; 1.6746 + } 1.6747 + else 1.6748 + { 1.6749 + armNextPC = reg[15].I & 0xFFFFFFFE; 1.6750 + reg[15].I = armNextPC + 2; 1.6751 + } 1.6752 + } 1.6753 + else 1.6754 + { 1.6755 + LDM_REG(1, 0); 1.6756 + LDM_REG(2, 1); 1.6757 + LDM_REG(4, 2); 1.6758 + LDM_REG(8, 3); 1.6759 + LDM_REG(16, 4); 1.6760 + LDM_REG(32, 5); 1.6761 + LDM_REG(64, 6); 1.6762 + LDM_REG(128, 7); 1.6763 + 1.6764 + if (armMode == 0x11) 1.6765 + { 1.6766 + LDM_REG(256, R8_FIQ); 1.6767 + LDM_REG(512, R9_FIQ); 1.6768 + LDM_REG(1024, R10_FIQ); 1.6769 + LDM_REG(2048, R11_FIQ); 1.6770 + LDM_REG(4096, R12_FIQ); 1.6771 + } 1.6772 + else 1.6773 + { 1.6774 + LDM_REG(256, 8); 1.6775 + LDM_REG(512, 9); 1.6776 + LDM_REG(1024, 10); 1.6777 + LDM_REG(2048, 11); 1.6778 + LDM_REG(4096, 12); 1.6779 + } 1.6780 + 1.6781 + if (armMode != 0x10 && armMode != 0x1f) 1.6782 + { 1.6783 + LDM_REG(8192, R13_USR); 1.6784 + LDM_REG(16384, R14_USR); 1.6785 + } 1.6786 + else 1.6787 + { 1.6788 + LDM_REG(8192, 13); 1.6789 + LDM_REG(16384, 14); 1.6790 + } 1.6791 + } 1.6792 + } 1.6793 + break; 1.6794 + CASE_16(0x8f0) 1.6795 + { 1.6796 + // LDMIA Rn!, {Rlist}^ 1.6797 + int base = (opcode & 0x000F0000) >> 16; 1.6798 + u32 temp = reg[base].I + 1.6799 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6800 + u32 address = reg[base].I & 0xFFFFFFFC; 1.6801 + clockTicks += 2; 1.6802 + int offset = 0; 1.6803 + if (opcode & 0x8000) 1.6804 + { 1.6805 + LDM_REG(1, 0); 1.6806 + LDM_REG(2, 1); 1.6807 + LDM_REG(4, 2); 1.6808 + LDM_REG(8, 3); 1.6809 + LDM_REG(16, 4); 1.6810 + LDM_REG(32, 5); 1.6811 + LDM_REG(64, 6); 1.6812 + LDM_REG(128, 7); 1.6813 + LDM_REG(256, 8); 1.6814 + LDM_REG(512, 9); 1.6815 + LDM_REG(1024, 10); 1.6816 + LDM_REG(2048, 11); 1.6817 + LDM_REG(4096, 12); 1.6818 + LDM_REG(8192, 13); 1.6819 + LDM_REG(16384, 14); 1.6820 + 1.6821 + reg[15].I = CPUReadMemory(address); 1.6822 + if (!offset) 1.6823 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.6824 + else 1.6825 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.6826 + 1.6827 + if (!(opcode & (1 << base))) 1.6828 + reg[base].I = temp; 1.6829 + 1.6830 + CPUSwitchMode(reg[17].I & 0x1f, false); 1.6831 + if (armState) 1.6832 + { 1.6833 + armNextPC = reg[15].I & 0xFFFFFFFC; 1.6834 + reg[15].I = armNextPC + 4; 1.6835 + } 1.6836 + else 1.6837 + { 1.6838 + armNextPC = reg[15].I & 0xFFFFFFFE; 1.6839 + reg[15].I = armNextPC + 2; 1.6840 + } 1.6841 + } 1.6842 + else 1.6843 + { 1.6844 + LDM_REG(1, 0); 1.6845 + LDM_REG(2, 1); 1.6846 + LDM_REG(4, 2); 1.6847 + LDM_REG(8, 3); 1.6848 + LDM_REG(16, 4); 1.6849 + LDM_REG(32, 5); 1.6850 + LDM_REG(64, 6); 1.6851 + LDM_REG(128, 7); 1.6852 + 1.6853 + if (armMode == 0x11) 1.6854 + { 1.6855 + LDM_REG(256, R8_FIQ); 1.6856 + LDM_REG(512, R9_FIQ); 1.6857 + LDM_REG(1024, R10_FIQ); 1.6858 + LDM_REG(2048, R11_FIQ); 1.6859 + LDM_REG(4096, R12_FIQ); 1.6860 + } 1.6861 + else 1.6862 + { 1.6863 + LDM_REG(256, 8); 1.6864 + LDM_REG(512, 9); 1.6865 + LDM_REG(1024, 10); 1.6866 + LDM_REG(2048, 11); 1.6867 + LDM_REG(4096, 12); 1.6868 + } 1.6869 + 1.6870 + if (armMode != 0x10 && armMode != 0x1f) 1.6871 + { 1.6872 + LDM_REG(8192, R13_USR); 1.6873 + LDM_REG(16384, R14_USR); 1.6874 + } 1.6875 + else 1.6876 + { 1.6877 + LDM_REG(8192, 13); 1.6878 + LDM_REG(16384, 14); 1.6879 + } 1.6880 + 1.6881 + if (!(opcode & (1 << base))) 1.6882 + reg[base].I = temp; 1.6883 + } 1.6884 + } 1.6885 + break; 1.6886 + 1.6887 + CASE_16(0x910) 1.6888 + { 1.6889 + // LDMDB Rn, {Rlist} 1.6890 + int base = (opcode & 0x000F0000) >> 16; 1.6891 + u32 temp = reg[base].I - 1.6892 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6893 + u32 address = temp & 0xFFFFFFFC; 1.6894 + clockTicks += 2; 1.6895 + int offset = 0; 1.6896 + LDM_REG(1, 0); 1.6897 + LDM_REG(2, 1); 1.6898 + LDM_REG(4, 2); 1.6899 + LDM_REG(8, 3); 1.6900 + LDM_REG(16, 4); 1.6901 + LDM_REG(32, 5); 1.6902 + LDM_REG(64, 6); 1.6903 + LDM_REG(128, 7); 1.6904 + LDM_REG(256, 8); 1.6905 + LDM_REG(512, 9); 1.6906 + LDM_REG(1024, 10); 1.6907 + LDM_REG(2048, 11); 1.6908 + LDM_REG(4096, 12); 1.6909 + LDM_REG(8192, 13); 1.6910 + LDM_REG(16384, 14); 1.6911 + if (opcode & 32768) 1.6912 + { 1.6913 + reg[15].I = CPUReadMemory(address); 1.6914 + if (!offset) 1.6915 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.6916 + else 1.6917 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.6918 + armNextPC = reg[15].I; 1.6919 + reg[15].I += 4; 1.6920 + } 1.6921 + } 1.6922 + break; 1.6923 + CASE_16(0x930) 1.6924 + { 1.6925 + // LDMDB Rn!, {Rlist} 1.6926 + int base = (opcode & 0x000F0000) >> 16; 1.6927 + u32 temp = reg[base].I - 1.6928 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6929 + u32 address = temp & 0xFFFFFFFC; 1.6930 + clockTicks += 2; 1.6931 + int offset = 0; 1.6932 + LDM_REG(1, 0); 1.6933 + LDM_REG(2, 1); 1.6934 + LDM_REG(4, 2); 1.6935 + LDM_REG(8, 3); 1.6936 + LDM_REG(16, 4); 1.6937 + LDM_REG(32, 5); 1.6938 + LDM_REG(64, 6); 1.6939 + LDM_REG(128, 7); 1.6940 + LDM_REG(256, 8); 1.6941 + LDM_REG(512, 9); 1.6942 + LDM_REG(1024, 10); 1.6943 + LDM_REG(2048, 11); 1.6944 + LDM_REG(4096, 12); 1.6945 + LDM_REG(8192, 13); 1.6946 + LDM_REG(16384, 14); 1.6947 + if (opcode & 32768) 1.6948 + { 1.6949 + reg[15].I = CPUReadMemory(address); 1.6950 + if (!offset) 1.6951 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.6952 + else 1.6953 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.6954 + armNextPC = reg[15].I; 1.6955 + reg[15].I += 4; 1.6956 + } 1.6957 + if (!(opcode & (1 << base))) 1.6958 + reg[base].I = temp; 1.6959 + } 1.6960 + break; 1.6961 + CASE_16(0x950) 1.6962 + { 1.6963 + // LDMDB Rn, {Rlist}^ 1.6964 + int base = (opcode & 0x000F0000) >> 16; 1.6965 + u32 temp = reg[base].I - 1.6966 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.6967 + u32 address = temp & 0xFFFFFFFC; 1.6968 + clockTicks += 2; 1.6969 + int offset = 0; 1.6970 + if (opcode & 0x8000) 1.6971 + { 1.6972 + LDM_REG(1, 0); 1.6973 + LDM_REG(2, 1); 1.6974 + LDM_REG(4, 2); 1.6975 + LDM_REG(8, 3); 1.6976 + LDM_REG(16, 4); 1.6977 + LDM_REG(32, 5); 1.6978 + LDM_REG(64, 6); 1.6979 + LDM_REG(128, 7); 1.6980 + LDM_REG(256, 8); 1.6981 + LDM_REG(512, 9); 1.6982 + LDM_REG(1024, 10); 1.6983 + LDM_REG(2048, 11); 1.6984 + LDM_REG(4096, 12); 1.6985 + LDM_REG(8192, 13); 1.6986 + LDM_REG(16384, 14); 1.6987 + 1.6988 + reg[15].I = CPUReadMemory(address); 1.6989 + if (!offset) 1.6990 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.6991 + else 1.6992 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.6993 + 1.6994 + CPUSwitchMode(reg[17].I & 0x1f, false); 1.6995 + if (armState) 1.6996 + { 1.6997 + armNextPC = reg[15].I & 0xFFFFFFFC; 1.6998 + reg[15].I = armNextPC + 4; 1.6999 + } 1.7000 + else 1.7001 + { 1.7002 + armNextPC = reg[15].I & 0xFFFFFFFE; 1.7003 + reg[15].I = armNextPC + 2; 1.7004 + } 1.7005 + } 1.7006 + else 1.7007 + { 1.7008 + LDM_REG(1, 0); 1.7009 + LDM_REG(2, 1); 1.7010 + LDM_REG(4, 2); 1.7011 + LDM_REG(8, 3); 1.7012 + LDM_REG(16, 4); 1.7013 + LDM_REG(32, 5); 1.7014 + LDM_REG(64, 6); 1.7015 + LDM_REG(128, 7); 1.7016 + 1.7017 + if (armMode == 0x11) 1.7018 + { 1.7019 + LDM_REG(256, R8_FIQ); 1.7020 + LDM_REG(512, R9_FIQ); 1.7021 + LDM_REG(1024, R10_FIQ); 1.7022 + LDM_REG(2048, R11_FIQ); 1.7023 + LDM_REG(4096, R12_FIQ); 1.7024 + } 1.7025 + else 1.7026 + { 1.7027 + LDM_REG(256, 8); 1.7028 + LDM_REG(512, 9); 1.7029 + LDM_REG(1024, 10); 1.7030 + LDM_REG(2048, 11); 1.7031 + LDM_REG(4096, 12); 1.7032 + } 1.7033 + 1.7034 + if (armMode != 0x10 && armMode != 0x1f) 1.7035 + { 1.7036 + LDM_REG(8192, R13_USR); 1.7037 + LDM_REG(16384, R14_USR); 1.7038 + } 1.7039 + else 1.7040 + { 1.7041 + LDM_REG(8192, 13); 1.7042 + LDM_REG(16384, 14); 1.7043 + } 1.7044 + } 1.7045 + } 1.7046 + break; 1.7047 + CASE_16(0x970) 1.7048 + { 1.7049 + // LDMDB Rn!, {Rlist}^ 1.7050 + int base = (opcode & 0x000F0000) >> 16; 1.7051 + u32 temp = reg[base].I - 1.7052 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.7053 + u32 address = temp & 0xFFFFFFFC; 1.7054 + clockTicks += 2; 1.7055 + int offset = 0; 1.7056 + if (opcode & 0x8000) 1.7057 + { 1.7058 + LDM_REG(1, 0); 1.7059 + LDM_REG(2, 1); 1.7060 + LDM_REG(4, 2); 1.7061 + LDM_REG(8, 3); 1.7062 + LDM_REG(16, 4); 1.7063 + LDM_REG(32, 5); 1.7064 + LDM_REG(64, 6); 1.7065 + LDM_REG(128, 7); 1.7066 + LDM_REG(256, 8); 1.7067 + LDM_REG(512, 9); 1.7068 + LDM_REG(1024, 10); 1.7069 + LDM_REG(2048, 11); 1.7070 + LDM_REG(4096, 12); 1.7071 + LDM_REG(8192, 13); 1.7072 + LDM_REG(16384, 14); 1.7073 + 1.7074 + reg[15].I = CPUReadMemory(address); 1.7075 + if (!offset) 1.7076 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.7077 + else 1.7078 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.7079 + 1.7080 + if (!(opcode & (1 << base))) 1.7081 + reg[base].I = temp; 1.7082 + 1.7083 + CPUSwitchMode(reg[17].I & 0x1f, false); 1.7084 + if (armState) 1.7085 + { 1.7086 + armNextPC = reg[15].I & 0xFFFFFFFC; 1.7087 + reg[15].I = armNextPC + 4; 1.7088 + } 1.7089 + else 1.7090 + { 1.7091 + armNextPC = reg[15].I & 0xFFFFFFFE; 1.7092 + reg[15].I = armNextPC + 2; 1.7093 + } 1.7094 + } 1.7095 + else 1.7096 + { 1.7097 + LDM_REG(1, 0); 1.7098 + LDM_REG(2, 1); 1.7099 + LDM_REG(4, 2); 1.7100 + LDM_REG(8, 3); 1.7101 + LDM_REG(16, 4); 1.7102 + LDM_REG(32, 5); 1.7103 + LDM_REG(64, 6); 1.7104 + LDM_REG(128, 7); 1.7105 + 1.7106 + if (armMode == 0x11) 1.7107 + { 1.7108 + LDM_REG(256, R8_FIQ); 1.7109 + LDM_REG(512, R9_FIQ); 1.7110 + LDM_REG(1024, R10_FIQ); 1.7111 + LDM_REG(2048, R11_FIQ); 1.7112 + LDM_REG(4096, R12_FIQ); 1.7113 + } 1.7114 + else 1.7115 + { 1.7116 + LDM_REG(256, 8); 1.7117 + LDM_REG(512, 9); 1.7118 + LDM_REG(1024, 10); 1.7119 + LDM_REG(2048, 11); 1.7120 + LDM_REG(4096, 12); 1.7121 + } 1.7122 + 1.7123 + if (armMode != 0x10 && armMode != 0x1f) 1.7124 + { 1.7125 + LDM_REG(8192, R13_USR); 1.7126 + LDM_REG(16384, R14_USR); 1.7127 + } 1.7128 + else 1.7129 + { 1.7130 + LDM_REG(8192, 13); 1.7131 + LDM_REG(16384, 14); 1.7132 + } 1.7133 + 1.7134 + if (!(opcode & (1 << base))) 1.7135 + reg[base].I = temp; 1.7136 + } 1.7137 + } 1.7138 + break; 1.7139 + 1.7140 + CASE_16(0x990) 1.7141 + { 1.7142 + // LDMIB Rn, {Rlist} 1.7143 + int base = (opcode & 0x000F0000) >> 16; 1.7144 + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; 1.7145 + clockTicks += 2; 1.7146 + int offset = 0; 1.7147 + LDM_REG(1, 0); 1.7148 + LDM_REG(2, 1); 1.7149 + LDM_REG(4, 2); 1.7150 + LDM_REG(8, 3); 1.7151 + LDM_REG(16, 4); 1.7152 + LDM_REG(32, 5); 1.7153 + LDM_REG(64, 6); 1.7154 + LDM_REG(128, 7); 1.7155 + LDM_REG(256, 8); 1.7156 + LDM_REG(512, 9); 1.7157 + LDM_REG(1024, 10); 1.7158 + LDM_REG(2048, 11); 1.7159 + LDM_REG(4096, 12); 1.7160 + LDM_REG(8192, 13); 1.7161 + LDM_REG(16384, 14); 1.7162 + if (opcode & 32768) 1.7163 + { 1.7164 + reg[15].I = CPUReadMemory(address); 1.7165 + if (!offset) 1.7166 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.7167 + else 1.7168 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.7169 + armNextPC = reg[15].I; 1.7170 + reg[15].I += 4; 1.7171 + } 1.7172 + } 1.7173 + break; 1.7174 + CASE_16(0x9b0) 1.7175 + { 1.7176 + // LDMIB Rn!, {Rlist} 1.7177 + int base = (opcode & 0x000F0000) >> 16; 1.7178 + u32 temp = reg[base].I + 1.7179 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.7180 + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; 1.7181 + clockTicks += 2; 1.7182 + int offset = 0; 1.7183 + LDM_REG(1, 0); 1.7184 + LDM_REG(2, 1); 1.7185 + LDM_REG(4, 2); 1.7186 + LDM_REG(8, 3); 1.7187 + LDM_REG(16, 4); 1.7188 + LDM_REG(32, 5); 1.7189 + LDM_REG(64, 6); 1.7190 + LDM_REG(128, 7); 1.7191 + LDM_REG(256, 8); 1.7192 + LDM_REG(512, 9); 1.7193 + LDM_REG(1024, 10); 1.7194 + LDM_REG(2048, 11); 1.7195 + LDM_REG(4096, 12); 1.7196 + LDM_REG(8192, 13); 1.7197 + LDM_REG(16384, 14); 1.7198 + if (opcode & 32768) 1.7199 + { 1.7200 + reg[15].I = CPUReadMemory(address); 1.7201 + if (!offset) 1.7202 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.7203 + else 1.7204 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.7205 + armNextPC = reg[15].I; 1.7206 + reg[15].I += 4; 1.7207 + } 1.7208 + if (!(opcode & (1 << base))) 1.7209 + reg[base].I = temp; 1.7210 + } 1.7211 + break; 1.7212 + CASE_16(0x9d0) 1.7213 + { 1.7214 + // LDMIB Rn, {Rlist}^ 1.7215 + int base = (opcode & 0x000F0000) >> 16; 1.7216 + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; 1.7217 + clockTicks += 2; 1.7218 + int offset = 0; 1.7219 + if (opcode & 0x8000) 1.7220 + { 1.7221 + LDM_REG(1, 0); 1.7222 + LDM_REG(2, 1); 1.7223 + LDM_REG(4, 2); 1.7224 + LDM_REG(8, 3); 1.7225 + LDM_REG(16, 4); 1.7226 + LDM_REG(32, 5); 1.7227 + LDM_REG(64, 6); 1.7228 + LDM_REG(128, 7); 1.7229 + LDM_REG(256, 8); 1.7230 + LDM_REG(512, 9); 1.7231 + LDM_REG(1024, 10); 1.7232 + LDM_REG(2048, 11); 1.7233 + LDM_REG(4096, 12); 1.7234 + LDM_REG(8192, 13); 1.7235 + LDM_REG(16384, 14); 1.7236 + 1.7237 + reg[15].I = CPUReadMemory(address); 1.7238 + if (!offset) 1.7239 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.7240 + else 1.7241 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.7242 + 1.7243 + CPUSwitchMode(reg[17].I & 0x1f, false); 1.7244 + if (armState) 1.7245 + { 1.7246 + armNextPC = reg[15].I & 0xFFFFFFFC; 1.7247 + reg[15].I = armNextPC + 4; 1.7248 + } 1.7249 + else 1.7250 + { 1.7251 + armNextPC = reg[15].I & 0xFFFFFFFE; 1.7252 + reg[15].I = armNextPC + 2; 1.7253 + } 1.7254 + } 1.7255 + else 1.7256 + { 1.7257 + LDM_REG(1, 0); 1.7258 + LDM_REG(2, 1); 1.7259 + LDM_REG(4, 2); 1.7260 + LDM_REG(8, 3); 1.7261 + LDM_REG(16, 4); 1.7262 + LDM_REG(32, 5); 1.7263 + LDM_REG(64, 6); 1.7264 + LDM_REG(128, 7); 1.7265 + 1.7266 + if (armMode == 0x11) 1.7267 + { 1.7268 + LDM_REG(256, R8_FIQ); 1.7269 + LDM_REG(512, R9_FIQ); 1.7270 + LDM_REG(1024, R10_FIQ); 1.7271 + LDM_REG(2048, R11_FIQ); 1.7272 + LDM_REG(4096, R12_FIQ); 1.7273 + } 1.7274 + else 1.7275 + { 1.7276 + LDM_REG(256, 8); 1.7277 + LDM_REG(512, 9); 1.7278 + LDM_REG(1024, 10); 1.7279 + LDM_REG(2048, 11); 1.7280 + LDM_REG(4096, 12); 1.7281 + } 1.7282 + 1.7283 + if (armMode != 0x10 && armMode != 0x1f) 1.7284 + { 1.7285 + LDM_REG(8192, R13_USR); 1.7286 + LDM_REG(16384, R14_USR); 1.7287 + } 1.7288 + else 1.7289 + { 1.7290 + LDM_REG(8192, 13); 1.7291 + LDM_REG(16384, 14); 1.7292 + } 1.7293 + } 1.7294 + } 1.7295 + break; 1.7296 + CASE_16(0x9f0) 1.7297 + { 1.7298 + // LDMIB Rn!, {Rlist}^ 1.7299 + int base = (opcode & 0x000F0000) >> 16; 1.7300 + u32 temp = reg[base].I + 1.7301 + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 1.7302 + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; 1.7303 + clockTicks += 2; 1.7304 + int offset = 0; 1.7305 + if (opcode & 0x8000) 1.7306 + { 1.7307 + LDM_REG(1, 0); 1.7308 + LDM_REG(2, 1); 1.7309 + LDM_REG(4, 2); 1.7310 + LDM_REG(8, 3); 1.7311 + LDM_REG(16, 4); 1.7312 + LDM_REG(32, 5); 1.7313 + LDM_REG(64, 6); 1.7314 + LDM_REG(128, 7); 1.7315 + LDM_REG(256, 8); 1.7316 + LDM_REG(512, 9); 1.7317 + LDM_REG(1024, 10); 1.7318 + LDM_REG(2048, 11); 1.7319 + LDM_REG(4096, 12); 1.7320 + LDM_REG(8192, 13); 1.7321 + LDM_REG(16384, 14); 1.7322 + 1.7323 + reg[15].I = CPUReadMemory(address); 1.7324 + if (!offset) 1.7325 + clockTicks += 2 + CPUUpdateTicksAccess32(address); 1.7326 + else 1.7327 + clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 1.7328 + 1.7329 + if (!(opcode & (1 << base))) 1.7330 + reg[base].I = temp; 1.7331 + 1.7332 + CPUSwitchMode(reg[17].I & 0x1f, false); 1.7333 + if (armState) 1.7334 + { 1.7335 + armNextPC = reg[15].I & 0xFFFFFFFC; 1.7336 + reg[15].I = armNextPC + 4; 1.7337 + } 1.7338 + else 1.7339 + { 1.7340 + armNextPC = reg[15].I & 0xFFFFFFFE; 1.7341 + reg[15].I = armNextPC + 2; 1.7342 + } 1.7343 + } 1.7344 + else 1.7345 + { 1.7346 + LDM_REG(1, 0); 1.7347 + LDM_REG(2, 1); 1.7348 + LDM_REG(4, 2); 1.7349 + LDM_REG(8, 3); 1.7350 + LDM_REG(16, 4); 1.7351 + LDM_REG(32, 5); 1.7352 + LDM_REG(64, 6); 1.7353 + LDM_REG(128, 7); 1.7354 + 1.7355 + if (armMode == 0x11) 1.7356 + { 1.7357 + LDM_REG(256, R8_FIQ); 1.7358 + LDM_REG(512, R9_FIQ); 1.7359 + LDM_REG(1024, R10_FIQ); 1.7360 + LDM_REG(2048, R11_FIQ); 1.7361 + LDM_REG(4096, R12_FIQ); 1.7362 + } 1.7363 + else 1.7364 + { 1.7365 + LDM_REG(256, 8); 1.7366 + LDM_REG(512, 9); 1.7367 + LDM_REG(1024, 10); 1.7368 + LDM_REG(2048, 11); 1.7369 + LDM_REG(4096, 12); 1.7370 + } 1.7371 + 1.7372 + if (armMode != 0x10 && armMode != 0x1f) 1.7373 + { 1.7374 + LDM_REG(8192, R13_USR); 1.7375 + LDM_REG(16384, R14_USR); 1.7376 + } 1.7377 + else 1.7378 + { 1.7379 + LDM_REG(8192, 13); 1.7380 + LDM_REG(16384, 14); 1.7381 + } 1.7382 + 1.7383 + if (!(opcode & (1 << base))) 1.7384 + reg[base].I = temp; 1.7385 + } 1.7386 + } 1.7387 + break; 1.7388 + CASE_256(0xa00) 1.7389 + { 1.7390 + // B <offset> 1.7391 + clockTicks += 3; 1.7392 + int offset = opcode & 0x00FFFFFF; 1.7393 + if (offset & 0x00800000) 1.7394 + { 1.7395 + offset |= 0xFF000000; 1.7396 + } 1.7397 + offset <<= 2; 1.7398 + reg[15].I += offset; 1.7399 + armNextPC = reg[15].I; 1.7400 + reg[15].I += 4; 1.7401 + } 1.7402 + break; 1.7403 + CASE_256(0xb00) 1.7404 + { 1.7405 + // BL <offset> 1.7406 + clockTicks += 3; 1.7407 + int offset = opcode & 0x00FFFFFF; 1.7408 + if (offset & 0x00800000) 1.7409 + { 1.7410 + offset |= 0xFF000000; 1.7411 + } 1.7412 + offset <<= 2; 1.7413 + reg[14].I = reg[15].I - 4; 1.7414 + reg[15].I += offset; 1.7415 + armNextPC = reg[15].I; 1.7416 + reg[15].I += 4; 1.7417 + } 1.7418 + break; 1.7419 + CASE_256(0xf00) 1.7420 + // SWI <comment> 1.7421 + clockTicks += 3; 1.7422 + CPUSoftwareInterrupt(opcode & 0x00FFFFFF); 1.7423 + break; 1.7424 +#ifdef GP_SUPPORT 1.7425 + case 0xe11: 1.7426 + case 0xe13: 1.7427 + case 0xe15: 1.7428 + case 0xe17: 1.7429 + case 0xe19: 1.7430 + case 0xe1b: 1.7431 + case 0xe1d: 1.7432 + case 0xe1f: 1.7433 + // MRC 1.7434 + break; 1.7435 + case 0xe01: 1.7436 + case 0xe03: 1.7437 + case 0xe05: 1.7438 + case 0xe07: 1.7439 + case 0xe09: 1.7440 + case 0xe0b: 1.7441 + case 0xe0d: 1.7442 + case 0xe0f: 1.7443 + // MRC 1.7444 + break; 1.7445 +#endif 1.7446 + default: 1.7447 +#ifdef GBA_LOGGING 1.7448 + if (systemVerbose & VERBOSE_UNDEFINED) 1.7449 + log("Undefined ARM instruction %08x at %08x\n", opcode, 1.7450 + armNextPC - 4); 1.7451 +#endif 1.7452 + CPUUndefinedException(); 1.7453 + break; 1.7454 + // END 1.7455 + } 1.7456 +}