1 // -*- C++ -*- 2 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 3 // Copyright (C) 1999-2003 Forgotten 4 // Copyright (C) 2004 Forgotten and the VBA development team 5 6 // This program is free software; you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation; either version 2, or(at your option) 9 // any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program; if not, write to the Free Software Foundation, 18 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 20 #ifdef BKPT_SUPPORT 21 #define CONSOLE_OUTPUT(a,b) \ 22 extern void (*dbgOutput)(char *, u32);\ 23 if((opcode == 0xe0000000) && (reg[0].I == 0xC0DED00D)) {\ 24 dbgOutput((a), (b));\ 25 } 26 #else 27 #define CONSOLE_OUTPUT(a,b) 28 #endif 29 30 #define OP_AND \ 31 reg[dest].I = reg[(opcode>>16)&15].I & value;\ 32 CONSOLE_OUTPUT(NULL,reg[2].I); 33 34 #define OP_ANDS \ 35 reg[dest].I = reg[(opcode>>16)&15].I & value;\ 36 \ 37 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\ 38 Z_FLAG = (reg[dest].I) ? false : true;\ 39 C_FLAG = C_OUT; 40 41 #define OP_EOR \ 42 reg[dest].I = reg[(opcode>>16)&15].I ^ value; 43 44 #define OP_EORS \ 45 reg[dest].I = reg[(opcode>>16)&15].I ^ value;\ 46 \ 47 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\ 48 Z_FLAG = (reg[dest].I) ? false : true;\ 49 C_FLAG = C_OUT; 50 #ifdef C_CORE 51 #define NEG(i) ((i) >> 31) 52 #define POS(i) ((~(i)) >> 31) 53 #define ADDCARRY(a, b, c) \ 54 C_FLAG = ((NEG(a) & NEG(b)) |\ 55 (NEG(a) & POS(c)) |\ 56 (NEG(b) & POS(c))) ? true : false; 57 #define ADDOVERFLOW(a, b, c) \ 58 V_FLAG = ((NEG(a) & NEG(b) & POS(c)) |\ 59 (POS(a) & POS(b) & NEG(c))) ? true : false; 60 #define SUBCARRY(a, b, c) \ 61 C_FLAG = ((NEG(a) & POS(b)) |\ 62 (NEG(a) & POS(c)) |\ 63 (POS(b) & POS(c))) ? true : false; 64 #define SUBOVERFLOW(a, b, c)\ 65 V_FLAG = ((NEG(a) & POS(b) & POS(c)) |\ 66 (POS(a) & NEG(b) & NEG(c))) ? true : false; 67 #define OP_SUB \ 68 {\ 69 reg[dest].I = reg[base].I - value;\ 70 } 71 #define OP_SUBS \ 72 {\ 73 u32 lhs = reg[base].I;\ 74 u32 rhs = value;\ 75 u32 res = lhs - rhs;\ 76 reg[dest].I = res;\ 77 Z_FLAG = (res == 0) ? true : false;\ 78 N_FLAG = NEG(res) ? true : false;\ 79 SUBCARRY(lhs, rhs, res);\ 80 SUBOVERFLOW(lhs, rhs, res);\ 81 } 82 #define OP_RSB \ 83 {\ 84 reg[dest].I = value - reg[base].I;\ 85 } 86 #define OP_RSBS \ 87 {\ 88 u32 lhs = reg[base].I;\ 89 u32 rhs = value;\ 90 u32 res = rhs - lhs;\ 91 reg[dest].I = res;\ 92 Z_FLAG = (res == 0) ? true : false;\ 93 N_FLAG = NEG(res) ? true : false;\ 94 SUBCARRY(rhs, lhs, res);\ 95 SUBOVERFLOW(rhs, lhs, res);\ 96 } 97 #define OP_ADD \ 98 {\ 99 reg[dest].I = reg[base].I + value;\ 100 } 101 #define OP_ADDS \ 102 {\ 103 u32 lhs = reg[base].I;\ 104 u32 rhs = value;\ 105 u32 res = lhs + rhs;\ 106 reg[dest].I = res;\ 107 Z_FLAG = (res == 0) ? true : false;\ 108 N_FLAG = NEG(res) ? true : false;\ 109 ADDCARRY(lhs, rhs, res);\ 110 ADDOVERFLOW(lhs, rhs, res);\ 111 } 112 #define OP_ADC \ 113 {\ 114 reg[dest].I = reg[base].I + value + (u32)C_FLAG;\ 115 } 116 #define OP_ADCS \ 117 {\ 118 u32 lhs = reg[base].I;\ 119 u32 rhs = value;\ 120 u32 res = lhs + rhs + (u32)C_FLAG;\ 121 reg[dest].I = res;\ 122 Z_FLAG = (res == 0) ? true : false;\ 123 N_FLAG = NEG(res) ? true : false;\ 124 ADDCARRY(lhs, rhs, res);\ 125 ADDOVERFLOW(lhs, rhs, res);\ 126 } 127 #define OP_SBC \ 128 {\ 129 reg[dest].I = reg[base].I - value - !((u32)C_FLAG);\ 130 } 131 #define OP_SBCS \ 132 {\ 133 u32 lhs = reg[base].I;\ 134 u32 rhs = value;\ 135 u32 res = lhs - rhs - !((u32)C_FLAG);\ 136 reg[dest].I = res;\ 137 Z_FLAG = (res == 0) ? true : false;\ 138 N_FLAG = NEG(res) ? true : false;\ 139 SUBCARRY(lhs, rhs, res);\ 140 SUBOVERFLOW(lhs, rhs, res);\ 141 } 142 #define OP_RSC \ 143 {\ 144 reg[dest].I = value - reg[base].I - !((u32)C_FLAG);\ 145 } 146 #define OP_RSCS \ 147 {\ 148 u32 lhs = reg[base].I;\ 149 u32 rhs = value;\ 150 u32 res = rhs - lhs - !((u32)C_FLAG);\ 151 reg[dest].I = res;\ 152 Z_FLAG = (res == 0) ? true : false;\ 153 N_FLAG = NEG(res) ? true : false;\ 154 SUBCARRY(rhs, lhs, res);\ 155 SUBOVERFLOW(rhs, lhs, res);\ 156 } 157 #define OP_CMP \ 158 {\ 159 u32 lhs = reg[base].I;\ 160 u32 rhs = value;\ 161 u32 res = lhs - rhs;\ 162 Z_FLAG = (res == 0) ? true : false;\ 163 N_FLAG = NEG(res) ? true : false;\ 164 SUBCARRY(lhs, rhs, res);\ 165 SUBOVERFLOW(lhs, rhs, res);\ 166 } 167 #define OP_CMN \ 168 {\ 169 u32 lhs = reg[base].I;\ 170 u32 rhs = value;\ 171 u32 res = lhs + rhs;\ 172 Z_FLAG = (res == 0) ? true : false;\ 173 N_FLAG = NEG(res) ? true : false;\ 174 ADDCARRY(lhs, rhs, res);\ 175 ADDOVERFLOW(lhs, rhs, res);\ 176 } 177 178 #define LOGICAL_LSL_REG \ 179 {\ 180 u32 v = reg[opcode & 0x0f].I;\ 181 C_OUT = (v >> (32 - shift)) & 1 ? true : false;\ 182 value = v << shift;\ 183 } 184 #define LOGICAL_LSR_REG \ 185 {\ 186 u32 v = reg[opcode & 0x0f].I;\ 187 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\ 188 value = v >> shift;\ 189 } 190 #define LOGICAL_ASR_REG \ 191 {\ 192 u32 v = reg[opcode & 0x0f].I;\ 193 C_OUT = ((s32)v >> (int)(shift - 1)) & 1 ? true : false;\ 194 value = (s32)v >> (int)shift;\ 195 } 196 #define LOGICAL_ROR_REG \ 197 {\ 198 u32 v = reg[opcode & 0x0f].I;\ 199 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\ 200 value = ((v << (32 - shift)) |\ 201 (v >> shift));\ 202 } 203 #define LOGICAL_RRX_REG \ 204 {\ 205 u32 v = reg[opcode & 0x0f].I;\ 206 shift = (int)C_FLAG;\ 207 C_OUT = (v & 1) ? true : false;\ 208 value = ((v >> 1) |\ 209 (shift << 31));\ 210 } 211 #define LOGICAL_ROR_IMM \ 212 {\ 213 u32 v = opcode & 0xff;\ 214 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\ 215 value = ((v << (32 - shift)) |\ 216 (v >> shift));\ 217 } 218 #define ARITHMETIC_LSL_REG \ 219 {\ 220 u32 v = reg[opcode & 0x0f].I;\ 221 value = v << shift;\ 222 } 223 #define ARITHMETIC_LSR_REG \ 224 {\ 225 u32 v = reg[opcode & 0x0f].I;\ 226 value = v >> shift;\ 227 } 228 #define ARITHMETIC_ASR_REG \ 229 {\ 230 u32 v = reg[opcode & 0x0f].I;\ 231 value = (s32)v >> (int)shift;\ 232 } 233 #define ARITHMETIC_ROR_REG \ 234 {\ 235 u32 v = reg[opcode & 0x0f].I;\ 236 value = ((v << (32 - shift)) |\ 237 (v >> shift));\ 238 } 239 #define ARITHMETIC_RRX_REG \ 240 {\ 241 u32 v = reg[opcode & 0x0f].I;\ 242 shift = (int)C_FLAG;\ 243 value = ((v >> 1) |\ 244 (shift << 31));\ 245 } 246 #define ARITHMETIC_ROR_IMM \ 247 {\ 248 u32 v = opcode & 0xff;\ 249 value = ((v << (32 - shift)) |\ 250 (v >> shift));\ 251 } 252 #define ROR_IMM_MSR \ 253 {\ 254 u32 v = opcode & 0xff;\ 255 value = ((v << (32 - shift)) |\ 256 (v >> shift));\ 257 } 258 #define ROR_VALUE \ 259 {\ 260 value = ((value << (32 - shift)) |\ 261 (value >> shift));\ 262 } 263 #define RCR_VALUE \ 264 {\ 265 shift = (int)C_FLAG;\ 266 value = ((value >> 1) |\ 267 (shift << 31));\ 268 } 269 #else 270 #ifdef __GNUC__ 271 #ifdef __POWERPC__ 272 #define OP_SUB \ 273 {\ 274 reg[dest].I = reg[base].I - value;\ 275 } 276 #define OP_SUBS \ 277 {\ 278 register int Flags; \ 279 register int Result; \ 280 asm volatile("subco. %0, %2, %3\n" \ 281 "mcrxr cr1\n" \ 282 "mfcr %1\n" \ 283 : "=r" (Result), \ 284 "=r" (Flags) \ 285 : "r" (reg[base].I), \ 286 "r" (value) \ 287 ); \ 288 reg[dest].I = Result; \ 289 Z_FLAG = (Flags >> 29) & 1; \ 290 N_FLAG = (Flags >> 31) & 1; \ 291 C_FLAG = (Flags >> 25) & 1; \ 292 V_FLAG = (Flags >> 26) & 1; \ 293 } 294 #define OP_RSB \ 295 {\ 296 reg[dest].I = value - reg[base].I;\ 297 } 298 #define OP_RSBS \ 299 {\ 300 register int Flags; \ 301 register int Result; \ 302 asm volatile("subfco. %0, %2, %3\n" \ 303 "mcrxr cr1\n" \ 304 "mfcr %1\n" \ 305 : "=r" (Result), \ 306 "=r" (Flags) \ 307 : "r" (reg[base].I), \ 308 "r" (value) \ 309 ); \ 310 reg[dest].I = Result; \ 311 Z_FLAG = (Flags >> 29) & 1; \ 312 N_FLAG = (Flags >> 31) & 1; \ 313 C_FLAG = (Flags >> 25) & 1; \ 314 V_FLAG = (Flags >> 26) & 1; \ 315 } 316 #define OP_ADD \ 317 {\ 318 reg[dest].I = reg[base].I + value;\ 319 } 320 321 #define OP_ADDS \ 322 {\ 323 register int Flags; \ 324 register int Result; \ 325 asm volatile("addco. %0, %2, %3\n" \ 326 "mcrxr cr1\n" \ 327 "mfcr %1\n" \ 328 : "=r" (Result), \ 329 "=r" (Flags) \ 330 : "r" (reg[base].I), \ 331 "r" (value) \ 332 ); \ 333 reg[dest].I = Result; \ 334 Z_FLAG = (Flags >> 29) & 1; \ 335 N_FLAG = (Flags >> 31) & 1; \ 336 C_FLAG = (Flags >> 25) & 1; \ 337 V_FLAG = (Flags >> 26) & 1; \ 338 } 339 #define OP_ADC \ 340 {\ 341 reg[dest].I = reg[base].I + value + (u32)C_FLAG;\ 342 } 343 #define OP_ADCS \ 344 {\ 345 register int Flags; \ 346 register int Result; \ 347 asm volatile("mtspr xer, %4\n" \ 348 "addeo. %0, %2, %3\n" \ 349 "mcrxr cr1\n" \ 350 "mfcr %1\n" \ 351 : "=r" (Result), \ 352 "=r" (Flags) \ 353 : "r" (reg[base].I), \ 354 "r" (value), \ 355 "r" (C_FLAG << 29) \ 356 ); \ 357 reg[dest].I = Result; \ 358 Z_FLAG = (Flags >> 29) & 1; \ 359 N_FLAG = (Flags >> 31) & 1; \ 360 C_FLAG = (Flags >> 25) & 1; \ 361 V_FLAG = (Flags >> 26) & 1; \ 362 } 363 #define OP_SBC \ 364 {\ 365 reg[dest].I = reg[base].I - value - (C_FLAG^1);\ 366 } 367 #define OP_SBCS \ 368 {\ 369 register int Flags; \ 370 register int Result; \ 371 asm volatile("mtspr xer, %4\n" \ 372 "subfeo. %0, %3, %2\n" \ 373 "mcrxr cr1\n" \ 374 "mfcr %1\n" \ 375 : "=r" (Result), \ 376 "=r" (Flags) \ 377 : "r" (reg[base].I), \ 378 "r" (value), \ 379 "r" (C_FLAG << 29) \ 380 ); \ 381 reg[dest].I = Result; \ 382 Z_FLAG = (Flags >> 29) & 1; \ 383 N_FLAG = (Flags >> 31) & 1; \ 384 C_FLAG = (Flags >> 25) & 1; \ 385 V_FLAG = (Flags >> 26) & 1; \ 386 } 387 #define OP_RSC \ 388 {\ 389 reg[dest].I = value - reg[base].I - (C_FLAG^1);\ 390 } 391 #define OP_RSCS \ 392 {\ 393 register int Flags; \ 394 register int Result; \ 395 asm volatile("mtspr xer, %4\n" \ 396 "subfeo. %0, %2, %3\n" \ 397 "mcrxr cr1\n" \ 398 "mfcr %1\n" \ 399 : "=r" (Result), \ 400 "=r" (Flags) \ 401 : "r" (reg[base].I), \ 402 "r" (value), \ 403 "r" (C_FLAG << 29) \ 404 ); \ 405 reg[dest].I = Result; \ 406 Z_FLAG = (Flags >> 29) & 1; \ 407 N_FLAG = (Flags >> 31) & 1; \ 408 C_FLAG = (Flags >> 25) & 1; \ 409 V_FLAG = (Flags >> 26) & 1; \ 410 } 411 #define OP_CMP \ 412 {\ 413 register int Flags; \ 414 register int Result; \ 415 asm volatile("subco. %0, %2, %3\n" \ 416 "mcrxr cr1\n" \ 417 "mfcr %1\n" \ 418 : "=r" (Result), \ 419 "=r" (Flags) \ 420 : "r" (reg[base].I), \ 421 "r" (value) \ 422 ); \ 423 Z_FLAG = (Flags >> 29) & 1; \ 424 N_FLAG = (Flags >> 31) & 1; \ 425 C_FLAG = (Flags >> 25) & 1; \ 426 V_FLAG = (Flags >> 26) & 1; \ 427 } 428 #define OP_CMN \ 429 {\ 430 register int Flags; \ 431 register int Result; \ 432 asm volatile("addco. %0, %2, %3\n" \ 433 "mcrxr cr1\n" \ 434 "mfcr %1\n" \ 435 : "=r" (Result), \ 436 "=r" (Flags) \ 437 : "r" (reg[base].I), \ 438 "r" (value) \ 439 ); \ 440 Z_FLAG = (Flags >> 29) & 1; \ 441 N_FLAG = (Flags >> 31) & 1; \ 442 C_FLAG = (Flags >> 25) & 1; \ 443 V_FLAG = (Flags >> 26) & 1; \ 444 } 445 446 #define LOGICAL_LSL_REG \ 447 {\ 448 u32 v = reg[opcode & 0x0f].I;\ 449 C_OUT = (v >> (32 - shift)) & 1 ? true : false;\ 450 value = v << shift;\ 451 } 452 #define LOGICAL_LSR_REG \ 453 {\ 454 u32 v = reg[opcode & 0x0f].I;\ 455 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\ 456 value = v >> shift;\ 457 } 458 #define LOGICAL_ASR_REG \ 459 {\ 460 u32 v = reg[opcode & 0x0f].I;\ 461 C_OUT = ((s32)v >> (int)(shift - 1)) & 1 ? true : false;\ 462 value = (s32)v >> (int)shift;\ 463 } 464 #define LOGICAL_ROR_REG \ 465 {\ 466 u32 v = reg[opcode & 0x0f].I;\ 467 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\ 468 value = ((v << (32 - shift)) |\ 469 (v >> shift));\ 470 } 471 #define LOGICAL_RRX_REG \ 472 {\ 473 u32 v = reg[opcode & 0x0f].I;\ 474 shift = (int)C_FLAG;\ 475 C_OUT = (v & 1) ? true : false;\ 476 value = ((v >> 1) |\ 477 (shift << 31));\ 478 } 479 #define LOGICAL_ROR_IMM \ 480 {\ 481 u32 v = opcode & 0xff;\ 482 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\ 483 value = ((v << (32 - shift)) |\ 484 (v >> shift));\ 485 } 486 #define ARITHMETIC_LSL_REG \ 487 {\ 488 u32 v = reg[opcode & 0x0f].I;\ 489 value = v << shift;\ 490 } 491 #define ARITHMETIC_LSR_REG \ 492 {\ 493 u32 v = reg[opcode & 0x0f].I;\ 494 value = v >> shift;\ 495 } 496 #define ARITHMETIC_ASR_REG \ 497 {\ 498 u32 v = reg[opcode & 0x0f].I;\ 499 value = (s32)v >> (int)shift;\ 500 } 501 #define ARITHMETIC_ROR_REG \ 502 {\ 503 u32 v = reg[opcode & 0x0f].I;\ 504 value = ((v << (32 - shift)) |\ 505 (v >> shift));\ 506 } 507 #define ARITHMETIC_RRX_REG \ 508 {\ 509 u32 v = reg[opcode & 0x0f].I;\ 510 shift = (int)C_FLAG;\ 511 value = ((v >> 1) |\ 512 (shift << 31));\ 513 } 514 #define ARITHMETIC_ROR_IMM \ 515 {\ 516 u32 v = opcode & 0xff;\ 517 value = ((v << (32 - shift)) |\ 518 (v >> shift));\ 519 } 520 #define ROR_IMM_MSR \ 521 {\ 522 u32 v = opcode & 0xff;\ 523 value = ((v << (32 - shift)) |\ 524 (v >> shift));\ 525 } 526 #define ROR_VALUE \ 527 {\ 528 value = ((value << (32 - shift)) |\ 529 (value >> shift));\ 530 } 531 #define RCR_VALUE \ 532 {\ 533 shift = (int)C_FLAG;\ 534 value = ((value >> 1) |\ 535 (shift << 31));\ 536 } 537 #else 538 #define OP_SUB \ 539 asm ("sub %1, %%ebx;"\ 540 : "=b" (reg[dest].I)\ 541 : "r" (value), "b" (reg[base].I)); 542 543 #define OP_SUBS \ 544 asm ("sub %1, %%ebx;"\ 545 "setsb N_FLAG;"\ 546 "setzb Z_FLAG;"\ 547 "setncb C_FLAG;"\ 548 "setob V_FLAG;"\ 549 : "=b" (reg[dest].I)\ 550 : "r" (value), "b" (reg[base].I)); 551 552 #define OP_RSB \ 553 asm ("sub %1, %%ebx;"\ 554 : "=b" (reg[dest].I)\ 555 : "r" (reg[base].I), "b" (value)); 556 557 #define OP_RSBS \ 558 asm ("sub %1, %%ebx;"\ 559 "setsb N_FLAG;"\ 560 "setzb Z_FLAG;"\ 561 "setncb C_FLAG;"\ 562 "setob V_FLAG;"\ 563 : "=b" (reg[dest].I)\ 564 : "r" (reg[base].I), "b" (value)); 565 566 #define OP_ADD \ 567 asm ("add %1, %%ebx;"\ 568 : "=b" (reg[dest].I)\ 569 : "r" (value), "b" (reg[base].I)); 570 571 #define OP_ADDS \ 572 asm ("add %1, %%ebx;"\ 573 "setsb N_FLAG;"\ 574 "setzb Z_FLAG;"\ 575 "setcb C_FLAG;"\ 576 "setob V_FLAG;"\ 577 : "=b" (reg[dest].I)\ 578 : "r" (value), "b" (reg[base].I)); 579 580 #define OP_ADC \ 581 asm ("bt $0, C_FLAG;"\ 582 "adc %1, %%ebx;"\ 583 : "=b" (reg[dest].I)\ 584 : "r" (value), "b" (reg[base].I)); 585 586 #define OP_ADCS \ 587 asm ("bt $0, C_FLAG;"\ 588 "adc %1, %%ebx;"\ 589 "setsb N_FLAG;"\ 590 "setzb Z_FLAG;"\ 591 "setcb C_FLAG;"\ 592 "setob V_FLAG;"\ 593 : "=b" (reg[dest].I)\ 594 : "r" (value), "b" (reg[base].I)); 595 596 #define OP_SBC \ 597 asm ("bt $0, C_FLAG;"\ 598 "cmc;"\ 599 "sbb %1, %%ebx;"\ 600 : "=b" (reg[dest].I)\ 601 : "r" (value), "b" (reg[base].I)); 602 603 #define OP_SBCS \ 604 asm ("bt $0, C_FLAG;"\ 605 "cmc;"\ 606 "sbb %1, %%ebx;"\ 607 "setsb N_FLAG;"\ 608 "setzb Z_FLAG;"\ 609 "setncb C_FLAG;"\ 610 "setob V_FLAG;"\ 611 : "=b" (reg[dest].I)\ 612 : "r" (value), "b" (reg[base].I)); 613 #define OP_RSC \ 614 asm ("bt $0, C_FLAG;"\ 615 "cmc;"\ 616 "sbb %1, %%ebx;"\ 617 : "=b" (reg[dest].I)\ 618 : "r" (reg[base].I), "b" (value)); 619 620 #define OP_RSCS \ 621 asm ("bt $0, C_FLAG;"\ 622 "cmc;"\ 623 "sbb %1, %%ebx;"\ 624 "setsb N_FLAG;"\ 625 "setzb Z_FLAG;"\ 626 "setncb C_FLAG;"\ 627 "setob V_FLAG;"\ 628 : "=b" (reg[dest].I)\ 629 : "r" (reg[base].I), "b" (value)); 630 #define OP_CMP \ 631 asm ("sub %0, %1;"\ 632 "setsb N_FLAG;"\ 633 "setzb Z_FLAG;"\ 634 "setncb C_FLAG;"\ 635 "setob V_FLAG;"\ 636 :\ 637 : "r" (value), "r" (reg[base].I)); 638 639 #define OP_CMN \ 640 asm ("add %0, %1;"\ 641 "setsb N_FLAG;"\ 642 "setzb Z_FLAG;"\ 643 "setcb C_FLAG;"\ 644 "setob V_FLAG;"\ 645 : \ 646 : "r" (value), "r" (reg[base].I)); 647 #define LOGICAL_LSL_REG \ 648 asm("shl %%cl, %%eax;"\ 649 "setcb %%cl;"\ 650 : "=a" (value), "=c" (C_OUT)\ 651 : "a" (reg[opcode & 0x0f].I), "c" (shift)); 652 653 #define LOGICAL_LSR_REG \ 654 asm("shr %%cl, %%eax;"\ 655 "setcb %%cl;"\ 656 : "=a" (value), "=c" (C_OUT)\ 657 : "a" (reg[opcode & 0x0f].I), "c" (shift)); 658 659 #define LOGICAL_ASR_REG \ 660 asm("sar %%cl, %%eax;"\ 661 "setcb %%cl;"\ 662 : "=a" (value), "=c" (C_OUT)\ 663 : "a" (reg[opcode & 0x0f].I), "c" (shift)); 664 665 #define LOGICAL_ROR_REG \ 666 asm("ror %%cl, %%eax;"\ 667 "setcb %%cl;"\ 668 : "=a" (value), "=c" (C_OUT)\ 669 : "a" (reg[opcode & 0x0f].I), "c" (shift)); 670 671 #define LOGICAL_RRX_REG \ 672 asm("bt $0, C_FLAG;"\ 673 "rcr $1, %%eax;"\ 674 "setcb %%cl;"\ 675 : "=a" (value), "=c" (C_OUT)\ 676 : "a" (reg[opcode & 0x0f].I)); 677 678 #define LOGICAL_ROR_IMM \ 679 asm("ror %%cl, %%eax;"\ 680 "setcb %%cl;"\ 681 : "=a" (value), "=c" (C_OUT)\ 682 : "a" (opcode & 0xff), "c" (shift)); 683 #define ARITHMETIC_LSL_REG \ 684 asm("\ 685 shl %%cl, %%eax;"\ 686 : "=a" (value)\ 687 : "a" (reg[opcode & 0x0f].I), "c" (shift)); 688 689 #define ARITHMETIC_LSR_REG \ 690 asm("\ 691 shr %%cl, %%eax;"\ 692 : "=a" (value)\ 693 : "a" (reg[opcode & 0x0f].I), "c" (shift)); 694 695 #define ARITHMETIC_ASR_REG \ 696 asm("\ 697 sar %%cl, %%eax;"\ 698 : "=a" (value)\ 699 : "a" (reg[opcode & 0x0f].I), "c" (shift)); 700 701 #define ARITHMETIC_ROR_REG \ 702 asm("\ 703 ror %%cl, %%eax;"\ 704 : "=a" (value)\ 705 : "a" (reg[opcode & 0x0f].I), "c" (shift)); 706 707 #define ARITHMETIC_RRX_REG \ 708 asm("\ 709 bt $0, C_FLAG;\ 710 rcr $1, %%eax;"\ 711 : "=a" (value)\ 712 : "a" (reg[opcode & 0x0f].I)); 713 714 #define ARITHMETIC_ROR_IMM \ 715 asm("\ 716 ror %%cl, %%eax;"\ 717 : "=a" (value)\ 718 : "a" (opcode & 0xff), "c" (shift)); 719 #define ROR_IMM_MSR \ 720 asm ("ror %%cl, %%eax;"\ 721 : "=a" (value)\ 722 : "a" (opcode & 0xFF), "c" (shift)); 723 #define ROR_VALUE \ 724 asm("ror %%cl, %0"\ 725 : "=r" (value)\ 726 : "r" (value), "c" (shift)); 727 #define RCR_VALUE \ 728 asm("bt $0, C_FLAG;"\ 729 "rcr $1, %0"\ 730 : "=r" (value)\ 731 : "r" (value)); 732 #endif 733 #else 734 #define OP_SUB \ 735 {\ 736 __asm mov ebx, base\ 737 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\ 738 __asm sub ebx, value\ 739 __asm mov eax, dest\ 740 __asm mov dword ptr [OFFSET reg+4*eax], ebx\ 741 } 742 743 #define OP_SUBS \ 744 {\ 745 __asm mov ebx, base\ 746 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\ 747 __asm sub ebx, value\ 748 __asm mov eax, dest\ 749 __asm mov dword ptr [OFFSET reg+4*eax], ebx\ 750 __asm sets byte ptr N_FLAG\ 751 __asm setz byte ptr Z_FLAG\ 752 __asm setnc byte ptr C_FLAG\ 753 __asm seto byte ptr V_FLAG\ 754 } 755 756 #define OP_RSB \ 757 {\ 758 __asm mov ebx, base\ 759 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\ 760 __asm mov eax, value\ 761 __asm sub eax, ebx\ 762 __asm mov ebx, dest\ 763 __asm mov dword ptr [OFFSET reg+4*ebx], eax\ 764 } 765 766 #define OP_RSBS \ 767 {\ 768 __asm mov ebx, base\ 769 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\ 770 __asm mov eax, value\ 771 __asm sub eax, ebx\ 772 __asm mov ebx, dest\ 773 __asm mov dword ptr [OFFSET reg+4*ebx], eax\ 774 __asm sets byte ptr N_FLAG\ 775 __asm setz byte ptr Z_FLAG\ 776 __asm setnc byte ptr C_FLAG\ 777 __asm seto byte ptr V_FLAG\ 778 } 779 780 #define OP_ADD \ 781 {\ 782 __asm mov ebx, base\ 783 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\ 784 __asm add ebx, value\ 785 __asm mov eax, dest\ 786 __asm mov dword ptr [OFFSET reg+4*eax], ebx\ 787 } 788 789 #define OP_ADDS \ 790 {\ 791 __asm mov ebx, base\ 792 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\ 793 __asm add ebx, value\ 794 __asm mov eax, dest\ 795 __asm mov dword ptr [OFFSET reg+4*eax], ebx\ 796 __asm sets byte ptr N_FLAG\ 797 __asm setz byte ptr Z_FLAG\ 798 __asm setc byte ptr C_FLAG\ 799 __asm seto byte ptr V_FLAG\ 800 } 801 802 #define OP_ADC \ 803 {\ 804 __asm mov ebx, base\ 805 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\ 806 __asm bt word ptr C_FLAG, 0\ 807 __asm adc ebx, value\ 808 __asm mov eax, dest\ 809 __asm mov dword ptr [OFFSET reg+4*eax], ebx\ 810 } 811 812 #define OP_ADCS \ 813 {\ 814 __asm mov ebx, base\ 815 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\ 816 __asm bt word ptr C_FLAG, 0\ 817 __asm adc ebx, value\ 818 __asm mov eax, dest\ 819 __asm mov dword ptr [OFFSET reg+4*eax], ebx\ 820 __asm sets byte ptr N_FLAG\ 821 __asm setz byte ptr Z_FLAG\ 822 __asm setc byte ptr C_FLAG\ 823 __asm seto byte ptr V_FLAG\ 824 } 825 826 #define OP_SBC \ 827 {\ 828 __asm mov ebx, base\ 829 __asm mov ebx, dword ptr [OFFSET reg + 4*ebx]\ 830 __asm mov eax, value\ 831 __asm bt word ptr C_FLAG, 0\ 832 __asm cmc\ 833 __asm sbb ebx, eax\ 834 __asm mov eax, dest\ 835 __asm mov dword ptr [OFFSET reg + 4*eax], ebx\ 836 } 837 838 #define OP_SBCS \ 839 {\ 840 __asm mov ebx, base\ 841 __asm mov ebx, dword ptr [OFFSET reg + 4*ebx]\ 842 __asm mov eax, value\ 843 __asm bt word ptr C_FLAG, 0\ 844 __asm cmc\ 845 __asm sbb ebx, eax\ 846 __asm mov eax, dest\ 847 __asm mov dword ptr [OFFSET reg + 4*eax], ebx\ 848 __asm sets byte ptr N_FLAG\ 849 __asm setz byte ptr Z_FLAG\ 850 __asm setnc byte ptr C_FLAG\ 851 __asm seto byte ptr V_FLAG\ 852 } 853 #define OP_RSC \ 854 {\ 855 __asm mov ebx, value\ 856 __asm mov eax, base\ 857 __asm mov eax, dword ptr[OFFSET reg + 4*eax]\ 858 __asm bt word ptr C_FLAG, 0\ 859 __asm cmc\ 860 __asm sbb ebx, eax\ 861 __asm mov eax, dest\ 862 __asm mov dword ptr [OFFSET reg + 4*eax], ebx\ 863 } 864 865 #define OP_RSCS \ 866 {\ 867 __asm mov ebx, value\ 868 __asm mov eax, base\ 869 __asm mov eax, dword ptr[OFFSET reg + 4*eax]\ 870 __asm bt word ptr C_FLAG, 0\ 871 __asm cmc\ 872 __asm sbb ebx, eax\ 873 __asm mov eax, dest\ 874 __asm mov dword ptr [OFFSET reg + 4*eax], ebx\ 875 __asm sets byte ptr N_FLAG\ 876 __asm setz byte ptr Z_FLAG\ 877 __asm setnc byte ptr C_FLAG\ 878 __asm seto byte ptr V_FLAG\ 879 } 880 #define OP_CMP \ 881 {\ 882 __asm mov eax, base\ 883 __asm mov ebx, dword ptr [OFFSET reg+4*eax]\ 884 __asm sub ebx, value\ 885 __asm sets byte ptr N_FLAG\ 886 __asm setz byte ptr Z_FLAG\ 887 __asm setnc byte ptr C_FLAG\ 888 __asm seto byte ptr V_FLAG\ 889 } 890 891 #define OP_CMN \ 892 {\ 893 __asm mov eax, base\ 894 __asm mov ebx, dword ptr [OFFSET reg+4*eax]\ 895 __asm add ebx, value\ 896 __asm sets byte ptr N_FLAG\ 897 __asm setz byte ptr Z_FLAG\ 898 __asm setc byte ptr C_FLAG\ 899 __asm seto byte ptr V_FLAG\ 900 } 901 #define LOGICAL_LSL_REG \ 902 __asm mov eax, opcode\ 903 __asm and eax, 0x0f\ 904 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\ 905 __asm mov cl, byte ptr shift\ 906 __asm shl eax, cl\ 907 __asm mov value, eax\ 908 __asm setc byte ptr C_OUT 909 910 #define LOGICAL_LSR_REG \ 911 __asm mov eax, opcode\ 912 __asm and eax, 0x0f\ 913 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\ 914 __asm mov cl, byte ptr shift\ 915 __asm shr eax, cl\ 916 __asm mov value, eax\ 917 __asm setc byte ptr C_OUT 918 919 #define LOGICAL_ASR_REG \ 920 __asm mov eax, opcode\ 921 __asm and eax, 0x0f\ 922 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\ 923 __asm mov cl, byte ptr shift\ 924 __asm sar eax, cl\ 925 __asm mov value, eax\ 926 __asm setc byte ptr C_OUT 927 928 #define LOGICAL_ROR_REG \ 929 __asm mov eax, opcode\ 930 __asm and eax, 0x0F\ 931 __asm mov eax, dword ptr [OFFSET reg + 4*eax]\ 932 __asm mov cl, byte ptr shift\ 933 __asm ror eax, cl\ 934 __asm mov value, eax\ 935 __asm setc byte ptr C_OUT 936 937 #define LOGICAL_RRX_REG \ 938 __asm mov eax, opcode\ 939 __asm and eax, 0x0F\ 940 __asm mov eax, dword ptr [OFFSET reg + 4*eax]\ 941 __asm bt word ptr C_OUT, 0\ 942 __asm rcr eax, 1\ 943 __asm mov value, eax\ 944 __asm setc byte ptr C_OUT 945 946 #define LOGICAL_ROR_IMM \ 947 __asm mov eax, opcode\ 948 __asm and eax, 0xff\ 949 __asm mov cl, byte ptr shift\ 950 __asm ror eax, cl\ 951 __asm mov value, eax\ 952 __asm setc byte ptr C_OUT 953 #define ARITHMETIC_LSL_REG \ 954 __asm mov eax, opcode\ 955 __asm and eax, 0x0f\ 956 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\ 957 __asm mov cl, byte ptr shift\ 958 __asm shl eax, cl\ 959 __asm mov value, eax 960 961 #define ARITHMETIC_LSR_REG \ 962 __asm mov eax, opcode\ 963 __asm and eax, 0x0f\ 964 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\ 965 __asm mov cl, byte ptr shift\ 966 __asm shr eax, cl\ 967 __asm mov value, eax 968 969 #define ARITHMETIC_ASR_REG \ 970 __asm mov eax, opcode\ 971 __asm and eax, 0x0f\ 972 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\ 973 __asm mov cl, byte ptr shift\ 974 __asm sar eax, cl\ 975 __asm mov value, eax 976 977 #define ARITHMETIC_ROR_REG \ 978 __asm mov eax, opcode\ 979 __asm and eax, 0x0F\ 980 __asm mov eax, dword ptr [OFFSET reg + 4*eax]\ 981 __asm mov cl, byte ptr shift\ 982 __asm ror eax, cl\ 983 __asm mov value, eax 984 985 #define ARITHMETIC_RRX_REG \ 986 __asm mov eax, opcode\ 987 __asm and eax, 0x0F\ 988 __asm mov eax, dword ptr [OFFSET reg + 4*eax]\ 989 __asm bt word ptr C_FLAG, 0\ 990 __asm rcr eax, 1\ 991 __asm mov value, eax 992 993 #define ARITHMETIC_ROR_IMM \ 994 __asm mov eax, opcode\ 995 __asm and eax, 0xff\ 996 __asm mov cl, byte ptr shift\ 997 __asm ror eax, cl\ 998 __asm mov value, eax 999 #define ROR_IMM_MSR \ 1000 {\ 1001 __asm mov eax, opcode\ 1002 __asm and eax, 0xff\ 1003 __asm mov cl, byte ptr shift\ 1004 __asm ror eax, CL\ 1005 __asm mov value, eax\ 1006 } 1007 #define ROR_VALUE \ 1008 {\ 1009 __asm mov cl, byte ptr shift\ 1010 __asm ror dword ptr value, cl\ 1011 } 1012 #define RCR_VALUE \ 1013 {\ 1014 __asm mov cl, byte ptr shift\ 1015 __asm bt word ptr C_FLAG, 0\ 1016 __asm rcr dword ptr value, 1\ 1017 } 1018 #endif 1019 #endif 1020 1021 #define OP_TST \ 1022 u32 res = reg[base].I & value;\ 1023 N_FLAG = (res & 0x80000000) ? true : false;\ 1024 Z_FLAG = (res) ? false : true;\ 1025 C_FLAG = C_OUT; 1026 1027 #define OP_TEQ \ 1028 u32 res = reg[base].I ^ value;\ 1029 N_FLAG = (res & 0x80000000) ? true : false;\ 1030 Z_FLAG = (res) ? false : true;\ 1031 C_FLAG = C_OUT; 1032 1033 #define OP_ORR \ 1034 reg[dest].I = reg[base].I | value; 1035 1036 #define OP_ORRS \ 1037 reg[dest].I = reg[base].I | value;\ 1038 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\ 1039 Z_FLAG = (reg[dest].I) ? false : true;\ 1040 C_FLAG = C_OUT; 1041 1042 #define OP_MOV \ 1043 reg[dest].I = value; 1044 1045 #define OP_MOVS \ 1046 reg[dest].I = value;\ 1047 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\ 1048 Z_FLAG = (reg[dest].I) ? false : true;\ 1049 C_FLAG = C_OUT; 1050 1051 #define OP_BIC \ 1052 reg[dest].I = reg[base].I & (~value); 1053 1054 #define OP_BICS \ 1055 reg[dest].I = reg[base].I & (~value);\ 1056 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\ 1057 Z_FLAG = (reg[dest].I) ? false : true;\ 1058 C_FLAG = C_OUT; 1059 1060 #define OP_MVN \ 1061 reg[dest].I = ~value; 1062 1063 #define OP_MVNS \ 1064 reg[dest].I = ~value; \ 1065 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\ 1066 Z_FLAG = (reg[dest].I) ? false : true;\ 1067 C_FLAG = C_OUT; 1068 1069 #define CASE_16(BASE) \ 1070 case BASE:\ 1071 case BASE+1:\ 1072 case BASE+2:\ 1073 case BASE+3:\ 1074 case BASE+4:\ 1075 case BASE+5:\ 1076 case BASE+6:\ 1077 case BASE+7:\ 1078 case BASE+8:\ 1079 case BASE+9:\ 1080 case BASE+10:\ 1081 case BASE+11:\ 1082 case BASE+12:\ 1083 case BASE+13:\ 1084 case BASE+14:\ 1085 case BASE+15: 1086 1087 #define CASE_256(BASE) \ 1088 CASE_16(BASE)\ 1089 CASE_16(BASE+0x10)\ 1090 CASE_16(BASE+0x20)\ 1091 CASE_16(BASE+0x30)\ 1092 CASE_16(BASE+0x40)\ 1093 CASE_16(BASE+0x50)\ 1094 CASE_16(BASE+0x60)\ 1095 CASE_16(BASE+0x70)\ 1096 CASE_16(BASE+0x80)\ 1097 CASE_16(BASE+0x90)\ 1098 CASE_16(BASE+0xa0)\ 1099 CASE_16(BASE+0xb0)\ 1100 CASE_16(BASE+0xc0)\ 1101 CASE_16(BASE+0xd0)\ 1102 CASE_16(BASE+0xe0)\ 1103 CASE_16(BASE+0xf0) 1104 1105 #define LOGICAL_DATA_OPCODE(OPCODE, OPCODE2, BASE) \ 1106 case BASE: \ 1107 case BASE+8:\ 1108 {\ 1109 /* OP Rd,Rb,Rm LSL # */ \ 1110 int base = (opcode >> 16) & 0x0F;\ 1111 int shift = (opcode >> 7) & 0x1F;\ 1112 int dest = (opcode>>12) & 15;\ 1113 bool C_OUT = C_FLAG;\ 1114 u32 value;\ 1115 \ 1116 if(shift) {\ 1117 LOGICAL_LSL_REG\ 1118 } else {\ 1119 value = reg[opcode & 0x0F].I;\ 1120 }\ 1121 if(dest == 15) {\ 1122 OPCODE2\ 1123 /* todo */\ 1124 if(opcode & 0x00100000) {\ 1125 clockTicks++;\ 1126 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1127 }\ 1128 if(armState) {\ 1129 reg[15].I &= 0xFFFFFFFC;\ 1130 armNextPC = reg[15].I;\ 1131 reg[15].I += 4;\ 1132 } else {\ 1133 reg[15].I &= 0xFFFFFFFE;\ 1134 armNextPC = reg[15].I;\ 1135 reg[15].I += 2;\ 1136 }\ 1137 } else {\ 1138 OPCODE \ 1139 }\ 1140 }\ 1141 break;\ 1142 case BASE+2:\ 1143 case BASE+10:\ 1144 {\ 1145 /* OP Rd,Rb,Rm LSR # */ \ 1146 int base = (opcode >> 16) & 0x0F;\ 1147 int shift = (opcode >> 7) & 0x1F;\ 1148 int dest = (opcode>>12) & 15;\ 1149 bool C_OUT = C_FLAG;\ 1150 u32 value;\ 1151 if(shift) {\ 1152 LOGICAL_LSR_REG\ 1153 } else {\ 1154 value = 0;\ 1155 C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false;\ 1156 }\ 1157 \ 1158 if(dest == 15) {\ 1159 OPCODE2\ 1160 /* todo */\ 1161 if(opcode & 0x00100000) {\ 1162 clockTicks++;\ 1163 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1164 }\ 1165 if(armState) {\ 1166 reg[15].I &= 0xFFFFFFFC;\ 1167 armNextPC = reg[15].I;\ 1168 reg[15].I += 4;\ 1169 } else {\ 1170 reg[15].I &= 0xFFFFFFFE;\ 1171 armNextPC = reg[15].I;\ 1172 reg[15].I += 2;\ 1173 }\ 1174 } else {\ 1175 OPCODE \ 1176 }\ 1177 }\ 1178 break;\ 1179 case BASE+4:\ 1180 case BASE+12:\ 1181 {\ 1182 /* OP Rd,Rb,Rm ASR # */\ 1183 int base = (opcode >> 16) & 0x0F;\ 1184 int shift = (opcode >> 7) & 0x1F;\ 1185 int dest = (opcode>>12) & 15;\ 1186 bool C_OUT = C_FLAG;\ 1187 u32 value;\ 1188 if(shift) {\ 1189 LOGICAL_ASR_REG\ 1190 } else {\ 1191 if(reg[opcode & 0x0F].I & 0x80000000){\ 1192 value = 0xFFFFFFFF;\ 1193 C_OUT = true;\ 1194 } else {\ 1195 value = 0;\ 1196 C_OUT = false;\ 1197 } \ 1198 }\ 1199 \ 1200 if(dest == 15) {\ 1201 OPCODE2\ 1202 /* todo */\ 1203 if(opcode & 0x00100000) {\ 1204 clockTicks++;\ 1205 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1206 }\ 1207 if(armState) {\ 1208 reg[15].I &= 0xFFFFFFFC;\ 1209 armNextPC = reg[15].I;\ 1210 reg[15].I += 4;\ 1211 } else {\ 1212 reg[15].I &= 0xFFFFFFFE;\ 1213 armNextPC = reg[15].I;\ 1214 reg[15].I += 2;\ 1215 }\ 1216 } else {\ 1217 OPCODE \ 1218 }\ 1219 }\ 1220 break;\ 1221 case BASE+6:\ 1222 case BASE+14:\ 1223 {\ 1224 /* OP Rd,Rb,Rm ROR # */\ 1225 int base = (opcode >> 16) & 0x0F;\ 1226 int shift = (opcode >> 7) & 0x1F;\ 1227 int dest = (opcode>>12) & 15;\ 1228 bool C_OUT = C_FLAG;\ 1229 u32 value;\ 1230 if(shift) {\ 1231 LOGICAL_ROR_REG\ 1232 } else {\ 1233 LOGICAL_RRX_REG\ 1234 }\ 1235 if(dest == 15) {\ 1236 OPCODE2\ 1237 /* todo */\ 1238 if(opcode & 0x00100000) {\ 1239 clockTicks++;\ 1240 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1241 }\ 1242 if(armState) {\ 1243 reg[15].I &= 0xFFFFFFFC;\ 1244 armNextPC = reg[15].I;\ 1245 reg[15].I += 4;\ 1246 } else {\ 1247 reg[15].I &= 0xFFFFFFFE;\ 1248 armNextPC = reg[15].I;\ 1249 reg[15].I += 2;\ 1250 }\ 1251 } else {\ 1252 OPCODE \ 1253 }\ 1254 }\ 1255 break;\ 1256 case BASE+1:\ 1257 {\ 1258 /* OP Rd,Rb,Rm LSL Rs */\ 1259 clockTicks++;\ 1260 int base = (opcode >> 16) & 0x0F;\ 1261 int shift = reg[(opcode >> 8)&15].B.B0;\ 1262 int dest = (opcode>>12) & 15;\ 1263 bool C_OUT = C_FLAG;\ 1264 u32 value;\ 1265 if(shift) {\ 1266 if(shift == 32) {\ 1267 value = 0;\ 1268 C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false);\ 1269 } else if(shift < 32) {\ 1270 LOGICAL_LSL_REG\ 1271 } else {\ 1272 value = 0;\ 1273 C_OUT = false;\ 1274 }\ 1275 } else {\ 1276 value = reg[opcode & 0x0F].I;\ 1277 }\ 1278 if(dest == 15) {\ 1279 OPCODE2\ 1280 /* todo */\ 1281 if(opcode & 0x00100000) {\ 1282 clockTicks++;\ 1283 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1284 }\ 1285 if(armState) {\ 1286 reg[15].I &= 0xFFFFFFFC;\ 1287 armNextPC = reg[15].I;\ 1288 reg[15].I += 4;\ 1289 } else {\ 1290 reg[15].I &= 0xFFFFFFFE;\ 1291 armNextPC = reg[15].I;\ 1292 reg[15].I += 2;\ 1293 }\ 1294 } else {\ 1295 OPCODE \ 1296 }\ 1297 }\ 1298 break;\ 1299 case BASE+3:\ 1300 {\ 1301 /* OP Rd,Rb,Rm LSR Rs */ \ 1302 clockTicks++;\ 1303 int base = (opcode >> 16) & 0x0F;\ 1304 int shift = reg[(opcode >> 8)&15].B.B0;\ 1305 int dest = (opcode>>12) & 15;\ 1306 bool C_OUT = C_FLAG;\ 1307 u32 value;\ 1308 if(shift) {\ 1309 if(shift == 32) {\ 1310 value = 0;\ 1311 C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false);\ 1312 } else if(shift < 32) {\ 1313 LOGICAL_LSR_REG\ 1314 } else {\ 1315 value = 0;\ 1316 C_OUT = false;\ 1317 }\ 1318 } else {\ 1319 value = reg[opcode & 0x0F].I;\ 1320 }\ 1321 if(dest == 15) {\ 1322 OPCODE2\ 1323 /* todo */\ 1324 if(opcode & 0x00100000) {\ 1325 clockTicks++;\ 1326 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1327 }\ 1328 if(armState) {\ 1329 reg[15].I &= 0xFFFFFFFC;\ 1330 armNextPC = reg[15].I;\ 1331 reg[15].I += 4;\ 1332 } else {\ 1333 reg[15].I &= 0xFFFFFFFE;\ 1334 armNextPC = reg[15].I;\ 1335 reg[15].I += 2;\ 1336 }\ 1337 } else {\ 1338 OPCODE \ 1339 }\ 1340 }\ 1341 break;\ 1342 case BASE+5:\ 1343 {\ 1344 /* OP Rd,Rb,Rm ASR Rs */ \ 1345 clockTicks++;\ 1346 int base = (opcode >> 16) & 0x0F;\ 1347 int shift = reg[(opcode >> 8)&15].B.B0;\ 1348 int dest = (opcode>>12) & 15;\ 1349 bool C_OUT = C_FLAG;\ 1350 u32 value;\ 1351 if(shift < 32) {\ 1352 if(shift) {\ 1353 LOGICAL_ASR_REG\ 1354 } else {\ 1355 value = reg[opcode & 0x0F].I;\ 1356 }\ 1357 } else {\ 1358 if(reg[opcode & 0x0F].I & 0x80000000){\ 1359 value = 0xFFFFFFFF;\ 1360 C_OUT = true;\ 1361 } else {\ 1362 value = 0;\ 1363 C_OUT = false;\ 1364 }\ 1365 }\ 1366 if(dest == 15) {\ 1367 OPCODE2\ 1368 /* todo */\ 1369 if(opcode & 0x00100000) {\ 1370 clockTicks++;\ 1371 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1372 }\ 1373 if(armState) {\ 1374 reg[15].I &= 0xFFFFFFFC;\ 1375 armNextPC = reg[15].I;\ 1376 reg[15].I += 4;\ 1377 } else {\ 1378 reg[15].I &= 0xFFFFFFFE;\ 1379 armNextPC = reg[15].I;\ 1380 reg[15].I += 2;\ 1381 }\ 1382 } else {\ 1383 OPCODE \ 1384 }\ 1385 }\ 1386 break;\ 1387 case BASE+7:\ 1388 {\ 1389 /* OP Rd,Rb,Rm ROR Rs */\ 1390 clockTicks++;\ 1391 int base = (opcode >> 16) & 0x0F;\ 1392 int shift = reg[(opcode >> 8)&15].B.B0;\ 1393 int dest = (opcode>>12) & 15;\ 1394 bool C_OUT = C_FLAG;\ 1395 u32 value;\ 1396 if(shift) {\ 1397 shift &= 0x1f;\ 1398 if(shift) {\ 1399 LOGICAL_ROR_REG\ 1400 } else {\ 1401 value = reg[opcode & 0x0F].I;\ 1402 C_OUT = (value & 0x80000000 ? true : false);\ 1403 }\ 1404 } else {\ 1405 value = reg[opcode & 0x0F].I;\ 1406 C_OUT = (value & 0x80000000 ? true : false);\ 1407 }\ 1408 if(dest == 15) {\ 1409 OPCODE2\ 1410 /* todo */\ 1411 if(opcode & 0x00100000) {\ 1412 clockTicks++;\ 1413 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1414 }\ 1415 if(armState) {\ 1416 reg[15].I &= 0xFFFFFFFC;\ 1417 armNextPC = reg[15].I;\ 1418 reg[15].I += 4;\ 1419 } else {\ 1420 reg[15].I &= 0xFFFFFFFE;\ 1421 armNextPC = reg[15].I;\ 1422 reg[15].I += 2;\ 1423 }\ 1424 } else {\ 1425 OPCODE \ 1426 }\ 1427 }\ 1428 break;\ 1429 case BASE+0x200:\ 1430 case BASE+0x201:\ 1431 case BASE+0x202:\ 1432 case BASE+0x203:\ 1433 case BASE+0x204:\ 1434 case BASE+0x205:\ 1435 case BASE+0x206:\ 1436 case BASE+0x207:\ 1437 case BASE+0x208:\ 1438 case BASE+0x209:\ 1439 case BASE+0x20a:\ 1440 case BASE+0x20b:\ 1441 case BASE+0x20c:\ 1442 case BASE+0x20d:\ 1443 case BASE+0x20e:\ 1444 case BASE+0x20f:\ 1445 {\ 1446 int shift = (opcode & 0xF00) >> 7;\ 1447 int base = (opcode >> 16) & 0x0F;\ 1448 int dest = (opcode >> 12) & 0x0F;\ 1449 bool C_OUT = C_FLAG;\ 1450 u32 value;\ 1451 if(shift) {\ 1452 LOGICAL_ROR_IMM\ 1453 } else {\ 1454 value = opcode & 0xff;\ 1455 }\ 1456 if(dest == 15) {\ 1457 OPCODE2\ 1458 /* todo */\ 1459 if(opcode & 0x00100000) {\ 1460 clockTicks++;\ 1461 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1462 }\ 1463 if(armState) {\ 1464 reg[15].I &= 0xFFFFFFFC;\ 1465 armNextPC = reg[15].I;\ 1466 reg[15].I += 4;\ 1467 } else {\ 1468 reg[15].I &= 0xFFFFFFFE;\ 1469 armNextPC = reg[15].I;\ 1470 reg[15].I += 2;\ 1471 }\ 1472 } else {\ 1473 OPCODE \ 1474 }\ 1475 }\ 1476 break; 1477 1478 #define LOGICAL_DATA_OPCODE_WITHOUT_base(OPCODE, OPCODE2, BASE) \ 1479 case BASE: \ 1480 case BASE+8:\ 1481 {\ 1482 /* OP Rd,Rb,Rm LSL # */ \ 1483 int shift = (opcode >> 7) & 0x1F;\ 1484 int dest = (opcode>>12) & 15;\ 1485 bool C_OUT = C_FLAG;\ 1486 u32 value;\ 1487 \ 1488 if(shift) {\ 1489 LOGICAL_LSL_REG\ 1490 } else {\ 1491 value = reg[opcode & 0x0F].I;\ 1492 }\ 1493 if(dest == 15) {\ 1494 OPCODE2\ 1495 /* todo */\ 1496 if(opcode & 0x00100000) {\ 1497 clockTicks++;\ 1498 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1499 }\ 1500 if(armState) {\ 1501 reg[15].I &= 0xFFFFFFFC;\ 1502 armNextPC = reg[15].I;\ 1503 reg[15].I += 4;\ 1504 } else {\ 1505 reg[15].I &= 0xFFFFFFFE;\ 1506 armNextPC = reg[15].I;\ 1507 reg[15].I += 2;\ 1508 }\ 1509 } else {\ 1510 OPCODE \ 1511 }\ 1512 }\ 1513 break;\ 1514 case BASE+2:\ 1515 case BASE+10:\ 1516 {\ 1517 /* OP Rd,Rb,Rm LSR # */ \ 1518 int shift = (opcode >> 7) & 0x1F;\ 1519 int dest = (opcode>>12) & 15;\ 1520 bool C_OUT = C_FLAG;\ 1521 u32 value;\ 1522 if(shift) {\ 1523 LOGICAL_LSR_REG\ 1524 } else {\ 1525 value = 0;\ 1526 C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false;\ 1527 }\ 1528 \ 1529 if(dest == 15) {\ 1530 OPCODE2\ 1531 /* todo */\ 1532 if(opcode & 0x00100000) {\ 1533 clockTicks++;\ 1534 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1535 }\ 1536 if(armState) {\ 1537 reg[15].I &= 0xFFFFFFFC;\ 1538 armNextPC = reg[15].I;\ 1539 reg[15].I += 4;\ 1540 } else {\ 1541 reg[15].I &= 0xFFFFFFFE;\ 1542 armNextPC = reg[15].I;\ 1543 reg[15].I += 2;\ 1544 }\ 1545 } else {\ 1546 OPCODE \ 1547 }\ 1548 }\ 1549 break;\ 1550 case BASE+4:\ 1551 case BASE+12:\ 1552 {\ 1553 /* OP Rd,Rb,Rm ASR # */\ 1554 int shift = (opcode >> 7) & 0x1F;\ 1555 int dest = (opcode>>12) & 15;\ 1556 bool C_OUT = C_FLAG;\ 1557 u32 value;\ 1558 if(shift) {\ 1559 LOGICAL_ASR_REG\ 1560 } else {\ 1561 if(reg[opcode & 0x0F].I & 0x80000000){\ 1562 value = 0xFFFFFFFF;\ 1563 C_OUT = true;\ 1564 } else {\ 1565 value = 0;\ 1566 C_OUT = false;\ 1567 } \ 1568 }\ 1569 \ 1570 if(dest == 15) {\ 1571 OPCODE2\ 1572 /* todo */\ 1573 if(opcode & 0x00100000) {\ 1574 clockTicks++;\ 1575 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1576 }\ 1577 if(armState) {\ 1578 reg[15].I &= 0xFFFFFFFC;\ 1579 armNextPC = reg[15].I;\ 1580 reg[15].I += 4;\ 1581 } else {\ 1582 reg[15].I &= 0xFFFFFFFE;\ 1583 armNextPC = reg[15].I;\ 1584 reg[15].I += 2;\ 1585 }\ 1586 } else {\ 1587 OPCODE \ 1588 }\ 1589 }\ 1590 break;\ 1591 case BASE+6:\ 1592 case BASE+14:\ 1593 {\ 1594 /* OP Rd,Rb,Rm ROR # */\ 1595 int shift = (opcode >> 7) & 0x1F;\ 1596 int dest = (opcode>>12) & 15;\ 1597 bool C_OUT = C_FLAG;\ 1598 u32 value;\ 1599 if(shift) {\ 1600 LOGICAL_ROR_REG\ 1601 } else {\ 1602 LOGICAL_RRX_REG\ 1603 }\ 1604 if(dest == 15) {\ 1605 OPCODE2\ 1606 /* todo */\ 1607 if(opcode & 0x00100000) {\ 1608 clockTicks++;\ 1609 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1610 }\ 1611 if(armState) {\ 1612 reg[15].I &= 0xFFFFFFFC;\ 1613 armNextPC = reg[15].I;\ 1614 reg[15].I += 4;\ 1615 } else {\ 1616 reg[15].I &= 0xFFFFFFFE;\ 1617 armNextPC = reg[15].I;\ 1618 reg[15].I += 2;\ 1619 }\ 1620 } else {\ 1621 OPCODE \ 1622 }\ 1623 }\ 1624 break;\ 1625 case BASE+1:\ 1626 {\ 1627 /* OP Rd,Rb,Rm LSL Rs */\ 1628 clockTicks++;\ 1629 int shift = reg[(opcode >> 8)&15].B.B0;\ 1630 int dest = (opcode>>12) & 15;\ 1631 bool C_OUT = C_FLAG;\ 1632 u32 value;\ 1633 if(shift) {\ 1634 if(shift == 32) {\ 1635 value = 0;\ 1636 C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false);\ 1637 } else if(shift < 32) {\ 1638 LOGICAL_LSL_REG\ 1639 } else {\ 1640 value = 0;\ 1641 C_OUT = false;\ 1642 }\ 1643 } else {\ 1644 value = reg[opcode & 0x0F].I;\ 1645 }\ 1646 if(dest == 15) {\ 1647 OPCODE2\ 1648 /* todo */\ 1649 if(opcode & 0x00100000) {\ 1650 clockTicks++;\ 1651 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1652 }\ 1653 if(armState) {\ 1654 reg[15].I &= 0xFFFFFFFC;\ 1655 armNextPC = reg[15].I;\ 1656 reg[15].I += 4;\ 1657 } else {\ 1658 reg[15].I &= 0xFFFFFFFE;\ 1659 armNextPC = reg[15].I;\ 1660 reg[15].I += 2;\ 1661 }\ 1662 } else {\ 1663 OPCODE \ 1664 }\ 1665 }\ 1666 break;\ 1667 case BASE+3:\ 1668 {\ 1669 /* OP Rd,Rb,Rm LSR Rs */ \ 1670 clockTicks++;\ 1671 int shift = reg[(opcode >> 8)&15].B.B0;\ 1672 int dest = (opcode>>12) & 15;\ 1673 bool C_OUT = C_FLAG;\ 1674 u32 value;\ 1675 if(shift) {\ 1676 if(shift == 32) {\ 1677 value = 0;\ 1678 C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false);\ 1679 } else if(shift < 32) {\ 1680 LOGICAL_LSR_REG\ 1681 } else {\ 1682 value = 0;\ 1683 C_OUT = false;\ 1684 }\ 1685 } else {\ 1686 value = reg[opcode & 0x0F].I;\ 1687 }\ 1688 if(dest == 15) {\ 1689 OPCODE2\ 1690 /* todo */\ 1691 if(opcode & 0x00100000) {\ 1692 clockTicks++;\ 1693 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1694 }\ 1695 if(armState) {\ 1696 reg[15].I &= 0xFFFFFFFC;\ 1697 armNextPC = reg[15].I;\ 1698 reg[15].I += 4;\ 1699 } else {\ 1700 reg[15].I &= 0xFFFFFFFE;\ 1701 armNextPC = reg[15].I;\ 1702 reg[15].I += 2;\ 1703 }\ 1704 } else {\ 1705 OPCODE \ 1706 }\ 1707 }\ 1708 break;\ 1709 case BASE+5:\ 1710 {\ 1711 /* OP Rd,Rb,Rm ASR Rs */ \ 1712 clockTicks++;\ 1713 int shift = reg[(opcode >> 8)&15].B.B0;\ 1714 int dest = (opcode>>12) & 15;\ 1715 bool C_OUT = C_FLAG;\ 1716 u32 value;\ 1717 if(shift < 32) {\ 1718 if(shift) {\ 1719 LOGICAL_ASR_REG\ 1720 } else {\ 1721 value = reg[opcode & 0x0F].I;\ 1722 }\ 1723 } else {\ 1724 if(reg[opcode & 0x0F].I & 0x80000000){\ 1725 value = 0xFFFFFFFF;\ 1726 C_OUT = true;\ 1727 } else {\ 1728 value = 0;\ 1729 C_OUT = false;\ 1730 }\ 1731 }\ 1732 if(dest == 15) {\ 1733 OPCODE2\ 1734 /* todo */\ 1735 if(opcode & 0x00100000) {\ 1736 clockTicks++;\ 1737 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1738 }\ 1739 if(armState) {\ 1740 reg[15].I &= 0xFFFFFFFC;\ 1741 armNextPC = reg[15].I;\ 1742 reg[15].I += 4;\ 1743 } else {\ 1744 reg[15].I &= 0xFFFFFFFE;\ 1745 armNextPC = reg[15].I;\ 1746 reg[15].I += 2;\ 1747 }\ 1748 } else {\ 1749 OPCODE \ 1750 }\ 1751 }\ 1752 break;\ 1753 case BASE+7:\ 1754 {\ 1755 /* OP Rd,Rb,Rm ROR Rs */\ 1756 clockTicks++;\ 1757 int shift = reg[(opcode >> 8)&15].B.B0;\ 1758 int dest = (opcode>>12) & 15;\ 1759 bool C_OUT = C_FLAG;\ 1760 u32 value;\ 1761 if(shift) {\ 1762 shift &= 0x1f;\ 1763 if(shift) {\ 1764 LOGICAL_ROR_REG\ 1765 } else {\ 1766 value = reg[opcode & 0x0F].I;\ 1767 C_OUT = (value & 0x80000000 ? true : false);\ 1768 }\ 1769 } else {\ 1770 value = reg[opcode & 0x0F].I;\ 1771 C_OUT = (value & 0x80000000 ? true : false);\ 1772 }\ 1773 if(dest == 15) {\ 1774 OPCODE2\ 1775 /* todo */\ 1776 if(opcode & 0x00100000) {\ 1777 clockTicks++;\ 1778 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1779 }\ 1780 if(armState) {\ 1781 reg[15].I &= 0xFFFFFFFC;\ 1782 armNextPC = reg[15].I;\ 1783 reg[15].I += 4;\ 1784 } else {\ 1785 reg[15].I &= 0xFFFFFFFE;\ 1786 armNextPC = reg[15].I;\ 1787 reg[15].I += 2;\ 1788 }\ 1789 } else {\ 1790 OPCODE \ 1791 }\ 1792 }\ 1793 break;\ 1794 case BASE+0x200:\ 1795 case BASE+0x201:\ 1796 case BASE+0x202:\ 1797 case BASE+0x203:\ 1798 case BASE+0x204:\ 1799 case BASE+0x205:\ 1800 case BASE+0x206:\ 1801 case BASE+0x207:\ 1802 case BASE+0x208:\ 1803 case BASE+0x209:\ 1804 case BASE+0x20a:\ 1805 case BASE+0x20b:\ 1806 case BASE+0x20c:\ 1807 case BASE+0x20d:\ 1808 case BASE+0x20e:\ 1809 case BASE+0x20f:\ 1810 {\ 1811 int shift = (opcode & 0xF00) >> 7;\ 1812 int dest = (opcode >> 12) & 0x0F;\ 1813 bool C_OUT = C_FLAG;\ 1814 u32 value;\ 1815 if(shift) {\ 1816 LOGICAL_ROR_IMM\ 1817 } else {\ 1818 value = opcode & 0xff;\ 1819 }\ 1820 if(dest == 15) {\ 1821 OPCODE2\ 1822 /* todo */\ 1823 if(opcode & 0x00100000) {\ 1824 clockTicks++;\ 1825 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1826 }\ 1827 if(armState) {\ 1828 reg[15].I &= 0xFFFFFFFC;\ 1829 armNextPC = reg[15].I;\ 1830 reg[15].I += 4;\ 1831 } else {\ 1832 reg[15].I &= 0xFFFFFFFE;\ 1833 armNextPC = reg[15].I;\ 1834 reg[15].I += 2;\ 1835 }\ 1836 } else {\ 1837 OPCODE \ 1838 }\ 1839 }\ 1840 break; 1841 1842 #define ARITHMETIC_DATA_OPCODE(OPCODE, OPCODE2, BASE) \ 1843 case BASE:\ 1844 case BASE+8:\ 1845 {\ 1846 /* OP Rd,Rb,Rm LSL # */\ 1847 int base = (opcode >> 16) & 0x0F;\ 1848 int shift = (opcode >> 7) & 0x1F;\ 1849 int dest = (opcode>>12) & 15;\ 1850 u32 value;\ 1851 if(shift) {\ 1852 ARITHMETIC_LSL_REG\ 1853 } else {\ 1854 value = reg[opcode & 0x0F].I;\ 1855 }\ 1856 if(dest == 15) {\ 1857 OPCODE2\ 1858 /* todo */\ 1859 if(opcode & 0x00100000) {\ 1860 clockTicks++;\ 1861 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1862 }\ 1863 if(armState) {\ 1864 reg[15].I &= 0xFFFFFFFC;\ 1865 armNextPC = reg[15].I;\ 1866 reg[15].I += 4;\ 1867 } else {\ 1868 reg[15].I &= 0xFFFFFFFE;\ 1869 armNextPC = reg[15].I;\ 1870 reg[15].I += 2;\ 1871 }\ 1872 } else {\ 1873 OPCODE \ 1874 }\ 1875 }\ 1876 break;\ 1877 case BASE+2:\ 1878 case BASE+10:\ 1879 {\ 1880 /* OP Rd,Rb,Rm LSR # */\ 1881 int base = (opcode >> 16) & 0x0F;\ 1882 int shift = (opcode >> 7) & 0x1F;\ 1883 int dest = (opcode>>12) & 15;\ 1884 u32 value;\ 1885 if(shift) {\ 1886 ARITHMETIC_LSR_REG\ 1887 } else {\ 1888 value = 0;\ 1889 }\ 1890 if(dest == 15) {\ 1891 OPCODE2\ 1892 /* todo */\ 1893 if(opcode & 0x00100000) {\ 1894 clockTicks++;\ 1895 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1896 }\ 1897 if(armState) {\ 1898 reg[15].I &= 0xFFFFFFFC;\ 1899 armNextPC = reg[15].I;\ 1900 reg[15].I += 4;\ 1901 } else {\ 1902 reg[15].I &= 0xFFFFFFFE;\ 1903 armNextPC = reg[15].I;\ 1904 reg[15].I += 2;\ 1905 }\ 1906 } else {\ 1907 OPCODE \ 1908 }\ 1909 }\ 1910 break;\ 1911 case BASE+4:\ 1912 case BASE+12:\ 1913 {\ 1914 /* OP Rd,Rb,Rm ASR # */\ 1915 int base = (opcode >> 16) & 0x0F;\ 1916 int shift = (opcode >> 7) & 0x1F;\ 1917 int dest = (opcode>>12) & 15;\ 1918 u32 value;\ 1919 if(shift) {\ 1920 ARITHMETIC_ASR_REG\ 1921 } else {\ 1922 if(reg[opcode & 0x0F].I & 0x80000000){\ 1923 value = 0xFFFFFFFF;\ 1924 } else value = 0;\ 1925 }\ 1926 if(dest == 15) {\ 1927 OPCODE2\ 1928 /* todo */\ 1929 if(opcode & 0x00100000) {\ 1930 clockTicks++;\ 1931 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1932 }\ 1933 if(armState) {\ 1934 reg[15].I &= 0xFFFFFFFC;\ 1935 armNextPC = reg[15].I;\ 1936 reg[15].I += 4;\ 1937 } else {\ 1938 reg[15].I &= 0xFFFFFFFE;\ 1939 armNextPC = reg[15].I;\ 1940 reg[15].I += 2;\ 1941 }\ 1942 } else {\ 1943 OPCODE \ 1944 }\ 1945 }\ 1946 break;\ 1947 case BASE+6:\ 1948 case BASE+14:\ 1949 {\ 1950 /* OP Rd,Rb,Rm ROR # */\ 1951 int base = (opcode >> 16) & 0x0F;\ 1952 int shift = (opcode >> 7) & 0x1F;\ 1953 int dest = (opcode>>12) & 15;\ 1954 u32 value;\ 1955 if(shift) {\ 1956 ARITHMETIC_ROR_REG\ 1957 } else {\ 1958 ARITHMETIC_RRX_REG\ 1959 }\ 1960 if(dest == 15) {\ 1961 OPCODE2\ 1962 /* todo */\ 1963 if(opcode & 0x00100000) {\ 1964 clockTicks++;\ 1965 CPUSwitchMode(reg[17].I & 0x1f, false);\ 1966 }\ 1967 if(armState) {\ 1968 reg[15].I &= 0xFFFFFFFC;\ 1969 armNextPC = reg[15].I;\ 1970 reg[15].I += 4;\ 1971 } else {\ 1972 reg[15].I &= 0xFFFFFFFE;\ 1973 armNextPC = reg[15].I;\ 1974 reg[15].I += 2;\ 1975 }\ 1976 } else {\ 1977 OPCODE \ 1978 }\ 1979 }\ 1980 break;\ 1981 case BASE+1:\ 1982 {\ 1983 /* OP Rd,Rb,Rm LSL Rs */\ 1984 clockTicks++;\ 1985 int base = (opcode >> 16) & 0x0F;\ 1986 int shift = reg[(opcode >> 8)&15].B.B0;\ 1987 int dest = (opcode>>12) & 15;\ 1988 u32 value;\ 1989 if(shift) {\ 1990 if(shift == 32) {\ 1991 value = 0;\ 1992 } else if(shift < 32) {\ 1993 ARITHMETIC_LSL_REG\ 1994 } else value = 0;\ 1995 } else {\ 1996 value = reg[opcode & 0x0F].I;\ 1997 }\ 1998 if(dest == 15) {\ 1999 OPCODE2\ 2000 /* todo */\ 2001 if(opcode & 0x00100000) {\ 2002 clockTicks++;\ 2003 CPUSwitchMode(reg[17].I & 0x1f, false);\ 2004 }\ 2005 if(armState) {\ 2006 reg[15].I &= 0xFFFFFFFC;\ 2007 armNextPC = reg[15].I;\ 2008 reg[15].I += 4;\ 2009 } else {\ 2010 reg[15].I &= 0xFFFFFFFE;\ 2011 armNextPC = reg[15].I;\ 2012 reg[15].I += 2;\ 2013 }\ 2014 } else {\ 2015 OPCODE \ 2016 }\ 2017 }\ 2018 break;\ 2019 case BASE+3:\ 2020 {\ 2021 /* OP Rd,Rb,Rm LSR Rs */\ 2022 clockTicks++;\ 2023 int base = (opcode >> 16) & 0x0F;\ 2024 int shift = reg[(opcode >> 8)&15].B.B0;\ 2025 int dest = (opcode>>12) & 15;\ 2026 u32 value;\ 2027 if(shift) {\ 2028 if(shift == 32) {\ 2029 value = 0;\ 2030 } else if(shift < 32) {\ 2031 ARITHMETIC_LSR_REG\ 2032 } else value = 0;\ 2033 } else {\ 2034 value = reg[opcode & 0x0F].I;\ 2035 }\ 2036 if(dest == 15) {\ 2037 OPCODE2\ 2038 /* todo */\ 2039 if(opcode & 0x00100000) {\ 2040 clockTicks++;\ 2041 CPUSwitchMode(reg[17].I & 0x1f, false);\ 2042 }\ 2043 if(armState) {\ 2044 reg[15].I &= 0xFFFFFFFC;\ 2045 armNextPC = reg[15].I;\ 2046 reg[15].I += 4;\ 2047 } else {\ 2048 reg[15].I &= 0xFFFFFFFE;\ 2049 armNextPC = reg[15].I;\ 2050 reg[15].I += 2;\ 2051 }\ 2052 } else {\ 2053 OPCODE \ 2054 }\ 2055 }\ 2056 break;\ 2057 case BASE+5:\ 2058 {\ 2059 /* OP Rd,Rb,Rm ASR Rs */\ 2060 clockTicks++;\ 2061 int base = (opcode >> 16) & 0x0F;\ 2062 int shift = reg[(opcode >> 8)&15].B.B0;\ 2063 int dest = (opcode>>12) & 15;\ 2064 u32 value;\ 2065 if(shift < 32) {\ 2066 if(shift) {\ 2067 ARITHMETIC_ASR_REG\ 2068 } else {\ 2069 value = reg[opcode & 0x0F].I;\ 2070 }\ 2071 } else {\ 2072 if(reg[opcode & 0x0F].I & 0x80000000){\ 2073 value = 0xFFFFFFFF;\ 2074 } else value = 0;\ 2075 }\ 2076 if(dest == 15) {\ 2077 OPCODE2\ 2078 /* todo */\ 2079 if(opcode & 0x00100000) {\ 2080 clockTicks++;\ 2081 CPUSwitchMode(reg[17].I & 0x1f, false);\ 2082 }\ 2083 if(armState) {\ 2084 reg[15].I &= 0xFFFFFFFC;\ 2085 armNextPC = reg[15].I;\ 2086 reg[15].I += 4;\ 2087 } else {\ 2088 reg[15].I &= 0xFFFFFFFE;\ 2089 armNextPC = reg[15].I;\ 2090 reg[15].I += 2;\ 2091 }\ 2092 } else {\ 2093 OPCODE \ 2094 }\ 2095 }\ 2096 break;\ 2097 case BASE+7:\ 2098 {\ 2099 /* OP Rd,Rb,Rm ROR Rs */\ 2100 clockTicks++;\ 2101 int base = (opcode >> 16) & 0x0F;\ 2102 int shift = reg[(opcode >> 8)&15].B.B0;\ 2103 int dest = (opcode>>12) & 15;\ 2104 u32 value;\ 2105 if(shift) {\ 2106 shift &= 0x1f;\ 2107 if(shift) {\ 2108 ARITHMETIC_ROR_REG\ 2109 } else {\ 2110 value = reg[opcode & 0x0F].I;\ 2111 }\ 2112 } else {\ 2113 value = reg[opcode & 0x0F].I;\ 2114 }\ 2115 if(dest == 15) {\ 2116 OPCODE2\ 2117 /* todo */\ 2118 if(opcode & 0x00100000) {\ 2119 clockTicks++;\ 2120 CPUSwitchMode(reg[17].I & 0x1f, false);\ 2121 }\ 2122 if(armState) {\ 2123 reg[15].I &= 0xFFFFFFFC;\ 2124 armNextPC = reg[15].I;\ 2125 reg[15].I += 4;\ 2126 } else {\ 2127 reg[15].I &= 0xFFFFFFFE;\ 2128 armNextPC = reg[15].I;\ 2129 reg[15].I += 2;\ 2130 }\ 2131 } else {\ 2132 OPCODE \ 2133 }\ 2134 }\ 2135 break;\ 2136 case BASE+0x200:\ 2137 case BASE+0x201:\ 2138 case BASE+0x202:\ 2139 case BASE+0x203:\ 2140 case BASE+0x204:\ 2141 case BASE+0x205:\ 2142 case BASE+0x206:\ 2143 case BASE+0x207:\ 2144 case BASE+0x208:\ 2145 case BASE+0x209:\ 2146 case BASE+0x20a:\ 2147 case BASE+0x20b:\ 2148 case BASE+0x20c:\ 2149 case BASE+0x20d:\ 2150 case BASE+0x20e:\ 2151 case BASE+0x20f:\ 2152 {\ 2153 int shift = (opcode & 0xF00) >> 7;\ 2154 int base = (opcode >> 16) & 0x0F;\ 2155 int dest = (opcode >> 12) & 0x0F;\ 2156 u32 value;\ 2157 {\ 2158 ARITHMETIC_ROR_IMM\ 2159 }\ 2160 if(dest == 15) {\ 2161 OPCODE2\ 2162 /* todo */\ 2163 if(opcode & 0x00100000) {\ 2164 clockTicks++;\ 2165 CPUSwitchMode(reg[17].I & 0x1f, false);\ 2166 }\ 2167 if(armState) {\ 2168 reg[15].I &= 0xFFFFFFFC;\ 2169 armNextPC = reg[15].I;\ 2170 reg[15].I += 4;\ 2171 } else {\ 2172 reg[15].I &= 0xFFFFFFFE;\ 2173 armNextPC = reg[15].I;\ 2174 reg[15].I += 2;\ 2175 }\ 2176 } else {\ 2177 OPCODE \ 2178 }\ 2179 }\ 2180 break; 2181 2182 u32 opcode = CPUReadMemoryQuick(armNextPC); 2183 2184 clockTicks = memoryWaitFetch32[(armNextPC >> 24) & 15]; 2185 2186 #ifndef FINAL_VERSION 2187 if(armNextPC == stop) { 2188 armNextPC++; 2189 } 2190 #endif 2191 2192 armNextPC = reg[15].I; 2193 reg[15].I += 4; 2194 int cond = opcode >> 28; 2195 // suggested optimization for frequent cases 2196 bool cond_res; 2197 if(cond == 0x0e) { 2198 cond_res = true; 2199 } else { 2200 switch(cond) { 2201 case 0x00: // EQ 2202 cond_res = Z_FLAG; 2203 break; 2204 case 0x01: // NE 2205 cond_res = !Z_FLAG; 2206 break; 2207 case 0x02: // CS 2208 cond_res = C_FLAG; 2209 break; 2210 case 0x03: // CC 2211 cond_res = !C_FLAG; 2212 break; 2213 case 0x04: // MI 2214 cond_res = N_FLAG; 2215 break; 2216 case 0x05: // PL 2217 cond_res = !N_FLAG; 2218 break; 2219 case 0x06: // VS 2220 cond_res = V_FLAG; 2221 break; 2222 case 0x07: // VC 2223 cond_res = !V_FLAG; 2224 break; 2225 case 0x08: // HI 2226 cond_res = C_FLAG && !Z_FLAG; 2227 break; 2228 case 0x09: // LS 2229 cond_res = !C_FLAG || Z_FLAG; 2230 break; 2231 case 0x0A: // GE 2232 cond_res = N_FLAG == V_FLAG; 2233 break; 2234 case 0x0B: // LT 2235 cond_res = N_FLAG != V_FLAG; 2236 break; 2237 case 0x0C: // GT 2238 cond_res = !Z_FLAG &&(N_FLAG == V_FLAG); 2239 break; 2240 case 0x0D: // LE 2241 cond_res = Z_FLAG || (N_FLAG != V_FLAG); 2242 break; 2243 case 0x0E: 2244 cond_res = true; 2245 break; 2246 case 0x0F: 2247 default: 2248 // ??? 2249 cond_res = false; 2250 break; 2251 } 2252 } 2253 2254 if(cond_res) { 2255 switch(((opcode>>16)&0xFF0) | ((opcode>>4)&0x0F)) { 2256 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_AND, OP_AND, 0x000); 2257 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_ANDS, OP_AND, 0x010); 2258 case 0x009: 2259 { 2260 // MUL Rd, Rm, Rs 2261 int dest = (opcode >> 16) & 0x0F; 2262 int mult = (opcode & 0x0F); 2263 u32 rs = reg[(opcode >> 8) & 0x0F].I; 2264 reg[dest].I = reg[mult].I * rs; 2265 if(((s32)rs)<0) 2266 rs = ~rs; 2267 if((rs & 0xFFFFFF00) == 0) 2268 clockTicks += 2; 2269 else if ((rs & 0xFFFF0000) == 0) 2270 clockTicks += 3; 2271 else if ((rs & 0xFF000000) == 0) 2272 clockTicks += 4; 2273 else 2274 clockTicks += 5; 2275 } 2276 break; 2277 case 0x019: 2278 { 2279 // MULS Rd, Rm, Rs 2280 int dest = (opcode >> 16) & 0x0F; 2281 int mult = (opcode & 0x0F); 2282 u32 rs = reg[(opcode >> 8) & 0x0F].I; 2283 reg[dest].I = reg[mult].I * rs; 2284 N_FLAG = (reg[dest].I & 0x80000000) ? true : false; 2285 Z_FLAG = (reg[dest].I) ? false : true; 2286 if(((s32)rs)<0) 2287 rs = ~rs; 2288 if((rs & 0xFFFFFF00) == 0) 2289 clockTicks += 2; 2290 else if ((rs & 0xFFFF0000) == 0) 2291 clockTicks += 3; 2292 else if ((rs & 0xFF000000) == 0) 2293 clockTicks += 4; 2294 else 2295 clockTicks += 5; 2296 } 2297 break; 2298 case 0x00b: 2299 case 0x02b: 2300 { 2301 // STRH Rd, [Rn], -Rm 2302 int base = (opcode >> 16) & 0x0F; 2303 int dest = (opcode >> 12) & 0x0F; 2304 u32 address = reg[base].I; 2305 int offset = reg[opcode & 0x0F].I; 2306 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2307 CPUWriteHalfWord(address, reg[dest].W.W0); 2308 address -= offset; 2309 reg[base].I = address; 2310 } 2311 break; 2312 case 0x04b: 2313 case 0x06b: 2314 { 2315 // STRH Rd, [Rn], #-offset 2316 int base = (opcode >> 16) & 0x0F; 2317 int dest = (opcode >> 12) & 0x0F; 2318 u32 address = reg[base].I; 2319 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 2320 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2321 CPUWriteHalfWord(address, reg[dest].W.W0); 2322 address -= offset; 2323 reg[base].I = address; 2324 } 2325 break; 2326 case 0x08b: 2327 case 0x0ab: 2328 { 2329 // STRH Rd, [Rn], Rm 2330 int base = (opcode >> 16) & 0x0F; 2331 int dest = (opcode >> 12) & 0x0F; 2332 u32 address = reg[base].I; 2333 int offset = reg[opcode & 0x0F].I; 2334 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2335 CPUWriteHalfWord(address, reg[dest].W.W0); 2336 address += offset; 2337 reg[base].I = address; 2338 } 2339 break; 2340 case 0x0cb: 2341 case 0x0eb: 2342 { 2343 // STRH Rd, [Rn], #offset 2344 int base = (opcode >> 16) & 0x0F; 2345 int dest = (opcode >> 12) & 0x0F; 2346 u32 address = reg[base].I; 2347 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 2348 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2349 CPUWriteHalfWord(address, reg[dest].W.W0); 2350 address += offset; 2351 reg[base].I = address; 2352 } 2353 break; 2354 case 0x10b: 2355 { 2356 // STRH Rd, [Rn, -Rm] 2357 int base = (opcode >> 16) & 0x0F; 2358 int dest = (opcode >> 12) & 0x0F; 2359 u32 address = reg[base].I - reg[opcode & 0x0F].I; 2360 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2361 CPUWriteHalfWord(address, reg[dest].W.W0); 2362 } 2363 break; 2364 case 0x12b: 2365 { 2366 // STRH Rd, [Rn, -Rm]! 2367 int base = (opcode >> 16) & 0x0F; 2368 int dest = (opcode >> 12) & 0x0F; 2369 u32 address = reg[base].I - reg[opcode & 0x0F].I; 2370 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2371 CPUWriteHalfWord(address, reg[dest].W.W0); 2372 reg[base].I = address; 2373 } 2374 break; 2375 case 0x14b: 2376 { 2377 // STRH Rd, [Rn, -#offset] 2378 int base = (opcode >> 16) & 0x0F; 2379 int dest = (opcode >> 12) & 0x0F; 2380 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2381 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2382 CPUWriteHalfWord(address, reg[dest].W.W0); 2383 } 2384 break; 2385 case 0x16b: 2386 { 2387 // STRH Rd, [Rn, -#offset]! 2388 int base = (opcode >> 16) & 0x0F; 2389 int dest = (opcode >> 12) & 0x0F; 2390 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2391 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2392 CPUWriteHalfWord(address, reg[dest].W.W0); 2393 reg[base].I = address; 2394 } 2395 break; 2396 case 0x18b: 2397 { 2398 // STRH Rd, [Rn, Rm] 2399 int base = (opcode >> 16) & 0x0F; 2400 int dest = (opcode >> 12) & 0x0F; 2401 u32 address = reg[base].I + reg[opcode & 0x0F].I; 2402 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2403 CPUWriteHalfWord(address, reg[dest].W.W0); 2404 } 2405 break; 2406 case 0x1ab: 2407 { 2408 // STRH Rd, [Rn, Rm]! 2409 int base = (opcode >> 16) & 0x0F; 2410 int dest = (opcode >> 12) & 0x0F; 2411 u32 address = reg[base].I + reg[opcode & 0x0F].I; 2412 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2413 CPUWriteHalfWord(address, reg[dest].W.W0); 2414 reg[base].I = address; 2415 } 2416 break; 2417 case 0x1cb: 2418 { 2419 // STRH Rd, [Rn, #offset] 2420 int base = (opcode >> 16) & 0x0F; 2421 int dest = (opcode >> 12) & 0x0F; 2422 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2423 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2424 CPUWriteHalfWord(address, reg[dest].W.W0); 2425 } 2426 break; 2427 case 0x1eb: 2428 { 2429 // STRH Rd, [Rn, #offset]! 2430 int base = (opcode >> 16) & 0x0F; 2431 int dest = (opcode >> 12) & 0x0F; 2432 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2433 clockTicks += 4 + CPUUpdateTicksAccess16(address); 2434 CPUWriteHalfWord(address, reg[dest].W.W0); 2435 reg[base].I = address; 2436 } 2437 break; 2438 case 0x01b: 2439 case 0x03b: 2440 { 2441 // LDRH Rd, [Rn], -Rm 2442 int base = (opcode >> 16) & 0x0F; 2443 int dest = (opcode >> 12) & 0x0F; 2444 u32 address = reg[base].I; 2445 int offset = reg[opcode & 0x0F].I; 2446 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2447 reg[dest].I = CPUReadHalfWord(address); 2448 if(dest != base) { 2449 address -= offset; 2450 reg[base].I = address; 2451 } 2452 } 2453 break; 2454 case 0x05b: 2455 case 0x07b: 2456 { 2457 // LDRH Rd, [Rn], #-offset 2458 int base = (opcode >> 16) & 0x0F; 2459 int dest = (opcode >> 12) & 0x0F; 2460 u32 address = reg[base].I; 2461 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 2462 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2463 reg[dest].I = CPUReadHalfWord(address); 2464 if(dest != base) { 2465 address -= offset; 2466 reg[base].I = address; 2467 } 2468 } 2469 break; 2470 case 0x09b: 2471 case 0x0bb: 2472 { 2473 // LDRH Rd, [Rn], Rm 2474 int base = (opcode >> 16) & 0x0F; 2475 int dest = (opcode >> 12) & 0x0F; 2476 u32 address = reg[base].I; 2477 int offset = reg[opcode & 0x0F].I; 2478 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2479 reg[dest].I = CPUReadHalfWord(address); 2480 if(dest != base) { 2481 address += offset; 2482 reg[base].I = address; 2483 } 2484 } 2485 break; 2486 case 0x0db: 2487 case 0x0fb: 2488 { 2489 // LDRH Rd, [Rn], #offset 2490 int base = (opcode >> 16) & 0x0F; 2491 int dest = (opcode >> 12) & 0x0F; 2492 u32 address = reg[base].I; 2493 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 2494 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2495 reg[dest].I = CPUReadHalfWord(address); 2496 if(dest != base) { 2497 address += offset; 2498 reg[base].I = address; 2499 } 2500 } 2501 break; 2502 case 0x11b: 2503 { 2504 // LDRH Rd, [Rn, -Rm] 2505 int base = (opcode >> 16) & 0x0F; 2506 int dest = (opcode >> 12) & 0x0F; 2507 u32 address = reg[base].I - reg[opcode & 0x0F].I; 2508 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2509 reg[dest].I = CPUReadHalfWord(address); 2510 } 2511 break; 2512 case 0x13b: 2513 { 2514 // LDRH Rd, [Rn, -Rm]! 2515 int base = (opcode >> 16) & 0x0F; 2516 int dest = (opcode >> 12) & 0x0F; 2517 u32 address = reg[base].I - reg[opcode & 0x0F].I; 2518 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2519 reg[dest].I = CPUReadHalfWord(address); 2520 if(dest != base) 2521 reg[base].I = address; 2522 } 2523 break; 2524 case 0x15b: 2525 { 2526 // LDRH Rd, [Rn, -#offset] 2527 int base = (opcode >> 16) & 0x0F; 2528 int dest = (opcode >> 12) & 0x0F; 2529 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2530 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2531 reg[dest].I = CPUReadHalfWord(address); 2532 } 2533 break; 2534 case 0x17b: 2535 { 2536 // LDRH Rd, [Rn, -#offset]! 2537 int base = (opcode >> 16) & 0x0F; 2538 int dest = (opcode >> 12) & 0x0F; 2539 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2540 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2541 reg[dest].I = CPUReadHalfWord(address); 2542 if(dest != base) 2543 reg[base].I = address; 2544 } 2545 break; 2546 case 0x19b: 2547 { 2548 // LDRH Rd, [Rn, Rm] 2549 int base = (opcode >> 16) & 0x0F; 2550 int dest = (opcode >> 12) & 0x0F; 2551 u32 address = reg[base].I + reg[opcode & 0x0F].I; 2552 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2553 reg[dest].I = CPUReadHalfWord(address); 2554 } 2555 break; 2556 case 0x1bb: 2557 { 2558 // LDRH Rd, [Rn, Rm]! 2559 int base = (opcode >> 16) & 0x0F; 2560 int dest = (opcode >> 12) & 0x0F; 2561 u32 address = reg[base].I + reg[opcode & 0x0F].I; 2562 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2563 reg[dest].I = CPUReadHalfWord(address); 2564 if(dest != base) 2565 reg[base].I = address; 2566 } 2567 break; 2568 case 0x1db: 2569 { 2570 // LDRH Rd, [Rn, #offset] 2571 int base = (opcode >> 16) & 0x0F; 2572 int dest = (opcode >> 12) & 0x0F; 2573 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2574 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2575 reg[dest].I = CPUReadHalfWord(address); 2576 } 2577 break; 2578 case 0x1fb: 2579 { 2580 // LDRH Rd, [Rn, #offset]! 2581 int base = (opcode >> 16) & 0x0F; 2582 int dest = (opcode >> 12) & 0x0F; 2583 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2584 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2585 reg[dest].I = CPUReadHalfWord(address); 2586 if(dest != base) 2587 reg[base].I = address; 2588 } 2589 break; 2590 case 0x01d: 2591 case 0x03d: 2592 { 2593 // LDRSB Rd, [Rn], -Rm 2594 int base = (opcode >> 16) & 0x0F; 2595 int dest = (opcode >> 12) & 0x0F; 2596 u32 address = reg[base].I; 2597 int offset = reg[opcode & 0x0F].I; 2598 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2599 reg[dest].I = (s8)CPUReadByte(address); 2600 if(dest != base) { 2601 address -= offset; 2602 reg[base].I = address; 2603 } 2604 } 2605 break; 2606 case 0x05d: 2607 case 0x07d: 2608 { 2609 // LDRSB Rd, [Rn], #-offset 2610 int base = (opcode >> 16) & 0x0F; 2611 int dest = (opcode >> 12) & 0x0F; 2612 u32 address = reg[base].I; 2613 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 2614 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2615 reg[dest].I = (s8)CPUReadByte(address); 2616 if(dest != base) { 2617 address -= offset; 2618 reg[base].I = address; 2619 } 2620 } 2621 break; 2622 case 0x09d: 2623 case 0x0bd: 2624 { 2625 // LDRSB Rd, [Rn], Rm 2626 int base = (opcode >> 16) & 0x0F; 2627 int dest = (opcode >> 12) & 0x0F; 2628 u32 address = reg[base].I; 2629 int offset = reg[opcode & 0x0F].I; 2630 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2631 reg[dest].I = (s8)CPUReadByte(address); 2632 if(dest != base) { 2633 address += offset; 2634 reg[base].I = address; 2635 } 2636 } 2637 break; 2638 case 0x0dd: 2639 case 0x0fd: 2640 { 2641 // LDRSB Rd, [Rn], #offset 2642 int base = (opcode >> 16) & 0x0F; 2643 int dest = (opcode >> 12) & 0x0F; 2644 u32 address = reg[base].I; 2645 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 2646 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2647 reg[dest].I = (s8)CPUReadByte(address); 2648 if(dest != base) { 2649 address += offset; 2650 reg[base].I = address; 2651 } 2652 } 2653 break; 2654 case 0x11d: 2655 { 2656 // LDRSB Rd, [Rn, -Rm] 2657 int base = (opcode >> 16) & 0x0F; 2658 int dest = (opcode >> 12) & 0x0F; 2659 u32 address = reg[base].I - reg[opcode & 0x0F].I; 2660 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2661 reg[dest].I = (s8)CPUReadByte(address); 2662 } 2663 break; 2664 case 0x13d: 2665 { 2666 // LDRSB Rd, [Rn, -Rm]! 2667 int base = (opcode >> 16) & 0x0F; 2668 int dest = (opcode >> 12) & 0x0F; 2669 u32 address = reg[base].I - reg[opcode & 0x0F].I; 2670 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2671 reg[dest].I = (s8)CPUReadByte(address); 2672 if(dest != base) 2673 reg[base].I = address; 2674 } 2675 break; 2676 case 0x15d: 2677 { 2678 // LDRSB Rd, [Rn, -#offset] 2679 int base = (opcode >> 16) & 0x0F; 2680 int dest = (opcode >> 12) & 0x0F; 2681 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2682 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2683 reg[dest].I = (s8)CPUReadByte(address); 2684 } 2685 break; 2686 case 0x17d: 2687 { 2688 // LDRSB Rd, [Rn, -#offset]! 2689 int base = (opcode >> 16) & 0x0F; 2690 int dest = (opcode >> 12) & 0x0F; 2691 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2692 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2693 reg[dest].I = (s8)CPUReadByte(address); 2694 if(dest != base) 2695 reg[base].I = address; 2696 } 2697 break; 2698 case 0x19d: 2699 { 2700 // LDRSB Rd, [Rn, Rm] 2701 int base = (opcode >> 16) & 0x0F; 2702 int dest = (opcode >> 12) & 0x0F; 2703 u32 address = reg[base].I + reg[opcode & 0x0F].I; 2704 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2705 reg[dest].I = (s8)CPUReadByte(address); 2706 } 2707 break; 2708 case 0x1bd: 2709 { 2710 // LDRSB Rd, [Rn, Rm]! 2711 int base = (opcode >> 16) & 0x0F; 2712 int dest = (opcode >> 12) & 0x0F; 2713 u32 address = reg[base].I + reg[opcode & 0x0F].I; 2714 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2715 reg[dest].I = (s8)CPUReadByte(address); 2716 if(dest != base) 2717 reg[base].I = address; 2718 } 2719 break; 2720 case 0x1dd: 2721 { 2722 // LDRSB Rd, [Rn, #offset] 2723 int base = (opcode >> 16) & 0x0F; 2724 int dest = (opcode >> 12) & 0x0F; 2725 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2726 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2727 reg[dest].I = (s8)CPUReadByte(address); 2728 } 2729 break; 2730 case 0x1fd: 2731 { 2732 // LDRSB Rd, [Rn, #offset]! 2733 int base = (opcode >> 16) & 0x0F; 2734 int dest = (opcode >> 12) & 0x0F; 2735 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2736 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2737 reg[dest].I = (s8)CPUReadByte(address); 2738 if(dest != base) 2739 reg[base].I = address; 2740 } 2741 break; 2742 case 0x01f: 2743 case 0x03f: 2744 { 2745 // LDRSH Rd, [Rn], -Rm 2746 int base = (opcode >> 16) & 0x0F; 2747 int dest = (opcode >> 12) & 0x0F; 2748 u32 address = reg[base].I; 2749 int offset = reg[opcode & 0x0F].I; 2750 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2751 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2752 if(dest != base) { 2753 address -= offset; 2754 reg[base].I = address; 2755 } 2756 } 2757 break; 2758 case 0x05f: 2759 case 0x07f: 2760 { 2761 // LDRSH Rd, [Rn], #-offset 2762 int base = (opcode >> 16) & 0x0F; 2763 int dest = (opcode >> 12) & 0x0F; 2764 u32 address = reg[base].I; 2765 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 2766 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2767 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2768 if(dest != base) { 2769 address -= offset; 2770 reg[base].I = address; 2771 } 2772 } 2773 break; 2774 case 0x09f: 2775 case 0x0bf: 2776 { 2777 // LDRSH Rd, [Rn], Rm 2778 int base = (opcode >> 16) & 0x0F; 2779 int dest = (opcode >> 12) & 0x0F; 2780 u32 address = reg[base].I; 2781 int offset = reg[opcode & 0x0F].I; 2782 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2783 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2784 if(dest != base) { 2785 address += offset; 2786 reg[base].I = address; 2787 } 2788 } 2789 break; 2790 case 0x0df: 2791 case 0x0ff: 2792 { 2793 // LDRSH Rd, [Rn], #offset 2794 int base = (opcode >> 16) & 0x0F; 2795 int dest = (opcode >> 12) & 0x0F; 2796 u32 address = reg[base].I; 2797 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0); 2798 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2799 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2800 if(dest != base) { 2801 address += offset; 2802 reg[base].I = address; 2803 } 2804 } 2805 break; 2806 case 0x11f: 2807 { 2808 // LDRSH Rd, [Rn, -Rm] 2809 int base = (opcode >> 16) & 0x0F; 2810 int dest = (opcode >> 12) & 0x0F; 2811 u32 address = reg[base].I - reg[opcode & 0x0F].I; 2812 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2813 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2814 } 2815 break; 2816 case 0x13f: 2817 { 2818 // LDRSH Rd, [Rn, -Rm]! 2819 int base = (opcode >> 16) & 0x0F; 2820 int dest = (opcode >> 12) & 0x0F; 2821 u32 address = reg[base].I - reg[opcode & 0x0F].I; 2822 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2823 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2824 if(dest != base) 2825 reg[base].I = address; 2826 } 2827 break; 2828 case 0x15f: 2829 { 2830 // LDRSH Rd, [Rn, -#offset] 2831 int base = (opcode >> 16) & 0x0F; 2832 int dest = (opcode >> 12) & 0x0F; 2833 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2834 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2835 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2836 } 2837 break; 2838 case 0x17f: 2839 { 2840 // LDRSH Rd, [Rn, -#offset]! 2841 int base = (opcode >> 16) & 0x0F; 2842 int dest = (opcode >> 12) & 0x0F; 2843 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2844 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2845 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2846 if(dest != base) 2847 reg[base].I = address; 2848 } 2849 break; 2850 case 0x19f: 2851 { 2852 // LDRSH Rd, [Rn, Rm] 2853 int base = (opcode >> 16) & 0x0F; 2854 int dest = (opcode >> 12) & 0x0F; 2855 u32 address = reg[base].I + reg[opcode & 0x0F].I; 2856 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2857 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2858 } 2859 break; 2860 case 0x1bf: 2861 { 2862 // LDRSH Rd, [Rn, Rm]! 2863 int base = (opcode >> 16) & 0x0F; 2864 int dest = (opcode >> 12) & 0x0F; 2865 u32 address = reg[base].I + reg[opcode & 0x0F].I; 2866 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2867 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2868 if(dest != base) 2869 reg[base].I = address; 2870 } 2871 break; 2872 case 0x1df: 2873 { 2874 // LDRSH Rd, [Rn, #offset] 2875 int base = (opcode >> 16) & 0x0F; 2876 int dest = (opcode >> 12) & 0x0F; 2877 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2878 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2879 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2880 } 2881 break; 2882 case 0x1ff: 2883 { 2884 // LDRSH Rd, [Rn, #offset]! 2885 int base = (opcode >> 16) & 0x0F; 2886 int dest = (opcode >> 12) & 0x0F; 2887 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0)); 2888 clockTicks += 3 + CPUUpdateTicksAccess16(address); 2889 reg[dest].I = (s16)CPUReadHalfWordSigned(address); 2890 if(dest != base) 2891 reg[base].I = address; 2892 } 2893 break; 2894 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EOR, OP_EOR, 0x020); 2895 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EORS, OP_EOR, 0x030); 2896 case 0x029: 2897 { 2898 // MLA Rd, Rm, Rs, Rn 2899 int dest = (opcode >> 16) & 0x0F; 2900 int mult = (opcode & 0x0F); 2901 u32 rs = reg[(opcode >> 8) & 0x0F].I; 2902 reg[dest].I = reg[mult].I * rs + reg[(opcode>>12)&0x0f].I; 2903 if(((s32)rs)<0) 2904 rs = ~rs; 2905 if((rs & 0xFFFFFF00) == 0) 2906 clockTicks += 3; 2907 else if ((rs & 0xFFFF0000) == 0) 2908 clockTicks += 4; 2909 else if ((rs & 0xFF000000) == 0) 2910 clockTicks += 5; 2911 else 2912 clockTicks += 6; 2913 } 2914 break; 2915 case 0x039: 2916 { 2917 // MLAS Rd, Rm, Rs, Rn 2918 int dest = (opcode >> 16) & 0x0F; 2919 int mult = (opcode & 0x0F); 2920 u32 rs = reg[(opcode >> 8) & 0x0F].I; 2921 reg[dest].I = reg[mult].I * rs + reg[(opcode>>12)&0x0f].I; 2922 N_FLAG = (reg[dest].I & 0x80000000) ? true : false; 2923 Z_FLAG = (reg[dest].I) ? false : true; 2924 if(((s32)rs)<0) 2925 rs = ~rs; 2926 if((rs & 0xFFFFFF00) == 0) 2927 clockTicks += 3; 2928 else if ((rs & 0xFFFF0000) == 0) 2929 clockTicks += 4; 2930 else if ((rs & 0xFF000000) == 0) 2931 clockTicks += 5; 2932 else 2933 clockTicks += 6; 2934 } 2935 break; 2936 ARITHMETIC_DATA_OPCODE(OP_SUB, OP_SUB, 0x040); 2937 ARITHMETIC_DATA_OPCODE(OP_SUBS, OP_SUB, 0x050); 2938 ARITHMETIC_DATA_OPCODE(OP_RSB, OP_RSB, 0x060); 2939 ARITHMETIC_DATA_OPCODE(OP_RSBS, OP_RSB, 0x070); 2940 ARITHMETIC_DATA_OPCODE(OP_ADD, OP_ADD, 0x080); 2941 ARITHMETIC_DATA_OPCODE(OP_ADDS, OP_ADD, 0x090); 2942 case 0x089: 2943 { 2944 // UMULL RdLo, RdHi, Rn, Rs 2945 u32 umult = reg[(opcode & 0x0F)].I; 2946 u32 usource = reg[(opcode >> 8) & 0x0F].I; 2947 int destLo = (opcode >> 12) & 0x0F; 2948 int destHi = (opcode >> 16) & 0x0F; 2949 u64 uTemp = ((u64)umult)*((u64)usource); 2950 reg[destLo].I = (u32)uTemp; 2951 reg[destHi].I = (u32)(uTemp >> 32); 2952 if ((usource & 0xFFFFFF00) == 0) 2953 clockTicks += 2; 2954 else if ((usource & 0xFFFF0000) == 0) 2955 clockTicks += 3; 2956 else if ((usource & 0xFF000000) == 0) 2957 clockTicks += 4; 2958 else 2959 clockTicks += 5; 2960 } 2961 break; 2962 case 0x099: 2963 { 2964 // UMULLS RdLo, RdHi, Rn, Rs 2965 u32 umult = reg[(opcode & 0x0F)].I; 2966 u32 usource = reg[(opcode >> 8) & 0x0F].I; 2967 int destLo = (opcode >> 12) & 0x0F; 2968 int destHi = (opcode >> 16) & 0x0F; 2969 u64 uTemp = ((u64)umult)*((u64)usource); 2970 reg[destLo].I = (u32)uTemp; 2971 reg[destHi].I = (u32)(uTemp >> 32); 2972 Z_FLAG = (uTemp) ? false : true; 2973 N_FLAG = (reg[destHi].I & 0x80000000) ? true : false; 2974 if ((usource & 0xFFFFFF00) == 0) 2975 clockTicks += 2; 2976 else if ((usource & 0xFFFF0000) == 0) 2977 clockTicks += 3; 2978 else if ((usource & 0xFF000000) == 0) 2979 clockTicks += 4; 2980 else 2981 clockTicks += 5; 2982 } 2983 break; 2984 ARITHMETIC_DATA_OPCODE(OP_ADC, OP_ADC, 0x0a0); 2985 ARITHMETIC_DATA_OPCODE(OP_ADCS, OP_ADC, 0x0b0); 2986 case 0x0a9: 2987 { 2988 // UMLAL RdLo, RdHi, Rn, Rs 2989 u32 umult = reg[(opcode & 0x0F)].I; 2990 u32 usource = reg[(opcode >> 8) & 0x0F].I; 2991 int destLo = (opcode >> 12) & 0x0F; 2992 int destHi = (opcode >> 16) & 0x0F; 2993 u64 uTemp = (u64)reg[destHi].I; 2994 uTemp <<= 32; 2995 uTemp |= (u64)reg[destLo].I; 2996 uTemp += ((u64)umult)*((u64)usource); 2997 reg[destLo].I = (u32)uTemp; 2998 reg[destHi].I = (u32)(uTemp >> 32); 2999 if ((usource & 0xFFFFFF00) == 0) 3000 clockTicks += 3; 3001 else if ((usource & 0xFFFF0000) == 0) 3002 clockTicks += 4; 3003 else if ((usource & 0xFF000000) == 0) 3004 clockTicks += 5; 3005 else 3006 clockTicks += 6; 3007 } 3008 break; 3009 case 0x0b9: 3010 { 3011 // UMLALS RdLo, RdHi, Rn, Rs 3012 u32 umult = reg[(opcode & 0x0F)].I; 3013 u32 usource = reg[(opcode >> 8) & 0x0F].I; 3014 int destLo = (opcode >> 12) & 0x0F; 3015 int destHi = (opcode >> 16) & 0x0F; 3016 u64 uTemp = (u64)reg[destHi].I; 3017 uTemp <<= 32; 3018 uTemp |= (u64)reg[destLo].I; 3019 uTemp += ((u64)umult)*((u64)usource); 3020 reg[destLo].I = (u32)uTemp; 3021 reg[destHi].I = (u32)(uTemp >> 32); 3022 Z_FLAG = (uTemp) ? false : true; 3023 N_FLAG = (reg[destHi].I & 0x80000000) ? true : false; 3024 if ((usource & 0xFFFFFF00) == 0) 3025 clockTicks += 3; 3026 else if ((usource & 0xFFFF0000) == 0) 3027 clockTicks += 4; 3028 else if ((usource & 0xFF000000) == 0) 3029 clockTicks += 5; 3030 else 3031 clockTicks += 6; 3032 } 3033 break; 3034 ARITHMETIC_DATA_OPCODE(OP_SBC, OP_SBC, 0x0c0); 3035 ARITHMETIC_DATA_OPCODE(OP_SBCS, OP_SBC, 0x0d0); 3036 case 0x0c9: 3037 { 3038 // SMULL RdLo, RdHi, Rm, Rs 3039 int destLo = (opcode >> 12) & 0x0F; 3040 int destHi = (opcode >> 16) & 0x0F; 3041 u32 rs = reg[(opcode >> 8) & 0x0F].I; 3042 s64 m = (s32)reg[(opcode & 0x0F)].I; 3043 s64 s = (s32)rs; 3044 s64 sTemp = m*s; 3045 reg[destLo].I = (u32)sTemp; 3046 reg[destHi].I = (u32)(sTemp >> 32); 3047 if(((s32)rs) < 0) 3048 rs = ~rs; 3049 if((rs & 0xFFFFFF00) == 0) 3050 clockTicks += 2; 3051 else if((rs & 0xFFFF0000) == 0) 3052 clockTicks += 3; 3053 else if((rs & 0xFF000000) == 0) 3054 clockTicks += 4; 3055 else 3056 clockTicks += 5; 3057 } 3058 break; 3059 case 0x0d9: 3060 { 3061 // SMULLS RdLo, RdHi, Rm, Rs 3062 int destLo = (opcode >> 12) & 0x0F; 3063 int destHi = (opcode >> 16) & 0x0F; 3064 u32 rs = reg[(opcode >> 8) & 0x0F].I; 3065 s64 m = (s32)reg[(opcode & 0x0F)].I; 3066 s64 s = (s32)rs; 3067 s64 sTemp = m*s; 3068 reg[destLo].I = (u32)sTemp; 3069 reg[destHi].I = (u32)(sTemp >> 32); 3070 Z_FLAG = (sTemp) ? false : true; 3071 N_FLAG = (sTemp < 0) ? true : false; 3072 if(((s32)rs) < 0) 3073 rs = ~rs; 3074 if((rs & 0xFFFFFF00) == 0) 3075 clockTicks += 2; 3076 else if((rs & 0xFFFF0000) == 0) 3077 clockTicks += 3; 3078 else if((rs & 0xFF000000) == 0) 3079 clockTicks += 4; 3080 else 3081 clockTicks += 5; 3082 } 3083 break; 3084 ARITHMETIC_DATA_OPCODE(OP_RSC, OP_RSC, 0x0e0); 3085 ARITHMETIC_DATA_OPCODE(OP_RSCS, OP_RSC, 0x0f0); 3086 case 0x0e9: 3087 { 3088 // SMLAL RdLo, RdHi, Rm, Rs 3089 int destLo = (opcode >> 12) & 0x0F; 3090 int destHi = (opcode >> 16) & 0x0F; 3091 u32 rs = reg[(opcode >> 8) & 0x0F].I; 3092 s64 m = (s32)reg[(opcode & 0x0F)].I; 3093 s64 s = (s32)rs; 3094 s64 sTemp = (u64)reg[destHi].I; 3095 sTemp <<= 32; 3096 sTemp |= (u64)reg[destLo].I; 3097 sTemp += m*s; 3098 reg[destLo].I = (u32)sTemp; 3099 reg[destHi].I = (u32)(sTemp >> 32); 3100 if(((s32)rs) < 0) 3101 rs = ~rs; 3102 if((rs & 0xFFFFFF00) == 0) 3103 clockTicks += 3; 3104 else if((rs & 0xFFFF0000) == 0) 3105 clockTicks += 4; 3106 else if((rs & 0xFF000000) == 0) 3107 clockTicks += 5; 3108 else 3109 clockTicks += 6; 3110 } 3111 break; 3112 case 0x0f9: 3113 { 3114 // SMLALS RdLo, RdHi, Rm, Rs 3115 int destLo = (opcode >> 12) & 0x0F; 3116 int destHi = (opcode >> 16) & 0x0F; 3117 u32 rs = reg[(opcode >> 8) & 0x0F].I; 3118 s64 m = (s32)reg[(opcode & 0x0F)].I; 3119 s64 s = (s32)rs; 3120 s64 sTemp = (u64)reg[destHi].I; 3121 sTemp <<= 32; 3122 sTemp |= (u64)reg[destLo].I; 3123 sTemp += m*s; 3124 reg[destLo].I = (u32)sTemp; 3125 reg[destHi].I = (u32)(sTemp >> 32); 3126 Z_FLAG = (sTemp) ? false : true; 3127 N_FLAG = (sTemp < 0) ? true : false; 3128 if(((s32)rs) < 0) 3129 rs = ~rs; 3130 if((rs & 0xFFFFFF00) == 0) 3131 clockTicks += 3; 3132 else if((rs & 0xFFFF0000) == 0) 3133 clockTicks += 4; 3134 else if((rs & 0xFF000000) == 0) 3135 clockTicks += 5; 3136 else 3137 clockTicks += 6; 3138 } 3139 break; 3140 LOGICAL_DATA_OPCODE(OP_TST, OP_TST, 0x110); 3141 case 0x100: 3142 // MRS Rd, CPSR 3143 // TODO: check if right instruction.... 3144 CPUUpdateCPSR(); 3145 reg[(opcode >> 12) & 0x0F].I = reg[16].I; 3146 break; 3147 case 0x109: 3148 { 3149 // SWP Rd, Rm, [Rn] 3150 u32 address = reg[(opcode >> 16) & 15].I; 3151 u32 temp = CPUReadMemory(address); 3152 CPUWriteMemory(address, reg[opcode&15].I); 3153 reg[(opcode >> 12) & 15].I = temp; 3154 } 3155 break; 3156 LOGICAL_DATA_OPCODE(OP_TEQ, OP_TEQ, 0x130); 3157 case 0x120: 3158 { 3159 // MSR CPSR_fields, Rm 3160 CPUUpdateCPSR(); 3161 u32 value = reg[opcode & 15].I; 3162 u32 newValue = reg[16].I; 3163 if(armMode > 0x10) { 3164 if(opcode & 0x00010000) 3165 newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF); 3166 if(opcode & 0x00020000) 3167 newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00); 3168 if(opcode & 0x00040000) 3169 newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000); 3170 } 3171 if(opcode & 0x00080000) 3172 newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000); 3173 newValue |= 0x10; 3174 CPUSwitchMode(newValue & 0x1f, false); 3175 reg[16].I = newValue; 3176 CPUUpdateFlags(); 3177 } 3178 break; 3179 case 0x121: 3180 { 3181 // BX Rm 3182 // TODO: check if right instruction... 3183 clockTicks += 3; 3184 int base = opcode & 0x0F; 3185 armState = reg[base].I & 1 ? false : true; 3186 if(armState) { 3187 reg[15].I = reg[base].I & 0xFFFFFFFC; 3188 armNextPC = reg[15].I; 3189 reg[15].I += 4; 3190 } else { 3191 reg[15].I = reg[base].I & 0xFFFFFFFE; 3192 armNextPC = reg[15].I; 3193 reg[15].I += 2; 3194 } 3195 } 3196 break; 3197 ARITHMETIC_DATA_OPCODE(OP_CMP, OP_CMP, 0x150); 3198 case 0x140: 3199 // MRS Rd, SPSR 3200 // TODO: check if right instruction... 3201 reg[(opcode >> 12) & 0x0F].I = reg[17].I; 3202 break; 3203 case 0x149: 3204 { 3205 // SWPB Rd, Rm, [Rn] 3206 u32 address = reg[(opcode >> 16) & 15].I; 3207 u32 temp = CPUReadByte(address); 3208 CPUWriteByte(address, reg[opcode&15].B.B0); 3209 reg[(opcode>>12)&15].I = temp; 3210 } 3211 break; 3212 ARITHMETIC_DATA_OPCODE(OP_CMN, OP_CMN, 0x170); 3213 case 0x160: 3214 { 3215 // MSR SPSR_fields, Rm 3216 u32 value = reg[opcode & 15].I; 3217 if(armMode > 0x10 && armMode < 0x1f) { 3218 if(opcode & 0x00010000) 3219 reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF); 3220 if(opcode & 0x00020000) 3221 reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00); 3222 if(opcode & 0x00040000) 3223 reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000); 3224 if(opcode & 0x00080000) 3225 reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000); 3226 } 3227 } 3228 break; 3229 LOGICAL_DATA_OPCODE (OP_ORR, OP_ORR, 0x180); 3230 LOGICAL_DATA_OPCODE (OP_ORRS, OP_ORR, 0x190); 3231 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOV, OP_MOV, 0x1a0); 3232 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOVS, OP_MOV, 0x1b0); 3233 LOGICAL_DATA_OPCODE (OP_BIC, OP_BIC, 0x1c0); 3234 LOGICAL_DATA_OPCODE (OP_BICS, OP_BIC, 0x1d0); 3235 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVN, OP_MVN, 0x1e0); 3236 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVNS, OP_MVN, 0x1f0); 3237 #ifdef BKPT_SUPPORT 3238 case 0x127: 3239 case 0x7ff: // for GDB support 3240 extern void (*dbgSignal)(int,int); 3241 reg[15].I -= 4; 3242 armNextPC -= 4; 3243 dbgSignal(5, (opcode & 0x0f)|((opcode>>4) & 0xfff0)); 3244 return; 3245 #endif 3246 case 0x320: 3247 case 0x321: 3248 case 0x322: 3249 case 0x323: 3250 case 0x324: 3251 case 0x325: 3252 case 0x326: 3253 case 0x327: 3254 case 0x328: 3255 case 0x329: 3256 case 0x32a: 3257 case 0x32b: 3258 case 0x32c: 3259 case 0x32d: 3260 case 0x32e: 3261 case 0x32f: 3262 { 3263 // MSR CPSR_fields, # 3264 CPUUpdateCPSR(); 3265 u32 value = opcode & 0xFF; 3266 int shift = (opcode & 0xF00) >> 7; 3267 if(shift) { 3268 ROR_IMM_MSR; 3269 } 3270 u32 newValue = reg[16].I; 3271 if(armMode > 0x10) { 3272 if(opcode & 0x00010000) 3273 newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF); 3274 if(opcode & 0x00020000) 3275 newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00); 3276 if(opcode & 0x00040000) 3277 newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000); 3278 } 3279 if(opcode & 0x00080000) 3280 newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000); 3281 3282 newValue |= 0x10; 3283 3284 CPUSwitchMode(newValue & 0x1f, false); 3285 reg[16].I = newValue; 3286 CPUUpdateFlags(); 3287 } 3288 break; 3289 case 0x360: 3290 case 0x361: 3291 case 0x362: 3292 case 0x363: 3293 case 0x364: 3294 case 0x365: 3295 case 0x366: 3296 case 0x367: 3297 case 0x368: 3298 case 0x369: 3299 case 0x36a: 3300 case 0x36b: 3301 case 0x36c: 3302 case 0x36d: 3303 case 0x36e: 3304 case 0x36f: 3305 { 3306 // MSR SPSR_fields, # 3307 if(armMode > 0x10 && armMode < 0x1f) { 3308 u32 value = opcode & 0xFF; 3309 int shift = (opcode & 0xF00) >> 7; 3310 if(shift) { 3311 ROR_IMM_MSR; 3312 } 3313 if(opcode & 0x00010000) 3314 reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF); 3315 if(opcode & 0x00020000) 3316 reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00); 3317 if(opcode & 0x00040000) 3318 reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000); 3319 if(opcode & 0x00080000) 3320 reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000); 3321 } 3322 } 3323 break; 3324 CASE_16(0x400) 3325 // T versions shouldn't be different on GBA 3326 CASE_16(0x420) 3327 { 3328 // STR Rd, [Rn], -# 3329 int offset = opcode & 0xFFF; 3330 int dest = (opcode >> 12) & 15; 3331 int base = (opcode >> 16) & 15; 3332 u32 address = reg[base].I; 3333 CPUWriteMemory(address, reg[dest].I); 3334 reg[base].I = address - offset; 3335 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3336 } 3337 break; 3338 CASE_16(0x480) 3339 // T versions shouldn't be different on GBA 3340 CASE_16(0x4a0) 3341 { 3342 // STR Rd, [Rn], # 3343 int offset = opcode & 0xFFF; 3344 int dest = (opcode >> 12) & 15; 3345 int base = (opcode >> 16) & 15; 3346 u32 address = reg[base].I; 3347 CPUWriteMemory(address, reg[dest].I); 3348 reg[base].I = address + offset; 3349 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3350 } 3351 break; 3352 CASE_16(0x500) 3353 { 3354 // STR Rd, [Rn, -#] 3355 int offset = opcode & 0xFFF; 3356 int dest = (opcode >> 12) & 15; 3357 int base = (opcode >> 16) & 15; 3358 u32 address = reg[base].I - offset; 3359 CPUWriteMemory(address, reg[dest].I); 3360 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3361 } 3362 break; 3363 CASE_16(0x520) 3364 { 3365 // STR Rd, [Rn, -#]! 3366 int offset = opcode & 0xFFF; 3367 int dest = (opcode >> 12) & 15; 3368 int base = (opcode >> 16) & 15; 3369 u32 address = reg[base].I - offset; 3370 reg[base].I = address; 3371 CPUWriteMemory(address, reg[dest].I); 3372 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3373 } 3374 break; 3375 CASE_16(0x580) 3376 { 3377 // STR Rd, [Rn, #] 3378 int offset = opcode & 0xFFF; 3379 int dest = (opcode >> 12) & 15; 3380 int base = (opcode >> 16) & 15; 3381 u32 address = reg[base].I + offset; 3382 CPUWriteMemory(address, reg[dest].I); 3383 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3384 } 3385 break; 3386 CASE_16(0x5a0) 3387 { 3388 // STR Rd, [Rn, #]! 3389 int offset = opcode & 0xFFF; 3390 int dest = (opcode >> 12) & 15; 3391 int base = (opcode >> 16) & 15; 3392 u32 address = reg[base].I + offset; 3393 reg[base].I = address; 3394 CPUWriteMemory(address, reg[dest].I); 3395 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3396 } 3397 break; 3398 CASE_16(0x410) 3399 { 3400 // LDR Rd, [Rn], -# 3401 int offset = opcode & 0xFFF; 3402 int dest = (opcode >> 12) & 15; 3403 int base = (opcode >> 16) & 15; 3404 u32 address = reg[base].I; 3405 reg[dest].I = CPUReadMemory(address); 3406 if(dest != base) 3407 reg[base].I -= offset; 3408 clockTicks += 3 + CPUUpdateTicksAccess32(address); 3409 if(dest == 15) { 3410 clockTicks += 2; 3411 reg[15].I &= 0xFFFFFFFC; 3412 armNextPC = reg[15].I; 3413 reg[15].I += 4; 3414 } 3415 } 3416 break; 3417 CASE_16(0x430) 3418 { 3419 // LDRT Rd, [Rn], -# 3420 int offset = opcode & 0xFFF; 3421 int dest = (opcode >> 12) & 15; 3422 int base = (opcode >> 16) & 15; 3423 u32 address = reg[base].I; 3424 reg[dest].I = CPUReadMemory(address); 3425 if(dest != base) 3426 reg[base].I -= offset; 3427 clockTicks += 3 + CPUUpdateTicksAccess32(address); 3428 } 3429 break; 3430 CASE_16(0x490) 3431 { 3432 // LDR Rd, [Rn], # 3433 int offset = opcode & 0xFFF; 3434 int dest = (opcode >> 12) & 15; 3435 int base = (opcode >> 16) & 15; 3436 u32 address = reg[base].I; 3437 reg[dest].I = CPUReadMemory(address); 3438 if(dest != base) 3439 reg[base].I += offset; 3440 clockTicks += 3 + CPUUpdateTicksAccess32(address); 3441 if(dest == 15) { 3442 clockTicks += 2; 3443 reg[15].I &= 0xFFFFFFFC; 3444 armNextPC = reg[15].I; 3445 reg[15].I += 4; 3446 } 3447 } 3448 break; 3449 CASE_16(0x4b0) 3450 { 3451 // LDRT Rd, [Rn], # 3452 int offset = opcode & 0xFFF; 3453 int dest = (opcode >> 12) & 15; 3454 int base = (opcode >> 16) & 15; 3455 u32 address = reg[base].I; 3456 reg[dest].I = CPUReadMemory(address); 3457 if(dest != base) 3458 reg[base].I += offset; 3459 clockTicks += 3 + CPUUpdateTicksAccess32(address); 3460 } 3461 break; 3462 CASE_16(0x510) 3463 { 3464 // LDR Rd, [Rn, -#] 3465 int offset = opcode & 0xFFF; 3466 int dest = (opcode >> 12) & 15; 3467 int base = (opcode >> 16) & 15; 3468 u32 address = reg[base].I - offset; 3469 reg[dest].I = CPUReadMemory(address); 3470 clockTicks += 3 + CPUUpdateTicksAccess32(address); 3471 if(dest == 15) { 3472 clockTicks += 2; 3473 reg[15].I &= 0xFFFFFFFC; 3474 armNextPC = reg[15].I; 3475 reg[15].I += 4; 3476 } 3477 } 3478 break; 3479 CASE_16(0x530) 3480 { 3481 // LDR Rd, [Rn, -#]! 3482 int offset = opcode & 0xFFF; 3483 int dest = (opcode >> 12) & 15; 3484 int base = (opcode >> 16) & 15; 3485 u32 address = reg[base].I - offset; 3486 reg[dest].I = CPUReadMemory(address); 3487 if(dest != base) 3488 reg[base].I = address; 3489 clockTicks += 3 + CPUUpdateTicksAccess32(address); 3490 if(dest == 15) { 3491 clockTicks += 2; 3492 reg[15].I &= 0xFFFFFFFC; 3493 armNextPC = reg[15].I; 3494 reg[15].I += 4; 3495 } 3496 } 3497 break; 3498 CASE_16(0x590) 3499 { 3500 // LDR Rd, [Rn, #] 3501 int offset = opcode & 0xFFF; 3502 int dest = (opcode >> 12) & 15; 3503 int base = (opcode >> 16) & 15; 3504 u32 address = reg[base].I + offset; 3505 reg[dest].I = CPUReadMemory(address); 3506 clockTicks += 3 + CPUUpdateTicksAccess32(address); 3507 if(dest == 15) { 3508 clockTicks += 2; 3509 reg[15].I &= 0xFFFFFFFC; 3510 armNextPC = reg[15].I; 3511 reg[15].I += 4; 3512 } 3513 } 3514 break; 3515 CASE_16(0x5b0) 3516 { 3517 // LDR Rd, [Rn, #]! 3518 int offset = opcode & 0xFFF; 3519 int dest = (opcode >> 12) & 15; 3520 int base = (opcode >> 16) & 15; 3521 u32 address = reg[base].I + offset; 3522 reg[dest].I = CPUReadMemory(address); 3523 if(dest != base) 3524 reg[base].I = address; 3525 clockTicks += 3 + CPUUpdateTicksAccess32(address); 3526 if(dest == 15) { 3527 clockTicks += 2; 3528 reg[15].I &= 0xFFFFFFFC; 3529 armNextPC = reg[15].I; 3530 reg[15].I += 4; 3531 } 3532 } 3533 break; 3534 CASE_16(0x440) 3535 // T versions shouldn't be different on GBA 3536 CASE_16(0x460) 3537 { 3538 // STRB Rd, [Rn], -# 3539 int offset = opcode & 0xFFF; 3540 int dest = (opcode >> 12) & 15; 3541 int base = (opcode >> 16) & 15; 3542 u32 address = reg[base].I; 3543 CPUWriteByte(address, reg[dest].B.B0); 3544 reg[base].I = address - offset; 3545 clockTicks += 2 + CPUUpdateTicksAccess16(address); 3546 } 3547 break; 3548 CASE_16(0x4c0) 3549 // T versions shouldn't be different on GBA 3550 CASE_16(0x4e0) 3551 // STRB Rd, [Rn], # 3552 { 3553 int offset = opcode & 0xFFF; 3554 int dest = (opcode >> 12) & 15; 3555 int base = (opcode >> 16) & 15; 3556 u32 address = reg[base].I; 3557 CPUWriteByte(address, reg[dest].B.B0); 3558 reg[base].I = address + offset; 3559 clockTicks += 2 + CPUUpdateTicksAccess16(address); 3560 } 3561 break; 3562 CASE_16(0x540) 3563 { 3564 // STRB Rd, [Rn, -#] 3565 int offset = opcode & 0xFFF; 3566 int dest = (opcode >> 12) & 15; 3567 int base = (opcode >> 16) & 15; 3568 u32 address = reg[base].I - offset; 3569 CPUWriteByte(address, reg[dest].B.B0); 3570 clockTicks += 2 + CPUUpdateTicksAccess16(address); 3571 } 3572 break; 3573 CASE_16(0x560) 3574 { 3575 // STRB Rd, [Rn, -#]! 3576 int offset = opcode & 0xFFF; 3577 int dest = (opcode >> 12) & 15; 3578 int base = (opcode >> 16) & 15; 3579 u32 address = reg[base].I - offset; 3580 reg[base].I = address; 3581 CPUWriteByte(address, reg[dest].B.B0); 3582 clockTicks += 2 + CPUUpdateTicksAccess16(address); 3583 } 3584 break; 3585 CASE_16(0x5c0) 3586 { 3587 // STRB Rd, [Rn, #] 3588 int offset = opcode & 0xFFF; 3589 int dest = (opcode >> 12) & 15; 3590 int base = (opcode >> 16) & 15; 3591 u32 address = reg[base].I + offset; 3592 CPUWriteByte(address, reg[dest].B.B0); 3593 clockTicks += 2 + CPUUpdateTicksAccess16(address); 3594 } 3595 break; 3596 CASE_16(0x5e0) 3597 { 3598 // STRB Rd, [Rn, #]! 3599 int offset = opcode & 0xFFF; 3600 int dest = (opcode >> 12) & 15; 3601 int base = (opcode >> 16) & 15; 3602 u32 address = reg[base].I + offset; 3603 reg[base].I = address; 3604 CPUWriteByte(address, reg[dest].I); 3605 clockTicks += 2 + CPUUpdateTicksAccess16(address); 3606 } 3607 break; 3608 CASE_16(0x450) 3609 // T versions shouldn't be different 3610 CASE_16(0x470) 3611 { 3612 // LDRB Rd, [Rn], -# 3613 int offset = opcode & 0xFFF; 3614 int dest = (opcode >> 12) & 15; 3615 int base = (opcode >> 16) & 15; 3616 u32 address = reg[base].I; 3617 reg[dest].I = CPUReadByte(address); 3618 if(dest != base) 3619 reg[base].I -= offset; 3620 clockTicks += 3 + CPUUpdateTicksAccess16(address); 3621 } 3622 break; 3623 CASE_16(0x4d0) 3624 CASE_16(0x4f0) // T versions should not be different 3625 { 3626 // LDRB Rd, [Rn], # 3627 int offset = opcode & 0xFFF; 3628 int dest = (opcode >> 12) & 15; 3629 int base = (opcode >> 16) & 15; 3630 u32 address = reg[base].I; 3631 reg[dest].I = CPUReadByte(address); 3632 if(dest != base) 3633 reg[base].I += offset; 3634 clockTicks += 3 + CPUUpdateTicksAccess16(address); 3635 } 3636 break; 3637 CASE_16(0x550) 3638 { 3639 // LDRB Rd, [Rn, -#] 3640 int offset = opcode & 0xFFF; 3641 int dest = (opcode >> 12) & 15; 3642 int base = (opcode >> 16) & 15; 3643 u32 address = reg[base].I - offset; 3644 reg[dest].I = CPUReadByte(address); 3645 clockTicks += 3 + CPUUpdateTicksAccess16(address); 3646 } 3647 break; 3648 CASE_16(0x570) 3649 { 3650 // LDRB Rd, [Rn, -#]! 3651 int offset = opcode & 0xFFF; 3652 int dest = (opcode >> 12) & 15; 3653 int base = (opcode >> 16) & 15; 3654 u32 address = reg[base].I - offset; 3655 reg[dest].I = CPUReadByte(address); 3656 if(dest != base) 3657 reg[base].I = address; 3658 clockTicks += 3 + CPUUpdateTicksAccess16(address); 3659 } 3660 break; 3661 CASE_16(0x5d0) 3662 { 3663 // LDRB Rd, [Rn, #] 3664 int offset = opcode & 0xFFF; 3665 int dest = (opcode >> 12) & 15; 3666 int base = (opcode >> 16) & 15; 3667 u32 address = reg[base].I + offset; 3668 reg[dest].I = CPUReadByte(address); 3669 clockTicks += 3 + CPUUpdateTicksAccess16(address); 3670 } 3671 break; 3672 CASE_16(0x5f0) 3673 { 3674 // LDRB Rd, [Rn, #]! 3675 int offset = opcode & 0xFFF; 3676 int dest = (opcode >> 12) & 15; 3677 int base = (opcode >> 16) & 15; 3678 u32 address = reg[base].I + offset; 3679 reg[dest].I = CPUReadByte(address); 3680 if(dest != base) 3681 reg[base].I = address; 3682 clockTicks += 3 + CPUUpdateTicksAccess16(address); 3683 } 3684 break; 3685 case 0x600: 3686 case 0x608: 3687 // T versions are the same 3688 case 0x620: 3689 case 0x628: 3690 { 3691 // STR Rd, [Rn], -Rm, LSL # 3692 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 3693 int dest = (opcode >> 12) & 15; 3694 int base = (opcode >> 16) & 15; 3695 u32 address = reg[base].I; 3696 CPUWriteMemory(address, reg[dest].I); 3697 reg[base].I = address - offset; 3698 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3699 } 3700 break; 3701 case 0x602: 3702 case 0x60a: 3703 // T versions are the same 3704 case 0x622: 3705 case 0x62a: 3706 { 3707 // STR Rd, [Rn], -Rm, LSR # 3708 int shift = (opcode >> 7) & 31; 3709 int offset = shift ? reg[opcode & 15].I >> shift : 0; 3710 int dest = (opcode >> 12) & 15; 3711 int base = (opcode >> 16) & 15; 3712 u32 address = reg[base].I; 3713 CPUWriteMemory(address, reg[dest].I); 3714 reg[base].I = address - offset; 3715 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3716 } 3717 break; 3718 case 0x604: 3719 case 0x60c: 3720 // T versions are the same 3721 case 0x624: 3722 case 0x62c: 3723 { 3724 // STR Rd, [Rn], -Rm, ASR # 3725 int shift = (opcode >> 7) & 31; 3726 int offset; 3727 if(shift) 3728 offset = (int)((s32)reg[opcode & 15].I >> shift); 3729 else if(reg[opcode & 15].I & 0x80000000) 3730 offset = 0xFFFFFFFF; 3731 else 3732 offset = 0; 3733 int dest = (opcode >> 12) & 15; 3734 int base = (opcode >> 16) & 15; 3735 u32 address = reg[base].I; 3736 CPUWriteMemory(address, reg[dest].I); 3737 reg[base].I = address - offset; 3738 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3739 } 3740 break; 3741 case 0x606: 3742 case 0x60e: 3743 // T versions are the same 3744 case 0x626: 3745 case 0x62e: 3746 { 3747 // STR Rd, [Rn], -Rm, ROR # 3748 int shift = (opcode >> 7) & 31; 3749 u32 value = reg[opcode & 15].I; 3750 if(shift) { 3751 ROR_VALUE; 3752 } else { 3753 RCR_VALUE; 3754 } 3755 int dest = (opcode >> 12) & 15; 3756 int base = (opcode >> 16) & 15; 3757 u32 address = reg[base].I; 3758 CPUWriteMemory(address, reg[dest].I); 3759 reg[base].I = address - value; 3760 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3761 } 3762 break; 3763 case 0x680: 3764 case 0x688: 3765 // T versions are the same 3766 case 0x6a0: 3767 case 0x6a8: 3768 { 3769 // STR Rd, [Rn], Rm, LSL # 3770 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 3771 int dest = (opcode >> 12) & 15; 3772 int base = (opcode >> 16) & 15; 3773 u32 address = reg[base].I; 3774 CPUWriteMemory(address, reg[dest].I); 3775 reg[base].I = address + offset; 3776 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3777 } 3778 break; 3779 case 0x682: 3780 case 0x68a: 3781 // T versions are the same 3782 case 0x6a2: 3783 case 0x6aa: 3784 { 3785 // STR Rd, [Rn], Rm, LSR # 3786 int shift = (opcode >> 7) & 31; 3787 int offset = shift ? reg[opcode & 15].I >> shift : 0; 3788 int dest = (opcode >> 12) & 15; 3789 int base = (opcode >> 16) & 15; 3790 u32 address = reg[base].I; 3791 CPUWriteMemory(address, reg[dest].I); 3792 reg[base].I = address + offset; 3793 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3794 } 3795 break; 3796 case 0x684: 3797 case 0x68c: 3798 // T versions are the same 3799 case 0x6a4: 3800 case 0x6ac: 3801 { 3802 // STR Rd, [Rn], Rm, ASR # 3803 int shift = (opcode >> 7) & 31; 3804 int offset; 3805 if(shift) 3806 offset = (int)((s32)reg[opcode & 15].I >> shift); 3807 else if(reg[opcode & 15].I & 0x80000000) 3808 offset = 0xFFFFFFFF; 3809 else 3810 offset = 0; 3811 int dest = (opcode >> 12) & 15; 3812 int base = (opcode >> 16) & 15; 3813 u32 address = reg[base].I; 3814 CPUWriteMemory(address, reg[dest].I); 3815 reg[base].I = address + offset; 3816 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3817 } 3818 break; 3819 case 0x686: 3820 case 0x68e: 3821 // T versions are the same 3822 case 0x6a6: 3823 case 0x6ae: 3824 { 3825 // STR Rd, [Rn], Rm, ROR # 3826 int shift = (opcode >> 7) & 31; 3827 u32 value = reg[opcode & 15].I; 3828 if(shift) { 3829 ROR_VALUE; 3830 } else { 3831 RCR_VALUE; 3832 } 3833 int dest = (opcode >> 12) & 15; 3834 int base = (opcode >> 16) & 15; 3835 u32 address = reg[base].I; 3836 CPUWriteMemory(address, reg[dest].I); 3837 reg[base].I = address + value; 3838 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3839 } 3840 break; 3841 case 0x700: 3842 case 0x708: 3843 { 3844 // STR Rd, [Rn, -Rm, LSL #] 3845 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 3846 int dest = (opcode >> 12) & 15; 3847 int base = (opcode >> 16) & 15; 3848 u32 address = reg[base].I - offset; 3849 CPUWriteMemory(address, reg[dest].I); 3850 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3851 } 3852 break; 3853 case 0x702: 3854 case 0x70a: 3855 { 3856 // STR Rd, [Rn, -Rm, LSR #] 3857 int shift = (opcode >> 7) & 31; 3858 int offset = shift ? reg[opcode & 15].I >> shift : 0; 3859 int dest = (opcode >> 12) & 15; 3860 int base = (opcode >> 16) & 15; 3861 u32 address = reg[base].I - offset; 3862 CPUWriteMemory(address, reg[dest].I); 3863 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3864 } 3865 break; 3866 case 0x704: 3867 case 0x70c: 3868 { 3869 // STR Rd, [Rn, -Rm, ASR #] 3870 int shift = (opcode >> 7) & 31; 3871 int offset; 3872 if(shift) 3873 offset = (int)((s32)reg[opcode & 15].I >> shift); 3874 else if(reg[opcode & 15].I & 0x80000000) 3875 offset = 0xFFFFFFFF; 3876 else 3877 offset = 0; 3878 int dest = (opcode >> 12) & 15; 3879 int base = (opcode >> 16) & 15; 3880 u32 address = reg[base].I - offset; 3881 CPUWriteMemory(address, reg[dest].I); 3882 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3883 } 3884 break; 3885 case 0x706: 3886 case 0x70e: 3887 { 3888 // STR Rd, [Rn, -Rm, ROR #] 3889 int shift = (opcode >> 7) & 31; 3890 u32 value = reg[opcode & 15].I; 3891 if(shift) { 3892 ROR_VALUE; 3893 } else { 3894 RCR_VALUE; 3895 } 3896 int dest = (opcode >> 12) & 15; 3897 int base = (opcode >> 16) & 15; 3898 u32 address = reg[base].I - value; 3899 CPUWriteMemory(address, reg[dest].I); 3900 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3901 } 3902 break; 3903 case 0x720: 3904 case 0x728: 3905 { 3906 // STR Rd, [Rn, -Rm, LSL #]! 3907 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 3908 int dest = (opcode >> 12) & 15; 3909 int base = (opcode >> 16) & 15; 3910 u32 address = reg[base].I - offset; 3911 reg[base].I = address; 3912 CPUWriteMemory(address, reg[dest].I); 3913 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3914 } 3915 break; 3916 case 0x722: 3917 case 0x72a: 3918 { 3919 // STR Rd, [Rn, -Rm, LSR #]! 3920 int shift = (opcode >> 7) & 31; 3921 int offset = shift ? reg[opcode & 15].I >> shift : 0; 3922 int dest = (opcode >> 12) & 15; 3923 int base = (opcode >> 16) & 15; 3924 u32 address = reg[base].I - offset; 3925 reg[base].I = address; 3926 CPUWriteMemory(address, reg[dest].I); 3927 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3928 } 3929 break; 3930 case 0x724: 3931 case 0x72c: 3932 { 3933 // STR Rd, [Rn, -Rm, ASR #]! 3934 int shift = (opcode >> 7) & 31; 3935 int offset; 3936 if(shift) 3937 offset = (int)((s32)reg[opcode & 15].I >> shift); 3938 else if(reg[opcode & 15].I & 0x80000000) 3939 offset = 0xFFFFFFFF; 3940 else 3941 offset = 0; 3942 int dest = (opcode >> 12) & 15; 3943 int base = (opcode >> 16) & 15; 3944 u32 address = reg[base].I - offset; 3945 reg[base].I = address; 3946 CPUWriteMemory(address, reg[dest].I); 3947 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3948 } 3949 break; 3950 case 0x726: 3951 case 0x72e: 3952 { 3953 // STR Rd, [Rn, -Rm, ROR #]! 3954 int shift = (opcode >> 7) & 31; 3955 u32 value = reg[opcode & 15].I; 3956 if(shift) { 3957 ROR_VALUE; 3958 } else { 3959 RCR_VALUE; 3960 } 3961 int dest = (opcode >> 12) & 15; 3962 int base = (opcode >> 16) & 15; 3963 u32 address = reg[base].I - value; 3964 reg[base].I = address; 3965 CPUWriteMemory(address, reg[dest].I); 3966 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3967 } 3968 break; 3969 case 0x780: 3970 case 0x788: 3971 { 3972 // STR Rd, [Rn, Rm, LSL #] 3973 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 3974 int dest = (opcode >> 12) & 15; 3975 int base = (opcode >> 16) & 15; 3976 u32 address = reg[base].I + offset; 3977 CPUWriteMemory(address, reg[dest].I); 3978 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3979 } 3980 break; 3981 case 0x782: 3982 case 0x78a: 3983 { 3984 // STR Rd, [Rn, Rm, LSR #] 3985 int shift = (opcode >> 7) & 31; 3986 int offset = shift ? reg[opcode & 15].I >> shift : 0; 3987 int dest = (opcode >> 12) & 15; 3988 int base = (opcode >> 16) & 15; 3989 u32 address = reg[base].I + offset; 3990 CPUWriteMemory(address, reg[dest].I); 3991 clockTicks += 2 + CPUUpdateTicksAccess32(address); 3992 } 3993 break; 3994 case 0x784: 3995 case 0x78c: 3996 { 3997 // STR Rd, [Rn, Rm, ASR #] 3998 int shift = (opcode >> 7) & 31; 3999 int offset; 4000 if(shift) 4001 offset = (int)((s32)reg[opcode & 15].I >> shift); 4002 else if(reg[opcode & 15].I & 0x80000000) 4003 offset = 0xFFFFFFFF; 4004 else 4005 offset = 0; 4006 int dest = (opcode >> 12) & 15; 4007 int base = (opcode >> 16) & 15; 4008 u32 address = reg[base].I + offset; 4009 CPUWriteMemory(address, reg[dest].I); 4010 clockTicks += 2 + CPUUpdateTicksAccess32(address); 4011 } 4012 break; 4013 case 0x786: 4014 case 0x78e: 4015 { 4016 // STR Rd, [Rn, Rm, ROR #] 4017 int shift = (opcode >> 7) & 31; 4018 u32 value = reg[opcode & 15].I; 4019 if(shift) { 4020 ROR_VALUE; 4021 } else { 4022 RCR_VALUE; 4023 } 4024 int dest = (opcode >> 12) & 15; 4025 int base = (opcode >> 16) & 15; 4026 u32 address = reg[base].I + value; 4027 CPUWriteMemory(address, reg[dest].I); 4028 clockTicks += 2 + CPUUpdateTicksAccess32(address); 4029 } 4030 break; 4031 case 0x7a0: 4032 case 0x7a8: 4033 { 4034 // STR Rd, [Rn, Rm, LSL #]! 4035 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4036 int dest = (opcode >> 12) & 15; 4037 int base = (opcode >> 16) & 15; 4038 u32 address = reg[base].I + offset; 4039 reg[base].I = address; 4040 CPUWriteMemory(address, reg[dest].I); 4041 clockTicks += 2 + CPUUpdateTicksAccess32(address); 4042 } 4043 break; 4044 case 0x7a2: 4045 case 0x7aa: 4046 { 4047 // STR Rd, [Rn, Rm, LSR #]! 4048 int shift = (opcode >> 7) & 31; 4049 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4050 int dest = (opcode >> 12) & 15; 4051 int base = (opcode >> 16) & 15; 4052 u32 address = reg[base].I + offset; 4053 reg[base].I = address; 4054 CPUWriteMemory(address, reg[dest].I); 4055 clockTicks += 2 + CPUUpdateTicksAccess32(address); 4056 } 4057 break; 4058 case 0x7a4: 4059 case 0x7ac: 4060 { 4061 // STR Rd, [Rn, Rm, ASR #]! 4062 int shift = (opcode >> 7) & 31; 4063 int offset; 4064 if(shift) 4065 offset = (int)((s32)reg[opcode & 15].I >> shift); 4066 else if(reg[opcode & 15].I & 0x80000000) 4067 offset = 0xFFFFFFFF; 4068 else 4069 offset = 0; 4070 int dest = (opcode >> 12) & 15; 4071 int base = (opcode >> 16) & 15; 4072 u32 address = reg[base].I + offset; 4073 reg[base].I = address; 4074 CPUWriteMemory(address, reg[dest].I); 4075 clockTicks += 2 + CPUUpdateTicksAccess32(address); 4076 } 4077 break; 4078 case 0x7a6: 4079 case 0x7ae: 4080 { 4081 // STR Rd, [Rn, Rm, ROR #]! 4082 int shift = (opcode >> 7) & 31; 4083 u32 value = reg[opcode & 15].I; 4084 if(shift) { 4085 ROR_VALUE; 4086 } else { 4087 RCR_VALUE; 4088 } 4089 int dest = (opcode >> 12) & 15; 4090 int base = (opcode >> 16) & 15; 4091 u32 address = reg[base].I + value; 4092 reg[base].I = address; 4093 CPUWriteMemory(address, reg[dest].I); 4094 clockTicks += 2 + CPUUpdateTicksAccess32(address); 4095 } 4096 break; 4097 case 0x610: 4098 case 0x618: 4099 // T versions are the same 4100 case 0x630: 4101 case 0x638: 4102 { 4103 // LDR Rd, [Rn], -Rm, LSL # 4104 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4105 int dest = (opcode >> 12) & 15; 4106 int base = (opcode >> 16) & 15; 4107 u32 address = reg[base].I; 4108 reg[dest].I = CPUReadMemory(address); 4109 if(dest != base) 4110 reg[base].I = address - offset; 4111 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4112 if(dest == 15) { 4113 clockTicks += 2; 4114 reg[15].I &= 0xFFFFFFFC; 4115 armNextPC = reg[15].I; 4116 reg[15].I += 4; 4117 } 4118 } 4119 break; 4120 case 0x612: 4121 case 0x61a: 4122 // T versions are the same 4123 case 0x632: 4124 case 0x63a: 4125 { 4126 // LDR Rd, [Rn], -Rm, LSR # 4127 int shift = (opcode >> 7) & 31; 4128 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4129 int dest = (opcode >> 12) & 15; 4130 int base = (opcode >> 16) & 15; 4131 u32 address = reg[base].I; 4132 reg[dest].I = CPUReadMemory(address); 4133 if(dest != base) 4134 reg[base].I = address - offset; 4135 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4136 if(dest == 15) { 4137 clockTicks += 2; 4138 reg[15].I &= 0xFFFFFFFC; 4139 armNextPC = reg[15].I; 4140 reg[15].I += 4; 4141 } 4142 } 4143 break; 4144 case 0x614: 4145 case 0x61c: 4146 // T versions are the same 4147 case 0x634: 4148 case 0x63c: 4149 { 4150 // LDR Rd, [Rn], -Rm, ASR # 4151 int shift = (opcode >> 7) & 31; 4152 int offset; 4153 if(shift) 4154 offset = (int)((s32)reg[opcode & 15].I >> shift); 4155 else if(reg[opcode & 15].I & 0x80000000) 4156 offset = 0xFFFFFFFF; 4157 else 4158 offset = 0; 4159 int dest = (opcode >> 12) & 15; 4160 int base = (opcode >> 16) & 15; 4161 u32 address = reg[base].I; 4162 reg[dest].I = CPUReadMemory(address); 4163 if(dest != base) 4164 reg[base].I = address - offset; 4165 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4166 if(dest == 15) { 4167 clockTicks += 2; 4168 reg[15].I &= 0xFFFFFFFC; 4169 armNextPC = reg[15].I; 4170 reg[15].I += 4; 4171 } 4172 } 4173 break; 4174 case 0x616: 4175 case 0x61e: 4176 // T versions are the same 4177 case 0x636: 4178 case 0x63e: 4179 { 4180 // LDR Rd, [Rn], -Rm, ROR # 4181 int shift = (opcode >> 7) & 31; 4182 u32 value = reg[opcode & 15].I; 4183 if(shift) { 4184 ROR_VALUE; 4185 } else { 4186 RCR_VALUE; 4187 } 4188 int dest = (opcode >> 12) & 15; 4189 int base = (opcode >> 16) & 15; 4190 u32 address = reg[base].I; 4191 reg[dest].I = CPUReadMemory(address); 4192 if(dest != base) 4193 reg[base].I = address - value; 4194 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4195 if(dest == 15) { 4196 clockTicks += 2; 4197 reg[15].I &= 0xFFFFFFFC; 4198 armNextPC = reg[15].I; 4199 reg[15].I += 4; 4200 } 4201 } 4202 break; 4203 case 0x690: 4204 case 0x698: 4205 // T versions are the same 4206 case 0x6b0: 4207 case 0x6b8: 4208 { 4209 // LDR Rd, [Rn], Rm, LSL # 4210 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4211 int dest = (opcode >> 12) & 15; 4212 int base = (opcode >> 16) & 15; 4213 u32 address = reg[base].I; 4214 reg[dest].I = CPUReadMemory(address); 4215 if(dest != base) 4216 reg[base].I = address + offset; 4217 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4218 if(dest == 15) { 4219 clockTicks += 2; 4220 reg[15].I &= 0xFFFFFFFC; 4221 armNextPC = reg[15].I; 4222 reg[15].I += 4; 4223 } 4224 } 4225 break; 4226 case 0x692: 4227 case 0x69a: 4228 // T versions are the same 4229 case 0x6b2: 4230 case 0x6ba: 4231 { 4232 // LDR Rd, [Rn], Rm, LSR # 4233 int shift = (opcode >> 7) & 31; 4234 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4235 int dest = (opcode >> 12) & 15; 4236 int base = (opcode >> 16) & 15; 4237 u32 address = reg[base].I; 4238 reg[dest].I = CPUReadMemory(address); 4239 if(dest != base) 4240 reg[base].I = address + offset; 4241 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4242 if(dest == 15) { 4243 clockTicks += 2; 4244 reg[15].I &= 0xFFFFFFFC; 4245 armNextPC = reg[15].I; 4246 reg[15].I += 4; 4247 } 4248 } 4249 break; 4250 case 0x694: 4251 case 0x69c: 4252 // T versions are the same 4253 case 0x6b4: 4254 case 0x6bc: 4255 { 4256 // LDR Rd, [Rn], Rm, ASR # 4257 int shift = (opcode >> 7) & 31; 4258 int offset; 4259 if(shift) 4260 offset = (int)((s32)reg[opcode & 15].I >> shift); 4261 else if(reg[opcode & 15].I & 0x80000000) 4262 offset = 0xFFFFFFFF; 4263 else 4264 offset = 0; 4265 int dest = (opcode >> 12) & 15; 4266 int base = (opcode >> 16) & 15; 4267 u32 address = reg[base].I; 4268 reg[dest].I = CPUReadMemory(address); 4269 if(dest != base) 4270 reg[base].I = address + offset; 4271 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4272 if(dest == 15) { 4273 clockTicks += 2; 4274 reg[15].I &= 0xFFFFFFFC; 4275 armNextPC = reg[15].I; 4276 reg[15].I += 4; 4277 } 4278 } 4279 break; 4280 case 0x696: 4281 case 0x69e: 4282 // T versions are the same 4283 case 0x6b6: 4284 case 0x6be: 4285 { 4286 // LDR Rd, [Rn], Rm, ROR # 4287 int shift = (opcode >> 7) & 31; 4288 u32 value = reg[opcode & 15].I; 4289 if(shift) { 4290 ROR_VALUE; 4291 } else { 4292 RCR_VALUE; 4293 } 4294 int dest = (opcode >> 12) & 15; 4295 int base = (opcode >> 16) & 15; 4296 u32 address = reg[base].I; 4297 reg[dest].I = CPUReadMemory(address); 4298 if(dest != base) 4299 reg[base].I = address + value; 4300 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4301 if(dest == 15) { 4302 clockTicks += 2; 4303 reg[15].I &= 0xFFFFFFFC; 4304 armNextPC = reg[15].I; 4305 reg[15].I += 4; 4306 } 4307 } 4308 break; 4309 case 0x710: 4310 case 0x718: 4311 { 4312 // LDR Rd, [Rn, -Rm, LSL #] 4313 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4314 int dest = (opcode >> 12) & 15; 4315 int base = (opcode >> 16) & 15; 4316 u32 address = reg[base].I - offset; 4317 reg[dest].I = CPUReadMemory(address); 4318 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4319 if(dest == 15) { 4320 clockTicks += 2; 4321 reg[15].I &= 0xFFFFFFFC; 4322 armNextPC = reg[15].I; 4323 reg[15].I += 4; 4324 } 4325 } 4326 break; 4327 case 0x712: 4328 case 0x71a: 4329 { 4330 // LDR Rd, [Rn, -Rm, LSR #] 4331 int shift = (opcode >> 7) & 31; 4332 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4333 int dest = (opcode >> 12) & 15; 4334 int base = (opcode >> 16) & 15; 4335 u32 address = reg[base].I - offset; 4336 reg[dest].I = CPUReadMemory(address); 4337 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4338 if(dest == 15) { 4339 clockTicks += 2; 4340 reg[15].I &= 0xFFFFFFFC; 4341 armNextPC = reg[15].I; 4342 reg[15].I += 4; 4343 } 4344 } 4345 break; 4346 case 0x714: 4347 case 0x71c: 4348 { 4349 // LDR Rd, [Rn, -Rm, ASR #] 4350 int shift = (opcode >> 7) & 31; 4351 int offset; 4352 if(shift) 4353 offset = (int)((s32)reg[opcode & 15].I >> shift); 4354 else if(reg[opcode & 15].I & 0x80000000) 4355 offset = 0xFFFFFFFF; 4356 else 4357 offset = 0; 4358 int dest = (opcode >> 12) & 15; 4359 int base = (opcode >> 16) & 15; 4360 u32 address = reg[base].I - offset; 4361 reg[dest].I = CPUReadMemory(address); 4362 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4363 if(dest == 15) { 4364 clockTicks += 2; 4365 reg[15].I &= 0xFFFFFFFC; 4366 armNextPC = reg[15].I; 4367 reg[15].I += 4; 4368 } 4369 } 4370 break; 4371 case 0x716: 4372 case 0x71e: 4373 { 4374 // LDR Rd, [Rn, -Rm, ROR #] 4375 int shift = (opcode >> 7) & 31; 4376 u32 value = reg[opcode & 15].I; 4377 if(shift) { 4378 ROR_VALUE; 4379 } else { 4380 RCR_VALUE; 4381 } 4382 int dest = (opcode >> 12) & 15; 4383 int base = (opcode >> 16) & 15; 4384 u32 address = reg[base].I - value; 4385 reg[dest].I = CPUReadMemory(address); 4386 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4387 if(dest == 15) { 4388 clockTicks += 2; 4389 reg[15].I &= 0xFFFFFFFC; 4390 armNextPC = reg[15].I; 4391 reg[15].I += 4; 4392 } 4393 } 4394 break; 4395 case 0x730: 4396 case 0x738: 4397 { 4398 // LDR Rd, [Rn, -Rm, LSL #]! 4399 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4400 int dest = (opcode >> 12) & 15; 4401 int base = (opcode >> 16) & 15; 4402 u32 address = reg[base].I - offset; 4403 reg[dest].I = CPUReadMemory(address); 4404 if(dest != base) 4405 reg[base].I = address; 4406 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4407 if(dest == 15) { 4408 clockTicks += 2; 4409 reg[15].I &= 0xFFFFFFFC; 4410 armNextPC = reg[15].I; 4411 reg[15].I += 4; 4412 } 4413 } 4414 break; 4415 case 0x732: 4416 case 0x73a: 4417 { 4418 // LDR Rd, [Rn, -Rm, LSR #]! 4419 int shift = (opcode >> 7) & 31; 4420 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4421 int dest = (opcode >> 12) & 15; 4422 int base = (opcode >> 16) & 15; 4423 u32 address = reg[base].I - offset; 4424 reg[dest].I = CPUReadMemory(address); 4425 if(dest != base) 4426 reg[base].I = address; 4427 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4428 if(dest == 15) { 4429 clockTicks += 2; 4430 reg[15].I &= 0xFFFFFFFC; 4431 armNextPC = reg[15].I; 4432 reg[15].I += 4; 4433 } 4434 } 4435 break; 4436 case 0x734: 4437 case 0x73c: 4438 { 4439 // LDR Rd, [Rn, -Rm, ASR #]! 4440 int shift = (opcode >> 7) & 31; 4441 int offset; 4442 if(shift) 4443 offset = (int)((s32)reg[opcode & 15].I >> shift); 4444 else if(reg[opcode & 15].I & 0x80000000) 4445 offset = 0xFFFFFFFF; 4446 else 4447 offset = 0; 4448 int dest = (opcode >> 12) & 15; 4449 int base = (opcode >> 16) & 15; 4450 u32 address = reg[base].I - offset; 4451 reg[dest].I = CPUReadMemory(address); 4452 if(dest != base) 4453 reg[base].I = address; 4454 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4455 if(dest == 15) { 4456 clockTicks += 2; 4457 reg[15].I &= 0xFFFFFFFC; 4458 armNextPC = reg[15].I; 4459 reg[15].I += 4; 4460 } 4461 } 4462 break; 4463 case 0x736: 4464 case 0x73e: 4465 { 4466 // LDR Rd, [Rn, -Rm, ROR #]! 4467 int shift = (opcode >> 7) & 31; 4468 u32 value = reg[opcode & 15].I; 4469 if(shift) { 4470 ROR_VALUE; 4471 } else { 4472 RCR_VALUE; 4473 } 4474 int dest = (opcode >> 12) & 15; 4475 int base = (opcode >> 16) & 15; 4476 u32 address = reg[base].I - value; 4477 reg[dest].I = CPUReadMemory(address); 4478 if(dest != base) 4479 reg[base].I = address; 4480 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4481 if(dest == 15) { 4482 clockTicks += 2; 4483 reg[15].I &= 0xFFFFFFFC; 4484 armNextPC = reg[15].I; 4485 reg[15].I += 4; 4486 } 4487 } 4488 break; 4489 case 0x790: 4490 case 0x798: 4491 { 4492 // LDR Rd, [Rn, Rm, LSL #] 4493 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4494 int dest = (opcode >> 12) & 15; 4495 int base = (opcode >> 16) & 15; 4496 u32 address = reg[base].I + offset; 4497 reg[dest].I = CPUReadMemory(address); 4498 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4499 if(dest == 15) { 4500 clockTicks += 2; 4501 reg[15].I &= 0xFFFFFFFC; 4502 armNextPC = reg[15].I; 4503 reg[15].I += 4; 4504 } 4505 } 4506 break; 4507 case 0x792: 4508 case 0x79a: 4509 { 4510 // LDR Rd, [Rn, Rm, LSR #] 4511 int shift = (opcode >> 7) & 31; 4512 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4513 int dest = (opcode >> 12) & 15; 4514 int base = (opcode >> 16) & 15; 4515 u32 address = reg[base].I + offset; 4516 reg[dest].I = CPUReadMemory(address); 4517 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4518 if(dest == 15) { 4519 clockTicks += 2; 4520 reg[15].I &= 0xFFFFFFFC; 4521 armNextPC = reg[15].I; 4522 reg[15].I += 4; 4523 } 4524 } 4525 break; 4526 case 0x794: 4527 case 0x79c: 4528 { 4529 // LDR Rd, [Rn, Rm, ASR #] 4530 int shift = (opcode >> 7) & 31; 4531 int offset; 4532 if(shift) 4533 offset = (int)((s32)reg[opcode & 15].I >> shift); 4534 else if(reg[opcode & 15].I & 0x80000000) 4535 offset = 0xFFFFFFFF; 4536 else 4537 offset = 0; 4538 int dest = (opcode >> 12) & 15; 4539 int base = (opcode >> 16) & 15; 4540 u32 address = reg[base].I + offset; 4541 reg[dest].I = CPUReadMemory(address); 4542 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4543 if(dest == 15) { 4544 clockTicks += 2; 4545 reg[15].I &= 0xFFFFFFFC; 4546 armNextPC = reg[15].I; 4547 reg[15].I += 4; 4548 } 4549 } 4550 break; 4551 case 0x796: 4552 case 0x79e: 4553 { 4554 // LDR Rd, [Rn, Rm, ROR #] 4555 int shift = (opcode >> 7) & 31; 4556 u32 value = reg[opcode & 15].I; 4557 if(shift) { 4558 ROR_VALUE; 4559 } else { 4560 RCR_VALUE; 4561 } 4562 int dest = (opcode >> 12) & 15; 4563 int base = (opcode >> 16) & 15; 4564 u32 address = reg[base].I + value; 4565 reg[dest].I = CPUReadMemory(address); 4566 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4567 if(dest == 15) { 4568 clockTicks += 2; 4569 reg[15].I &= 0xFFFFFFFC; 4570 armNextPC = reg[15].I; 4571 reg[15].I += 4; 4572 } 4573 } 4574 break; 4575 case 0x7b0: 4576 case 0x7b8: 4577 { 4578 // LDR Rd, [Rn, Rm, LSL #]! 4579 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4580 int dest = (opcode >> 12) & 15; 4581 int base = (opcode >> 16) & 15; 4582 u32 address = reg[base].I + offset; 4583 reg[dest].I = CPUReadMemory(address); 4584 if(dest != base) 4585 reg[base].I = address; 4586 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4587 if(dest == 15) { 4588 clockTicks += 2; 4589 reg[15].I &= 0xFFFFFFFC; 4590 armNextPC = reg[15].I; 4591 reg[15].I += 4; 4592 } 4593 } 4594 break; 4595 case 0x7b2: 4596 case 0x7ba: 4597 { 4598 // LDR Rd, [Rn, Rm, LSR #]! 4599 int shift = (opcode >> 7) & 31; 4600 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4601 int dest = (opcode >> 12) & 15; 4602 int base = (opcode >> 16) & 15; 4603 u32 address = reg[base].I + offset; 4604 reg[dest].I = CPUReadMemory(address); 4605 if(dest != base) 4606 reg[base].I = address; 4607 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4608 if(dest == 15) { 4609 clockTicks += 2; 4610 reg[15].I &= 0xFFFFFFFC; 4611 armNextPC = reg[15].I; 4612 reg[15].I += 4; 4613 } 4614 } 4615 break; 4616 case 0x7b4: 4617 case 0x7bc: 4618 { 4619 // LDR Rd, [Rn, Rm, ASR #]! 4620 int shift = (opcode >> 7) & 31; 4621 int offset; 4622 if(shift) 4623 offset = (int)((s32)reg[opcode & 15].I >> shift); 4624 else if(reg[opcode & 15].I & 0x80000000) 4625 offset = 0xFFFFFFFF; 4626 else 4627 offset = 0; 4628 int dest = (opcode >> 12) & 15; 4629 int base = (opcode >> 16) & 15; 4630 u32 address = reg[base].I + offset; 4631 reg[dest].I = CPUReadMemory(address); 4632 if(dest != base) 4633 reg[base].I = address; 4634 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4635 if(dest == 15) { 4636 clockTicks += 2; 4637 reg[15].I &= 0xFFFFFFFC; 4638 armNextPC = reg[15].I; 4639 reg[15].I += 4; 4640 } 4641 } 4642 break; 4643 case 0x7b6: 4644 case 0x7be: 4645 { 4646 // LDR Rd, [Rn, Rm, ROR #]! 4647 int shift = (opcode >> 7) & 31; 4648 u32 value = reg[opcode & 15].I; 4649 if(shift) { 4650 ROR_VALUE; 4651 } else { 4652 RCR_VALUE; 4653 } 4654 int dest = (opcode >> 12) & 15; 4655 int base = (opcode >> 16) & 15; 4656 u32 address = reg[base].I + value; 4657 reg[dest].I = CPUReadMemory(address); 4658 if(dest != base) 4659 reg[base].I = address; 4660 clockTicks += 3 + CPUUpdateTicksAccess32(address); 4661 if(dest == 15) { 4662 clockTicks += 2; 4663 reg[15].I &= 0xFFFFFFFC; 4664 armNextPC = reg[15].I; 4665 reg[15].I += 4; 4666 } 4667 } 4668 break; 4669 case 0x640: 4670 case 0x648: 4671 // T versions are the same 4672 case 0x660: 4673 case 0x668: 4674 { 4675 // STRB Rd, [Rn], -Rm, LSL # 4676 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4677 int dest = (opcode >> 12) & 15; 4678 int base = (opcode >> 16) & 15; 4679 u32 address = reg[base].I; 4680 CPUWriteByte(address, reg[dest].B.B0); 4681 reg[base].I = address - offset; 4682 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4683 } 4684 break; 4685 case 0x642: 4686 case 0x64a: 4687 // T versions are the same 4688 case 0x662: 4689 case 0x66a: 4690 { 4691 // STRB Rd, [Rn], -Rm, LSR # 4692 int shift = (opcode >> 7) & 31; 4693 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4694 int dest = (opcode >> 12) & 15; 4695 int base = (opcode >> 16) & 15; 4696 u32 address = reg[base].I; 4697 CPUWriteByte(address, reg[dest].B.B0); 4698 reg[base].I = address - offset; 4699 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4700 } 4701 break; 4702 case 0x644: 4703 case 0x64c: 4704 // T versions are the same 4705 case 0x664: 4706 case 0x66c: 4707 { 4708 // STRB Rd, [Rn], -Rm, ASR # 4709 int shift = (opcode >> 7) & 31; 4710 int offset; 4711 if(shift) 4712 offset = (int)((s32)reg[opcode & 15].I >> shift); 4713 else if(reg[opcode & 15].I & 0x80000000) 4714 offset = 0xFFFFFFFF; 4715 else 4716 offset = 0; 4717 int dest = (opcode >> 12) & 15; 4718 int base = (opcode >> 16) & 15; 4719 u32 address = reg[base].I; 4720 CPUWriteByte(address, reg[dest].B.B0); 4721 reg[base].I = address - offset; 4722 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4723 } 4724 break; 4725 case 0x646: 4726 case 0x64e: 4727 // T versions are the same 4728 case 0x666: 4729 case 0x66e: 4730 { 4731 // STRB Rd, [Rn], -Rm, ROR # 4732 int shift = (opcode >> 7) & 31; 4733 u32 value = reg[opcode & 15].I; 4734 if(shift) { 4735 ROR_VALUE; 4736 } else { 4737 RCR_VALUE; 4738 } 4739 int dest = (opcode >> 12) & 15; 4740 int base = (opcode >> 16) & 15; 4741 u32 address = reg[base].I; 4742 CPUWriteByte(address, reg[dest].B.B0); 4743 reg[base].I = address - value; 4744 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4745 } 4746 break; 4747 case 0x6c0: 4748 case 0x6c8: 4749 // T versions are the same 4750 case 0x6e0: 4751 case 0x6e8: 4752 { 4753 // STRB Rd, [Rn], Rm, LSL # 4754 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4755 int dest = (opcode >> 12) & 15; 4756 int base = (opcode >> 16) & 15; 4757 u32 address = reg[base].I; 4758 CPUWriteByte(address, reg[dest].B.B0); 4759 reg[base].I = address + offset; 4760 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4761 } 4762 break; 4763 case 0x6c2: 4764 case 0x6ca: 4765 // T versions are the same 4766 case 0x6e2: 4767 case 0x6ea: 4768 { 4769 // STRB Rd, [Rn], Rm, LSR # 4770 int shift = (opcode >> 7) & 31; 4771 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4772 int dest = (opcode >> 12) & 15; 4773 int base = (opcode >> 16) & 15; 4774 u32 address = reg[base].I; 4775 CPUWriteByte(address, reg[dest].B.B0); 4776 reg[base].I = address + offset; 4777 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4778 } 4779 break; 4780 case 0x6c4: 4781 case 0x6cc: 4782 // T versions are the same 4783 case 0x6e4: 4784 case 0x6ec: 4785 { 4786 // STR Rd, [Rn], Rm, ASR # 4787 int shift = (opcode >> 7) & 31; 4788 int offset; 4789 if(shift) 4790 offset = (int)((s32)reg[opcode & 15].I >> shift); 4791 else if(reg[opcode & 15].I & 0x80000000) 4792 offset = 0xFFFFFFFF; 4793 else 4794 offset = 0; 4795 int dest = (opcode >> 12) & 15; 4796 int base = (opcode >> 16) & 15; 4797 u32 address = reg[base].I; 4798 CPUWriteByte(address, reg[dest].B.B0); 4799 reg[base].I = address + offset; 4800 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4801 } 4802 break; 4803 case 0x6c6: 4804 case 0x6ce: 4805 // T versions are the same 4806 case 0x6e6: 4807 case 0x6ee: 4808 { 4809 // STRB Rd, [Rn], Rm, ROR # 4810 int shift = (opcode >> 7) & 31; 4811 u32 value = reg[opcode & 15].I; 4812 if(shift) { 4813 ROR_VALUE; 4814 } else { 4815 RCR_VALUE; 4816 } 4817 int dest = (opcode >> 12) & 15; 4818 int base = (opcode >> 16) & 15; 4819 u32 address = reg[base].I; 4820 CPUWriteByte(address, reg[dest].B.B0); 4821 reg[base].I = address + value; 4822 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4823 } 4824 break; 4825 case 0x740: 4826 case 0x748: 4827 { 4828 // STRB Rd, [Rn, -Rm, LSL #] 4829 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4830 int dest = (opcode >> 12) & 15; 4831 int base = (opcode >> 16) & 15; 4832 u32 address = reg[base].I - offset; 4833 CPUWriteByte(address, reg[dest].B.B0); 4834 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4835 } 4836 break; 4837 case 0x742: 4838 case 0x74a: 4839 { 4840 // STRB Rd, [Rn, -Rm, LSR #] 4841 int shift = (opcode >> 7) & 31; 4842 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4843 int dest = (opcode >> 12) & 15; 4844 int base = (opcode >> 16) & 15; 4845 u32 address = reg[base].I - offset; 4846 CPUWriteByte(address, reg[dest].B.B0); 4847 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4848 } 4849 break; 4850 case 0x744: 4851 case 0x74c: 4852 { 4853 // STRB Rd, [Rn, -Rm, ASR #] 4854 int shift = (opcode >> 7) & 31; 4855 int offset; 4856 if(shift) 4857 offset = (int)((s32)reg[opcode & 15].I >> shift); 4858 else if(reg[opcode & 15].I & 0x80000000) 4859 offset = 0xFFFFFFFF; 4860 else 4861 offset = 0; 4862 int dest = (opcode >> 12) & 15; 4863 int base = (opcode >> 16) & 15; 4864 u32 address = reg[base].I - offset; 4865 CPUWriteByte(address, reg[dest].B.B0); 4866 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4867 } 4868 break; 4869 case 0x746: 4870 case 0x74e: 4871 { 4872 // STRB Rd, [Rn, -Rm, ROR #] 4873 int shift = (opcode >> 7) & 31; 4874 u32 value = reg[opcode & 15].I; 4875 if(shift) { 4876 ROR_VALUE; 4877 } else { 4878 RCR_VALUE; 4879 } 4880 int dest = (opcode >> 12) & 15; 4881 int base = (opcode >> 16) & 15; 4882 u32 address = reg[base].I - value; 4883 CPUWriteByte(address, reg[dest].B.B0); 4884 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4885 } 4886 break; 4887 case 0x760: 4888 case 0x768: 4889 { 4890 // STRB Rd, [Rn, -Rm, LSL #]! 4891 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4892 int dest = (opcode >> 12) & 15; 4893 int base = (opcode >> 16) & 15; 4894 u32 address = reg[base].I - offset; 4895 reg[base].I = address; 4896 CPUWriteByte(address, reg[dest].B.B0); 4897 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4898 } 4899 break; 4900 case 0x762: 4901 case 0x76a: 4902 { 4903 // STRB Rd, [Rn, -Rm, LSR #]! 4904 int shift = (opcode >> 7) & 31; 4905 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4906 int dest = (opcode >> 12) & 15; 4907 int base = (opcode >> 16) & 15; 4908 u32 address = reg[base].I - offset; 4909 reg[base].I = address; 4910 CPUWriteByte(address, reg[dest].B.B0); 4911 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4912 } 4913 break; 4914 case 0x764: 4915 case 0x76c: 4916 { 4917 // STRB Rd, [Rn, -Rm, ASR #]! 4918 int shift = (opcode >> 7) & 31; 4919 int offset; 4920 if(shift) 4921 offset = (int)((s32)reg[opcode & 15].I >> shift); 4922 else if(reg[opcode & 15].I & 0x80000000) 4923 offset = 0xFFFFFFFF; 4924 else 4925 offset = 0; 4926 int dest = (opcode >> 12) & 15; 4927 int base = (opcode >> 16) & 15; 4928 u32 address = reg[base].I - offset; 4929 reg[base].I = address; 4930 CPUWriteByte(address, reg[dest].B.B0); 4931 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4932 } 4933 break; 4934 case 0x766: 4935 case 0x76e: 4936 { 4937 // STRB Rd, [Rn, -Rm, ROR #]! 4938 int shift = (opcode >> 7) & 31; 4939 u32 value = reg[opcode & 15].I; 4940 if(shift) { 4941 ROR_VALUE; 4942 } else { 4943 RCR_VALUE; 4944 } 4945 int dest = (opcode >> 12) & 15; 4946 int base = (opcode >> 16) & 15; 4947 u32 address = reg[base].I - value; 4948 reg[base].I = address; 4949 CPUWriteByte(address, reg[dest].B.B0); 4950 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4951 } 4952 break; 4953 case 0x7c0: 4954 case 0x7c8: 4955 { 4956 // STRB Rd, [Rn, Rm, LSL #] 4957 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 4958 int dest = (opcode >> 12) & 15; 4959 int base = (opcode >> 16) & 15; 4960 u32 address = reg[base].I + offset; 4961 CPUWriteByte(address, reg[dest].B.B0); 4962 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4963 } 4964 break; 4965 case 0x7c2: 4966 case 0x7ca: 4967 { 4968 // STRB Rd, [Rn, Rm, LSR #] 4969 int shift = (opcode >> 7) & 31; 4970 int offset = shift ? reg[opcode & 15].I >> shift : 0; 4971 int dest = (opcode >> 12) & 15; 4972 int base = (opcode >> 16) & 15; 4973 u32 address = reg[base].I + offset; 4974 CPUWriteByte(address, reg[dest].B.B0); 4975 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4976 } 4977 break; 4978 case 0x7c4: 4979 case 0x7cc: 4980 { 4981 // STRB Rd, [Rn, Rm, ASR #] 4982 int shift = (opcode >> 7) & 31; 4983 int offset; 4984 if(shift) 4985 offset = (int)((s32)reg[opcode & 15].I >> shift); 4986 else if(reg[opcode & 15].I & 0x80000000) 4987 offset = 0xFFFFFFFF; 4988 else 4989 offset = 0; 4990 int dest = (opcode >> 12) & 15; 4991 int base = (opcode >> 16) & 15; 4992 u32 address = reg[base].I + offset; 4993 CPUWriteByte(address, reg[dest].B.B0); 4994 clockTicks += 2 + CPUUpdateTicksAccess16(address); 4995 } 4996 break; 4997 case 0x7c6: 4998 case 0x7ce: 4999 { 5000 // STRB Rd, [Rn, Rm, ROR #] 5001 int shift = (opcode >> 7) & 31; 5002 u32 value = reg[opcode & 15].I; 5003 if(shift) { 5004 ROR_VALUE; 5005 } else { 5006 RCR_VALUE; 5007 } 5008 int dest = (opcode >> 12) & 15; 5009 int base = (opcode >> 16) & 15; 5010 u32 address = reg[base].I + value; 5011 CPUWriteByte(address, reg[dest].B.B0); 5012 clockTicks += 2 + CPUUpdateTicksAccess16(address); 5013 } 5014 break; 5015 case 0x7e0: 5016 case 0x7e8: 5017 { 5018 // STRB Rd, [Rn, Rm, LSL #]! 5019 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 5020 int dest = (opcode >> 12) & 15; 5021 int base = (opcode >> 16) & 15; 5022 u32 address = reg[base].I + offset; 5023 reg[base].I = address; 5024 CPUWriteByte(address, reg[dest].B.B0); 5025 clockTicks += 2 + CPUUpdateTicksAccess16(address); 5026 } 5027 break; 5028 case 0x7e2: 5029 case 0x7ea: 5030 { 5031 // STRB Rd, [Rn, Rm, LSR #]! 5032 int shift = (opcode >> 7) & 31; 5033 int offset = shift ? reg[opcode & 15].I >> shift : 0; 5034 int dest = (opcode >> 12) & 15; 5035 int base = (opcode >> 16) & 15; 5036 u32 address = reg[base].I + offset; 5037 reg[base].I = address; 5038 CPUWriteByte(address, reg[dest].B.B0); 5039 clockTicks += 2 + CPUUpdateTicksAccess16(address); 5040 } 5041 break; 5042 case 0x7e4: 5043 case 0x7ec: 5044 { 5045 // STRB Rd, [Rn, Rm, ASR #]! 5046 int shift = (opcode >> 7) & 31; 5047 int offset; 5048 if(shift) 5049 offset = (int)((s32)reg[opcode & 15].I >> shift); 5050 else if(reg[opcode & 15].I & 0x80000000) 5051 offset = 0xFFFFFFFF; 5052 else 5053 offset = 0; 5054 int dest = (opcode >> 12) & 15; 5055 int base = (opcode >> 16) & 15; 5056 u32 address = reg[base].I + offset; 5057 reg[base].I = address; 5058 CPUWriteByte(address, reg[dest].B.B0); 5059 clockTicks += 2 + CPUUpdateTicksAccess16(address); 5060 } 5061 break; 5062 case 0x7e6: 5063 case 0x7ee: 5064 { 5065 // STRB Rd, [Rn, Rm, ROR #]! 5066 int shift = (opcode >> 7) & 31; 5067 u32 value = reg[opcode & 15].I; 5068 if(shift) { 5069 ROR_VALUE; 5070 } else { 5071 RCR_VALUE; 5072 } 5073 int dest = (opcode >> 12) & 15; 5074 int base = (opcode >> 16) & 15; 5075 u32 address = reg[base].I + value; 5076 reg[base].I = address; 5077 CPUWriteByte(address, reg[dest].B.B0); 5078 clockTicks += 2 + CPUUpdateTicksAccess16(address); 5079 } 5080 break; 5081 case 0x650: 5082 case 0x658: 5083 // T versions are the same 5084 case 0x670: 5085 case 0x678: 5086 { 5087 // LDRB Rd, [Rn], -Rm, LSL # 5088 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 5089 int dest = (opcode >> 12) & 15; 5090 int base = (opcode >> 16) & 15; 5091 u32 address = reg[base].I; 5092 reg[dest].I = CPUReadByte(address); 5093 if(dest != base) 5094 reg[base].I = address - offset; 5095 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5096 } 5097 break; 5098 case 0x652: 5099 case 0x65a: 5100 // T versions are the same 5101 case 0x672: 5102 case 0x67a: 5103 { 5104 // LDRB Rd, [Rn], -Rm, LSR # 5105 int shift = (opcode >> 7) & 31; 5106 int offset = shift ? reg[opcode & 15].I >> shift : 0; 5107 int dest = (opcode >> 12) & 15; 5108 int base = (opcode >> 16) & 15; 5109 u32 address = reg[base].I; 5110 reg[dest].I = CPUReadByte(address); 5111 if(dest != base) 5112 reg[base].I = address - offset; 5113 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5114 } 5115 break; 5116 case 0x654: 5117 case 0x65c: 5118 // T versions are the same 5119 case 0x674: 5120 case 0x67c: 5121 { 5122 // LDRB Rd, [Rn], -Rm, ASR # 5123 int shift = (opcode >> 7) & 31; 5124 int offset; 5125 if(shift) 5126 offset = (int)((s32)reg[opcode & 15].I >> shift); 5127 else if(reg[opcode & 15].I & 0x80000000) 5128 offset = 0xFFFFFFFF; 5129 else 5130 offset = 0; 5131 int dest = (opcode >> 12) & 15; 5132 int base = (opcode >> 16) & 15; 5133 u32 address = reg[base].I; 5134 reg[dest].I = CPUReadByte(address); 5135 if(dest != base) 5136 reg[base].I = address - offset; 5137 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5138 } 5139 break; 5140 case 0x656: 5141 case 0x65e: 5142 // T versions are the same 5143 case 0x676: 5144 case 0x67e: 5145 { 5146 // LDRB Rd, [Rn], -Rm, ROR # 5147 int shift = (opcode >> 7) & 31; 5148 u32 value = reg[opcode & 15].I; 5149 if(shift) { 5150 ROR_VALUE; 5151 } else { 5152 RCR_VALUE; 5153 } 5154 int dest = (opcode >> 12) & 15; 5155 int base = (opcode >> 16) & 15; 5156 u32 address = reg[base].I; 5157 reg[dest].I = CPUReadByte(address); 5158 if(dest != base) 5159 reg[base].I = address - value; 5160 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5161 } 5162 break; 5163 case 0x6d0: 5164 case 0x6d8: 5165 // T versions are the same 5166 case 0x6f0: 5167 case 0x6f8: 5168 { 5169 // LDRB Rd, [Rn], Rm, LSL # 5170 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 5171 int dest = (opcode >> 12) & 15; 5172 int base = (opcode >> 16) & 15; 5173 u32 address = reg[base].I; 5174 reg[dest].I = CPUReadByte(address); 5175 if(dest != base) 5176 reg[base].I = address + offset; 5177 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5178 } 5179 break; 5180 case 0x6d2: 5181 case 0x6da: 5182 // T versions are the same 5183 case 0x6f2: 5184 case 0x6fa: 5185 { 5186 // LDRB Rd, [Rn], Rm, LSR # 5187 int shift = (opcode >> 7) & 31; 5188 int offset = shift ? reg[opcode & 15].I >> shift : 0; 5189 int dest = (opcode >> 12) & 15; 5190 int base = (opcode >> 16) & 15; 5191 u32 address = reg[base].I; 5192 reg[dest].I = CPUReadByte(address); 5193 if(dest != base) 5194 reg[base].I = address + offset; 5195 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5196 } 5197 break; 5198 case 0x6d4: 5199 case 0x6dc: 5200 // T versions are the same 5201 case 0x6f4: 5202 case 0x6fc: 5203 { 5204 // LDRB Rd, [Rn], Rm, ASR # 5205 int shift = (opcode >> 7) & 31; 5206 int offset; 5207 if(shift) 5208 offset = (int)((s32)reg[opcode & 15].I >> shift); 5209 else if(reg[opcode & 15].I & 0x80000000) 5210 offset = 0xFFFFFFFF; 5211 else 5212 offset = 0; 5213 int dest = (opcode >> 12) & 15; 5214 int base = (opcode >> 16) & 15; 5215 u32 address = reg[base].I; 5216 reg[dest].I = CPUReadByte(address); 5217 if(dest != base) 5218 reg[base].I = address + offset; 5219 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5220 } 5221 break; 5222 case 0x6d6: 5223 case 0x6de: 5224 // T versions are the same 5225 case 0x6f6: 5226 case 0x6fe: 5227 { 5228 // LDRB Rd, [Rn], Rm, ROR # 5229 int shift = (opcode >> 7) & 31; 5230 u32 value = reg[opcode & 15].I; 5231 if(shift) { 5232 ROR_VALUE; 5233 } else { 5234 RCR_VALUE; 5235 } 5236 int dest = (opcode >> 12) & 15; 5237 int base = (opcode >> 16) & 15; 5238 u32 address = reg[base].I; 5239 reg[dest].I = CPUReadByte(address); 5240 if(dest != base) 5241 reg[base].I = address + value; 5242 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5243 } 5244 break; 5245 case 0x750: 5246 case 0x758: 5247 { 5248 // LDRB Rd, [Rn, -Rm, LSL #] 5249 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 5250 int dest = (opcode >> 12) & 15; 5251 int base = (opcode >> 16) & 15; 5252 u32 address = reg[base].I - offset; 5253 reg[dest].I = CPUReadByte(address); 5254 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5255 } 5256 break; 5257 case 0x752: 5258 case 0x75a: 5259 { 5260 // LDRB Rd, [Rn, -Rm, LSR #] 5261 int shift = (opcode >> 7) & 31; 5262 int offset = shift ? reg[opcode & 15].I >> shift : 0; 5263 int dest = (opcode >> 12) & 15; 5264 int base = (opcode >> 16) & 15; 5265 u32 address = reg[base].I - offset; 5266 reg[dest].I = CPUReadByte(address); 5267 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5268 } 5269 break; 5270 case 0x754: 5271 case 0x75c: 5272 { 5273 // LDRB Rd, [Rn, -Rm, ASR #] 5274 int shift = (opcode >> 7) & 31; 5275 int offset; 5276 if(shift) 5277 offset = (int)((s32)reg[opcode & 15].I >> shift); 5278 else if(reg[opcode & 15].I & 0x80000000) 5279 offset = 0xFFFFFFFF; 5280 else 5281 offset = 0; 5282 int dest = (opcode >> 12) & 15; 5283 int base = (opcode >> 16) & 15; 5284 u32 address = reg[base].I - offset; 5285 reg[dest].I = CPUReadByte(address); 5286 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5287 } 5288 break; 5289 case 0x756: 5290 case 0x75e: 5291 { 5292 // LDRB Rd, [Rn, -Rm, ROR #] 5293 int shift = (opcode >> 7) & 31; 5294 u32 value = reg[opcode & 15].I; 5295 if(shift) { 5296 ROR_VALUE; 5297 } else { 5298 RCR_VALUE; 5299 } 5300 int dest = (opcode >> 12) & 15; 5301 int base = (opcode >> 16) & 15; 5302 u32 address = reg[base].I - value; 5303 reg[dest].I = CPUReadByte(address); 5304 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5305 } 5306 break; 5307 case 0x770: 5308 case 0x778: 5309 { 5310 // LDRB Rd, [Rn, -Rm, LSL #]! 5311 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 5312 int dest = (opcode >> 12) & 15; 5313 int base = (opcode >> 16) & 15; 5314 u32 address = reg[base].I - offset; 5315 reg[dest].I = CPUReadByte(address); 5316 if(dest != base) 5317 reg[base].I = address; 5318 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5319 } 5320 break; 5321 case 0x772: 5322 case 0x77a: 5323 { 5324 // LDRB Rd, [Rn, -Rm, LSR #]! 5325 int shift = (opcode >> 7) & 31; 5326 int offset = shift ? reg[opcode & 15].I >> shift : 0; 5327 int dest = (opcode >> 12) & 15; 5328 int base = (opcode >> 16) & 15; 5329 u32 address = reg[base].I - offset; 5330 reg[dest].I = CPUReadByte(address); 5331 if(dest != base) 5332 reg[base].I = address; 5333 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5334 } 5335 break; 5336 case 0x774: 5337 case 0x77c: 5338 { 5339 // LDRB Rd, [Rn, -Rm, ASR #]! 5340 int shift = (opcode >> 7) & 31; 5341 int offset; 5342 if(shift) 5343 offset = (int)((s32)reg[opcode & 15].I >> shift); 5344 else if(reg[opcode & 15].I & 0x80000000) 5345 offset = 0xFFFFFFFF; 5346 else 5347 offset = 0; 5348 int dest = (opcode >> 12) & 15; 5349 int base = (opcode >> 16) & 15; 5350 u32 address = reg[base].I - offset; 5351 reg[dest].I = CPUReadByte(address); 5352 if(dest != base) 5353 reg[base].I = address; 5354 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5355 } 5356 break; 5357 case 0x776: 5358 case 0x77e: 5359 { 5360 // LDRB Rd, [Rn, -Rm, ROR #]! 5361 int shift = (opcode >> 7) & 31; 5362 u32 value = reg[opcode & 15].I; 5363 if(shift) { 5364 ROR_VALUE; 5365 } else { 5366 RCR_VALUE; 5367 } 5368 int dest = (opcode >> 12) & 15; 5369 int base = (opcode >> 16) & 15; 5370 u32 address = reg[base].I - value; 5371 reg[dest].I = CPUReadByte(address); 5372 if(dest != base) 5373 reg[base].I = address; 5374 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5375 } 5376 break; 5377 case 0x7d0: 5378 case 0x7d8: 5379 { 5380 // LDRB Rd, [Rn, Rm, LSL #] 5381 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 5382 int dest = (opcode >> 12) & 15; 5383 int base = (opcode >> 16) & 15; 5384 u32 address = reg[base].I + offset; 5385 reg[dest].I = CPUReadByte(address); 5386 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5387 } 5388 break; 5389 case 0x7d2: 5390 case 0x7da: 5391 { 5392 // LDRB Rd, [Rn, Rm, LSR #] 5393 int shift = (opcode >> 7) & 31; 5394 int offset = shift ? reg[opcode & 15].I >> shift : 0; 5395 int dest = (opcode >> 12) & 15; 5396 int base = (opcode >> 16) & 15; 5397 u32 address = reg[base].I + offset; 5398 reg[dest].I = CPUReadByte(address); 5399 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5400 } 5401 break; 5402 case 0x7d4: 5403 case 0x7dc: 5404 { 5405 // LDRB Rd, [Rn, Rm, ASR #] 5406 int shift = (opcode >> 7) & 31; 5407 int offset; 5408 if(shift) 5409 offset = (int)((s32)reg[opcode & 15].I >> shift); 5410 else if(reg[opcode & 15].I & 0x80000000) 5411 offset = 0xFFFFFFFF; 5412 else 5413 offset = 0; 5414 int dest = (opcode >> 12) & 15; 5415 int base = (opcode >> 16) & 15; 5416 u32 address = reg[base].I + offset; 5417 reg[dest].I = CPUReadByte(address); 5418 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5419 } 5420 break; 5421 case 0x7d6: 5422 case 0x7de: 5423 { 5424 // LDRB Rd, [Rn, Rm, ROR #] 5425 int shift = (opcode >> 7) & 31; 5426 u32 value = reg[opcode & 15].I; 5427 if(shift) { 5428 ROR_VALUE; 5429 } else { 5430 RCR_VALUE; 5431 } 5432 int dest = (opcode >> 12) & 15; 5433 int base = (opcode >> 16) & 15; 5434 u32 address = reg[base].I + value; 5435 reg[dest].I = CPUReadByte(address); 5436 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5437 } 5438 break; 5439 case 0x7f0: 5440 case 0x7f8: 5441 { 5442 // LDRB Rd, [Rn, Rm, LSL #]! 5443 int offset = reg[opcode & 15].I << ((opcode>>7)& 31); 5444 int dest = (opcode >> 12) & 15; 5445 int base = (opcode >> 16) & 15; 5446 u32 address = reg[base].I + offset; 5447 reg[dest].I = CPUReadByte(address); 5448 if(dest != base) 5449 reg[base].I = address; 5450 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5451 } 5452 break; 5453 case 0x7f2: 5454 case 0x7fa: 5455 { 5456 // LDRB Rd, [Rn, Rm, LSR #]! 5457 int shift = (opcode >> 7) & 31; 5458 int offset = shift ? reg[opcode & 15].I >> shift : 0; 5459 int dest = (opcode >> 12) & 15; 5460 int base = (opcode >> 16) & 15; 5461 u32 address = reg[base].I + offset; 5462 reg[dest].I = CPUReadByte(address); 5463 if(dest != base) 5464 reg[base].I = address; 5465 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5466 } 5467 break; 5468 case 0x7f4: 5469 case 0x7fc: 5470 { 5471 // LDRB Rd, [Rn, Rm, ASR #]! 5472 int shift = (opcode >> 7) & 31; 5473 int offset; 5474 if(shift) 5475 offset = (int)((s32)reg[opcode & 15].I >> shift); 5476 else if(reg[opcode & 15].I & 0x80000000) 5477 offset = 0xFFFFFFFF; 5478 else 5479 offset = 0; 5480 int dest = (opcode >> 12) & 15; 5481 int base = (opcode >> 16) & 15; 5482 u32 address = reg[base].I + offset; 5483 reg[dest].I = CPUReadByte(address); 5484 if(dest != base) 5485 reg[base].I = address; 5486 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5487 } 5488 break; 5489 case 0x7f6: 5490 case 0x7fe: 5491 { 5492 // LDRB Rd, [Rn, Rm, ROR #]! 5493 int shift = (opcode >> 7) & 31; 5494 u32 value = reg[opcode & 15].I; 5495 if(shift) { 5496 ROR_VALUE; 5497 } else { 5498 RCR_VALUE; 5499 } 5500 int dest = (opcode >> 12) & 15; 5501 int base = (opcode >> 16) & 15; 5502 u32 address = reg[base].I + value; 5503 reg[dest].I = CPUReadByte(address); 5504 if(dest != base) 5505 reg[base].I = address; 5506 clockTicks += 3 + CPUUpdateTicksAccess16(address); 5507 } 5508 break; 5509 #define STMW_REG(val,num) \ 5510 if(opcode & (val)) {\ 5511 CPUWriteMemory(address, reg[(num)].I);\ 5512 if(!offset) {\ 5513 reg[base].I = temp;\ 5514 clockTicks += 1 + CPUUpdateTicksAccess32(address);\ 5515 offset = 1;\ 5516 } else {\ 5517 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);\ 5518 }\ 5519 address += 4;\ 5520 } 5521 #define STM_REG(val,num) \ 5522 if(opcode & (val)) {\ 5523 CPUWriteMemory(address, reg[(num)].I);\ 5524 if(!offset) {\ 5525 clockTicks += 1 + CPUUpdateTicksAccess32(address);\ 5526 offset = 1;\ 5527 } else {\ 5528 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);\ 5529 }\ 5530 address += 4;\ 5531 } 5532 5533 CASE_16(0x800) 5534 // STMDA Rn, {Rlist} 5535 { 5536 int base = (opcode & 0x000F0000) >> 16; 5537 u32 temp = reg[base].I - 5538 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 5539 u32 address = (temp + 4) & 0xFFFFFFFC; 5540 clockTicks += 2; 5541 int offset = 0; 5542 STM_REG(1, 0); 5543 STM_REG(2, 1); 5544 STM_REG(4, 2); 5545 STM_REG(8, 3); 5546 STM_REG(16, 4); 5547 STM_REG(32, 5); 5548 STM_REG(64, 6); 5549 STM_REG(128, 7); 5550 STM_REG(256, 8); 5551 STM_REG(512, 9); 5552 STM_REG(1024, 10); 5553 STM_REG(2048, 11); 5554 STM_REG(4096, 12); 5555 STM_REG(8192, 13); 5556 STM_REG(16384, 14); 5557 if(opcode & 32768) { 5558 CPUWriteMemory(address, reg[15].I+4); 5559 if(!offset) 5560 clockTicks += 1 + CPUUpdateTicksAccess32(address); 5561 else 5562 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 5563 } 5564 } 5565 break; 5566 CASE_16(0x820) 5567 { 5568 // STMDA Rn!, {Rlist} 5569 int base = (opcode & 0x000F0000) >> 16; 5570 u32 temp = reg[base].I - 5571 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 5572 u32 address = (temp+4) & 0xFFFFFFFC; 5573 clockTicks += 2; 5574 int offset = 0; 5575 5576 STMW_REG(1, 0); 5577 STMW_REG(2, 1); 5578 STMW_REG(4, 2); 5579 STMW_REG(8, 3); 5580 STMW_REG(16, 4); 5581 STMW_REG(32, 5); 5582 STMW_REG(64, 6); 5583 STMW_REG(128, 7); 5584 STMW_REG(256, 8); 5585 STMW_REG(512, 9); 5586 STMW_REG(1024, 10); 5587 STMW_REG(2048, 11); 5588 STMW_REG(4096, 12); 5589 STMW_REG(8192, 13); 5590 STMW_REG(16384, 14); 5591 if(opcode & 32768) { 5592 CPUWriteMemory(address, reg[15].I+4); 5593 if(!offset) 5594 clockTicks += 1 + CPUUpdateTicksAccess32(address); 5595 else 5596 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 5597 reg[base].I = temp; 5598 } 5599 } 5600 break; 5601 CASE_16(0x840) 5602 { 5603 // STMDA Rn, {Rlist}^ 5604 int base = (opcode & 0x000F0000) >> 16; 5605 u32 temp = reg[base].I - 5606 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 5607 u32 address = (temp+4) & 0xFFFFFFFC; 5608 clockTicks += 2; 5609 int offset = 0; 5610 5611 STM_REG(1, 0); 5612 STM_REG(2, 1); 5613 STM_REG(4, 2); 5614 STM_REG(8, 3); 5615 STM_REG(16, 4); 5616 STM_REG(32, 5); 5617 STM_REG(64, 6); 5618 STM_REG(128, 7); 5619 5620 if(armMode == 0x11) { 5621 STM_REG(256, R8_FIQ); 5622 STM_REG(512, R9_FIQ); 5623 STM_REG(1024, R10_FIQ); 5624 STM_REG(2048, R11_FIQ); 5625 STM_REG(4096, R12_FIQ); 5626 } else { 5627 STM_REG(256, 8); 5628 STM_REG(512, 9); 5629 STM_REG(1024, 10); 5630 STM_REG(2048, 11); 5631 STM_REG(4096, 12); 5632 } 5633 5634 if(armMode != 0x10 && armMode != 0x1f) { 5635 STM_REG(8192, R13_USR); 5636 STM_REG(16384, R14_USR); 5637 } else { 5638 STM_REG(8192, 13); 5639 STM_REG(16384, 14); 5640 } 5641 5642 if(opcode & 32768) { 5643 CPUWriteMemory(address, reg[15].I+4); 5644 if(!offset) 5645 clockTicks += 1 + CPUUpdateTicksAccess32(address); 5646 else 5647 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 5648 } 5649 } 5650 break; 5651 CASE_16(0x860) 5652 { 5653 // STMDA Rn!, {Rlist}^ 5654 int base = (opcode & 0x000F0000) >> 16; 5655 u32 temp = reg[base].I - 5656 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 5657 u32 address = (temp+4) & 0xFFFFFFFC; 5658 clockTicks += 2; 5659 int offset = 0; 5660 5661 STMW_REG(1, 0); 5662 STMW_REG(2, 1); 5663 STMW_REG(4, 2); 5664 STMW_REG(8, 3); 5665 STMW_REG(16, 4); 5666 STMW_REG(32, 5); 5667 STMW_REG(64, 6); 5668 STMW_REG(128, 7); 5669 5670 if(armMode == 0x11) { 5671 STMW_REG(256, R8_FIQ); 5672 STMW_REG(512, R9_FIQ); 5673 STMW_REG(1024, R10_FIQ); 5674 STMW_REG(2048, R11_FIQ); 5675 STMW_REG(4096, R12_FIQ); 5676 } else { 5677 STMW_REG(256, 8); 5678 STMW_REG(512, 9); 5679 STMW_REG(1024, 10); 5680 STMW_REG(2048, 11); 5681 STMW_REG(4096, 12); 5682 } 5683 5684 if(armMode != 0x10 && armMode != 0x1f) { 5685 STMW_REG(8192, R13_USR); 5686 STMW_REG(16384, R14_USR); 5687 } else { 5688 STMW_REG(8192, 13); 5689 STMW_REG(16384, 14); 5690 } 5691 5692 if(opcode & 32768) { 5693 CPUWriteMemory(address, reg[15].I+4); 5694 if(!offset) 5695 clockTicks += 1 + CPUUpdateTicksAccess32(address); 5696 else 5697 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 5698 reg[base].I = temp; 5699 } 5700 } 5701 break; 5702 5703 CASE_16(0x880) 5704 { 5705 // STMIA Rn, {Rlist} 5706 int base = (opcode & 0x000F0000) >> 16; 5707 u32 address = reg[base].I & 0xFFFFFFFC; 5708 clockTicks += 2; 5709 int offset = 0; 5710 STM_REG(1, 0); 5711 STM_REG(2, 1); 5712 STM_REG(4, 2); 5713 STM_REG(8, 3); 5714 STM_REG(16, 4); 5715 STM_REG(32, 5); 5716 STM_REG(64, 6); 5717 STM_REG(128, 7); 5718 STM_REG(256, 8); 5719 STM_REG(512, 9); 5720 STM_REG(1024, 10); 5721 STM_REG(2048, 11); 5722 STM_REG(4096, 12); 5723 STM_REG(8192, 13); 5724 STM_REG(16384, 14); 5725 if(opcode & 32768) { 5726 CPUWriteMemory(address, reg[15].I+4); 5727 if(!offset) 5728 clockTicks += 1 + CPUUpdateTicksAccess32(address); 5729 else 5730 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 5731 } 5732 } 5733 break; 5734 CASE_16(0x8a0) 5735 { 5736 // STMIA Rn!, {Rlist} 5737 int base = (opcode & 0x000F0000) >> 16; 5738 u32 address = reg[base].I & 0xFFFFFFFC; 5739 clockTicks += 2; 5740 int offset = 0; 5741 u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] + 5742 cpuBitsSet[(opcode >> 8) & 255]); 5743 STMW_REG(1, 0); 5744 STMW_REG(2, 1); 5745 STMW_REG(4, 2); 5746 STMW_REG(8, 3); 5747 STMW_REG(16, 4); 5748 STMW_REG(32, 5); 5749 STMW_REG(64, 6); 5750 STMW_REG(128, 7); 5751 STMW_REG(256, 8); 5752 STMW_REG(512, 9); 5753 STMW_REG(1024, 10); 5754 STMW_REG(2048, 11); 5755 STMW_REG(4096, 12); 5756 STMW_REG(8192, 13); 5757 STMW_REG(16384, 14); 5758 if(opcode & 32768) { 5759 CPUWriteMemory(address, reg[15].I+4); 5760 if(!offset) { 5761 reg[base].I = temp; 5762 clockTicks += 1 + CPUUpdateTicksAccess32(address); 5763 } else 5764 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 5765 } 5766 } 5767 break; 5768 CASE_16(0x8c0) 5769 { 5770 // STMIA Rn, {Rlist}^ 5771 int base = (opcode & 0x000F0000) >> 16; 5772 u32 address = reg[base].I & 0xFFFFFFFC; 5773 clockTicks += 2; 5774 int offset = 0; 5775 STM_REG(1, 0); 5776 STM_REG(2, 1); 5777 STM_REG(4, 2); 5778 STM_REG(8, 3); 5779 STM_REG(16, 4); 5780 STM_REG(32, 5); 5781 STM_REG(64, 6); 5782 STM_REG(128, 7); 5783 if(armMode == 0x11) { 5784 STM_REG(256, R8_FIQ); 5785 STM_REG(512, R9_FIQ); 5786 STM_REG(1024, R10_FIQ); 5787 STM_REG(2048, R11_FIQ); 5788 STM_REG(4096, R12_FIQ); 5789 } else { 5790 STM_REG(256, 8); 5791 STM_REG(512, 9); 5792 STM_REG(1024, 10); 5793 STM_REG(2048, 11); 5794 STM_REG(4096, 12); 5795 } 5796 if(armMode != 0x10 && armMode != 0x1f) { 5797 STM_REG(8192, R13_USR); 5798 STM_REG(16384, R14_USR); 5799 } else { 5800 STM_REG(8192, 13); 5801 STM_REG(16384, 14); 5802 } 5803 if(opcode & 32768) { 5804 CPUWriteMemory(address, reg[15].I+4); 5805 if(!offset) 5806 clockTicks += 1 + CPUUpdateTicksAccess32(address); 5807 else 5808 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 5809 } 5810 } 5811 break; 5812 CASE_16(0x8e0) 5813 { 5814 // STMIA Rn!, {Rlist}^ 5815 int base = (opcode & 0x000F0000) >> 16; 5816 u32 address = reg[base].I & 0xFFFFFFFC; 5817 clockTicks += 2; 5818 int offset = 0; 5819 u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] + 5820 cpuBitsSet[(opcode >> 8) & 255]); 5821 STMW_REG(1, 0); 5822 STMW_REG(2, 1); 5823 STMW_REG(4, 2); 5824 STMW_REG(8, 3); 5825 STMW_REG(16, 4); 5826 STMW_REG(32, 5); 5827 STMW_REG(64, 6); 5828 STMW_REG(128, 7); 5829 if(armMode == 0x11) { 5830 STMW_REG(256, R8_FIQ); 5831 STMW_REG(512, R9_FIQ); 5832 STMW_REG(1024, R10_FIQ); 5833 STMW_REG(2048, R11_FIQ); 5834 STMW_REG(4096, R12_FIQ); 5835 } else { 5836 STMW_REG(256, 8); 5837 STMW_REG(512, 9); 5838 STMW_REG(1024, 10); 5839 STMW_REG(2048, 11); 5840 STMW_REG(4096, 12); 5841 } 5842 if(armMode != 0x10 && armMode != 0x1f) { 5843 STMW_REG(8192, R13_USR); 5844 STMW_REG(16384, R14_USR); 5845 } else { 5846 STMW_REG(8192, 13); 5847 STMW_REG(16384, 14); 5848 } 5849 if(opcode & 32768) { 5850 CPUWriteMemory(address, reg[15].I+4); 5851 if(!offset) { 5852 reg[base].I = temp; 5853 clockTicks += 1 + CPUUpdateTicksAccess32(address); 5854 } else 5855 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 5856 } 5857 } 5858 break; 5859 5860 CASE_16(0x900) 5861 { 5862 // STMDB Rn, {Rlist} 5863 int base = (opcode & 0x000F0000) >> 16; 5864 u32 temp = reg[base].I - 5865 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 5866 u32 address = temp & 0xFFFFFFFC; 5867 clockTicks += 2; 5868 int offset = 0; 5869 STM_REG(1, 0); 5870 STM_REG(2, 1); 5871 STM_REG(4, 2); 5872 STM_REG(8, 3); 5873 STM_REG(16, 4); 5874 STM_REG(32, 5); 5875 STM_REG(64, 6); 5876 STM_REG(128, 7); 5877 STM_REG(256, 8); 5878 STM_REG(512, 9); 5879 STM_REG(1024, 10); 5880 STM_REG(2048, 11); 5881 STM_REG(4096, 12); 5882 STM_REG(8192, 13); 5883 STM_REG(16384, 14); 5884 if(opcode & 32768) { 5885 CPUWriteMemory(address, reg[15].I+4); 5886 if(!offset) 5887 clockTicks += 1 + CPUUpdateTicksAccess32(address); 5888 else 5889 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 5890 } 5891 } 5892 break; 5893 CASE_16(0x920) 5894 { 5895 // STMDB Rn!, {Rlist} 5896 int base = (opcode & 0x000F0000) >> 16; 5897 u32 temp = reg[base].I - 5898 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 5899 u32 address = temp & 0xFFFFFFFC; 5900 clockTicks += 2; 5901 int offset = 0; 5902 5903 STMW_REG(1, 0); 5904 STMW_REG(2, 1); 5905 STMW_REG(4, 2); 5906 STMW_REG(8, 3); 5907 STMW_REG(16, 4); 5908 STMW_REG(32, 5); 5909 STMW_REG(64, 6); 5910 STMW_REG(128, 7); 5911 STMW_REG(256, 8); 5912 STMW_REG(512, 9); 5913 STMW_REG(1024, 10); 5914 STMW_REG(2048, 11); 5915 STMW_REG(4096, 12); 5916 STMW_REG(8192, 13); 5917 STMW_REG(16384, 14); 5918 if(opcode & 32768) { 5919 CPUWriteMemory(address, reg[15].I+4); 5920 if(!offset) 5921 clockTicks += 1 + CPUUpdateTicksAccess32(address); 5922 else 5923 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 5924 reg[base].I = temp; 5925 } 5926 } 5927 break; 5928 CASE_16(0x940) 5929 { 5930 // STMDB Rn, {Rlist}^ 5931 int base = (opcode & 0x000F0000) >> 16; 5932 u32 temp = reg[base].I - 5933 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 5934 u32 address = temp & 0xFFFFFFFC; 5935 clockTicks += 2; 5936 int offset = 0; 5937 5938 STM_REG(1, 0); 5939 STM_REG(2, 1); 5940 STM_REG(4, 2); 5941 STM_REG(8, 3); 5942 STM_REG(16, 4); 5943 STM_REG(32, 5); 5944 STM_REG(64, 6); 5945 STM_REG(128, 7); 5946 5947 if(armMode == 0x11) { 5948 STM_REG(256, R8_FIQ); 5949 STM_REG(512, R9_FIQ); 5950 STM_REG(1024, R10_FIQ); 5951 STM_REG(2048, R11_FIQ); 5952 STM_REG(4096, R12_FIQ); 5953 } else { 5954 STM_REG(256, 8); 5955 STM_REG(512, 9); 5956 STM_REG(1024, 10); 5957 STM_REG(2048, 11); 5958 STM_REG(4096, 12); 5959 } 5960 5961 if(armMode != 0x10 && armMode != 0x1f) { 5962 STM_REG(8192, R13_USR); 5963 STM_REG(16384, R14_USR); 5964 } else { 5965 STM_REG(8192, 13); 5966 STM_REG(16384, 14); 5967 } 5968 5969 if(opcode & 32768) { 5970 CPUWriteMemory(address, reg[15].I+4); 5971 if(!offset) 5972 clockTicks += 1 + CPUUpdateTicksAccess32(address); 5973 else 5974 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 5975 } 5976 } 5977 break; 5978 CASE_16(0x960) 5979 { 5980 // STMDB Rn!, {Rlist}^ 5981 int base = (opcode & 0x000F0000) >> 16; 5982 u32 temp = reg[base].I - 5983 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 5984 u32 address = temp & 0xFFFFFFFC; 5985 clockTicks += 2; 5986 int offset = 0; 5987 5988 STMW_REG(1, 0); 5989 STMW_REG(2, 1); 5990 STMW_REG(4, 2); 5991 STMW_REG(8, 3); 5992 STMW_REG(16, 4); 5993 STMW_REG(32, 5); 5994 STMW_REG(64, 6); 5995 STMW_REG(128, 7); 5996 5997 if(armMode == 0x11) { 5998 STMW_REG(256, R8_FIQ); 5999 STMW_REG(512, R9_FIQ); 6000 STMW_REG(1024, R10_FIQ); 6001 STMW_REG(2048, R11_FIQ); 6002 STMW_REG(4096, R12_FIQ); 6003 } else { 6004 STMW_REG(256, 8); 6005 STMW_REG(512, 9); 6006 STMW_REG(1024, 10); 6007 STMW_REG(2048, 11); 6008 STMW_REG(4096, 12); 6009 } 6010 6011 if(armMode != 0x10 && armMode != 0x1f) { 6012 STMW_REG(8192, R13_USR); 6013 STMW_REG(16384, R14_USR); 6014 } else { 6015 STMW_REG(8192, 13); 6016 STMW_REG(16384, 14); 6017 } 6018 6019 if(opcode & 32768) { 6020 CPUWriteMemory(address, reg[15].I+4); 6021 if(!offset) 6022 clockTicks += 1 + CPUUpdateTicksAccess32(address); 6023 else 6024 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 6025 reg[base].I = temp; 6026 } 6027 } 6028 break; 6029 6030 CASE_16(0x980) 6031 // STMIB Rn, {Rlist} 6032 { 6033 int base = (opcode & 0x000F0000) >> 16; 6034 u32 address = (reg[base].I+4) & 0xFFFFFFFC; 6035 clockTicks += 2; 6036 int offset = 0; 6037 STM_REG(1, 0); 6038 STM_REG(2, 1); 6039 STM_REG(4, 2); 6040 STM_REG(8, 3); 6041 STM_REG(16, 4); 6042 STM_REG(32, 5); 6043 STM_REG(64, 6); 6044 STM_REG(128, 7); 6045 STM_REG(256, 8); 6046 STM_REG(512, 9); 6047 STM_REG(1024, 10); 6048 STM_REG(2048, 11); 6049 STM_REG(4096, 12); 6050 STM_REG(8192, 13); 6051 STM_REG(16384, 14); 6052 if(opcode & 32768) { 6053 CPUWriteMemory(address, reg[15].I+4); 6054 if(!offset) 6055 clockTicks += 1 + CPUUpdateTicksAccess32(address); 6056 else 6057 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 6058 } 6059 } 6060 break; 6061 CASE_16(0x9a0) 6062 { 6063 // STMIB Rn!, {Rlist} 6064 int base = (opcode & 0x000F0000) >> 16; 6065 u32 address = (reg[base].I+4) & 0xFFFFFFFC; 6066 clockTicks += 2; 6067 int offset = 0; 6068 u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] + 6069 cpuBitsSet[(opcode >> 8) & 255]); 6070 STMW_REG(1, 0); 6071 STMW_REG(2, 1); 6072 STMW_REG(4, 2); 6073 STMW_REG(8, 3); 6074 STMW_REG(16, 4); 6075 STMW_REG(32, 5); 6076 STMW_REG(64, 6); 6077 STMW_REG(128, 7); 6078 STMW_REG(256, 8); 6079 STMW_REG(512, 9); 6080 STMW_REG(1024, 10); 6081 STMW_REG(2048, 11); 6082 STMW_REG(4096, 12); 6083 STMW_REG(8192, 13); 6084 STMW_REG(16384, 14); 6085 if(opcode & 32768) { 6086 CPUWriteMemory(address, reg[15].I+4); 6087 if(!offset) { 6088 reg[base].I = temp; 6089 clockTicks += 1 + CPUUpdateTicksAccess32(address); 6090 } else 6091 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 6092 } 6093 } 6094 break; 6095 CASE_16(0x9c0) 6096 { 6097 // STMIB Rn, {Rlist}^ 6098 int base = (opcode & 0x000F0000) >> 16; 6099 u32 address = (reg[base].I+4) & 0xFFFFFFFC; 6100 clockTicks += 2; 6101 int offset = 0; 6102 STM_REG(1, 0); 6103 STM_REG(2, 1); 6104 STM_REG(4, 2); 6105 STM_REG(8, 3); 6106 STM_REG(16, 4); 6107 STM_REG(32, 5); 6108 STM_REG(64, 6); 6109 STM_REG(128, 7); 6110 if(armMode == 0x11) { 6111 STM_REG(256, R8_FIQ); 6112 STM_REG(512, R9_FIQ); 6113 STM_REG(1024, R10_FIQ); 6114 STM_REG(2048, R11_FIQ); 6115 STM_REG(4096, R12_FIQ); 6116 } else { 6117 STM_REG(256, 8); 6118 STM_REG(512, 9); 6119 STM_REG(1024, 10); 6120 STM_REG(2048, 11); 6121 STM_REG(4096, 12); 6122 } 6123 if(armMode != 0x10 && armMode != 0x1f) { 6124 STM_REG(8192, R13_USR); 6125 STM_REG(16384, R14_USR); 6126 } else { 6127 STM_REG(8192, 13); 6128 STM_REG(16384, 14); 6129 } 6130 if(opcode & 32768) { 6131 CPUWriteMemory(address, reg[15].I+4); 6132 if(!offset) 6133 clockTicks += 1 + CPUUpdateTicksAccess32(address); 6134 else 6135 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 6136 } 6137 } 6138 break; 6139 CASE_16(0x9e0) 6140 { 6141 // STMIB Rn!, {Rlist}^ 6142 int base = (opcode & 0x000F0000) >> 16; 6143 u32 address = (reg[base].I+4) & 0xFFFFFFFC; 6144 clockTicks += 2; 6145 int offset = 0; 6146 u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] + 6147 cpuBitsSet[(opcode >> 8) & 255]); 6148 STMW_REG(1, 0); 6149 STMW_REG(2, 1); 6150 STMW_REG(4, 2); 6151 STMW_REG(8, 3); 6152 STMW_REG(16, 4); 6153 STMW_REG(32, 5); 6154 STMW_REG(64, 6); 6155 STMW_REG(128, 7); 6156 if(armMode == 0x11) { 6157 STMW_REG(256, R8_FIQ); 6158 STMW_REG(512, R9_FIQ); 6159 STMW_REG(1024, R10_FIQ); 6160 STMW_REG(2048, R11_FIQ); 6161 STMW_REG(4096, R12_FIQ); 6162 } else { 6163 STMW_REG(256, 8); 6164 STMW_REG(512, 9); 6165 STMW_REG(1024, 10); 6166 STMW_REG(2048, 11); 6167 STMW_REG(4096, 12); 6168 } 6169 if(armMode != 0x10 && armMode != 0x1f) { 6170 STMW_REG(8192, R13_USR); 6171 STMW_REG(16384, R14_USR); 6172 } else { 6173 STMW_REG(8192, 13); 6174 STMW_REG(16384, 14); 6175 } 6176 if(opcode & 32768) { 6177 CPUWriteMemory(address, reg[15].I+4); 6178 if(!offset) { 6179 reg[base].I = temp; 6180 clockTicks += 1 + CPUUpdateTicksAccess32(address); 6181 } else 6182 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); 6183 } 6184 } 6185 break; 6186 6187 #define LDM_REG(val,num) \ 6188 if(opcode & (val)) {\ 6189 reg[(num)].I = CPUReadMemory(address);\ 6190 if(offset)\ 6191 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);\ 6192 else {\ 6193 clockTicks += 1 + CPUUpdateTicksAccess32(address);\ 6194 offset = 1;\ 6195 }\ 6196 address += 4;\ 6197 } 6198 6199 CASE_16(0x810) 6200 { 6201 // LDMDA Rn, {Rlist} 6202 int base = (opcode & 0x000F0000) >> 16; 6203 u32 temp = reg[base].I - 6204 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 6205 u32 address = (temp + 4) & 0xFFFFFFFC; 6206 clockTicks += 2; 6207 int offset = 0; 6208 LDM_REG(1, 0); 6209 LDM_REG(2, 1); 6210 LDM_REG(4, 2); 6211 LDM_REG(8, 3); 6212 LDM_REG(16, 4); 6213 LDM_REG(32, 5); 6214 LDM_REG(64, 6); 6215 LDM_REG(128, 7); 6216 LDM_REG(256, 8); 6217 LDM_REG(512, 9); 6218 LDM_REG(1024, 10); 6219 LDM_REG(2048, 11); 6220 LDM_REG(4096, 12); 6221 LDM_REG(8192, 13); 6222 LDM_REG(16384, 14); 6223 if(opcode & 32768) { 6224 reg[15].I = CPUReadMemory(address); 6225 if (!offset) 6226 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6227 else 6228 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6229 armNextPC = reg[15].I; 6230 reg[15].I += 4; 6231 } 6232 } 6233 break; 6234 CASE_16(0x830) 6235 { 6236 // LDMDA Rn!, {Rlist} 6237 int base = (opcode & 0x000F0000) >> 16; 6238 u32 temp = reg[base].I - 6239 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 6240 u32 address = (temp + 4) & 0xFFFFFFFC; 6241 clockTicks += 2; 6242 int offset = 0; 6243 LDM_REG(1, 0); 6244 LDM_REG(2, 1); 6245 LDM_REG(4, 2); 6246 LDM_REG(8, 3); 6247 LDM_REG(16, 4); 6248 LDM_REG(32, 5); 6249 LDM_REG(64, 6); 6250 LDM_REG(128, 7); 6251 LDM_REG(256, 8); 6252 LDM_REG(512, 9); 6253 LDM_REG(1024, 10); 6254 LDM_REG(2048, 11); 6255 LDM_REG(4096, 12); 6256 LDM_REG(8192, 13); 6257 LDM_REG(16384, 14); 6258 if(opcode & 32768) { 6259 reg[15].I = CPUReadMemory(address); 6260 if (!offset) 6261 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6262 else 6263 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6264 armNextPC = reg[15].I; 6265 reg[15].I += 4; 6266 } 6267 if(!(opcode & (1 << base))) 6268 reg[base].I = temp; 6269 } 6270 break; 6271 CASE_16(0x850) 6272 { 6273 // LDMDA Rn, {Rlist}^ 6274 int base = (opcode & 0x000F0000) >> 16; 6275 u32 temp = reg[base].I - 6276 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 6277 u32 address = (temp + 4) & 0xFFFFFFFC; 6278 clockTicks += 2; 6279 int offset = 0; 6280 if(opcode & 0x8000) { 6281 LDM_REG(1, 0); 6282 LDM_REG(2, 1); 6283 LDM_REG(4, 2); 6284 LDM_REG(8, 3); 6285 LDM_REG(16, 4); 6286 LDM_REG(32, 5); 6287 LDM_REG(64, 6); 6288 LDM_REG(128, 7); 6289 LDM_REG(256, 8); 6290 LDM_REG(512, 9); 6291 LDM_REG(1024, 10); 6292 LDM_REG(2048, 11); 6293 LDM_REG(4096, 12); 6294 LDM_REG(8192, 13); 6295 LDM_REG(16384, 14); 6296 6297 reg[15].I = CPUReadMemory(address); 6298 if (!offset) 6299 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6300 else 6301 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6302 6303 CPUSwitchMode(reg[17].I & 0x1f, false); 6304 if(armState) { 6305 armNextPC = reg[15].I & 0xFFFFFFFC; 6306 reg[15].I = armNextPC + 4; 6307 } else { 6308 armNextPC = reg[15].I & 0xFFFFFFFE; 6309 reg[15].I = armNextPC + 2; 6310 } 6311 } else { 6312 LDM_REG(1, 0); 6313 LDM_REG(2, 1); 6314 LDM_REG(4, 2); 6315 LDM_REG(8, 3); 6316 LDM_REG(16, 4); 6317 LDM_REG(32, 5); 6318 LDM_REG(64, 6); 6319 LDM_REG(128, 7); 6320 6321 if(armMode == 0x11) { 6322 LDM_REG(256, R8_FIQ); 6323 LDM_REG(512, R9_FIQ); 6324 LDM_REG(1024, R10_FIQ); 6325 LDM_REG(2048, R11_FIQ); 6326 LDM_REG(4096, R12_FIQ); 6327 } else { 6328 LDM_REG(256, 8); 6329 LDM_REG(512, 9); 6330 LDM_REG(1024, 10); 6331 LDM_REG(2048, 11); 6332 LDM_REG(4096, 12); 6333 } 6334 6335 if(armMode != 0x10 && armMode != 0x1f) { 6336 LDM_REG(8192, R13_USR); 6337 LDM_REG(16384, R14_USR); 6338 } else { 6339 LDM_REG(8192, 13); 6340 LDM_REG(16384, 14); 6341 } 6342 } 6343 } 6344 break; 6345 CASE_16(0x870) 6346 { 6347 // LDMDA Rn!, {Rlist}^ 6348 int base = (opcode & 0x000F0000) >> 16; 6349 u32 temp = reg[base].I - 6350 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 6351 u32 address = (temp + 4) & 0xFFFFFFFC; 6352 clockTicks += 2; 6353 int offset = 0; 6354 if(opcode & 0x8000) { 6355 LDM_REG(1, 0); 6356 LDM_REG(2, 1); 6357 LDM_REG(4, 2); 6358 LDM_REG(8, 3); 6359 LDM_REG(16, 4); 6360 LDM_REG(32, 5); 6361 LDM_REG(64, 6); 6362 LDM_REG(128, 7); 6363 LDM_REG(256, 8); 6364 LDM_REG(512, 9); 6365 LDM_REG(1024, 10); 6366 LDM_REG(2048, 11); 6367 LDM_REG(4096, 12); 6368 LDM_REG(8192, 13); 6369 LDM_REG(16384, 14); 6370 6371 reg[15].I = CPUReadMemory(address); 6372 if(!offset) 6373 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6374 else 6375 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6376 6377 if(!(opcode & (1 << base))) 6378 reg[base].I = temp; 6379 6380 CPUSwitchMode(reg[17].I & 0x1f, false); 6381 if(armState) { 6382 armNextPC = reg[15].I & 0xFFFFFFFC; 6383 reg[15].I = armNextPC + 4; 6384 } else { 6385 armNextPC = reg[15].I & 0xFFFFFFFE; 6386 reg[15].I = armNextPC + 2; 6387 } 6388 } else { 6389 LDM_REG(1, 0); 6390 LDM_REG(2, 1); 6391 LDM_REG(4, 2); 6392 LDM_REG(8, 3); 6393 LDM_REG(16, 4); 6394 LDM_REG(32, 5); 6395 LDM_REG(64, 6); 6396 LDM_REG(128, 7); 6397 6398 if(armMode == 0x11) { 6399 LDM_REG(256, R8_FIQ); 6400 LDM_REG(512, R9_FIQ); 6401 LDM_REG(1024, R10_FIQ); 6402 LDM_REG(2048, R11_FIQ); 6403 LDM_REG(4096, R12_FIQ); 6404 } else { 6405 LDM_REG(256, 8); 6406 LDM_REG(512, 9); 6407 LDM_REG(1024, 10); 6408 LDM_REG(2048, 11); 6409 LDM_REG(4096, 12); 6410 } 6411 6412 if(armMode != 0x10 && armMode != 0x1f) { 6413 LDM_REG(8192, R13_USR); 6414 LDM_REG(16384, R14_USR); 6415 } else { 6416 LDM_REG(8192, 13); 6417 LDM_REG(16384, 14); 6418 } 6419 6420 if(!(opcode & (1 << base))) 6421 reg[base].I = temp; 6422 } 6423 } 6424 break; 6425 6426 CASE_16(0x890) 6427 { 6428 // LDMIA Rn, {Rlist} 6429 int base = (opcode & 0x000F0000) >> 16; 6430 u32 address = reg[base].I & 0xFFFFFFFC; 6431 clockTicks += 2; 6432 int offset = 0; 6433 LDM_REG(1, 0); 6434 LDM_REG(2, 1); 6435 LDM_REG(4, 2); 6436 LDM_REG(8, 3); 6437 LDM_REG(16, 4); 6438 LDM_REG(32, 5); 6439 LDM_REG(64, 6); 6440 LDM_REG(128, 7); 6441 LDM_REG(256, 8); 6442 LDM_REG(512, 9); 6443 LDM_REG(1024, 10); 6444 LDM_REG(2048, 11); 6445 LDM_REG(4096, 12); 6446 LDM_REG(8192, 13); 6447 LDM_REG(16384, 14); 6448 if(opcode & 32768) { 6449 reg[15].I = CPUReadMemory(address); 6450 if (!offset) 6451 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6452 else 6453 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6454 armNextPC = reg[15].I; 6455 reg[15].I += 4; 6456 } 6457 } 6458 break; 6459 CASE_16(0x8b0) 6460 { 6461 // LDMIA Rn!, {Rlist} 6462 int base = (opcode & 0x000F0000) >> 16; 6463 u32 temp = reg[base].I + 6464 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 6465 u32 address = reg[base].I & 0xFFFFFFFC; 6466 clockTicks += 2; 6467 int offset = 0; 6468 LDM_REG(1, 0); 6469 LDM_REG(2, 1); 6470 LDM_REG(4, 2); 6471 LDM_REG(8, 3); 6472 LDM_REG(16, 4); 6473 LDM_REG(32, 5); 6474 LDM_REG(64, 6); 6475 LDM_REG(128, 7); 6476 LDM_REG(256, 8); 6477 LDM_REG(512, 9); 6478 LDM_REG(1024, 10); 6479 LDM_REG(2048, 11); 6480 LDM_REG(4096, 12); 6481 LDM_REG(8192, 13); 6482 LDM_REG(16384, 14); 6483 if(opcode & 32768) { 6484 reg[15].I = CPUReadMemory(address); 6485 if (!offset) 6486 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6487 else 6488 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6489 armNextPC = reg[15].I; 6490 reg[15].I += 4; 6491 } 6492 if(!(opcode & (1 << base))) 6493 reg[base].I = temp; 6494 } 6495 break; 6496 CASE_16(0x8d0) 6497 { 6498 // LDMIA Rn, {Rlist}^ 6499 int base = (opcode & 0x000F0000) >> 16; 6500 u32 address = reg[base].I & 0xFFFFFFFC; 6501 clockTicks += 2; 6502 int offset = 0; 6503 if(opcode & 0x8000) { 6504 LDM_REG(1, 0); 6505 LDM_REG(2, 1); 6506 LDM_REG(4, 2); 6507 LDM_REG(8, 3); 6508 LDM_REG(16, 4); 6509 LDM_REG(32, 5); 6510 LDM_REG(64, 6); 6511 LDM_REG(128, 7); 6512 LDM_REG(256, 8); 6513 LDM_REG(512, 9); 6514 LDM_REG(1024, 10); 6515 LDM_REG(2048, 11); 6516 LDM_REG(4096, 12); 6517 LDM_REG(8192, 13); 6518 LDM_REG(16384, 14); 6519 6520 reg[15].I = CPUReadMemory(address); 6521 if (!offset) 6522 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6523 else 6524 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6525 6526 CPUSwitchMode(reg[17].I & 0x1f, false); 6527 if(armState) { 6528 armNextPC = reg[15].I & 0xFFFFFFFC; 6529 reg[15].I = armNextPC + 4; 6530 } else { 6531 armNextPC = reg[15].I & 0xFFFFFFFE; 6532 reg[15].I = armNextPC + 2; 6533 } 6534 } else { 6535 LDM_REG(1, 0); 6536 LDM_REG(2, 1); 6537 LDM_REG(4, 2); 6538 LDM_REG(8, 3); 6539 LDM_REG(16, 4); 6540 LDM_REG(32, 5); 6541 LDM_REG(64, 6); 6542 LDM_REG(128, 7); 6543 6544 if(armMode == 0x11) { 6545 LDM_REG(256, R8_FIQ); 6546 LDM_REG(512, R9_FIQ); 6547 LDM_REG(1024, R10_FIQ); 6548 LDM_REG(2048, R11_FIQ); 6549 LDM_REG(4096, R12_FIQ); 6550 } else { 6551 LDM_REG(256, 8); 6552 LDM_REG(512, 9); 6553 LDM_REG(1024, 10); 6554 LDM_REG(2048, 11); 6555 LDM_REG(4096, 12); 6556 } 6557 6558 if(armMode != 0x10 && armMode != 0x1f) { 6559 LDM_REG(8192, R13_USR); 6560 LDM_REG(16384, R14_USR); 6561 } else { 6562 LDM_REG(8192, 13); 6563 LDM_REG(16384, 14); 6564 } 6565 } 6566 } 6567 break; 6568 CASE_16(0x8f0) 6569 { 6570 // LDMIA Rn!, {Rlist}^ 6571 int base = (opcode & 0x000F0000) >> 16; 6572 u32 temp = reg[base].I + 6573 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 6574 u32 address = reg[base].I & 0xFFFFFFFC; 6575 clockTicks += 2; 6576 int offset = 0; 6577 if(opcode & 0x8000) { 6578 LDM_REG(1, 0); 6579 LDM_REG(2, 1); 6580 LDM_REG(4, 2); 6581 LDM_REG(8, 3); 6582 LDM_REG(16, 4); 6583 LDM_REG(32, 5); 6584 LDM_REG(64, 6); 6585 LDM_REG(128, 7); 6586 LDM_REG(256, 8); 6587 LDM_REG(512, 9); 6588 LDM_REG(1024, 10); 6589 LDM_REG(2048, 11); 6590 LDM_REG(4096, 12); 6591 LDM_REG(8192, 13); 6592 LDM_REG(16384, 14); 6593 6594 reg[15].I = CPUReadMemory(address); 6595 if(!offset) 6596 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6597 else 6598 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6599 6600 if(!(opcode & (1 << base))) 6601 reg[base].I = temp; 6602 6603 CPUSwitchMode(reg[17].I & 0x1f, false); 6604 if(armState) { 6605 armNextPC = reg[15].I & 0xFFFFFFFC; 6606 reg[15].I = armNextPC + 4; 6607 } else { 6608 armNextPC = reg[15].I & 0xFFFFFFFE; 6609 reg[15].I = armNextPC + 2; 6610 } 6611 } else { 6612 LDM_REG(1, 0); 6613 LDM_REG(2, 1); 6614 LDM_REG(4, 2); 6615 LDM_REG(8, 3); 6616 LDM_REG(16, 4); 6617 LDM_REG(32, 5); 6618 LDM_REG(64, 6); 6619 LDM_REG(128, 7); 6620 6621 if(armMode == 0x11) { 6622 LDM_REG(256, R8_FIQ); 6623 LDM_REG(512, R9_FIQ); 6624 LDM_REG(1024, R10_FIQ); 6625 LDM_REG(2048, R11_FIQ); 6626 LDM_REG(4096, R12_FIQ); 6627 } else { 6628 LDM_REG(256, 8); 6629 LDM_REG(512, 9); 6630 LDM_REG(1024, 10); 6631 LDM_REG(2048, 11); 6632 LDM_REG(4096, 12); 6633 } 6634 6635 if(armMode != 0x10 && armMode != 0x1f) { 6636 LDM_REG(8192, R13_USR); 6637 LDM_REG(16384, R14_USR); 6638 } else { 6639 LDM_REG(8192, 13); 6640 LDM_REG(16384, 14); 6641 } 6642 6643 if(!(opcode & (1 << base))) 6644 reg[base].I = temp; 6645 } 6646 } 6647 break; 6648 6649 CASE_16(0x910) 6650 { 6651 // LDMDB Rn, {Rlist} 6652 int base = (opcode & 0x000F0000) >> 16; 6653 u32 temp = reg[base].I - 6654 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 6655 u32 address = temp & 0xFFFFFFFC; 6656 clockTicks += 2; 6657 int offset = 0; 6658 LDM_REG(1, 0); 6659 LDM_REG(2, 1); 6660 LDM_REG(4, 2); 6661 LDM_REG(8, 3); 6662 LDM_REG(16, 4); 6663 LDM_REG(32, 5); 6664 LDM_REG(64, 6); 6665 LDM_REG(128, 7); 6666 LDM_REG(256, 8); 6667 LDM_REG(512, 9); 6668 LDM_REG(1024, 10); 6669 LDM_REG(2048, 11); 6670 LDM_REG(4096, 12); 6671 LDM_REG(8192, 13); 6672 LDM_REG(16384, 14); 6673 if(opcode & 32768) { 6674 reg[15].I = CPUReadMemory(address); 6675 if (!offset) 6676 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6677 else 6678 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6679 armNextPC = reg[15].I; 6680 reg[15].I += 4; 6681 } 6682 } 6683 break; 6684 CASE_16(0x930) 6685 { 6686 // LDMDB Rn!, {Rlist} 6687 int base = (opcode & 0x000F0000) >> 16; 6688 u32 temp = reg[base].I - 6689 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 6690 u32 address = temp & 0xFFFFFFFC; 6691 clockTicks += 2; 6692 int offset = 0; 6693 LDM_REG(1, 0); 6694 LDM_REG(2, 1); 6695 LDM_REG(4, 2); 6696 LDM_REG(8, 3); 6697 LDM_REG(16, 4); 6698 LDM_REG(32, 5); 6699 LDM_REG(64, 6); 6700 LDM_REG(128, 7); 6701 LDM_REG(256, 8); 6702 LDM_REG(512, 9); 6703 LDM_REG(1024, 10); 6704 LDM_REG(2048, 11); 6705 LDM_REG(4096, 12); 6706 LDM_REG(8192, 13); 6707 LDM_REG(16384, 14); 6708 if(opcode & 32768) { 6709 reg[15].I = CPUReadMemory(address); 6710 if (!offset) 6711 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6712 else 6713 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6714 armNextPC = reg[15].I; 6715 reg[15].I += 4; 6716 } 6717 if(!(opcode & (1 << base))) 6718 reg[base].I = temp; 6719 } 6720 break; 6721 CASE_16(0x950) 6722 { 6723 // LDMDB Rn, {Rlist}^ 6724 int base = (opcode & 0x000F0000) >> 16; 6725 u32 temp = reg[base].I - 6726 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 6727 u32 address = temp & 0xFFFFFFFC; 6728 clockTicks += 2; 6729 int offset = 0; 6730 if(opcode & 0x8000) { 6731 LDM_REG(1, 0); 6732 LDM_REG(2, 1); 6733 LDM_REG(4, 2); 6734 LDM_REG(8, 3); 6735 LDM_REG(16, 4); 6736 LDM_REG(32, 5); 6737 LDM_REG(64, 6); 6738 LDM_REG(128, 7); 6739 LDM_REG(256, 8); 6740 LDM_REG(512, 9); 6741 LDM_REG(1024, 10); 6742 LDM_REG(2048, 11); 6743 LDM_REG(4096, 12); 6744 LDM_REG(8192, 13); 6745 LDM_REG(16384, 14); 6746 6747 reg[15].I = CPUReadMemory(address); 6748 if (!offset) 6749 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6750 else 6751 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6752 6753 CPUSwitchMode(reg[17].I & 0x1f, false); 6754 if(armState) { 6755 armNextPC = reg[15].I & 0xFFFFFFFC; 6756 reg[15].I = armNextPC + 4; 6757 } else { 6758 armNextPC = reg[15].I & 0xFFFFFFFE; 6759 reg[15].I = armNextPC + 2; 6760 } 6761 } else { 6762 LDM_REG(1, 0); 6763 LDM_REG(2, 1); 6764 LDM_REG(4, 2); 6765 LDM_REG(8, 3); 6766 LDM_REG(16, 4); 6767 LDM_REG(32, 5); 6768 LDM_REG(64, 6); 6769 LDM_REG(128, 7); 6770 6771 if(armMode == 0x11) { 6772 LDM_REG(256, R8_FIQ); 6773 LDM_REG(512, R9_FIQ); 6774 LDM_REG(1024, R10_FIQ); 6775 LDM_REG(2048, R11_FIQ); 6776 LDM_REG(4096, R12_FIQ); 6777 } else { 6778 LDM_REG(256, 8); 6779 LDM_REG(512, 9); 6780 LDM_REG(1024, 10); 6781 LDM_REG(2048, 11); 6782 LDM_REG(4096, 12); 6783 } 6784 6785 if(armMode != 0x10 && armMode != 0x1f) { 6786 LDM_REG(8192, R13_USR); 6787 LDM_REG(16384, R14_USR); 6788 } else { 6789 LDM_REG(8192, 13); 6790 LDM_REG(16384, 14); 6791 } 6792 } 6793 } 6794 break; 6795 CASE_16(0x970) 6796 { 6797 // LDMDB Rn!, {Rlist}^ 6798 int base = (opcode & 0x000F0000) >> 16; 6799 u32 temp = reg[base].I - 6800 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 6801 u32 address = temp & 0xFFFFFFFC; 6802 clockTicks += 2; 6803 int offset = 0; 6804 if(opcode & 0x8000) { 6805 LDM_REG(1, 0); 6806 LDM_REG(2, 1); 6807 LDM_REG(4, 2); 6808 LDM_REG(8, 3); 6809 LDM_REG(16, 4); 6810 LDM_REG(32, 5); 6811 LDM_REG(64, 6); 6812 LDM_REG(128, 7); 6813 LDM_REG(256, 8); 6814 LDM_REG(512, 9); 6815 LDM_REG(1024, 10); 6816 LDM_REG(2048, 11); 6817 LDM_REG(4096, 12); 6818 LDM_REG(8192, 13); 6819 LDM_REG(16384, 14); 6820 6821 reg[15].I = CPUReadMemory(address); 6822 if(!offset) 6823 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6824 else 6825 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6826 6827 if(!(opcode & (1 << base))) 6828 reg[base].I = temp; 6829 6830 CPUSwitchMode(reg[17].I & 0x1f, false); 6831 if(armState) { 6832 armNextPC = reg[15].I & 0xFFFFFFFC; 6833 reg[15].I = armNextPC + 4; 6834 } else { 6835 armNextPC = reg[15].I & 0xFFFFFFFE; 6836 reg[15].I = armNextPC + 2; 6837 } 6838 } else { 6839 LDM_REG(1, 0); 6840 LDM_REG(2, 1); 6841 LDM_REG(4, 2); 6842 LDM_REG(8, 3); 6843 LDM_REG(16, 4); 6844 LDM_REG(32, 5); 6845 LDM_REG(64, 6); 6846 LDM_REG(128, 7); 6847 6848 if(armMode == 0x11) { 6849 LDM_REG(256, R8_FIQ); 6850 LDM_REG(512, R9_FIQ); 6851 LDM_REG(1024, R10_FIQ); 6852 LDM_REG(2048, R11_FIQ); 6853 LDM_REG(4096, R12_FIQ); 6854 } else { 6855 LDM_REG(256, 8); 6856 LDM_REG(512, 9); 6857 LDM_REG(1024, 10); 6858 LDM_REG(2048, 11); 6859 LDM_REG(4096, 12); 6860 } 6861 6862 if(armMode != 0x10 && armMode != 0x1f) { 6863 LDM_REG(8192, R13_USR); 6864 LDM_REG(16384, R14_USR); 6865 } else { 6866 LDM_REG(8192, 13); 6867 LDM_REG(16384, 14); 6868 } 6869 6870 if(!(opcode & (1 << base))) 6871 reg[base].I = temp; 6872 } 6873 } 6874 break; 6875 6876 CASE_16(0x990) 6877 { 6878 // LDMIB Rn, {Rlist} 6879 int base = (opcode & 0x000F0000) >> 16; 6880 u32 address = (reg[base].I+4) & 0xFFFFFFFC; 6881 clockTicks += 2; 6882 int offset = 0; 6883 LDM_REG(1, 0); 6884 LDM_REG(2, 1); 6885 LDM_REG(4, 2); 6886 LDM_REG(8, 3); 6887 LDM_REG(16, 4); 6888 LDM_REG(32, 5); 6889 LDM_REG(64, 6); 6890 LDM_REG(128, 7); 6891 LDM_REG(256, 8); 6892 LDM_REG(512, 9); 6893 LDM_REG(1024, 10); 6894 LDM_REG(2048, 11); 6895 LDM_REG(4096, 12); 6896 LDM_REG(8192, 13); 6897 LDM_REG(16384, 14); 6898 if(opcode & 32768) { 6899 reg[15].I = CPUReadMemory(address); 6900 if (!offset) 6901 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6902 else 6903 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6904 armNextPC = reg[15].I; 6905 reg[15].I += 4; 6906 } 6907 } 6908 break; 6909 CASE_16(0x9b0) 6910 { 6911 // LDMIB Rn!, {Rlist} 6912 int base = (opcode & 0x000F0000) >> 16; 6913 u32 temp = reg[base].I + 6914 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 6915 u32 address = (reg[base].I+4) & 0xFFFFFFFC; 6916 clockTicks += 2; 6917 int offset = 0; 6918 LDM_REG(1, 0); 6919 LDM_REG(2, 1); 6920 LDM_REG(4, 2); 6921 LDM_REG(8, 3); 6922 LDM_REG(16, 4); 6923 LDM_REG(32, 5); 6924 LDM_REG(64, 6); 6925 LDM_REG(128, 7); 6926 LDM_REG(256, 8); 6927 LDM_REG(512, 9); 6928 LDM_REG(1024, 10); 6929 LDM_REG(2048, 11); 6930 LDM_REG(4096, 12); 6931 LDM_REG(8192, 13); 6932 LDM_REG(16384, 14); 6933 if(opcode & 32768) { 6934 reg[15].I = CPUReadMemory(address); 6935 if (!offset) 6936 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6937 else 6938 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6939 armNextPC = reg[15].I; 6940 reg[15].I += 4; 6941 } 6942 if(!(opcode & (1 << base))) 6943 reg[base].I = temp; 6944 } 6945 break; 6946 CASE_16(0x9d0) 6947 { 6948 // LDMIB Rn, {Rlist}^ 6949 int base = (opcode & 0x000F0000) >> 16; 6950 u32 address = (reg[base].I+4) & 0xFFFFFFFC; 6951 clockTicks += 2; 6952 int offset = 0; 6953 if(opcode & 0x8000) { 6954 LDM_REG(1, 0); 6955 LDM_REG(2, 1); 6956 LDM_REG(4, 2); 6957 LDM_REG(8, 3); 6958 LDM_REG(16, 4); 6959 LDM_REG(32, 5); 6960 LDM_REG(64, 6); 6961 LDM_REG(128, 7); 6962 LDM_REG(256, 8); 6963 LDM_REG(512, 9); 6964 LDM_REG(1024, 10); 6965 LDM_REG(2048, 11); 6966 LDM_REG(4096, 12); 6967 LDM_REG(8192, 13); 6968 LDM_REG(16384, 14); 6969 6970 reg[15].I = CPUReadMemory(address); 6971 if (!offset) 6972 clockTicks += 2 + CPUUpdateTicksAccess32(address); 6973 else 6974 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 6975 6976 CPUSwitchMode(reg[17].I & 0x1f, false); 6977 if(armState) { 6978 armNextPC = reg[15].I & 0xFFFFFFFC; 6979 reg[15].I = armNextPC + 4; 6980 } else { 6981 armNextPC = reg[15].I & 0xFFFFFFFE; 6982 reg[15].I = armNextPC + 2; 6983 } 6984 } else { 6985 LDM_REG(1, 0); 6986 LDM_REG(2, 1); 6987 LDM_REG(4, 2); 6988 LDM_REG(8, 3); 6989 LDM_REG(16, 4); 6990 LDM_REG(32, 5); 6991 LDM_REG(64, 6); 6992 LDM_REG(128, 7); 6993 6994 if(armMode == 0x11) { 6995 LDM_REG(256, R8_FIQ); 6996 LDM_REG(512, R9_FIQ); 6997 LDM_REG(1024, R10_FIQ); 6998 LDM_REG(2048, R11_FIQ); 6999 LDM_REG(4096, R12_FIQ); 7000 } else { 7001 LDM_REG(256, 8); 7002 LDM_REG(512, 9); 7003 LDM_REG(1024, 10); 7004 LDM_REG(2048, 11); 7005 LDM_REG(4096, 12); 7006 } 7007 7008 if(armMode != 0x10 && armMode != 0x1f) { 7009 LDM_REG(8192, R13_USR); 7010 LDM_REG(16384, R14_USR); 7011 } else { 7012 LDM_REG(8192, 13); 7013 LDM_REG(16384, 14); 7014 } 7015 } 7016 } 7017 break; 7018 CASE_16(0x9f0) 7019 { 7020 // LDMIB Rn!, {Rlist}^ 7021 int base = (opcode & 0x000F0000) >> 16; 7022 u32 temp = reg[base].I + 7023 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); 7024 u32 address = (reg[base].I+4) & 0xFFFFFFFC; 7025 clockTicks += 2; 7026 int offset = 0; 7027 if(opcode & 0x8000) { 7028 LDM_REG(1, 0); 7029 LDM_REG(2, 1); 7030 LDM_REG(4, 2); 7031 LDM_REG(8, 3); 7032 LDM_REG(16, 4); 7033 LDM_REG(32, 5); 7034 LDM_REG(64, 6); 7035 LDM_REG(128, 7); 7036 LDM_REG(256, 8); 7037 LDM_REG(512, 9); 7038 LDM_REG(1024, 10); 7039 LDM_REG(2048, 11); 7040 LDM_REG(4096, 12); 7041 LDM_REG(8192, 13); 7042 LDM_REG(16384, 14); 7043 7044 reg[15].I = CPUReadMemory(address); 7045 if(!offset) 7046 clockTicks += 2 + CPUUpdateTicksAccess32(address); 7047 else 7048 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address); 7049 7050 if(!(opcode & (1 << base))) 7051 reg[base].I = temp; 7052 7053 CPUSwitchMode(reg[17].I & 0x1f, false); 7054 if(armState) { 7055 armNextPC = reg[15].I & 0xFFFFFFFC; 7056 reg[15].I = armNextPC + 4; 7057 } else { 7058 armNextPC = reg[15].I & 0xFFFFFFFE; 7059 reg[15].I = armNextPC + 2; 7060 } 7061 } else { 7062 LDM_REG(1, 0); 7063 LDM_REG(2, 1); 7064 LDM_REG(4, 2); 7065 LDM_REG(8, 3); 7066 LDM_REG(16, 4); 7067 LDM_REG(32, 5); 7068 LDM_REG(64, 6); 7069 LDM_REG(128, 7); 7070 7071 if(armMode == 0x11) { 7072 LDM_REG(256, R8_FIQ); 7073 LDM_REG(512, R9_FIQ); 7074 LDM_REG(1024, R10_FIQ); 7075 LDM_REG(2048, R11_FIQ); 7076 LDM_REG(4096, R12_FIQ); 7077 } else { 7078 LDM_REG(256, 8); 7079 LDM_REG(512, 9); 7080 LDM_REG(1024, 10); 7081 LDM_REG(2048, 11); 7082 LDM_REG(4096, 12); 7083 } 7084 7085 if(armMode != 0x10 && armMode != 0x1f) { 7086 LDM_REG(8192, R13_USR); 7087 LDM_REG(16384, R14_USR); 7088 } else { 7089 LDM_REG(8192, 13); 7090 LDM_REG(16384, 14); 7091 } 7092 7093 if(!(opcode & (1 << base))) 7094 reg[base].I = temp; 7095 } 7096 } 7097 break; 7098 CASE_256(0xa00) 7099 { 7100 // B <offset> 7101 clockTicks += 3; 7102 int offset = opcode & 0x00FFFFFF; 7103 if(offset & 0x00800000) { 7104 offset |= 0xFF000000; 7105 } 7106 offset <<= 2; 7107 reg[15].I += offset; 7108 armNextPC = reg[15].I; 7109 reg[15].I += 4; 7110 } 7111 break; 7112 CASE_256(0xb00) 7113 { 7114 // BL <offset> 7115 clockTicks += 3; 7116 int offset = opcode & 0x00FFFFFF; 7117 if(offset & 0x00800000) { 7118 offset |= 0xFF000000; 7119 } 7120 offset <<= 2; 7121 reg[14].I = reg[15].I - 4; 7122 reg[15].I += offset; 7123 armNextPC = reg[15].I; 7124 reg[15].I += 4; 7125 } 7126 break; 7127 CASE_256(0xf00) 7128 // SWI <comment> 7129 clockTicks += 3; 7130 CPUSoftwareInterrupt(opcode & 0x00FFFFFF); 7131 break; 7132 #ifdef GP_SUPPORT 7133 case 0xe11: 7134 case 0xe13: 7135 case 0xe15: 7136 case 0xe17: 7137 case 0xe19: 7138 case 0xe1b: 7139 case 0xe1d: 7140 case 0xe1f: 7141 // MRC 7142 break; 7143 case 0xe01: 7144 case 0xe03: 7145 case 0xe05: 7146 case 0xe07: 7147 case 0xe09: 7148 case 0xe0b: 7149 case 0xe0d: 7150 case 0xe0f: 7151 // MRC 7152 break; 7153 #endif 7154 default: 7155 #ifdef DEV_VERSION 7156 if(systemVerbose & VERBOSE_UNDEFINED) 7157 log("Undefined ARM instruction %08x at %08x\n", opcode, 7158 armNextPC-4); 7159 #endif 7160 CPUUndefinedException(); 7161 break; 7162 // END 7163 } 7164 } 7165