1 /* armemu.c -- Main instruction emulation: ARM7 Instruction Emulator. 2 Copyright (C) 1994 Advanced RISC Machines Ltd. 3 Modifications to add arch. v4 support by <jsmith@cygnus.com>. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, see <http://www.gnu.org/licenses/>. */ 17 18 #include "armdefs.h" 19 #include "armemu.h" 20 #include "armos.h" 21 #include "iwmmxt.h" 22 23 static ARMword GetDPRegRHS (ARMul_State *, ARMword); 24 static ARMword GetDPSRegRHS (ARMul_State *, ARMword); 25 static void WriteR15 (ARMul_State *, ARMword); 26 static void WriteSR15 (ARMul_State *, ARMword); 27 static void WriteR15Branch (ARMul_State *, ARMword); 28 static void WriteR15Load (ARMul_State *, ARMword); 29 static ARMword GetLSRegRHS (ARMul_State *, ARMword); 30 static ARMword GetLS7RHS (ARMul_State *, ARMword); 31 static unsigned LoadWord (ARMul_State *, ARMword, ARMword); 32 static unsigned LoadHalfWord (ARMul_State *, ARMword, ARMword, int); 33 static unsigned LoadByte (ARMul_State *, ARMword, ARMword, int); 34 static unsigned StoreWord (ARMul_State *, ARMword, ARMword); 35 static unsigned StoreHalfWord (ARMul_State *, ARMword, ARMword); 36 static unsigned StoreByte (ARMul_State *, ARMword, ARMword); 37 static void LoadMult (ARMul_State *, ARMword, ARMword, ARMword); 38 static void StoreMult (ARMul_State *, ARMword, ARMword, ARMword); 39 static void LoadSMult (ARMul_State *, ARMword, ARMword, ARMword); 40 static void StoreSMult (ARMul_State *, ARMword, ARMword, ARMword); 41 static unsigned Multiply64 (ARMul_State *, ARMword, int, int); 42 static unsigned MultiplyAdd64 (ARMul_State *, ARMword, int, int); 43 static void Handle_Load_Double (ARMul_State *, ARMword); 44 static void Handle_Store_Double (ARMul_State *, ARMword); 45 46 #define LUNSIGNED (0) /* unsigned operation */ 47 #define LSIGNED (1) /* signed operation */ 48 #define LDEFAULT (0) /* default : do nothing */ 49 #define LSCC (1) /* set condition codes on result */ 50 51 extern int stop_simulator; 52 53 /* Short-hand macros for LDR/STR. */ 54 55 /* Store post decrement writeback. */ 56 #define SHDOWNWB() \ 57 lhs = LHS ; \ 58 if (StoreHalfWord (state, instr, lhs)) \ 59 LSBase = lhs - GetLS7RHS (state, instr); 60 61 /* Store post increment writeback. */ 62 #define SHUPWB() \ 63 lhs = LHS ; \ 64 if (StoreHalfWord (state, instr, lhs)) \ 65 LSBase = lhs + GetLS7RHS (state, instr); 66 67 /* Store pre decrement. */ 68 #define SHPREDOWN() \ 69 (void)StoreHalfWord (state, instr, LHS - GetLS7RHS (state, instr)); 70 71 /* Store pre decrement writeback. */ 72 #define SHPREDOWNWB() \ 73 temp = LHS - GetLS7RHS (state, instr); \ 74 if (StoreHalfWord (state, instr, temp)) \ 75 LSBase = temp; 76 77 /* Store pre increment. */ 78 #define SHPREUP() \ 79 (void)StoreHalfWord (state, instr, LHS + GetLS7RHS (state, instr)); 80 81 /* Store pre increment writeback. */ 82 #define SHPREUPWB() \ 83 temp = LHS + GetLS7RHS (state, instr); \ 84 if (StoreHalfWord (state, instr, temp)) \ 85 LSBase = temp; 86 87 /* Load post decrement writeback. */ 88 #define LHPOSTDOWN() \ 89 { \ 90 int done = 1; \ 91 lhs = LHS; \ 92 temp = lhs - GetLS7RHS (state, instr); \ 93 \ 94 switch (BITS (5, 6)) \ 95 { \ 96 case 1: /* H */ \ 97 if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \ 98 LSBase = temp; \ 99 break; \ 100 case 2: /* SB */ \ 101 if (LoadByte (state, instr, lhs, LSIGNED)) \ 102 LSBase = temp; \ 103 break; \ 104 case 3: /* SH */ \ 105 if (LoadHalfWord (state, instr, lhs, LSIGNED)) \ 106 LSBase = temp; \ 107 break; \ 108 case 0: /* SWP handled elsewhere. */ \ 109 default: \ 110 done = 0; \ 111 break; \ 112 } \ 113 if (done) \ 114 break; \ 115 } 116 117 /* Load post increment writeback. */ 118 #define LHPOSTUP() \ 119 { \ 120 int done = 1; \ 121 lhs = LHS; \ 122 temp = lhs + GetLS7RHS (state, instr); \ 123 \ 124 switch (BITS (5, 6)) \ 125 { \ 126 case 1: /* H */ \ 127 if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \ 128 LSBase = temp; \ 129 break; \ 130 case 2: /* SB */ \ 131 if (LoadByte (state, instr, lhs, LSIGNED)) \ 132 LSBase = temp; \ 133 break; \ 134 case 3: /* SH */ \ 135 if (LoadHalfWord (state, instr, lhs, LSIGNED)) \ 136 LSBase = temp; \ 137 break; \ 138 case 0: /* SWP handled elsewhere. */ \ 139 default: \ 140 done = 0; \ 141 break; \ 142 } \ 143 if (done) \ 144 break; \ 145 } 146 147 /* Load pre decrement. */ 148 #define LHPREDOWN() \ 149 { \ 150 int done = 1; \ 151 \ 152 temp = LHS - GetLS7RHS (state, instr); \ 153 switch (BITS (5, 6)) \ 154 { \ 155 case 1: /* H */ \ 156 (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \ 157 break; \ 158 case 2: /* SB */ \ 159 (void) LoadByte (state, instr, temp, LSIGNED); \ 160 break; \ 161 case 3: /* SH */ \ 162 (void) LoadHalfWord (state, instr, temp, LSIGNED); \ 163 break; \ 164 case 0: \ 165 /* SWP handled elsewhere. */ \ 166 default: \ 167 done = 0; \ 168 break; \ 169 } \ 170 if (done) \ 171 break; \ 172 } 173 174 /* Load pre decrement writeback. */ 175 #define LHPREDOWNWB() \ 176 { \ 177 int done = 1; \ 178 \ 179 temp = LHS - GetLS7RHS (state, instr); \ 180 switch (BITS (5, 6)) \ 181 { \ 182 case 1: /* H */ \ 183 if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \ 184 LSBase = temp; \ 185 break; \ 186 case 2: /* SB */ \ 187 if (LoadByte (state, instr, temp, LSIGNED)) \ 188 LSBase = temp; \ 189 break; \ 190 case 3: /* SH */ \ 191 if (LoadHalfWord (state, instr, temp, LSIGNED)) \ 192 LSBase = temp; \ 193 break; \ 194 case 0: \ 195 /* SWP handled elsewhere. */ \ 196 default: \ 197 done = 0; \ 198 break; \ 199 } \ 200 if (done) \ 201 break; \ 202 } 203 204 /* Load pre increment. */ 205 #define LHPREUP() \ 206 { \ 207 int done = 1; \ 208 \ 209 temp = LHS + GetLS7RHS (state, instr); \ 210 switch (BITS (5, 6)) \ 211 { \ 212 case 1: /* H */ \ 213 (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \ 214 break; \ 215 case 2: /* SB */ \ 216 (void) LoadByte (state, instr, temp, LSIGNED); \ 217 break; \ 218 case 3: /* SH */ \ 219 (void) LoadHalfWord (state, instr, temp, LSIGNED); \ 220 break; \ 221 case 0: \ 222 /* SWP handled elsewhere. */ \ 223 default: \ 224 done = 0; \ 225 break; \ 226 } \ 227 if (done) \ 228 break; \ 229 } 230 231 /* Load pre increment writeback. */ 232 #define LHPREUPWB() \ 233 { \ 234 int done = 1; \ 235 \ 236 temp = LHS + GetLS7RHS (state, instr); \ 237 switch (BITS (5, 6)) \ 238 { \ 239 case 1: /* H */ \ 240 if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \ 241 LSBase = temp; \ 242 break; \ 243 case 2: /* SB */ \ 244 if (LoadByte (state, instr, temp, LSIGNED)) \ 245 LSBase = temp; \ 246 break; \ 247 case 3: /* SH */ \ 248 if (LoadHalfWord (state, instr, temp, LSIGNED)) \ 249 LSBase = temp; \ 250 break; \ 251 case 0: \ 252 /* SWP handled elsewhere. */ \ 253 default: \ 254 done = 0; \ 255 break; \ 256 } \ 257 if (done) \ 258 break; \ 259 } 260 261 /* Attempt to emulate an ARMv6 instruction. 262 Returns non-zero upon success. */ 263 264 #ifdef MODE32 265 static int 266 handle_v6_insn (ARMul_State * state, ARMword instr) 267 { 268 ARMword val; 269 ARMword Rd; 270 ARMword Rm; 271 ARMword Rn; 272 273 switch (BITS (20, 27)) 274 { 275 #if 0 276 case 0x03: printf ("Unhandled v6 insn: ldr\n"); break; 277 case 0x04: printf ("Unhandled v6 insn: umaal\n"); break; 278 case 0x06: printf ("Unhandled v6 insn: mls/str\n"); break; 279 case 0x16: printf ("Unhandled v6 insn: smi\n"); break; 280 case 0x18: printf ("Unhandled v6 insn: strex\n"); break; 281 case 0x19: printf ("Unhandled v6 insn: ldrex\n"); break; 282 case 0x1a: printf ("Unhandled v6 insn: strexd\n"); break; 283 case 0x1b: printf ("Unhandled v6 insn: ldrexd\n"); break; 284 case 0x1c: printf ("Unhandled v6 insn: strexb\n"); break; 285 case 0x1d: printf ("Unhandled v6 insn: ldrexb\n"); break; 286 case 0x1e: printf ("Unhandled v6 insn: strexh\n"); break; 287 case 0x1f: printf ("Unhandled v6 insn: ldrexh\n"); break; 288 case 0x32: printf ("Unhandled v6 insn: nop/sev/wfe/wfi/yield\n"); break; 289 case 0x3f: printf ("Unhandled v6 insn: rbit\n"); break; 290 #endif 291 case 0x61: printf ("Unhandled v6 insn: sadd/ssub\n"); break; 292 case 0x63: printf ("Unhandled v6 insn: shadd/shsub\n"); break; 293 case 0x6c: printf ("Unhandled v6 insn: uxtb16/uxtab16\n"); break; 294 case 0x70: printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); break; 295 case 0x74: printf ("Unhandled v6 insn: smlald/smlsld\n"); break; 296 case 0x75: printf ("Unhandled v6 insn: smmla/smmls/smmul\n"); break; 297 case 0x78: printf ("Unhandled v6 insn: usad/usada8\n"); break; 298 299 case 0x30: 300 { 301 /* MOVW<c> <Rd>,#<imm16> 302 instr[31,28] = cond 303 instr[27,20] = 0011 0000 304 instr[19,16] = imm4 305 instr[15,12] = Rd 306 instr[11, 0] = imm12. */ 307 Rd = BITS (12, 15); 308 val = (BITS (16, 19) << 12) | BITS (0, 11); 309 state->Reg[Rd] = val; 310 return 1; 311 } 312 313 case 0x34: 314 { 315 /* MOVT<c> <Rd>,#<imm16> 316 instr[31,28] = cond 317 instr[27,20] = 0011 0100 318 instr[19,16] = imm4 319 instr[15,12] = Rd 320 instr[11, 0] = imm12. */ 321 Rd = BITS (12, 15); 322 val = (BITS (16, 19) << 12) | BITS (0, 11); 323 state->Reg[Rd] &= 0xFFFF; 324 state->Reg[Rd] |= val << 16; 325 return 1; 326 } 327 328 case 0x62: 329 { 330 ARMword val1; 331 ARMword val2; 332 ARMsword n, m, r; 333 int i; 334 335 Rd = BITS (12, 15); 336 Rn = BITS (16, 19); 337 Rm = BITS (0, 3); 338 339 if (Rd == 15 || Rn == 15 || Rm == 15) 340 break; 341 342 val1 = state->Reg[Rn]; 343 val2 = state->Reg[Rm]; 344 345 switch (BITS (4, 11)) 346 { 347 case 0xF1: /* QADD16<c> <Rd>,<Rn>,<Rm>. */ 348 state->Reg[Rd] = 0; 349 350 for (i = 0; i < 32; i+= 16) 351 { 352 n = (val1 >> i) & 0xFFFF; 353 if (n & 0x8000) 354 n |= -1 << 16; 355 356 m = (val2 >> i) & 0xFFFF; 357 if (m & 0x8000) 358 m |= -1 << 16; 359 360 r = n + m; 361 362 if (r > 0x7FFF) 363 r = 0x7FFF; 364 else if (r < -(0x8000)) 365 r = - 0x8000; 366 367 state->Reg[Rd] |= (r & 0xFFFF) << i; 368 } 369 return 1; 370 371 case 0xF3: /* QASX<c> <Rd>,<Rn>,<Rm>. */ 372 n = val1 & 0xFFFF; 373 if (n & 0x8000) 374 n |= -1 << 16; 375 376 m = (val2 >> 16) & 0xFFFF; 377 if (m & 0x8000) 378 m |= -1 << 16; 379 380 r = n - m; 381 382 if (r > 0x7FFF) 383 r = 0x7FFF; 384 else if (r < -(0x8000)) 385 r = - 0x8000; 386 387 state->Reg[Rd] = (r & 0xFFFF); 388 389 n = (val1 >> 16) & 0xFFFF; 390 if (n & 0x8000) 391 n |= -1 << 16; 392 393 m = val2 & 0xFFFF; 394 if (m & 0x8000) 395 m |= -1 << 16; 396 397 r = n + m; 398 399 if (r > 0x7FFF) 400 r = 0x7FFF; 401 else if (r < -(0x8000)) 402 r = - 0x8000; 403 404 state->Reg[Rd] |= (r & 0xFFFF) << 16; 405 return 1; 406 407 case 0xF5: /* QSAX<c> <Rd>,<Rn>,<Rm>. */ 408 n = val1 & 0xFFFF; 409 if (n & 0x8000) 410 n |= -1 << 16; 411 412 m = (val2 >> 16) & 0xFFFF; 413 if (m & 0x8000) 414 m |= -1 << 16; 415 416 r = n + m; 417 418 if (r > 0x7FFF) 419 r = 0x7FFF; 420 else if (r < -(0x8000)) 421 r = - 0x8000; 422 423 state->Reg[Rd] = (r & 0xFFFF); 424 425 n = (val1 >> 16) & 0xFFFF; 426 if (n & 0x8000) 427 n |= -1 << 16; 428 429 m = val2 & 0xFFFF; 430 if (m & 0x8000) 431 m |= -1 << 16; 432 433 r = n - m; 434 435 if (r > 0x7FFF) 436 r = 0x7FFF; 437 else if (r < -(0x8000)) 438 r = - 0x8000; 439 440 state->Reg[Rd] |= (r & 0xFFFF) << 16; 441 return 1; 442 443 case 0xF7: /* QSUB16<c> <Rd>,<Rn>,<Rm>. */ 444 state->Reg[Rd] = 0; 445 446 for (i = 0; i < 32; i+= 16) 447 { 448 n = (val1 >> i) & 0xFFFF; 449 if (n & 0x8000) 450 n |= -1 << 16; 451 452 m = (val2 >> i) & 0xFFFF; 453 if (m & 0x8000) 454 m |= -1 << 16; 455 456 r = n - m; 457 458 if (r > 0x7FFF) 459 r = 0x7FFF; 460 else if (r < -(0x8000)) 461 r = - 0x8000; 462 463 state->Reg[Rd] |= (r & 0xFFFF) << i; 464 } 465 return 1; 466 467 case 0xF9: /* QADD8<c> <Rd>,<Rn>,<Rm>. */ 468 state->Reg[Rd] = 0; 469 470 for (i = 0; i < 32; i+= 8) 471 { 472 n = (val1 >> i) & 0xFF; 473 if (n & 0x80) 474 n |= -1 << 8; 475 476 m = (val2 >> i) & 0xFF; 477 if (m & 0x80) 478 m |= -1 << 8; 479 480 r = n + m; 481 482 if (r > 127) 483 r = 127; 484 else if (r < -128) 485 r = -128; 486 487 state->Reg[Rd] |= (r & 0xFF) << i; 488 } 489 return 1; 490 491 case 0xFF: /* QSUB8<c> <Rd>,<Rn>,<Rm>. */ 492 state->Reg[Rd] = 0; 493 494 for (i = 0; i < 32; i+= 8) 495 { 496 n = (val1 >> i) & 0xFF; 497 if (n & 0x80) 498 n |= -1 << 8; 499 500 m = (val2 >> i) & 0xFF; 501 if (m & 0x80) 502 m |= -1 << 8; 503 504 r = n - m; 505 506 if (r > 127) 507 r = 127; 508 else if (r < -128) 509 r = -128; 510 511 state->Reg[Rd] |= (r & 0xFF) << i; 512 } 513 return 1; 514 515 default: 516 break; 517 } 518 break; 519 } 520 521 case 0x65: 522 { 523 ARMword valn; 524 ARMword valm; 525 ARMword res1, res2, res3, res4; 526 527 /* U{ADD|SUB}{8|16}<c> <Rd>, <Rn>, <Rm> 528 instr[31,28] = cond 529 instr[27,20] = 0110 0101 530 instr[19,16] = Rn 531 instr[15,12] = Rd 532 instr[11, 8] = 1111 533 instr[ 7, 4] = opcode: UADD8 (1001), UADD16 (0001), USUB8 (1111), USUB16 (0111) 534 instr[ 3, 0] = Rm. */ 535 if (BITS (8, 11) != 0xF) 536 break; 537 538 Rn = BITS (16, 19); 539 Rd = BITS (12, 15); 540 Rm = BITS (0, 3); 541 542 if (Rn == 15 || Rd == 15 || Rm == 15) 543 { 544 ARMul_UndefInstr (state, instr); 545 state->Emulate = FALSE; 546 break; 547 } 548 549 valn = state->Reg[Rn]; 550 valm = state->Reg[Rm]; 551 552 switch (BITS (4, 7)) 553 { 554 case 1: /* UADD16. */ 555 res1 = (valn & 0xFFFF) + (valm & 0xFFFF); 556 if (res1 > 0xFFFF) 557 state->Cpsr |= (GE0 | GE1); 558 else 559 state->Cpsr &= ~ (GE0 | GE1); 560 561 res2 = (valn >> 16) + (valm >> 16); 562 if (res2 > 0xFFFF) 563 state->Cpsr |= (GE2 | GE3); 564 else 565 state->Cpsr &= ~ (GE2 | GE3); 566 567 state->Reg[Rd] = (res1 & 0xFFFF) | (res2 << 16); 568 return 1; 569 570 case 7: /* USUB16. */ 571 res1 = (valn & 0xFFFF) - (valm & 0xFFFF); 572 if (res1 & 0x800000) 573 state->Cpsr |= (GE0 | GE1); 574 else 575 state->Cpsr &= ~ (GE0 | GE1); 576 577 res2 = (valn >> 16) - (valm >> 16); 578 if (res2 & 0x800000) 579 state->Cpsr |= (GE2 | GE3); 580 else 581 state->Cpsr &= ~ (GE2 | GE3); 582 583 state->Reg[Rd] = (res1 & 0xFFFF) | (res2 << 16); 584 return 1; 585 586 case 9: /* UADD8. */ 587 res1 = (valn & 0xFF) + (valm & 0xFF); 588 if (res1 > 0xFF) 589 state->Cpsr |= GE0; 590 else 591 state->Cpsr &= ~ GE0; 592 593 res2 = ((valn >> 8) & 0xFF) + ((valm >> 8) & 0xFF); 594 if (res2 > 0xFF) 595 state->Cpsr |= GE1; 596 else 597 state->Cpsr &= ~ GE1; 598 599 res3 = ((valn >> 16) & 0xFF) + ((valm >> 16) & 0xFF); 600 if (res3 > 0xFF) 601 state->Cpsr |= GE2; 602 else 603 state->Cpsr &= ~ GE2; 604 605 res4 = (valn >> 24) + (valm >> 24); 606 if (res4 > 0xFF) 607 state->Cpsr |= GE3; 608 else 609 state->Cpsr &= ~ GE3; 610 611 state->Reg[Rd] = (res1 & 0xFF) | ((res2 << 8) & 0xFF00) 612 | ((res3 << 16) & 0xFF0000) | (res4 << 24); 613 return 1; 614 615 case 15: /* USUB8. */ 616 res1 = (valn & 0xFF) - (valm & 0xFF); 617 if (res1 & 0x800000) 618 state->Cpsr |= GE0; 619 else 620 state->Cpsr &= ~ GE0; 621 622 res2 = ((valn >> 8) & 0XFF) - ((valm >> 8) & 0xFF); 623 if (res2 & 0x800000) 624 state->Cpsr |= GE1; 625 else 626 state->Cpsr &= ~ GE1; 627 628 res3 = ((valn >> 16) & 0XFF) - ((valm >> 16) & 0xFF); 629 if (res3 & 0x800000) 630 state->Cpsr |= GE2; 631 else 632 state->Cpsr &= ~ GE2; 633 634 res4 = (valn >> 24) - (valm >> 24) ; 635 if (res4 & 0x800000) 636 state->Cpsr |= GE3; 637 else 638 state->Cpsr &= ~ GE3; 639 640 state->Reg[Rd] = (res1 & 0xFF) | ((res2 << 8) & 0xFF00) 641 | ((res3 << 16) & 0xFF0000) | (res4 << 24); 642 return 1; 643 644 default: 645 break; 646 } 647 break; 648 } 649 650 case 0x68: 651 { 652 ARMword res; 653 654 /* PKHBT<c> <Rd>,<Rn>,<Rm>{,LSL #<imm>} 655 PKHTB<c> <Rd>,<Rn>,<Rm>{,ASR #<imm>} 656 SXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>} 657 SXTB16<c> <Rd>,<Rm>{,<rotation>} 658 SEL<c> <Rd>,<Rn>,<Rm> 659 660 instr[31,28] = cond 661 instr[27,20] = 0110 1000 662 instr[19,16] = Rn 663 instr[15,12] = Rd 664 instr[11, 7] = imm5 (PKH), 11111 (SEL), rr000 (SXTAB16 & SXTB16), 665 instr[6] = tb (PKH), 0 (SEL), 1 (SXT) 666 instr[5] = opcode: PKH (0), SEL/SXT (1) 667 instr[4] = 1 668 instr[ 3, 0] = Rm. */ 669 670 if (BIT (4) != 1) 671 break; 672 673 if (BIT (5) == 0) 674 { 675 /* FIXME: Add implementation of PKH. */ 676 fprintf (stderr, "PKH: NOT YET IMPLEMENTED\n"); 677 ARMul_UndefInstr (state, instr); 678 break; 679 } 680 681 if (BIT (6) == 1) 682 { 683 /* FIXME: Add implementation of SXT. */ 684 fprintf (stderr, "SXT: NOT YET IMPLEMENTED\n"); 685 ARMul_UndefInstr (state, instr); 686 break; 687 } 688 689 Rn = BITS (16, 19); 690 Rd = BITS (12, 15); 691 Rm = BITS (0, 3); 692 if (Rn == 15 || Rm == 15 || Rd == 15) 693 { 694 ARMul_UndefInstr (state, instr); 695 state->Emulate = FALSE; 696 break; 697 } 698 699 res = (state->Reg[(state->Cpsr & GE0) ? Rn : Rm]) & 0xFF; 700 res |= (state->Reg[(state->Cpsr & GE1) ? Rn : Rm]) & 0xFF00; 701 res |= (state->Reg[(state->Cpsr & GE2) ? Rn : Rm]) & 0xFF0000; 702 res |= (state->Reg[(state->Cpsr & GE3) ? Rn : Rm]) & 0xFF000000; 703 state->Reg[Rd] = res; 704 return 1; 705 } 706 707 case 0x6a: 708 { 709 int ror = -1; 710 711 switch (BITS (4, 11)) 712 { 713 case 0x07: ror = 0; break; 714 case 0x47: ror = 8; break; 715 case 0x87: ror = 16; break; 716 case 0xc7: ror = 24; break; 717 718 case 0x01: 719 case 0xf3: 720 printf ("Unhandled v6 insn: ssat\n"); 721 return 0; 722 723 default: 724 break; 725 } 726 727 if (ror == -1) 728 { 729 if (BITS (4, 6) == 0x7) 730 { 731 printf ("Unhandled v6 insn: ssat\n"); 732 return 0; 733 } 734 break; 735 } 736 737 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF); 738 if (Rm & 0x80) 739 Rm |= 0xffffff00; 740 741 if (BITS (16, 19) == 0xf) 742 /* SXTB */ 743 state->Reg[BITS (12, 15)] = Rm; 744 else 745 /* SXTAB */ 746 state->Reg[BITS (12, 15)] += Rm; 747 } 748 return 1; 749 750 case 0x6b: 751 { 752 int ror = -1; 753 754 switch (BITS (4, 11)) 755 { 756 case 0x07: ror = 0; break; 757 case 0x47: ror = 8; break; 758 case 0x87: ror = 16; break; 759 case 0xc7: ror = 24; break; 760 761 case 0xf3: 762 { 763 /* REV<c> <Rd>,<Rm> 764 instr[31,28] = cond 765 instr[27,20] = 0110 1011 766 instr[19,16] = 1111 767 instr[15,12] = Rd 768 instr[11, 4] = 1111 0011 769 instr[ 3, 0] = Rm. */ 770 if (BITS (16, 19) != 0xF) 771 break; 772 773 Rd = BITS (12, 15); 774 Rm = BITS (0, 3); 775 if (Rd == 15 || Rm == 15) 776 { 777 ARMul_UndefInstr (state, instr); 778 state->Emulate = FALSE; 779 break; 780 } 781 782 val = state->Reg[Rm] << 24; 783 val |= ((state->Reg[Rm] << 8) & 0xFF0000); 784 val |= ((state->Reg[Rm] >> 8) & 0xFF00); 785 val |= ((state->Reg[Rm] >> 24)); 786 state->Reg[Rd] = val; 787 return 1; 788 } 789 790 case 0xfb: 791 { 792 /* REV16<c> <Rd>,<Rm>. */ 793 if (BITS (16, 19) != 0xF) 794 break; 795 796 Rd = BITS (12, 15); 797 Rm = BITS (0, 3); 798 if (Rd == 15 || Rm == 15) 799 { 800 ARMul_UndefInstr (state, instr); 801 state->Emulate = FALSE; 802 break; 803 } 804 805 val = 0; 806 val |= ((state->Reg[Rm] >> 8) & 0x00FF00FF); 807 val |= ((state->Reg[Rm] << 8) & 0xFF00FF00); 808 state->Reg[Rd] = val; 809 return 1; 810 } 811 812 default: 813 break; 814 } 815 816 if (ror == -1) 817 break; 818 819 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF); 820 if (Rm & 0x8000) 821 Rm |= 0xffff0000; 822 823 if (BITS (16, 19) == 0xf) 824 /* SXTH */ 825 state->Reg[BITS (12, 15)] = Rm; 826 else 827 /* SXTAH */ 828 state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm; 829 } 830 return 1; 831 832 case 0x6e: 833 { 834 int ror = -1; 835 836 switch (BITS (4, 11)) 837 { 838 case 0x07: ror = 0; break; 839 case 0x47: ror = 8; break; 840 case 0x87: ror = 16; break; 841 case 0xc7: ror = 24; break; 842 843 case 0x01: 844 case 0xf3: 845 printf ("Unhandled v6 insn: usat\n"); 846 return 0; 847 848 default: 849 break; 850 } 851 852 if (ror == -1) 853 { 854 if (BITS (4, 6) == 0x7) 855 { 856 printf ("Unhandled v6 insn: usat\n"); 857 return 0; 858 } 859 break; 860 } 861 862 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF); 863 864 if (BITS (16, 19) == 0xf) 865 /* UXTB */ 866 state->Reg[BITS (12, 15)] = Rm; 867 else 868 /* UXTAB */ 869 state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm; 870 } 871 return 1; 872 873 case 0x6f: 874 { 875 int i; 876 int ror = -1; 877 878 switch (BITS (4, 11)) 879 { 880 case 0x07: ror = 0; break; 881 case 0x47: ror = 8; break; 882 case 0x87: ror = 16; break; 883 case 0xc7: ror = 24; break; 884 885 case 0xf3: /* RBIT */ 886 if (BITS (16, 19) != 0xF) 887 break; 888 Rd = BITS (12, 15); 889 state->Reg[Rd] = 0; 890 Rm = state->Reg[BITS (0, 3)]; 891 for (i = 0; i < 32; i++) 892 if (Rm & (1 << i)) 893 state->Reg[Rd] |= (1 << (31 - i)); 894 return 1; 895 896 case 0xfb: 897 printf ("Unhandled v6 insn: revsh\n"); 898 return 0; 899 900 default: 901 break; 902 } 903 904 if (ror == -1) 905 break; 906 907 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF); 908 909 if (BITS (16, 19) == 0xf) 910 /* UXT */ 911 state->Reg[BITS (12, 15)] = Rm; 912 else 913 /* UXTAH */ 914 state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; 915 } 916 return 1; 917 918 case 0x7c: 919 case 0x7d: 920 { 921 int lsb; 922 int msb; 923 ARMword mask; 924 925 /* BFC<c> <Rd>,#<lsb>,#<width> 926 BFI<c> <Rd>,<Rn>,#<lsb>,#<width> 927 928 instr[31,28] = cond 929 instr[27,21] = 0111 110 930 instr[20,16] = msb 931 instr[15,12] = Rd 932 instr[11, 7] = lsb 933 instr[ 6, 4] = 001 1111 934 instr[ 3, 0] = Rn (BFI) / 1111 (BFC). */ 935 936 if (BITS (4, 6) != 0x1) 937 break; 938 939 Rd = BITS (12, 15); 940 if (Rd == 15) 941 { 942 ARMul_UndefInstr (state, instr); 943 state->Emulate = FALSE; 944 } 945 946 lsb = BITS (7, 11); 947 msb = BITS (16, 20); 948 if (lsb > msb) 949 { 950 ARMul_UndefInstr (state, instr); 951 state->Emulate = FALSE; 952 } 953 954 mask = -1 << lsb; 955 mask &= ~(-1 << (msb + 1)); 956 state->Reg[Rd] &= ~ mask; 957 958 Rn = BITS (0, 3); 959 if (Rn != 0xF) 960 { 961 ARMword val = state->Reg[Rn] & ~(-1 << ((msb + 1) - lsb)); 962 state->Reg[Rd] |= val << lsb; 963 } 964 return 1; 965 } 966 967 case 0x7b: 968 case 0x7a: /* SBFX<c> <Rd>,<Rn>,#<lsb>,#<width>. */ 969 { 970 int lsb; 971 int widthm1; 972 ARMsword sval; 973 974 if (BITS (4, 6) != 0x5) 975 break; 976 977 Rd = BITS (12, 15); 978 if (Rd == 15) 979 { 980 ARMul_UndefInstr (state, instr); 981 state->Emulate = FALSE; 982 } 983 984 Rn = BITS (0, 3); 985 if (Rn == 15) 986 { 987 ARMul_UndefInstr (state, instr); 988 state->Emulate = FALSE; 989 } 990 991 lsb = BITS (7, 11); 992 widthm1 = BITS (16, 20); 993 994 sval = state->Reg[Rn]; 995 sval <<= (31 - (lsb + widthm1)); 996 sval >>= (31 - widthm1); 997 state->Reg[Rd] = sval; 998 999 return 1; 1000 } 1001 1002 case 0x7f: 1003 case 0x7e: 1004 { 1005 int lsb; 1006 int widthm1; 1007 1008 /* UBFX<c> <Rd>,<Rn>,#<lsb>,#<width> 1009 instr[31,28] = cond 1010 instr[27,21] = 0111 111 1011 instr[20,16] = widthm1 1012 instr[15,12] = Rd 1013 instr[11, 7] = lsb 1014 instr[ 6, 4] = 101 1015 instr[ 3, 0] = Rn. */ 1016 1017 if (BITS (4, 6) != 0x5) 1018 break; 1019 1020 Rd = BITS (12, 15); 1021 if (Rd == 15) 1022 { 1023 ARMul_UndefInstr (state, instr); 1024 state->Emulate = FALSE; 1025 } 1026 1027 Rn = BITS (0, 3); 1028 if (Rn == 15) 1029 { 1030 ARMul_UndefInstr (state, instr); 1031 state->Emulate = FALSE; 1032 } 1033 1034 lsb = BITS (7, 11); 1035 widthm1 = BITS (16, 20); 1036 1037 val = state->Reg[Rn]; 1038 val >>= lsb; 1039 val &= ~(-1 << (widthm1 + 1)); 1040 1041 state->Reg[Rd] = val; 1042 1043 return 1; 1044 } 1045 #if 0 1046 case 0x84: printf ("Unhandled v6 insn: srs\n"); break; 1047 #endif 1048 default: 1049 break; 1050 } 1051 printf ("Unhandled v6 insn: UNKNOWN: %08x\n", instr); 1052 return 0; 1053 } 1054 #endif 1055 1056 static void 1057 handle_VFP_move (ARMul_State * state, ARMword instr) 1058 { 1059 switch (BITS (20, 27)) 1060 { 1061 case 0xC4: 1062 case 0xC5: 1063 switch (BITS (4, 11)) 1064 { 1065 case 0xA1: 1066 case 0xA3: 1067 { 1068 /* VMOV two core <-> two VFP single precision. */ 1069 int sreg = (BITS (0, 3) << 1) | BIT (5); 1070 1071 if (BIT (20)) 1072 { 1073 state->Reg[BITS (12, 15)] = VFP_uword (sreg); 1074 state->Reg[BITS (16, 19)] = VFP_uword (sreg + 1); 1075 } 1076 else 1077 { 1078 VFP_uword (sreg) = state->Reg[BITS (12, 15)]; 1079 VFP_uword (sreg + 1) = state->Reg[BITS (16, 19)]; 1080 } 1081 } 1082 break; 1083 1084 case 0xB1: 1085 case 0xB3: 1086 { 1087 /* VMOV two core <-> VFP double precision. */ 1088 int dreg = BITS (0, 3) | (BIT (5) << 4); 1089 1090 if (BIT (20)) 1091 { 1092 if (trace) 1093 fprintf (stderr, " VFP: VMOV: r%d r%d <= d%d\n", 1094 BITS (12, 15), BITS (16, 19), dreg); 1095 1096 state->Reg[BITS (12, 15)] = VFP_dword (dreg); 1097 state->Reg[BITS (16, 19)] = VFP_dword (dreg) >> 32; 1098 } 1099 else 1100 { 1101 VFP_dword (dreg) = state->Reg[BITS (16, 19)]; 1102 VFP_dword (dreg) <<= 32; 1103 VFP_dword (dreg) |= state->Reg[BITS (12, 15)]; 1104 1105 if (trace) 1106 fprintf (stderr, " VFP: VMOV: d%d <= r%d r%d : %g\n", 1107 dreg, BITS (16, 19), BITS (12, 15), 1108 VFP_dval (dreg)); 1109 } 1110 } 1111 break; 1112 1113 default: 1114 fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27)); 1115 break; 1116 } 1117 break; 1118 1119 case 0xe0: 1120 case 0xe1: 1121 /* VMOV single core <-> VFP single precision. */ 1122 if (BITS (0, 6) != 0x10 || BITS (8, 11) != 0xA) 1123 fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27)); 1124 else 1125 { 1126 int sreg = (BITS (16, 19) << 1) | BIT (7); 1127 1128 if (BIT (20)) 1129 state->Reg[DESTReg] = VFP_uword (sreg); 1130 else 1131 VFP_uword (sreg) = state->Reg[DESTReg]; 1132 } 1133 break; 1134 1135 default: 1136 fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27)); 1137 return; 1138 } 1139 } 1140 1141 /* EMULATION of ARM6. */ 1142 1143 /* The PC pipeline value depends on whether ARM 1144 or Thumb instructions are being executed. */ 1145 ARMword isize; 1146 1147 ARMword 1148 #ifdef MODE32 1149 ARMul_Emulate32 (ARMul_State * state) 1150 #else 1151 ARMul_Emulate26 (ARMul_State * state) 1152 #endif 1153 { 1154 ARMword instr; /* The current instruction. */ 1155 ARMword dest = 0; /* Almost the DestBus. */ 1156 ARMword temp; /* Ubiquitous third hand. */ 1157 ARMword pc = 0; /* The address of the current instruction. */ 1158 ARMword lhs; /* Almost the ABus and BBus. */ 1159 ARMword rhs; 1160 ARMword decoded = 0; /* Instruction pipeline. */ 1161 ARMword loaded = 0; 1162 1163 /* Execute the next instruction. */ 1164 1165 if (state->NextInstr < PRIMEPIPE) 1166 { 1167 decoded = state->decoded; 1168 loaded = state->loaded; 1169 pc = state->pc; 1170 } 1171 1172 do 1173 { 1174 /* Just keep going. */ 1175 isize = INSN_SIZE; 1176 1177 switch (state->NextInstr) 1178 { 1179 case SEQ: 1180 /* Advance the pipeline, and an S cycle. */ 1181 state->Reg[15] += isize; 1182 pc += isize; 1183 instr = decoded; 1184 decoded = loaded; 1185 loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize); 1186 break; 1187 1188 case NONSEQ: 1189 /* Advance the pipeline, and an N cycle. */ 1190 state->Reg[15] += isize; 1191 pc += isize; 1192 instr = decoded; 1193 decoded = loaded; 1194 loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize); 1195 NORMALCYCLE; 1196 break; 1197 1198 case PCINCEDSEQ: 1199 /* Program counter advanced, and an S cycle. */ 1200 pc += isize; 1201 instr = decoded; 1202 decoded = loaded; 1203 loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize); 1204 NORMALCYCLE; 1205 break; 1206 1207 case PCINCEDNONSEQ: 1208 /* Program counter advanced, and an N cycle. */ 1209 pc += isize; 1210 instr = decoded; 1211 decoded = loaded; 1212 loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize); 1213 NORMALCYCLE; 1214 break; 1215 1216 case RESUME: 1217 /* The program counter has been changed. */ 1218 pc = state->Reg[15]; 1219 #ifndef MODE32 1220 pc = pc & R15PCBITS; 1221 #endif 1222 state->Reg[15] = pc + (isize * 2); 1223 state->Aborted = 0; 1224 instr = ARMul_ReLoadInstr (state, pc, isize); 1225 decoded = ARMul_ReLoadInstr (state, pc + isize, isize); 1226 loaded = ARMul_ReLoadInstr (state, pc + isize * 2, isize); 1227 NORMALCYCLE; 1228 break; 1229 1230 default: 1231 /* The program counter has been changed. */ 1232 pc = state->Reg[15]; 1233 #ifndef MODE32 1234 pc = pc & R15PCBITS; 1235 #endif 1236 state->Reg[15] = pc + (isize * 2); 1237 state->Aborted = 0; 1238 instr = ARMul_LoadInstrN (state, pc, isize); 1239 decoded = ARMul_LoadInstrS (state, pc + (isize), isize); 1240 loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize); 1241 NORMALCYCLE; 1242 break; 1243 } 1244 1245 if (state->EventSet) 1246 ARMul_EnvokeEvent (state); 1247 1248 if (! TFLAG && trace) 1249 { 1250 fprintf (stderr, "pc: %x, ", pc & ~1); 1251 if (! disas) 1252 fprintf (stderr, "instr: %x\n", instr); 1253 } 1254 1255 if (instr == 0 || pc < 0x10) 1256 { 1257 ARMul_Abort (state, ARMUndefinedInstrV); 1258 state->Emulate = FALSE; 1259 } 1260 1261 #if 0 /* Enable this code to help track down stack alignment bugs. */ 1262 { 1263 static ARMword old_sp = -1; 1264 1265 if (old_sp != state->Reg[13]) 1266 { 1267 old_sp = state->Reg[13]; 1268 fprintf (stderr, "pc: %08x: SP set to %08x%s\n", 1269 pc & ~1, old_sp, (old_sp % 8) ? " [UNALIGNED!]" : ""); 1270 } 1271 } 1272 #endif 1273 1274 if (state->Exception) 1275 { 1276 /* Any exceptions ? */ 1277 if (state->NresetSig == LOW) 1278 { 1279 ARMul_Abort (state, ARMul_ResetV); 1280 break; 1281 } 1282 else if (!state->NfiqSig && !FFLAG) 1283 { 1284 ARMul_Abort (state, ARMul_FIQV); 1285 break; 1286 } 1287 else if (!state->NirqSig && !IFLAG) 1288 { 1289 ARMul_Abort (state, ARMul_IRQV); 1290 break; 1291 } 1292 } 1293 1294 if (state->CallDebug > 0) 1295 { 1296 instr = ARMul_Debug (state, pc, instr); 1297 if (state->Emulate < ONCE) 1298 { 1299 state->NextInstr = RESUME; 1300 break; 1301 } 1302 if (state->Debug) 1303 { 1304 fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n", 1305 (long) pc, (long) instr, (long) state->Mode); 1306 (void) fgetc (stdin); 1307 } 1308 } 1309 else if (state->Emulate < ONCE) 1310 { 1311 state->NextInstr = RESUME; 1312 break; 1313 } 1314 1315 state->NumInstrs++; 1316 1317 #ifdef MODET 1318 /* Provide Thumb instruction decoding. If the processor is in Thumb 1319 mode, then we can simply decode the Thumb instruction, and map it 1320 to the corresponding ARM instruction (by directly loading the 1321 instr variable, and letting the normal ARM simulator 1322 execute). There are some caveats to ensure that the correct 1323 pipelined PC value is used when executing Thumb code, and also for 1324 dealing with the BL instruction. */ 1325 if (TFLAG) 1326 { 1327 ARMword new; 1328 1329 /* Check if in Thumb mode. */ 1330 switch (ARMul_ThumbDecode (state, pc, instr, &new)) 1331 { 1332 case t_undefined: 1333 /* This is a Thumb instruction. */ 1334 ARMul_UndefInstr (state, instr); 1335 goto donext; 1336 1337 case t_branch: 1338 /* Already processed. */ 1339 goto donext; 1340 1341 case t_decoded: 1342 /* ARM instruction available. */ 1343 if (disas || trace) 1344 { 1345 fprintf (stderr, " emulate as: "); 1346 if (trace) 1347 fprintf (stderr, "%08x ", new); 1348 if (! disas) 1349 fprintf (stderr, "\n"); 1350 } 1351 instr = new; 1352 /* So continue instruction decoding. */ 1353 break; 1354 default: 1355 break; 1356 } 1357 } 1358 #endif 1359 if (disas) 1360 print_insn (instr); 1361 1362 /* Check the condition codes. */ 1363 if ((temp = TOPBITS (28)) == AL) 1364 /* Vile deed in the need for speed. */ 1365 goto mainswitch; 1366 1367 /* Check the condition code. */ 1368 switch ((int) TOPBITS (28)) 1369 { 1370 case AL: 1371 temp = TRUE; 1372 break; 1373 case NV: 1374 if (state->is_v5) 1375 { 1376 if (BITS (25, 27) == 5) /* BLX(1) */ 1377 { 1378 ARMword dest; 1379 1380 state->Reg[14] = pc + 4; 1381 1382 /* Force entry into Thumb mode. */ 1383 dest = pc + 8 + 1; 1384 if (BIT (23)) 1385 dest += (NEGBRANCH + (BIT (24) << 1)); 1386 else 1387 dest += POSBRANCH + (BIT (24) << 1); 1388 1389 WriteR15Branch (state, dest); 1390 goto donext; 1391 } 1392 else if ((instr & 0xFC70F000) == 0xF450F000) 1393 /* The PLD instruction. Ignored. */ 1394 goto donext; 1395 else if ( ((instr & 0xfe500f00) == 0xfc100100) 1396 || ((instr & 0xfe500f00) == 0xfc000100)) 1397 /* wldrw and wstrw are unconditional. */ 1398 goto mainswitch; 1399 else 1400 /* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2. */ 1401 ARMul_UndefInstr (state, instr); 1402 } 1403 temp = FALSE; 1404 break; 1405 case EQ: 1406 temp = ZFLAG; 1407 break; 1408 case NE: 1409 temp = !ZFLAG; 1410 break; 1411 case VS: 1412 temp = VFLAG; 1413 break; 1414 case VC: 1415 temp = !VFLAG; 1416 break; 1417 case MI: 1418 temp = NFLAG; 1419 break; 1420 case PL: 1421 temp = !NFLAG; 1422 break; 1423 case CS: 1424 temp = CFLAG; 1425 break; 1426 case CC: 1427 temp = !CFLAG; 1428 break; 1429 case HI: 1430 temp = (CFLAG && !ZFLAG); 1431 break; 1432 case LS: 1433 temp = (!CFLAG || ZFLAG); 1434 break; 1435 case GE: 1436 temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); 1437 break; 1438 case LT: 1439 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); 1440 break; 1441 case GT: 1442 temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG)); 1443 break; 1444 case LE: 1445 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG; 1446 break; 1447 } /* cc check */ 1448 1449 /* Handle the Clock counter here. */ 1450 if (state->is_XScale) 1451 { 1452 ARMword cp14r0; 1453 int ok; 1454 1455 ok = state->CPRead[14] (state, 0, & cp14r0); 1456 1457 if (ok && (cp14r0 & ARMul_CP14_R0_ENABLE)) 1458 { 1459 unsigned long newcycles, nowtime = ARMul_Time (state); 1460 1461 newcycles = nowtime - state->LastTime; 1462 state->LastTime = nowtime; 1463 1464 if (cp14r0 & ARMul_CP14_R0_CCD) 1465 { 1466 if (state->CP14R0_CCD == -1) 1467 state->CP14R0_CCD = newcycles; 1468 else 1469 state->CP14R0_CCD += newcycles; 1470 1471 if (state->CP14R0_CCD >= 64) 1472 { 1473 newcycles = 0; 1474 1475 while (state->CP14R0_CCD >= 64) 1476 state->CP14R0_CCD -= 64, newcycles++; 1477 1478 goto check_PMUintr; 1479 } 1480 } 1481 else 1482 { 1483 ARMword cp14r1; 1484 int do_int; 1485 1486 state->CP14R0_CCD = -1; 1487 check_PMUintr: 1488 do_int = 0; 1489 cp14r0 |= ARMul_CP14_R0_FLAG2; 1490 (void) state->CPWrite[14] (state, 0, cp14r0); 1491 1492 ok = state->CPRead[14] (state, 1, & cp14r1); 1493 1494 /* Coded like this for portability. */ 1495 while (ok && newcycles) 1496 { 1497 if (cp14r1 == 0xffffffff) 1498 { 1499 cp14r1 = 0; 1500 do_int = 1; 1501 } 1502 else 1503 cp14r1 ++; 1504 1505 newcycles --; 1506 } 1507 1508 (void) state->CPWrite[14] (state, 1, cp14r1); 1509 1510 if (do_int && (cp14r0 & ARMul_CP14_R0_INTEN2)) 1511 { 1512 ARMword temp; 1513 1514 if (state->CPRead[13] (state, 8, & temp) 1515 && (temp & ARMul_CP13_R8_PMUS)) 1516 ARMul_Abort (state, ARMul_FIQV); 1517 else 1518 ARMul_Abort (state, ARMul_IRQV); 1519 } 1520 } 1521 } 1522 } 1523 1524 /* Handle hardware instructions breakpoints here. */ 1525 if (state->is_XScale) 1526 { 1527 if ( (pc | 3) == (read_cp15_reg (14, 0, 8) | 2) 1528 || (pc | 3) == (read_cp15_reg (14, 0, 9) | 2)) 1529 { 1530 if (XScale_debug_moe (state, ARMul_CP14_R10_MOE_IB)) 1531 ARMul_OSHandleSWI (state, SWI_Breakpoint); 1532 } 1533 } 1534 1535 /* Actual execution of instructions begins here. */ 1536 /* If the condition codes don't match, stop here. */ 1537 if (temp) 1538 { 1539 mainswitch: 1540 1541 if (state->is_XScale) 1542 { 1543 if (BIT (20) == 0 && BITS (25, 27) == 0) 1544 { 1545 if (BITS (4, 7) == 0xD) 1546 { 1547 /* XScale Load Consecutive insn. */ 1548 ARMword temp = GetLS7RHS (state, instr); 1549 ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp; 1550 ARMword addr = BIT (24) ? temp2 : LHS; 1551 1552 if (BIT (12)) 1553 ARMul_UndefInstr (state, instr); 1554 else if (addr & 7) 1555 /* Alignment violation. */ 1556 ARMul_Abort (state, ARMul_DataAbortV); 1557 else 1558 { 1559 int wb = BIT (21) || (! BIT (24)); 1560 1561 state->Reg[BITS (12, 15)] = 1562 ARMul_LoadWordN (state, addr); 1563 state->Reg[BITS (12, 15) + 1] = 1564 ARMul_LoadWordN (state, addr + 4); 1565 if (wb) 1566 LSBase = temp2; 1567 } 1568 1569 goto donext; 1570 } 1571 else if (BITS (4, 7) == 0xF) 1572 { 1573 /* XScale Store Consecutive insn. */ 1574 ARMword temp = GetLS7RHS (state, instr); 1575 ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp; 1576 ARMword addr = BIT (24) ? temp2 : LHS; 1577 1578 if (BIT (12)) 1579 ARMul_UndefInstr (state, instr); 1580 else if (addr & 7) 1581 /* Alignment violation. */ 1582 ARMul_Abort (state, ARMul_DataAbortV); 1583 else 1584 { 1585 ARMul_StoreWordN (state, addr, 1586 state->Reg[BITS (12, 15)]); 1587 ARMul_StoreWordN (state, addr + 4, 1588 state->Reg[BITS (12, 15) + 1]); 1589 1590 if (BIT (21)|| ! BIT (24)) 1591 LSBase = temp2; 1592 } 1593 1594 goto donext; 1595 } 1596 } 1597 1598 if (ARMul_HandleIwmmxt (state, instr)) 1599 goto donext; 1600 } 1601 1602 switch ((int) BITS (20, 27)) 1603 { 1604 /* Data Processing Register RHS Instructions. */ 1605 1606 case 0x00: /* AND reg and MUL */ 1607 #ifdef MODET 1608 if (BITS (4, 11) == 0xB) 1609 { 1610 /* STRH register offset, no write-back, down, post indexed. */ 1611 SHDOWNWB (); 1612 break; 1613 } 1614 if (BITS (4, 7) == 0xD) 1615 { 1616 Handle_Load_Double (state, instr); 1617 break; 1618 } 1619 if (BITS (4, 7) == 0xF) 1620 { 1621 Handle_Store_Double (state, instr); 1622 break; 1623 } 1624 #endif 1625 if (BITS (4, 7) == 9) 1626 { 1627 /* MUL */ 1628 rhs = state->Reg[MULRHSReg]; 1629 if (MULLHSReg == MULDESTReg) 1630 { 1631 UNDEF_MULDestEQOp1; 1632 state->Reg[MULDESTReg] = 0; 1633 } 1634 else if (MULDESTReg != 15) 1635 state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs; 1636 else 1637 UNDEF_MULPCDest; 1638 1639 for (dest = 0, temp = 0; dest < 32; dest ++) 1640 if (rhs & (1L << dest)) 1641 temp = dest; 1642 1643 /* Mult takes this many/2 I cycles. */ 1644 ARMul_Icycles (state, ARMul_MultTable[temp], 0L); 1645 } 1646 else 1647 { 1648 /* AND reg. */ 1649 rhs = DPRegRHS; 1650 dest = LHS & rhs; 1651 WRITEDEST (dest); 1652 } 1653 break; 1654 1655 case 0x01: /* ANDS reg and MULS */ 1656 #ifdef MODET 1657 if ((BITS (4, 11) & 0xF9) == 0x9) 1658 /* LDR register offset, no write-back, down, post indexed. */ 1659 LHPOSTDOWN (); 1660 /* Fall through to rest of decoding. */ 1661 #endif 1662 if (BITS (4, 7) == 9) 1663 { 1664 /* MULS */ 1665 rhs = state->Reg[MULRHSReg]; 1666 1667 if (MULLHSReg == MULDESTReg) 1668 { 1669 UNDEF_MULDestEQOp1; 1670 state->Reg[MULDESTReg] = 0; 1671 CLEARN; 1672 SETZ; 1673 } 1674 else if (MULDESTReg != 15) 1675 { 1676 dest = state->Reg[MULLHSReg] * rhs; 1677 ARMul_NegZero (state, dest); 1678 state->Reg[MULDESTReg] = dest; 1679 } 1680 else 1681 UNDEF_MULPCDest; 1682 1683 for (dest = 0, temp = 0; dest < 32; dest ++) 1684 if (rhs & (1L << dest)) 1685 temp = dest; 1686 1687 /* Mult takes this many/2 I cycles. */ 1688 ARMul_Icycles (state, ARMul_MultTable[temp], 0L); 1689 } 1690 else 1691 { 1692 /* ANDS reg. */ 1693 rhs = DPSRegRHS; 1694 dest = LHS & rhs; 1695 WRITESDEST (dest); 1696 } 1697 break; 1698 1699 case 0x02: /* EOR reg and MLA */ 1700 #ifdef MODET 1701 if (BITS (4, 11) == 0xB) 1702 { 1703 /* STRH register offset, write-back, down, post indexed. */ 1704 SHDOWNWB (); 1705 break; 1706 } 1707 #endif 1708 if (BITS (4, 7) == 9) 1709 { /* MLA */ 1710 rhs = state->Reg[MULRHSReg]; 1711 if (MULLHSReg == MULDESTReg) 1712 { 1713 UNDEF_MULDestEQOp1; 1714 state->Reg[MULDESTReg] = state->Reg[MULACCReg]; 1715 } 1716 else if (MULDESTReg != 15) 1717 state->Reg[MULDESTReg] = 1718 state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg]; 1719 else 1720 UNDEF_MULPCDest; 1721 1722 for (dest = 0, temp = 0; dest < 32; dest ++) 1723 if (rhs & (1L << dest)) 1724 temp = dest; 1725 1726 /* Mult takes this many/2 I cycles. */ 1727 ARMul_Icycles (state, ARMul_MultTable[temp], 0L); 1728 } 1729 else 1730 { 1731 rhs = DPRegRHS; 1732 dest = LHS ^ rhs; 1733 WRITEDEST (dest); 1734 } 1735 break; 1736 1737 case 0x03: /* EORS reg and MLAS */ 1738 #ifdef MODET 1739 if ((BITS (4, 11) & 0xF9) == 0x9) 1740 /* LDR register offset, write-back, down, post-indexed. */ 1741 LHPOSTDOWN (); 1742 /* Fall through to rest of the decoding. */ 1743 #endif 1744 if (BITS (4, 7) == 9) 1745 { 1746 /* MLAS */ 1747 rhs = state->Reg[MULRHSReg]; 1748 1749 if (MULLHSReg == MULDESTReg) 1750 { 1751 UNDEF_MULDestEQOp1; 1752 dest = state->Reg[MULACCReg]; 1753 ARMul_NegZero (state, dest); 1754 state->Reg[MULDESTReg] = dest; 1755 } 1756 else if (MULDESTReg != 15) 1757 { 1758 dest = 1759 state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg]; 1760 ARMul_NegZero (state, dest); 1761 state->Reg[MULDESTReg] = dest; 1762 } 1763 else 1764 UNDEF_MULPCDest; 1765 1766 for (dest = 0, temp = 0; dest < 32; dest ++) 1767 if (rhs & (1L << dest)) 1768 temp = dest; 1769 1770 /* Mult takes this many/2 I cycles. */ 1771 ARMul_Icycles (state, ARMul_MultTable[temp], 0L); 1772 } 1773 else 1774 { 1775 /* EORS Reg. */ 1776 rhs = DPSRegRHS; 1777 dest = LHS ^ rhs; 1778 WRITESDEST (dest); 1779 } 1780 break; 1781 1782 case 0x04: /* SUB reg */ 1783 #ifdef MODET 1784 if (BITS (4, 7) == 0xB) 1785 { 1786 /* STRH immediate offset, no write-back, down, post indexed. */ 1787 SHDOWNWB (); 1788 break; 1789 } 1790 if (BITS (4, 7) == 0xD) 1791 { 1792 Handle_Load_Double (state, instr); 1793 break; 1794 } 1795 if (BITS (4, 7) == 0xF) 1796 { 1797 Handle_Store_Double (state, instr); 1798 break; 1799 } 1800 #endif 1801 rhs = DPRegRHS; 1802 dest = LHS - rhs; 1803 WRITEDEST (dest); 1804 break; 1805 1806 case 0x05: /* SUBS reg */ 1807 #ifdef MODET 1808 if ((BITS (4, 7) & 0x9) == 0x9) 1809 /* LDR immediate offset, no write-back, down, post indexed. */ 1810 LHPOSTDOWN (); 1811 /* Fall through to the rest of the instruction decoding. */ 1812 #endif 1813 lhs = LHS; 1814 rhs = DPRegRHS; 1815 dest = lhs - rhs; 1816 1817 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) 1818 { 1819 ARMul_SubCarry (state, lhs, rhs, dest); 1820 ARMul_SubOverflow (state, lhs, rhs, dest); 1821 } 1822 else 1823 { 1824 CLEARC; 1825 CLEARV; 1826 } 1827 WRITESDEST (dest); 1828 break; 1829 1830 case 0x06: /* RSB reg */ 1831 #ifdef MODET 1832 if (BITS (4, 7) == 0xB) 1833 { 1834 /* STRH immediate offset, write-back, down, post indexed. */ 1835 SHDOWNWB (); 1836 break; 1837 } 1838 #endif 1839 rhs = DPRegRHS; 1840 dest = rhs - LHS; 1841 WRITEDEST (dest); 1842 break; 1843 1844 case 0x07: /* RSBS reg */ 1845 #ifdef MODET 1846 if ((BITS (4, 7) & 0x9) == 0x9) 1847 /* LDR immediate offset, write-back, down, post indexed. */ 1848 LHPOSTDOWN (); 1849 /* Fall through to remainder of instruction decoding. */ 1850 #endif 1851 lhs = LHS; 1852 rhs = DPRegRHS; 1853 dest = rhs - lhs; 1854 1855 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) 1856 { 1857 ARMul_SubCarry (state, rhs, lhs, dest); 1858 ARMul_SubOverflow (state, rhs, lhs, dest); 1859 } 1860 else 1861 { 1862 CLEARC; 1863 CLEARV; 1864 } 1865 WRITESDEST (dest); 1866 break; 1867 1868 case 0x08: /* ADD reg */ 1869 #ifdef MODET 1870 if (BITS (4, 11) == 0xB) 1871 { 1872 /* STRH register offset, no write-back, up, post indexed. */ 1873 SHUPWB (); 1874 break; 1875 } 1876 if (BITS (4, 7) == 0xD) 1877 { 1878 Handle_Load_Double (state, instr); 1879 break; 1880 } 1881 if (BITS (4, 7) == 0xF) 1882 { 1883 Handle_Store_Double (state, instr); 1884 break; 1885 } 1886 #endif 1887 #ifdef MODET 1888 if (BITS (4, 7) == 0x9) 1889 { 1890 /* MULL */ 1891 /* 32x32 = 64 */ 1892 ARMul_Icycles (state, 1893 Multiply64 (state, instr, LUNSIGNED, 1894 LDEFAULT), 0L); 1895 break; 1896 } 1897 #endif 1898 rhs = DPRegRHS; 1899 dest = LHS + rhs; 1900 WRITEDEST (dest); 1901 break; 1902 1903 case 0x09: /* ADDS reg */ 1904 #ifdef MODET 1905 if ((BITS (4, 11) & 0xF9) == 0x9) 1906 /* LDR register offset, no write-back, up, post indexed. */ 1907 LHPOSTUP (); 1908 /* Fall through to remaining instruction decoding. */ 1909 #endif 1910 #ifdef MODET 1911 if (BITS (4, 7) == 0x9) 1912 { 1913 /* MULL */ 1914 /* 32x32=64 */ 1915 ARMul_Icycles (state, 1916 Multiply64 (state, instr, LUNSIGNED, LSCC), 1917 0L); 1918 break; 1919 } 1920 #endif 1921 lhs = LHS; 1922 rhs = DPRegRHS; 1923 dest = lhs + rhs; 1924 ASSIGNZ (dest == 0); 1925 if ((lhs | rhs) >> 30) 1926 { 1927 /* Possible C,V,N to set. */ 1928 ASSIGNN (NEG (dest)); 1929 ARMul_AddCarry (state, lhs, rhs, dest); 1930 ARMul_AddOverflow (state, lhs, rhs, dest); 1931 } 1932 else 1933 { 1934 CLEARN; 1935 CLEARC; 1936 CLEARV; 1937 } 1938 WRITESDEST (dest); 1939 break; 1940 1941 case 0x0a: /* ADC reg */ 1942 #ifdef MODET 1943 if (BITS (4, 11) == 0xB) 1944 { 1945 /* STRH register offset, write-back, up, post-indexed. */ 1946 SHUPWB (); 1947 break; 1948 } 1949 if (BITS (4, 7) == 0x9) 1950 { 1951 /* MULL */ 1952 /* 32x32=64 */ 1953 ARMul_Icycles (state, 1954 MultiplyAdd64 (state, instr, LUNSIGNED, 1955 LDEFAULT), 0L); 1956 break; 1957 } 1958 #endif 1959 rhs = DPRegRHS; 1960 dest = LHS + rhs + CFLAG; 1961 WRITEDEST (dest); 1962 break; 1963 1964 case 0x0b: /* ADCS reg */ 1965 #ifdef MODET 1966 if ((BITS (4, 11) & 0xF9) == 0x9) 1967 /* LDR register offset, write-back, up, post indexed. */ 1968 LHPOSTUP (); 1969 /* Fall through to remaining instruction decoding. */ 1970 if (BITS (4, 7) == 0x9) 1971 { 1972 /* MULL */ 1973 /* 32x32=64 */ 1974 ARMul_Icycles (state, 1975 MultiplyAdd64 (state, instr, LUNSIGNED, 1976 LSCC), 0L); 1977 break; 1978 } 1979 #endif 1980 lhs = LHS; 1981 rhs = DPRegRHS; 1982 dest = lhs + rhs + CFLAG; 1983 ASSIGNZ (dest == 0); 1984 if ((lhs | rhs) >> 30) 1985 { 1986 /* Possible C,V,N to set. */ 1987 ASSIGNN (NEG (dest)); 1988 ARMul_AddCarry (state, lhs, rhs, dest); 1989 ARMul_AddOverflow (state, lhs, rhs, dest); 1990 } 1991 else 1992 { 1993 CLEARN; 1994 CLEARC; 1995 CLEARV; 1996 } 1997 WRITESDEST (dest); 1998 break; 1999 2000 case 0x0c: /* SBC reg */ 2001 #ifdef MODET 2002 if (BITS (4, 7) == 0xB) 2003 { 2004 /* STRH immediate offset, no write-back, up post indexed. */ 2005 SHUPWB (); 2006 break; 2007 } 2008 if (BITS (4, 7) == 0xD) 2009 { 2010 Handle_Load_Double (state, instr); 2011 break; 2012 } 2013 if (BITS (4, 7) == 0xF) 2014 { 2015 Handle_Store_Double (state, instr); 2016 break; 2017 } 2018 if (BITS (4, 7) == 0x9) 2019 { 2020 /* MULL */ 2021 /* 32x32=64 */ 2022 ARMul_Icycles (state, 2023 Multiply64 (state, instr, LSIGNED, LDEFAULT), 2024 0L); 2025 break; 2026 } 2027 #endif 2028 rhs = DPRegRHS; 2029 dest = LHS - rhs - !CFLAG; 2030 WRITEDEST (dest); 2031 break; 2032 2033 case 0x0d: /* SBCS reg */ 2034 #ifdef MODET 2035 if ((BITS (4, 7) & 0x9) == 0x9) 2036 /* LDR immediate offset, no write-back, up, post indexed. */ 2037 LHPOSTUP (); 2038 2039 if (BITS (4, 7) == 0x9) 2040 { 2041 /* MULL */ 2042 /* 32x32=64 */ 2043 ARMul_Icycles (state, 2044 Multiply64 (state, instr, LSIGNED, LSCC), 2045 0L); 2046 break; 2047 } 2048 #endif 2049 lhs = LHS; 2050 rhs = DPRegRHS; 2051 dest = lhs - rhs - !CFLAG; 2052 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) 2053 { 2054 ARMul_SubCarry (state, lhs, rhs, dest); 2055 ARMul_SubOverflow (state, lhs, rhs, dest); 2056 } 2057 else 2058 { 2059 CLEARC; 2060 CLEARV; 2061 } 2062 WRITESDEST (dest); 2063 break; 2064 2065 case 0x0e: /* RSC reg */ 2066 #ifdef MODET 2067 if (BITS (4, 7) == 0xB) 2068 { 2069 /* STRH immediate offset, write-back, up, post indexed. */ 2070 SHUPWB (); 2071 break; 2072 } 2073 2074 if (BITS (4, 7) == 0x9) 2075 { 2076 /* MULL */ 2077 /* 32x32=64 */ 2078 ARMul_Icycles (state, 2079 MultiplyAdd64 (state, instr, LSIGNED, 2080 LDEFAULT), 0L); 2081 break; 2082 } 2083 #endif 2084 rhs = DPRegRHS; 2085 dest = rhs - LHS - !CFLAG; 2086 WRITEDEST (dest); 2087 break; 2088 2089 case 0x0f: /* RSCS reg */ 2090 #ifdef MODET 2091 if ((BITS (4, 7) & 0x9) == 0x9) 2092 /* LDR immediate offset, write-back, up, post indexed. */ 2093 LHPOSTUP (); 2094 /* Fall through to remaining instruction decoding. */ 2095 2096 if (BITS (4, 7) == 0x9) 2097 { 2098 /* MULL */ 2099 /* 32x32=64 */ 2100 ARMul_Icycles (state, 2101 MultiplyAdd64 (state, instr, LSIGNED, LSCC), 2102 0L); 2103 break; 2104 } 2105 #endif 2106 lhs = LHS; 2107 rhs = DPRegRHS; 2108 dest = rhs - lhs - !CFLAG; 2109 2110 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) 2111 { 2112 ARMul_SubCarry (state, rhs, lhs, dest); 2113 ARMul_SubOverflow (state, rhs, lhs, dest); 2114 } 2115 else 2116 { 2117 CLEARC; 2118 CLEARV; 2119 } 2120 WRITESDEST (dest); 2121 break; 2122 2123 case 0x10: /* TST reg and MRS CPSR and SWP word. */ 2124 if (state->is_v5e) 2125 { 2126 if (BIT (4) == 0 && BIT (7) == 1) 2127 { 2128 /* ElSegundo SMLAxy insn. */ 2129 ARMword op1 = state->Reg[BITS (0, 3)]; 2130 ARMword op2 = state->Reg[BITS (8, 11)]; 2131 ARMword Rn = state->Reg[BITS (12, 15)]; 2132 2133 if (BIT (5)) 2134 op1 >>= 16; 2135 if (BIT (6)) 2136 op2 >>= 16; 2137 op1 &= 0xFFFF; 2138 op2 &= 0xFFFF; 2139 if (op1 & 0x8000) 2140 op1 -= 65536; 2141 if (op2 & 0x8000) 2142 op2 -= 65536; 2143 op1 *= op2; 2144 2145 if (AddOverflow (op1, Rn, op1 + Rn)) 2146 SETS; 2147 state->Reg[BITS (16, 19)] = op1 + Rn; 2148 break; 2149 } 2150 2151 if (BITS (4, 11) == 5) 2152 { 2153 /* ElSegundo QADD insn. */ 2154 ARMword op1 = state->Reg[BITS (0, 3)]; 2155 ARMword op2 = state->Reg[BITS (16, 19)]; 2156 ARMword result = op1 + op2; 2157 if (AddOverflow (op1, op2, result)) 2158 { 2159 result = POS (result) ? 0x80000000 : 0x7fffffff; 2160 SETS; 2161 } 2162 state->Reg[BITS (12, 15)] = result; 2163 break; 2164 } 2165 } 2166 #ifdef MODET 2167 if (BITS (4, 11) == 0xB) 2168 { 2169 /* STRH register offset, no write-back, down, pre indexed. */ 2170 SHPREDOWN (); 2171 break; 2172 } 2173 if (BITS (4, 7) == 0xD) 2174 { 2175 Handle_Load_Double (state, instr); 2176 break; 2177 } 2178 if (BITS (4, 7) == 0xF) 2179 { 2180 Handle_Store_Double (state, instr); 2181 break; 2182 } 2183 #endif 2184 if (BITS (4, 11) == 9) 2185 { 2186 /* SWP */ 2187 UNDEF_SWPPC; 2188 temp = LHS; 2189 BUSUSEDINCPCS; 2190 #ifndef MODE32 2191 if (VECTORACCESS (temp) || ADDREXCEPT (temp)) 2192 { 2193 INTERNALABORT (temp); 2194 (void) ARMul_LoadWordN (state, temp); 2195 (void) ARMul_LoadWordN (state, temp); 2196 } 2197 else 2198 #endif 2199 dest = ARMul_SwapWord (state, temp, state->Reg[RHSReg]); 2200 if (temp & 3) 2201 DEST = ARMul_Align (state, temp, dest); 2202 else 2203 DEST = dest; 2204 if (state->abortSig || state->Aborted) 2205 TAKEABORT; 2206 } 2207 else if ((BITS (0, 11) == 0) && (LHSReg == 15)) 2208 { /* MRS CPSR */ 2209 UNDEF_MRSPC; 2210 DEST = ECC | EINT | EMODE; 2211 } 2212 else 2213 { 2214 #ifdef MODE32 2215 if (state->is_v6 2216 && handle_v6_insn (state, instr)) 2217 break; 2218 #endif 2219 UNDEF_Test; 2220 } 2221 break; 2222 2223 case 0x11: /* TSTP reg */ 2224 #ifdef MODET 2225 if ((BITS (4, 11) & 0xF9) == 0x9) 2226 /* LDR register offset, no write-back, down, pre indexed. */ 2227 LHPREDOWN (); 2228 /* Continue with remaining instruction decode. */ 2229 #endif 2230 if (DESTReg == 15) 2231 { 2232 /* TSTP reg */ 2233 #ifdef MODE32 2234 state->Cpsr = GETSPSR (state->Bank); 2235 ARMul_CPSRAltered (state); 2236 #else 2237 rhs = DPRegRHS; 2238 temp = LHS & rhs; 2239 SETR15PSR (temp); 2240 #endif 2241 } 2242 else 2243 { 2244 /* TST reg */ 2245 rhs = DPSRegRHS; 2246 dest = LHS & rhs; 2247 ARMul_NegZero (state, dest); 2248 } 2249 break; 2250 2251 case 0x12: /* TEQ reg and MSR reg to CPSR (ARM6). */ 2252 if (state->is_v5) 2253 { 2254 if (BITS (4, 7) == 3) 2255 { 2256 /* BLX(2) */ 2257 ARMword temp; 2258 2259 if (TFLAG) 2260 temp = (pc + 2) | 1; 2261 else 2262 temp = pc + 4; 2263 2264 WriteR15Branch (state, state->Reg[RHSReg]); 2265 state->Reg[14] = temp; 2266 break; 2267 } 2268 } 2269 2270 if (state->is_v5e) 2271 { 2272 if (BIT (4) == 0 && BIT (7) == 1 2273 && (BIT (5) == 0 || BITS (12, 15) == 0)) 2274 { 2275 /* ElSegundo SMLAWy/SMULWy insn. */ 2276 ARMdword op1 = state->Reg[BITS (0, 3)]; 2277 ARMdword op2 = state->Reg[BITS (8, 11)]; 2278 ARMdword result; 2279 2280 if (BIT (6)) 2281 op2 >>= 16; 2282 if (op1 & 0x80000000) 2283 op1 -= 1ULL << 32; 2284 op2 &= 0xFFFF; 2285 if (op2 & 0x8000) 2286 op2 -= 65536; 2287 result = (op1 * op2) >> 16; 2288 2289 if (BIT (5) == 0) 2290 { 2291 ARMword Rn = state->Reg[BITS (12, 15)]; 2292 2293 if (AddOverflow (result, Rn, result + Rn)) 2294 SETS; 2295 result += Rn; 2296 } 2297 state->Reg[BITS (16, 19)] = result; 2298 break; 2299 } 2300 2301 if (BITS (4, 11) == 5) 2302 { 2303 /* ElSegundo QSUB insn. */ 2304 ARMword op1 = state->Reg[BITS (0, 3)]; 2305 ARMword op2 = state->Reg[BITS (16, 19)]; 2306 ARMword result = op1 - op2; 2307 2308 if (SubOverflow (op1, op2, result)) 2309 { 2310 result = POS (result) ? 0x80000000 : 0x7fffffff; 2311 SETS; 2312 } 2313 2314 state->Reg[BITS (12, 15)] = result; 2315 break; 2316 } 2317 } 2318 #ifdef MODET 2319 if (BITS (4, 11) == 0xB) 2320 { 2321 /* STRH register offset, write-back, down, pre indexed. */ 2322 SHPREDOWNWB (); 2323 break; 2324 } 2325 if (BITS (4, 27) == 0x12FFF1) 2326 { 2327 /* BX */ 2328 WriteR15Branch (state, state->Reg[RHSReg]); 2329 break; 2330 } 2331 if (BITS (4, 7) == 0xD) 2332 { 2333 Handle_Load_Double (state, instr); 2334 break; 2335 } 2336 if (BITS (4, 7) == 0xF) 2337 { 2338 Handle_Store_Double (state, instr); 2339 break; 2340 } 2341 #endif 2342 if (state->is_v5) 2343 { 2344 if (BITS (4, 7) == 0x7) 2345 { 2346 extern int SWI_vector_installed; 2347 2348 /* Hardware is allowed to optionally override this 2349 instruction and treat it as a breakpoint. Since 2350 this is a simulator not hardware, we take the position 2351 that if a SWI vector was not installed, then an Abort 2352 vector was probably not installed either, and so 2353 normally this instruction would be ignored, even if an 2354 Abort is generated. This is a bad thing, since GDB 2355 uses this instruction for its breakpoints (at least in 2356 Thumb mode it does). So intercept the instruction here 2357 and generate a breakpoint SWI instead. */ 2358 if (! SWI_vector_installed) 2359 ARMul_OSHandleSWI (state, SWI_Breakpoint); 2360 else 2361 { 2362 /* BKPT - normally this will cause an abort, but on the 2363 XScale we must check the DCSR. */ 2364 XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc); 2365 if (!XScale_debug_moe (state, ARMul_CP14_R10_MOE_BT)) 2366 break; 2367 } 2368 2369 /* Force the next instruction to be refetched. */ 2370 state->NextInstr = RESUME; 2371 break; 2372 } 2373 } 2374 if (DESTReg == 15) 2375 { 2376 /* MSR reg to CPSR. */ 2377 UNDEF_MSRPC; 2378 temp = DPRegRHS; 2379 #ifdef MODET 2380 /* Don't allow TBIT to be set by MSR. */ 2381 temp &= ~ TBIT; 2382 #endif 2383 ARMul_FixCPSR (state, instr, temp); 2384 } 2385 #ifdef MODE32 2386 else if (state->is_v6 2387 && handle_v6_insn (state, instr)) 2388 break; 2389 #endif 2390 else 2391 UNDEF_Test; 2392 2393 break; 2394 2395 case 0x13: /* TEQP reg */ 2396 #ifdef MODET 2397 if ((BITS (4, 11) & 0xF9) == 0x9) 2398 /* LDR register offset, write-back, down, pre indexed. */ 2399 LHPREDOWNWB (); 2400 /* Continue with remaining instruction decode. */ 2401 #endif 2402 if (DESTReg == 15) 2403 { 2404 /* TEQP reg */ 2405 #ifdef MODE32 2406 state->Cpsr = GETSPSR (state->Bank); 2407 ARMul_CPSRAltered (state); 2408 #else 2409 rhs = DPRegRHS; 2410 temp = LHS ^ rhs; 2411 SETR15PSR (temp); 2412 #endif 2413 } 2414 else 2415 { 2416 /* TEQ Reg. */ 2417 rhs = DPSRegRHS; 2418 dest = LHS ^ rhs; 2419 ARMul_NegZero (state, dest); 2420 } 2421 break; 2422 2423 case 0x14: /* CMP reg and MRS SPSR and SWP byte. */ 2424 if (state->is_v5e) 2425 { 2426 if (BIT (4) == 0 && BIT (7) == 1) 2427 { 2428 /* ElSegundo SMLALxy insn. */ 2429 ARMdword op1 = state->Reg[BITS (0, 3)]; 2430 ARMdword op2 = state->Reg[BITS (8, 11)]; 2431 ARMdword dest; 2432 2433 if (BIT (5)) 2434 op1 >>= 16; 2435 if (BIT (6)) 2436 op2 >>= 16; 2437 op1 &= 0xFFFF; 2438 if (op1 & 0x8000) 2439 op1 -= 65536; 2440 op2 &= 0xFFFF; 2441 if (op2 & 0x8000) 2442 op2 -= 65536; 2443 2444 dest = (ARMdword) state->Reg[BITS (16, 19)] << 32; 2445 dest |= state->Reg[BITS (12, 15)]; 2446 dest += op1 * op2; 2447 state->Reg[BITS (12, 15)] = dest; 2448 state->Reg[BITS (16, 19)] = dest >> 32; 2449 break; 2450 } 2451 2452 if (BITS (4, 11) == 5) 2453 { 2454 /* ElSegundo QDADD insn. */ 2455 ARMword op1 = state->Reg[BITS (0, 3)]; 2456 ARMword op2 = state->Reg[BITS (16, 19)]; 2457 ARMword op2d = op2 + op2; 2458 ARMword result; 2459 2460 if (AddOverflow (op2, op2, op2d)) 2461 { 2462 SETS; 2463 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; 2464 } 2465 2466 result = op1 + op2d; 2467 if (AddOverflow (op1, op2d, result)) 2468 { 2469 SETS; 2470 result = POS (result) ? 0x80000000 : 0x7fffffff; 2471 } 2472 2473 state->Reg[BITS (12, 15)] = result; 2474 break; 2475 } 2476 } 2477 #ifdef MODET 2478 if (BITS (4, 7) == 0xB) 2479 { 2480 /* STRH immediate offset, no write-back, down, pre indexed. */ 2481 SHPREDOWN (); 2482 break; 2483 } 2484 if (BITS (4, 7) == 0xD) 2485 { 2486 Handle_Load_Double (state, instr); 2487 break; 2488 } 2489 if (BITS (4, 7) == 0xF) 2490 { 2491 Handle_Store_Double (state, instr); 2492 break; 2493 } 2494 #endif 2495 if (BITS (4, 11) == 9) 2496 { 2497 /* SWP */ 2498 UNDEF_SWPPC; 2499 temp = LHS; 2500 BUSUSEDINCPCS; 2501 #ifndef MODE32 2502 if (VECTORACCESS (temp) || ADDREXCEPT (temp)) 2503 { 2504 INTERNALABORT (temp); 2505 (void) ARMul_LoadByte (state, temp); 2506 (void) ARMul_LoadByte (state, temp); 2507 } 2508 else 2509 #endif 2510 DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]); 2511 if (state->abortSig || state->Aborted) 2512 TAKEABORT; 2513 } 2514 else if ((BITS (0, 11) == 0) && (LHSReg == 15)) 2515 { 2516 /* MRS SPSR */ 2517 UNDEF_MRSPC; 2518 DEST = GETSPSR (state->Bank); 2519 } 2520 #ifdef MODE32 2521 else if (state->is_v6 2522 && handle_v6_insn (state, instr)) 2523 break; 2524 #endif 2525 else 2526 UNDEF_Test; 2527 2528 break; 2529 2530 case 0x15: /* CMPP reg. */ 2531 #ifdef MODET 2532 if ((BITS (4, 7) & 0x9) == 0x9) 2533 /* LDR immediate offset, no write-back, down, pre indexed. */ 2534 LHPREDOWN (); 2535 /* Continue with remaining instruction decode. */ 2536 #endif 2537 if (DESTReg == 15) 2538 { 2539 /* CMPP reg. */ 2540 #ifdef MODE32 2541 state->Cpsr = GETSPSR (state->Bank); 2542 ARMul_CPSRAltered (state); 2543 #else 2544 rhs = DPRegRHS; 2545 temp = LHS - rhs; 2546 SETR15PSR (temp); 2547 #endif 2548 } 2549 else 2550 { 2551 /* CMP reg. */ 2552 lhs = LHS; 2553 rhs = DPRegRHS; 2554 dest = lhs - rhs; 2555 ARMul_NegZero (state, dest); 2556 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) 2557 { 2558 ARMul_SubCarry (state, lhs, rhs, dest); 2559 ARMul_SubOverflow (state, lhs, rhs, dest); 2560 } 2561 else 2562 { 2563 CLEARC; 2564 CLEARV; 2565 } 2566 } 2567 break; 2568 2569 case 0x16: /* CMN reg and MSR reg to SPSR */ 2570 if (state->is_v5e) 2571 { 2572 if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0) 2573 { 2574 /* ElSegundo SMULxy insn. */ 2575 ARMword op1 = state->Reg[BITS (0, 3)]; 2576 ARMword op2 = state->Reg[BITS (8, 11)]; 2577 2578 if (BIT (5)) 2579 op1 >>= 16; 2580 if (BIT (6)) 2581 op2 >>= 16; 2582 op1 &= 0xFFFF; 2583 op2 &= 0xFFFF; 2584 if (op1 & 0x8000) 2585 op1 -= 65536; 2586 if (op2 & 0x8000) 2587 op2 -= 65536; 2588 2589 state->Reg[BITS (16, 19)] = op1 * op2; 2590 break; 2591 } 2592 2593 if (BITS (4, 11) == 5) 2594 { 2595 /* ElSegundo QDSUB insn. */ 2596 ARMword op1 = state->Reg[BITS (0, 3)]; 2597 ARMword op2 = state->Reg[BITS (16, 19)]; 2598 ARMword op2d = op2 + op2; 2599 ARMword result; 2600 2601 if (AddOverflow (op2, op2, op2d)) 2602 { 2603 SETS; 2604 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; 2605 } 2606 2607 result = op1 - op2d; 2608 if (SubOverflow (op1, op2d, result)) 2609 { 2610 SETS; 2611 result = POS (result) ? 0x80000000 : 0x7fffffff; 2612 } 2613 2614 state->Reg[BITS (12, 15)] = result; 2615 break; 2616 } 2617 } 2618 2619 if (state->is_v5) 2620 { 2621 if (BITS (4, 11) == 0xF1 && BITS (16, 19) == 0xF) 2622 { 2623 /* ARM5 CLZ insn. */ 2624 ARMword op1 = state->Reg[BITS (0, 3)]; 2625 int result = 32; 2626 2627 if (op1) 2628 for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1) 2629 result++; 2630 2631 state->Reg[BITS (12, 15)] = result; 2632 break; 2633 } 2634 } 2635 #ifdef MODET 2636 if (BITS (4, 7) == 0xB) 2637 { 2638 /* STRH immediate offset, write-back, down, pre indexed. */ 2639 SHPREDOWNWB (); 2640 break; 2641 } 2642 if (BITS (4, 7) == 0xD) 2643 { 2644 Handle_Load_Double (state, instr); 2645 break; 2646 } 2647 if (BITS (4, 7) == 0xF) 2648 { 2649 Handle_Store_Double (state, instr); 2650 break; 2651 } 2652 #endif 2653 if (DESTReg == 15) 2654 { 2655 /* MSR */ 2656 UNDEF_MSRPC; 2657 ARMul_FixSPSR (state, instr, DPRegRHS); 2658 } 2659 else 2660 { 2661 #ifdef MODE32 2662 if (state->is_v6 2663 && handle_v6_insn (state, instr)) 2664 break; 2665 #endif 2666 UNDEF_Test; 2667 } 2668 break; 2669 2670 case 0x17: /* CMNP reg */ 2671 #ifdef MODET 2672 if ((BITS (4, 7) & 0x9) == 0x9) 2673 /* LDR immediate offset, write-back, down, pre indexed. */ 2674 LHPREDOWNWB (); 2675 /* Continue with remaining instruction decoding. */ 2676 #endif 2677 if (DESTReg == 15) 2678 { 2679 #ifdef MODE32 2680 state->Cpsr = GETSPSR (state->Bank); 2681 ARMul_CPSRAltered (state); 2682 #else 2683 rhs = DPRegRHS; 2684 temp = LHS + rhs; 2685 SETR15PSR (temp); 2686 #endif 2687 break; 2688 } 2689 else 2690 { 2691 /* CMN reg. */ 2692 lhs = LHS; 2693 rhs = DPRegRHS; 2694 dest = lhs + rhs; 2695 ASSIGNZ (dest == 0); 2696 if ((lhs | rhs) >> 30) 2697 { 2698 /* Possible C,V,N to set. */ 2699 ASSIGNN (NEG (dest)); 2700 ARMul_AddCarry (state, lhs, rhs, dest); 2701 ARMul_AddOverflow (state, lhs, rhs, dest); 2702 } 2703 else 2704 { 2705 CLEARN; 2706 CLEARC; 2707 CLEARV; 2708 } 2709 } 2710 break; 2711 2712 case 0x18: /* ORR reg */ 2713 #ifdef MODET 2714 if (BITS (4, 11) == 0xB) 2715 { 2716 /* STRH register offset, no write-back, up, pre indexed. */ 2717 SHPREUP (); 2718 break; 2719 } 2720 if (BITS (4, 7) == 0xD) 2721 { 2722 Handle_Load_Double (state, instr); 2723 break; 2724 } 2725 if (BITS (4, 7) == 0xF) 2726 { 2727 Handle_Store_Double (state, instr); 2728 break; 2729 } 2730 #endif 2731 rhs = DPRegRHS; 2732 dest = LHS | rhs; 2733 WRITEDEST (dest); 2734 break; 2735 2736 case 0x19: /* ORRS reg */ 2737 #ifdef MODET 2738 if ((BITS (4, 11) & 0xF9) == 0x9) 2739 /* LDR register offset, no write-back, up, pre indexed. */ 2740 LHPREUP (); 2741 /* Continue with remaining instruction decoding. */ 2742 #endif 2743 rhs = DPSRegRHS; 2744 dest = LHS | rhs; 2745 WRITESDEST (dest); 2746 break; 2747 2748 case 0x1a: /* MOV reg */ 2749 #ifdef MODET 2750 if (BITS (4, 11) == 0xB) 2751 { 2752 /* STRH register offset, write-back, up, pre indexed. */ 2753 SHPREUPWB (); 2754 break; 2755 } 2756 if (BITS (4, 7) == 0xD) 2757 { 2758 Handle_Load_Double (state, instr); 2759 break; 2760 } 2761 if (BITS (4, 7) == 0xF) 2762 { 2763 Handle_Store_Double (state, instr); 2764 break; 2765 } 2766 #endif 2767 dest = DPRegRHS; 2768 WRITEDEST (dest); 2769 break; 2770 2771 case 0x1b: /* MOVS reg */ 2772 #ifdef MODET 2773 if ((BITS (4, 11) & 0xF9) == 0x9) 2774 /* LDR register offset, write-back, up, pre indexed. */ 2775 LHPREUPWB (); 2776 /* Continue with remaining instruction decoding. */ 2777 #endif 2778 dest = DPSRegRHS; 2779 WRITESDEST (dest); 2780 break; 2781 2782 case 0x1c: /* BIC reg */ 2783 #ifdef MODET 2784 if (BITS (4, 7) == 0xB) 2785 { 2786 /* STRH immediate offset, no write-back, up, pre indexed. */ 2787 SHPREUP (); 2788 break; 2789 } 2790 if (BITS (4, 7) == 0xD) 2791 { 2792 Handle_Load_Double (state, instr); 2793 break; 2794 } 2795 else if (BITS (4, 7) == 0xF) 2796 { 2797 Handle_Store_Double (state, instr); 2798 break; 2799 } 2800 #endif 2801 rhs = DPRegRHS; 2802 dest = LHS & ~rhs; 2803 WRITEDEST (dest); 2804 break; 2805 2806 case 0x1d: /* BICS reg */ 2807 #ifdef MODET 2808 if ((BITS (4, 7) & 0x9) == 0x9) 2809 /* LDR immediate offset, no write-back, up, pre indexed. */ 2810 LHPREUP (); 2811 /* Continue with instruction decoding. */ 2812 #endif 2813 rhs = DPSRegRHS; 2814 dest = LHS & ~rhs; 2815 WRITESDEST (dest); 2816 break; 2817 2818 case 0x1e: /* MVN reg */ 2819 #ifdef MODET 2820 if (BITS (4, 7) == 0xB) 2821 { 2822 /* STRH immediate offset, write-back, up, pre indexed. */ 2823 SHPREUPWB (); 2824 break; 2825 } 2826 if (BITS (4, 7) == 0xD) 2827 { 2828 Handle_Load_Double (state, instr); 2829 break; 2830 } 2831 if (BITS (4, 7) == 0xF) 2832 { 2833 Handle_Store_Double (state, instr); 2834 break; 2835 } 2836 #endif 2837 dest = ~DPRegRHS; 2838 WRITEDEST (dest); 2839 break; 2840 2841 case 0x1f: /* MVNS reg */ 2842 #ifdef MODET 2843 if ((BITS (4, 7) & 0x9) == 0x9) 2844 /* LDR immediate offset, write-back, up, pre indexed. */ 2845 LHPREUPWB (); 2846 /* Continue instruction decoding. */ 2847 #endif 2848 dest = ~DPSRegRHS; 2849 WRITESDEST (dest); 2850 break; 2851 2852 2853 /* Data Processing Immediate RHS Instructions. */ 2854 2855 case 0x20: /* AND immed */ 2856 dest = LHS & DPImmRHS; 2857 WRITEDEST (dest); 2858 break; 2859 2860 case 0x21: /* ANDS immed */ 2861 DPSImmRHS; 2862 dest = LHS & rhs; 2863 WRITESDEST (dest); 2864 break; 2865 2866 case 0x22: /* EOR immed */ 2867 dest = LHS ^ DPImmRHS; 2868 WRITEDEST (dest); 2869 break; 2870 2871 case 0x23: /* EORS immed */ 2872 DPSImmRHS; 2873 dest = LHS ^ rhs; 2874 WRITESDEST (dest); 2875 break; 2876 2877 case 0x24: /* SUB immed */ 2878 dest = LHS - DPImmRHS; 2879 WRITEDEST (dest); 2880 break; 2881 2882 case 0x25: /* SUBS immed */ 2883 lhs = LHS; 2884 rhs = DPImmRHS; 2885 dest = lhs - rhs; 2886 2887 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) 2888 { 2889 ARMul_SubCarry (state, lhs, rhs, dest); 2890 ARMul_SubOverflow (state, lhs, rhs, dest); 2891 } 2892 else 2893 { 2894 CLEARC; 2895 CLEARV; 2896 } 2897 WRITESDEST (dest); 2898 break; 2899 2900 case 0x26: /* RSB immed */ 2901 dest = DPImmRHS - LHS; 2902 WRITEDEST (dest); 2903 break; 2904 2905 case 0x27: /* RSBS immed */ 2906 lhs = LHS; 2907 rhs = DPImmRHS; 2908 dest = rhs - lhs; 2909 2910 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) 2911 { 2912 ARMul_SubCarry (state, rhs, lhs, dest); 2913 ARMul_SubOverflow (state, rhs, lhs, dest); 2914 } 2915 else 2916 { 2917 CLEARC; 2918 CLEARV; 2919 } 2920 WRITESDEST (dest); 2921 break; 2922 2923 case 0x28: /* ADD immed */ 2924 dest = LHS + DPImmRHS; 2925 WRITEDEST (dest); 2926 break; 2927 2928 case 0x29: /* ADDS immed */ 2929 lhs = LHS; 2930 rhs = DPImmRHS; 2931 dest = lhs + rhs; 2932 ASSIGNZ (dest == 0); 2933 2934 if ((lhs | rhs) >> 30) 2935 { 2936 /* Possible C,V,N to set. */ 2937 ASSIGNN (NEG (dest)); 2938 ARMul_AddCarry (state, lhs, rhs, dest); 2939 ARMul_AddOverflow (state, lhs, rhs, dest); 2940 } 2941 else 2942 { 2943 CLEARN; 2944 CLEARC; 2945 CLEARV; 2946 } 2947 WRITESDEST (dest); 2948 break; 2949 2950 case 0x2a: /* ADC immed */ 2951 dest = LHS + DPImmRHS + CFLAG; 2952 WRITEDEST (dest); 2953 break; 2954 2955 case 0x2b: /* ADCS immed */ 2956 lhs = LHS; 2957 rhs = DPImmRHS; 2958 dest = lhs + rhs + CFLAG; 2959 ASSIGNZ (dest == 0); 2960 if ((lhs | rhs) >> 30) 2961 { 2962 /* Possible C,V,N to set. */ 2963 ASSIGNN (NEG (dest)); 2964 ARMul_AddCarry (state, lhs, rhs, dest); 2965 ARMul_AddOverflow (state, lhs, rhs, dest); 2966 } 2967 else 2968 { 2969 CLEARN; 2970 CLEARC; 2971 CLEARV; 2972 } 2973 WRITESDEST (dest); 2974 break; 2975 2976 case 0x2c: /* SBC immed */ 2977 dest = LHS - DPImmRHS - !CFLAG; 2978 WRITEDEST (dest); 2979 break; 2980 2981 case 0x2d: /* SBCS immed */ 2982 lhs = LHS; 2983 rhs = DPImmRHS; 2984 dest = lhs - rhs - !CFLAG; 2985 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) 2986 { 2987 ARMul_SubCarry (state, lhs, rhs, dest); 2988 ARMul_SubOverflow (state, lhs, rhs, dest); 2989 } 2990 else 2991 { 2992 CLEARC; 2993 CLEARV; 2994 } 2995 WRITESDEST (dest); 2996 break; 2997 2998 case 0x2e: /* RSC immed */ 2999 dest = DPImmRHS - LHS - !CFLAG; 3000 WRITEDEST (dest); 3001 break; 3002 3003 case 0x2f: /* RSCS immed */ 3004 lhs = LHS; 3005 rhs = DPImmRHS; 3006 dest = rhs - lhs - !CFLAG; 3007 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) 3008 { 3009 ARMul_SubCarry (state, rhs, lhs, dest); 3010 ARMul_SubOverflow (state, rhs, lhs, dest); 3011 } 3012 else 3013 { 3014 CLEARC; 3015 CLEARV; 3016 } 3017 WRITESDEST (dest); 3018 break; 3019 3020 case 0x30: /* MOVW immed */ 3021 #ifdef MODE32 3022 if (state->is_v6 3023 && handle_v6_insn (state, instr)) 3024 break; 3025 #endif 3026 dest = BITS (0, 11); 3027 dest |= (BITS (16, 19) << 12); 3028 WRITEDEST (dest); 3029 break; 3030 3031 case 0x31: /* TSTP immed */ 3032 if (DESTReg == 15) 3033 { 3034 /* TSTP immed. */ 3035 #ifdef MODE32 3036 state->Cpsr = GETSPSR (state->Bank); 3037 ARMul_CPSRAltered (state); 3038 #else 3039 temp = LHS & DPImmRHS; 3040 SETR15PSR (temp); 3041 #endif 3042 } 3043 else 3044 { 3045 /* TST immed. */ 3046 DPSImmRHS; 3047 dest = LHS & rhs; 3048 ARMul_NegZero (state, dest); 3049 } 3050 break; 3051 3052 case 0x32: /* TEQ immed and MSR immed to CPSR */ 3053 if (DESTReg == 15) 3054 /* MSR immed to CPSR. */ 3055 ARMul_FixCPSR (state, instr, DPImmRHS); 3056 #ifdef MODE32 3057 else if (state->is_v6 3058 && handle_v6_insn (state, instr)) 3059 break; 3060 #endif 3061 else 3062 UNDEF_Test; 3063 break; 3064 3065 case 0x33: /* TEQP immed */ 3066 if (DESTReg == 15) 3067 { 3068 /* TEQP immed. */ 3069 #ifdef MODE32 3070 state->Cpsr = GETSPSR (state->Bank); 3071 ARMul_CPSRAltered (state); 3072 #else 3073 temp = LHS ^ DPImmRHS; 3074 SETR15PSR (temp); 3075 #endif 3076 } 3077 else 3078 { 3079 DPSImmRHS; /* TEQ immed */ 3080 dest = LHS ^ rhs; 3081 ARMul_NegZero (state, dest); 3082 } 3083 break; 3084 3085 case 0x34: /* MOVT immed */ 3086 #ifdef MODE32 3087 if (state->is_v6 3088 && handle_v6_insn (state, instr)) 3089 break; 3090 #endif 3091 DEST &= 0xFFFF; 3092 dest = BITS (0, 11); 3093 dest |= (BITS (16, 19) << 12); 3094 DEST |= (dest << 16); 3095 break; 3096 3097 case 0x35: /* CMPP immed */ 3098 if (DESTReg == 15) 3099 { 3100 /* CMPP immed. */ 3101 #ifdef MODE32 3102 state->Cpsr = GETSPSR (state->Bank); 3103 ARMul_CPSRAltered (state); 3104 #else 3105 temp = LHS - DPImmRHS; 3106 SETR15PSR (temp); 3107 #endif 3108 break; 3109 } 3110 else 3111 { 3112 /* CMP immed. */ 3113 lhs = LHS; 3114 rhs = DPImmRHS; 3115 dest = lhs - rhs; 3116 ARMul_NegZero (state, dest); 3117 3118 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) 3119 { 3120 ARMul_SubCarry (state, lhs, rhs, dest); 3121 ARMul_SubOverflow (state, lhs, rhs, dest); 3122 } 3123 else 3124 { 3125 CLEARC; 3126 CLEARV; 3127 } 3128 } 3129 break; 3130 3131 case 0x36: /* CMN immed and MSR immed to SPSR */ 3132 if (DESTReg == 15) 3133 ARMul_FixSPSR (state, instr, DPImmRHS); 3134 #ifdef MODE32 3135 else if (state->is_v6 3136 && handle_v6_insn (state, instr)) 3137 break; 3138 #endif 3139 else 3140 UNDEF_Test; 3141 break; 3142 3143 case 0x37: /* CMNP immed. */ 3144 if (DESTReg == 15) 3145 { 3146 /* CMNP immed. */ 3147 #ifdef MODE32 3148 state->Cpsr = GETSPSR (state->Bank); 3149 ARMul_CPSRAltered (state); 3150 #else 3151 temp = LHS + DPImmRHS; 3152 SETR15PSR (temp); 3153 #endif 3154 break; 3155 } 3156 else 3157 { 3158 /* CMN immed. */ 3159 lhs = LHS; 3160 rhs = DPImmRHS; 3161 dest = lhs + rhs; 3162 ASSIGNZ (dest == 0); 3163 if ((lhs | rhs) >> 30) 3164 { 3165 /* Possible C,V,N to set. */ 3166 ASSIGNN (NEG (dest)); 3167 ARMul_AddCarry (state, lhs, rhs, dest); 3168 ARMul_AddOverflow (state, lhs, rhs, dest); 3169 } 3170 else 3171 { 3172 CLEARN; 3173 CLEARC; 3174 CLEARV; 3175 } 3176 } 3177 break; 3178 3179 case 0x38: /* ORR immed. */ 3180 dest = LHS | DPImmRHS; 3181 WRITEDEST (dest); 3182 break; 3183 3184 case 0x39: /* ORRS immed. */ 3185 DPSImmRHS; 3186 dest = LHS | rhs; 3187 WRITESDEST (dest); 3188 break; 3189 3190 case 0x3a: /* MOV immed. */ 3191 dest = DPImmRHS; 3192 WRITEDEST (dest); 3193 break; 3194 3195 case 0x3b: /* MOVS immed. */ 3196 DPSImmRHS; 3197 WRITESDEST (rhs); 3198 break; 3199 3200 case 0x3c: /* BIC immed. */ 3201 dest = LHS & ~DPImmRHS; 3202 WRITEDEST (dest); 3203 break; 3204 3205 case 0x3d: /* BICS immed. */ 3206 DPSImmRHS; 3207 dest = LHS & ~rhs; 3208 WRITESDEST (dest); 3209 break; 3210 3211 case 0x3e: /* MVN immed. */ 3212 dest = ~DPImmRHS; 3213 WRITEDEST (dest); 3214 break; 3215 3216 case 0x3f: /* MVNS immed. */ 3217 DPSImmRHS; 3218 WRITESDEST (~rhs); 3219 break; 3220 3221 3222 /* Single Data Transfer Immediate RHS Instructions. */ 3223 3224 case 0x40: /* Store Word, No WriteBack, Post Dec, Immed. */ 3225 lhs = LHS; 3226 if (StoreWord (state, instr, lhs)) 3227 LSBase = lhs - LSImmRHS; 3228 break; 3229 3230 case 0x41: /* Load Word, No WriteBack, Post Dec, Immed. */ 3231 lhs = LHS; 3232 if (LoadWord (state, instr, lhs)) 3233 LSBase = lhs - LSImmRHS; 3234 break; 3235 3236 case 0x42: /* Store Word, WriteBack, Post Dec, Immed. */ 3237 UNDEF_LSRBaseEQDestWb; 3238 UNDEF_LSRPCBaseWb; 3239 lhs = LHS; 3240 temp = lhs - LSImmRHS; 3241 state->NtransSig = LOW; 3242 if (StoreWord (state, instr, lhs)) 3243 LSBase = temp; 3244 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3245 break; 3246 3247 case 0x43: /* Load Word, WriteBack, Post Dec, Immed. */ 3248 UNDEF_LSRBaseEQDestWb; 3249 UNDEF_LSRPCBaseWb; 3250 lhs = LHS; 3251 state->NtransSig = LOW; 3252 if (LoadWord (state, instr, lhs)) 3253 LSBase = lhs - LSImmRHS; 3254 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3255 break; 3256 3257 case 0x44: /* Store Byte, No WriteBack, Post Dec, Immed. */ 3258 lhs = LHS; 3259 if (StoreByte (state, instr, lhs)) 3260 LSBase = lhs - LSImmRHS; 3261 break; 3262 3263 case 0x45: /* Load Byte, No WriteBack, Post Dec, Immed. */ 3264 lhs = LHS; 3265 if (LoadByte (state, instr, lhs, LUNSIGNED)) 3266 LSBase = lhs - LSImmRHS; 3267 break; 3268 3269 case 0x46: /* Store Byte, WriteBack, Post Dec, Immed. */ 3270 UNDEF_LSRBaseEQDestWb; 3271 UNDEF_LSRPCBaseWb; 3272 lhs = LHS; 3273 state->NtransSig = LOW; 3274 if (StoreByte (state, instr, lhs)) 3275 LSBase = lhs - LSImmRHS; 3276 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3277 break; 3278 3279 case 0x47: /* Load Byte, WriteBack, Post Dec, Immed. */ 3280 UNDEF_LSRBaseEQDestWb; 3281 UNDEF_LSRPCBaseWb; 3282 lhs = LHS; 3283 state->NtransSig = LOW; 3284 if (LoadByte (state, instr, lhs, LUNSIGNED)) 3285 LSBase = lhs - LSImmRHS; 3286 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3287 break; 3288 3289 case 0x48: /* Store Word, No WriteBack, Post Inc, Immed. */ 3290 lhs = LHS; 3291 if (StoreWord (state, instr, lhs)) 3292 LSBase = lhs + LSImmRHS; 3293 break; 3294 3295 case 0x49: /* Load Word, No WriteBack, Post Inc, Immed. */ 3296 lhs = LHS; 3297 if (LoadWord (state, instr, lhs)) 3298 LSBase = lhs + LSImmRHS; 3299 break; 3300 3301 case 0x4a: /* Store Word, WriteBack, Post Inc, Immed. */ 3302 UNDEF_LSRBaseEQDestWb; 3303 UNDEF_LSRPCBaseWb; 3304 lhs = LHS; 3305 state->NtransSig = LOW; 3306 if (StoreWord (state, instr, lhs)) 3307 LSBase = lhs + LSImmRHS; 3308 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3309 break; 3310 3311 case 0x4b: /* Load Word, WriteBack, Post Inc, Immed. */ 3312 UNDEF_LSRBaseEQDestWb; 3313 UNDEF_LSRPCBaseWb; 3314 lhs = LHS; 3315 state->NtransSig = LOW; 3316 if (LoadWord (state, instr, lhs)) 3317 LSBase = lhs + LSImmRHS; 3318 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3319 break; 3320 3321 case 0x4c: /* Store Byte, No WriteBack, Post Inc, Immed. */ 3322 lhs = LHS; 3323 if (StoreByte (state, instr, lhs)) 3324 LSBase = lhs + LSImmRHS; 3325 break; 3326 3327 case 0x4d: /* Load Byte, No WriteBack, Post Inc, Immed. */ 3328 lhs = LHS; 3329 if (LoadByte (state, instr, lhs, LUNSIGNED)) 3330 LSBase = lhs + LSImmRHS; 3331 break; 3332 3333 case 0x4e: /* Store Byte, WriteBack, Post Inc, Immed. */ 3334 UNDEF_LSRBaseEQDestWb; 3335 UNDEF_LSRPCBaseWb; 3336 lhs = LHS; 3337 state->NtransSig = LOW; 3338 if (StoreByte (state, instr, lhs)) 3339 LSBase = lhs + LSImmRHS; 3340 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3341 break; 3342 3343 case 0x4f: /* Load Byte, WriteBack, Post Inc, Immed. */ 3344 UNDEF_LSRBaseEQDestWb; 3345 UNDEF_LSRPCBaseWb; 3346 lhs = LHS; 3347 state->NtransSig = LOW; 3348 if (LoadByte (state, instr, lhs, LUNSIGNED)) 3349 LSBase = lhs + LSImmRHS; 3350 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3351 break; 3352 3353 3354 case 0x50: /* Store Word, No WriteBack, Pre Dec, Immed. */ 3355 (void) StoreWord (state, instr, LHS - LSImmRHS); 3356 break; 3357 3358 case 0x51: /* Load Word, No WriteBack, Pre Dec, Immed. */ 3359 (void) LoadWord (state, instr, LHS - LSImmRHS); 3360 break; 3361 3362 case 0x52: /* Store Word, WriteBack, Pre Dec, Immed. */ 3363 UNDEF_LSRBaseEQDestWb; 3364 UNDEF_LSRPCBaseWb; 3365 temp = LHS - LSImmRHS; 3366 if (StoreWord (state, instr, temp)) 3367 LSBase = temp; 3368 break; 3369 3370 case 0x53: /* Load Word, WriteBack, Pre Dec, Immed. */ 3371 UNDEF_LSRBaseEQDestWb; 3372 UNDEF_LSRPCBaseWb; 3373 temp = LHS - LSImmRHS; 3374 if (LoadWord (state, instr, temp)) 3375 LSBase = temp; 3376 break; 3377 3378 case 0x54: /* Store Byte, No WriteBack, Pre Dec, Immed. */ 3379 (void) StoreByte (state, instr, LHS - LSImmRHS); 3380 break; 3381 3382 case 0x55: /* Load Byte, No WriteBack, Pre Dec, Immed. */ 3383 (void) LoadByte (state, instr, LHS - LSImmRHS, LUNSIGNED); 3384 break; 3385 3386 case 0x56: /* Store Byte, WriteBack, Pre Dec, Immed. */ 3387 UNDEF_LSRBaseEQDestWb; 3388 UNDEF_LSRPCBaseWb; 3389 temp = LHS - LSImmRHS; 3390 if (StoreByte (state, instr, temp)) 3391 LSBase = temp; 3392 break; 3393 3394 case 0x57: /* Load Byte, WriteBack, Pre Dec, Immed. */ 3395 UNDEF_LSRBaseEQDestWb; 3396 UNDEF_LSRPCBaseWb; 3397 temp = LHS - LSImmRHS; 3398 if (LoadByte (state, instr, temp, LUNSIGNED)) 3399 LSBase = temp; 3400 break; 3401 3402 case 0x58: /* Store Word, No WriteBack, Pre Inc, Immed. */ 3403 (void) StoreWord (state, instr, LHS + LSImmRHS); 3404 break; 3405 3406 case 0x59: /* Load Word, No WriteBack, Pre Inc, Immed. */ 3407 (void) LoadWord (state, instr, LHS + LSImmRHS); 3408 break; 3409 3410 case 0x5a: /* Store Word, WriteBack, Pre Inc, Immed. */ 3411 UNDEF_LSRBaseEQDestWb; 3412 UNDEF_LSRPCBaseWb; 3413 temp = LHS + LSImmRHS; 3414 if (StoreWord (state, instr, temp)) 3415 LSBase = temp; 3416 break; 3417 3418 case 0x5b: /* Load Word, WriteBack, Pre Inc, Immed. */ 3419 UNDEF_LSRBaseEQDestWb; 3420 UNDEF_LSRPCBaseWb; 3421 temp = LHS + LSImmRHS; 3422 if (LoadWord (state, instr, temp)) 3423 LSBase = temp; 3424 break; 3425 3426 case 0x5c: /* Store Byte, No WriteBack, Pre Inc, Immed. */ 3427 (void) StoreByte (state, instr, LHS + LSImmRHS); 3428 break; 3429 3430 case 0x5d: /* Load Byte, No WriteBack, Pre Inc, Immed. */ 3431 (void) LoadByte (state, instr, LHS + LSImmRHS, LUNSIGNED); 3432 break; 3433 3434 case 0x5e: /* Store Byte, WriteBack, Pre Inc, Immed. */ 3435 UNDEF_LSRBaseEQDestWb; 3436 UNDEF_LSRPCBaseWb; 3437 temp = LHS + LSImmRHS; 3438 if (StoreByte (state, instr, temp)) 3439 LSBase = temp; 3440 break; 3441 3442 case 0x5f: /* Load Byte, WriteBack, Pre Inc, Immed. */ 3443 UNDEF_LSRBaseEQDestWb; 3444 UNDEF_LSRPCBaseWb; 3445 temp = LHS + LSImmRHS; 3446 if (LoadByte (state, instr, temp, LUNSIGNED)) 3447 LSBase = temp; 3448 break; 3449 3450 3451 /* Single Data Transfer Register RHS Instructions. */ 3452 3453 case 0x60: /* Store Word, No WriteBack, Post Dec, Reg. */ 3454 if (BIT (4)) 3455 { 3456 #ifdef MODE32 3457 if (state->is_v6 3458 && handle_v6_insn (state, instr)) 3459 break; 3460 #endif 3461 ARMul_UndefInstr (state, instr); 3462 break; 3463 } 3464 UNDEF_LSRBaseEQOffWb; 3465 UNDEF_LSRBaseEQDestWb; 3466 UNDEF_LSRPCBaseWb; 3467 UNDEF_LSRPCOffWb; 3468 lhs = LHS; 3469 if (StoreWord (state, instr, lhs)) 3470 LSBase = lhs - LSRegRHS; 3471 break; 3472 3473 case 0x61: /* Load Word, No WriteBack, Post Dec, Reg. */ 3474 if (BIT (4)) 3475 { 3476 #ifdef MODE32 3477 if (state->is_v6 3478 && handle_v6_insn (state, instr)) 3479 break; 3480 #endif 3481 ARMul_UndefInstr (state, instr); 3482 break; 3483 } 3484 UNDEF_LSRBaseEQOffWb; 3485 UNDEF_LSRBaseEQDestWb; 3486 UNDEF_LSRPCBaseWb; 3487 UNDEF_LSRPCOffWb; 3488 lhs = LHS; 3489 temp = lhs - LSRegRHS; 3490 if (LoadWord (state, instr, lhs)) 3491 LSBase = temp; 3492 break; 3493 3494 case 0x62: /* Store Word, WriteBack, Post Dec, Reg. */ 3495 if (BIT (4)) 3496 { 3497 #ifdef MODE32 3498 if (state->is_v6 3499 && handle_v6_insn (state, instr)) 3500 break; 3501 #endif 3502 ARMul_UndefInstr (state, instr); 3503 break; 3504 } 3505 UNDEF_LSRBaseEQOffWb; 3506 UNDEF_LSRBaseEQDestWb; 3507 UNDEF_LSRPCBaseWb; 3508 UNDEF_LSRPCOffWb; 3509 lhs = LHS; 3510 state->NtransSig = LOW; 3511 if (StoreWord (state, instr, lhs)) 3512 LSBase = lhs - LSRegRHS; 3513 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3514 break; 3515 3516 case 0x63: /* Load Word, WriteBack, Post Dec, Reg. */ 3517 if (BIT (4)) 3518 { 3519 #ifdef MODE32 3520 if (state->is_v6 3521 && handle_v6_insn (state, instr)) 3522 break; 3523 #endif 3524 ARMul_UndefInstr (state, instr); 3525 break; 3526 } 3527 UNDEF_LSRBaseEQOffWb; 3528 UNDEF_LSRBaseEQDestWb; 3529 UNDEF_LSRPCBaseWb; 3530 UNDEF_LSRPCOffWb; 3531 lhs = LHS; 3532 temp = lhs - LSRegRHS; 3533 state->NtransSig = LOW; 3534 if (LoadWord (state, instr, lhs)) 3535 LSBase = temp; 3536 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3537 break; 3538 3539 case 0x64: /* Store Byte, No WriteBack, Post Dec, Reg. */ 3540 if (BIT (4)) 3541 { 3542 #ifdef MODE32 3543 if (state->is_v6 3544 && handle_v6_insn (state, instr)) 3545 break; 3546 #endif 3547 ARMul_UndefInstr (state, instr); 3548 break; 3549 } 3550 UNDEF_LSRBaseEQOffWb; 3551 UNDEF_LSRBaseEQDestWb; 3552 UNDEF_LSRPCBaseWb; 3553 UNDEF_LSRPCOffWb; 3554 lhs = LHS; 3555 if (StoreByte (state, instr, lhs)) 3556 LSBase = lhs - LSRegRHS; 3557 break; 3558 3559 case 0x65: /* Load Byte, No WriteBack, Post Dec, Reg. */ 3560 if (BIT (4)) 3561 { 3562 #ifdef MODE32 3563 if (state->is_v6 3564 && handle_v6_insn (state, instr)) 3565 break; 3566 #endif 3567 ARMul_UndefInstr (state, instr); 3568 break; 3569 } 3570 UNDEF_LSRBaseEQOffWb; 3571 UNDEF_LSRBaseEQDestWb; 3572 UNDEF_LSRPCBaseWb; 3573 UNDEF_LSRPCOffWb; 3574 lhs = LHS; 3575 temp = lhs - LSRegRHS; 3576 if (LoadByte (state, instr, lhs, LUNSIGNED)) 3577 LSBase = temp; 3578 break; 3579 3580 case 0x66: /* Store Byte, WriteBack, Post Dec, Reg. */ 3581 if (BIT (4)) 3582 { 3583 #ifdef MODE32 3584 if (state->is_v6 3585 && handle_v6_insn (state, instr)) 3586 break; 3587 #endif 3588 ARMul_UndefInstr (state, instr); 3589 break; 3590 } 3591 UNDEF_LSRBaseEQOffWb; 3592 UNDEF_LSRBaseEQDestWb; 3593 UNDEF_LSRPCBaseWb; 3594 UNDEF_LSRPCOffWb; 3595 lhs = LHS; 3596 state->NtransSig = LOW; 3597 if (StoreByte (state, instr, lhs)) 3598 LSBase = lhs - LSRegRHS; 3599 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3600 break; 3601 3602 case 0x67: /* Load Byte, WriteBack, Post Dec, Reg. */ 3603 if (BIT (4)) 3604 { 3605 #ifdef MODE32 3606 if (state->is_v6 3607 && handle_v6_insn (state, instr)) 3608 break; 3609 #endif 3610 ARMul_UndefInstr (state, instr); 3611 break; 3612 } 3613 UNDEF_LSRBaseEQOffWb; 3614 UNDEF_LSRBaseEQDestWb; 3615 UNDEF_LSRPCBaseWb; 3616 UNDEF_LSRPCOffWb; 3617 lhs = LHS; 3618 temp = lhs - LSRegRHS; 3619 state->NtransSig = LOW; 3620 if (LoadByte (state, instr, lhs, LUNSIGNED)) 3621 LSBase = temp; 3622 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3623 break; 3624 3625 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ 3626 if (BIT (4)) 3627 { 3628 #ifdef MODE32 3629 if (state->is_v6 3630 && handle_v6_insn (state, instr)) 3631 break; 3632 #endif 3633 ARMul_UndefInstr (state, instr); 3634 break; 3635 } 3636 UNDEF_LSRBaseEQOffWb; 3637 UNDEF_LSRBaseEQDestWb; 3638 UNDEF_LSRPCBaseWb; 3639 UNDEF_LSRPCOffWb; 3640 lhs = LHS; 3641 if (StoreWord (state, instr, lhs)) 3642 LSBase = lhs + LSRegRHS; 3643 break; 3644 3645 case 0x69: /* Load Word, No WriteBack, Post Inc, Reg. */ 3646 if (BIT (4)) 3647 { 3648 #ifdef MODE32 3649 if (state->is_v6 3650 && handle_v6_insn (state, instr)) 3651 break; 3652 #endif 3653 ARMul_UndefInstr (state, instr); 3654 break; 3655 } 3656 UNDEF_LSRBaseEQOffWb; 3657 UNDEF_LSRBaseEQDestWb; 3658 UNDEF_LSRPCBaseWb; 3659 UNDEF_LSRPCOffWb; 3660 lhs = LHS; 3661 temp = lhs + LSRegRHS; 3662 if (LoadWord (state, instr, lhs)) 3663 LSBase = temp; 3664 break; 3665 3666 case 0x6a: /* Store Word, WriteBack, Post Inc, Reg. */ 3667 if (BIT (4)) 3668 { 3669 #ifdef MODE32 3670 if (state->is_v6 3671 && handle_v6_insn (state, instr)) 3672 break; 3673 #endif 3674 ARMul_UndefInstr (state, instr); 3675 break; 3676 } 3677 UNDEF_LSRBaseEQOffWb; 3678 UNDEF_LSRBaseEQDestWb; 3679 UNDEF_LSRPCBaseWb; 3680 UNDEF_LSRPCOffWb; 3681 lhs = LHS; 3682 state->NtransSig = LOW; 3683 if (StoreWord (state, instr, lhs)) 3684 LSBase = lhs + LSRegRHS; 3685 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3686 break; 3687 3688 case 0x6b: /* Load Word, WriteBack, Post Inc, Reg. */ 3689 if (BIT (4)) 3690 { 3691 #ifdef MODE32 3692 if (state->is_v6 3693 && handle_v6_insn (state, instr)) 3694 break; 3695 #endif 3696 ARMul_UndefInstr (state, instr); 3697 break; 3698 } 3699 UNDEF_LSRBaseEQOffWb; 3700 UNDEF_LSRBaseEQDestWb; 3701 UNDEF_LSRPCBaseWb; 3702 UNDEF_LSRPCOffWb; 3703 lhs = LHS; 3704 temp = lhs + LSRegRHS; 3705 state->NtransSig = LOW; 3706 if (LoadWord (state, instr, lhs)) 3707 LSBase = temp; 3708 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3709 break; 3710 3711 case 0x6c: /* Store Byte, No WriteBack, Post Inc, Reg. */ 3712 if (BIT (4)) 3713 { 3714 #ifdef MODE32 3715 if (state->is_v6 3716 && handle_v6_insn (state, instr)) 3717 break; 3718 #endif 3719 ARMul_UndefInstr (state, instr); 3720 break; 3721 } 3722 UNDEF_LSRBaseEQOffWb; 3723 UNDEF_LSRBaseEQDestWb; 3724 UNDEF_LSRPCBaseWb; 3725 UNDEF_LSRPCOffWb; 3726 lhs = LHS; 3727 if (StoreByte (state, instr, lhs)) 3728 LSBase = lhs + LSRegRHS; 3729 break; 3730 3731 case 0x6d: /* Load Byte, No WriteBack, Post Inc, Reg. */ 3732 if (BIT (4)) 3733 { 3734 #ifdef MODE32 3735 if (state->is_v6 3736 && handle_v6_insn (state, instr)) 3737 break; 3738 #endif 3739 ARMul_UndefInstr (state, instr); 3740 break; 3741 } 3742 UNDEF_LSRBaseEQOffWb; 3743 UNDEF_LSRBaseEQDestWb; 3744 UNDEF_LSRPCBaseWb; 3745 UNDEF_LSRPCOffWb; 3746 lhs = LHS; 3747 temp = lhs + LSRegRHS; 3748 if (LoadByte (state, instr, lhs, LUNSIGNED)) 3749 LSBase = temp; 3750 break; 3751 3752 case 0x6e: /* Store Byte, WriteBack, Post Inc, Reg. */ 3753 if (BIT (4)) 3754 { 3755 #ifdef MODE32 3756 if (state->is_v6 3757 && handle_v6_insn (state, instr)) 3758 break; 3759 #endif 3760 ARMul_UndefInstr (state, instr); 3761 break; 3762 } 3763 UNDEF_LSRBaseEQOffWb; 3764 UNDEF_LSRBaseEQDestWb; 3765 UNDEF_LSRPCBaseWb; 3766 UNDEF_LSRPCOffWb; 3767 lhs = LHS; 3768 state->NtransSig = LOW; 3769 if (StoreByte (state, instr, lhs)) 3770 LSBase = lhs + LSRegRHS; 3771 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3772 break; 3773 3774 case 0x6f: /* Load Byte, WriteBack, Post Inc, Reg. */ 3775 if (BIT (4)) 3776 { 3777 #ifdef MODE32 3778 if (state->is_v6 3779 && handle_v6_insn (state, instr)) 3780 break; 3781 #endif 3782 ARMul_UndefInstr (state, instr); 3783 break; 3784 } 3785 UNDEF_LSRBaseEQOffWb; 3786 UNDEF_LSRBaseEQDestWb; 3787 UNDEF_LSRPCBaseWb; 3788 UNDEF_LSRPCOffWb; 3789 lhs = LHS; 3790 temp = lhs + LSRegRHS; 3791 state->NtransSig = LOW; 3792 if (LoadByte (state, instr, lhs, LUNSIGNED)) 3793 LSBase = temp; 3794 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 3795 break; 3796 3797 3798 case 0x70: /* Store Word, No WriteBack, Pre Dec, Reg. */ 3799 if (BIT (4)) 3800 { 3801 #ifdef MODE32 3802 if (state->is_v6 3803 && handle_v6_insn (state, instr)) 3804 break; 3805 #endif 3806 ARMul_UndefInstr (state, instr); 3807 break; 3808 } 3809 (void) StoreWord (state, instr, LHS - LSRegRHS); 3810 break; 3811 3812 case 0x71: /* Load Word, No WriteBack, Pre Dec, Reg. */ 3813 if (BIT (4)) 3814 { 3815 #ifdef MODE32 3816 if (state->is_v6 3817 && handle_v6_insn (state, instr)) 3818 break; 3819 #endif 3820 ARMul_UndefInstr (state, instr); 3821 break; 3822 } 3823 (void) LoadWord (state, instr, LHS - LSRegRHS); 3824 break; 3825 3826 case 0x72: /* Store Word, WriteBack, Pre Dec, Reg. */ 3827 if (BIT (4)) 3828 { 3829 #ifdef MODE32 3830 if (state->is_v6 3831 && handle_v6_insn (state, instr)) 3832 break; 3833 #endif 3834 ARMul_UndefInstr (state, instr); 3835 break; 3836 } 3837 UNDEF_LSRBaseEQOffWb; 3838 UNDEF_LSRBaseEQDestWb; 3839 UNDEF_LSRPCBaseWb; 3840 UNDEF_LSRPCOffWb; 3841 temp = LHS - LSRegRHS; 3842 if (StoreWord (state, instr, temp)) 3843 LSBase = temp; 3844 break; 3845 3846 case 0x73: /* Load Word, WriteBack, Pre Dec, Reg. */ 3847 if (BIT (4)) 3848 { 3849 #ifdef MODE32 3850 if (state->is_v6 3851 && handle_v6_insn (state, instr)) 3852 break; 3853 #endif 3854 ARMul_UndefInstr (state, instr); 3855 break; 3856 } 3857 UNDEF_LSRBaseEQOffWb; 3858 UNDEF_LSRBaseEQDestWb; 3859 UNDEF_LSRPCBaseWb; 3860 UNDEF_LSRPCOffWb; 3861 temp = LHS - LSRegRHS; 3862 if (LoadWord (state, instr, temp)) 3863 LSBase = temp; 3864 break; 3865 3866 case 0x74: /* Store Byte, No WriteBack, Pre Dec, Reg. */ 3867 if (BIT (4)) 3868 { 3869 #ifdef MODE32 3870 if (state->is_v6 3871 && handle_v6_insn (state, instr)) 3872 break; 3873 #endif 3874 ARMul_UndefInstr (state, instr); 3875 break; 3876 } 3877 (void) StoreByte (state, instr, LHS - LSRegRHS); 3878 break; 3879 3880 case 0x75: /* Load Byte, No WriteBack, Pre Dec, Reg. */ 3881 if (BIT (4)) 3882 { 3883 #ifdef MODE32 3884 if (state->is_v6 3885 && handle_v6_insn (state, instr)) 3886 break; 3887 #endif 3888 ARMul_UndefInstr (state, instr); 3889 break; 3890 } 3891 (void) LoadByte (state, instr, LHS - LSRegRHS, LUNSIGNED); 3892 break; 3893 3894 case 0x76: /* Store Byte, WriteBack, Pre Dec, Reg. */ 3895 if (BIT (4)) 3896 { 3897 #ifdef MODE32 3898 if (state->is_v6 3899 && handle_v6_insn (state, instr)) 3900 break; 3901 #endif 3902 ARMul_UndefInstr (state, instr); 3903 break; 3904 } 3905 UNDEF_LSRBaseEQOffWb; 3906 UNDEF_LSRBaseEQDestWb; 3907 UNDEF_LSRPCBaseWb; 3908 UNDEF_LSRPCOffWb; 3909 temp = LHS - LSRegRHS; 3910 if (StoreByte (state, instr, temp)) 3911 LSBase = temp; 3912 break; 3913 3914 case 0x77: /* Load Byte, WriteBack, Pre Dec, Reg. */ 3915 if (BIT (4)) 3916 { 3917 #ifdef MODE32 3918 if (state->is_v6 3919 && handle_v6_insn (state, instr)) 3920 break; 3921 #endif 3922 ARMul_UndefInstr (state, instr); 3923 break; 3924 } 3925 UNDEF_LSRBaseEQOffWb; 3926 UNDEF_LSRBaseEQDestWb; 3927 UNDEF_LSRPCBaseWb; 3928 UNDEF_LSRPCOffWb; 3929 temp = LHS - LSRegRHS; 3930 if (LoadByte (state, instr, temp, LUNSIGNED)) 3931 LSBase = temp; 3932 break; 3933 3934 case 0x78: /* Store Word, No WriteBack, Pre Inc, Reg. */ 3935 if (BIT (4)) 3936 { 3937 #ifdef MODE32 3938 if (state->is_v6 3939 && handle_v6_insn (state, instr)) 3940 break; 3941 #endif 3942 ARMul_UndefInstr (state, instr); 3943 break; 3944 } 3945 (void) StoreWord (state, instr, LHS + LSRegRHS); 3946 break; 3947 3948 case 0x79: /* Load Word, No WriteBack, Pre Inc, Reg. */ 3949 if (BIT (4)) 3950 { 3951 #ifdef MODE32 3952 if (state->is_v6 3953 && handle_v6_insn (state, instr)) 3954 break; 3955 #endif 3956 ARMul_UndefInstr (state, instr); 3957 break; 3958 } 3959 (void) LoadWord (state, instr, LHS + LSRegRHS); 3960 break; 3961 3962 case 0x7a: /* Store Word, WriteBack, Pre Inc, Reg. */ 3963 if (BIT (4)) 3964 { 3965 #ifdef MODE32 3966 if (state->is_v6 3967 && handle_v6_insn (state, instr)) 3968 break; 3969 #endif 3970 ARMul_UndefInstr (state, instr); 3971 break; 3972 } 3973 UNDEF_LSRBaseEQOffWb; 3974 UNDEF_LSRBaseEQDestWb; 3975 UNDEF_LSRPCBaseWb; 3976 UNDEF_LSRPCOffWb; 3977 temp = LHS + LSRegRHS; 3978 if (StoreWord (state, instr, temp)) 3979 LSBase = temp; 3980 break; 3981 3982 case 0x7b: /* Load Word, WriteBack, Pre Inc, Reg. */ 3983 if (BIT (4)) 3984 { 3985 #ifdef MODE32 3986 if (state->is_v6 3987 && handle_v6_insn (state, instr)) 3988 break; 3989 #endif 3990 ARMul_UndefInstr (state, instr); 3991 break; 3992 } 3993 UNDEF_LSRBaseEQOffWb; 3994 UNDEF_LSRBaseEQDestWb; 3995 UNDEF_LSRPCBaseWb; 3996 UNDEF_LSRPCOffWb; 3997 temp = LHS + LSRegRHS; 3998 if (LoadWord (state, instr, temp)) 3999 LSBase = temp; 4000 break; 4001 4002 case 0x7c: /* Store Byte, No WriteBack, Pre Inc, Reg. */ 4003 if (BIT (4)) 4004 { 4005 #ifdef MODE32 4006 if (state->is_v6 4007 && handle_v6_insn (state, instr)) 4008 break; 4009 #endif 4010 ARMul_UndefInstr (state, instr); 4011 break; 4012 } 4013 (void) StoreByte (state, instr, LHS + LSRegRHS); 4014 break; 4015 4016 case 0x7d: /* Load Byte, No WriteBack, Pre Inc, Reg. */ 4017 if (BIT (4)) 4018 { 4019 #ifdef MODE32 4020 if (state->is_v6 4021 && handle_v6_insn (state, instr)) 4022 break; 4023 #endif 4024 ARMul_UndefInstr (state, instr); 4025 break; 4026 } 4027 (void) LoadByte (state, instr, LHS + LSRegRHS, LUNSIGNED); 4028 break; 4029 4030 case 0x7e: /* Store Byte, WriteBack, Pre Inc, Reg. */ 4031 if (BIT (4)) 4032 { 4033 #ifdef MODE32 4034 if (state->is_v6 4035 && handle_v6_insn (state, instr)) 4036 break; 4037 #endif 4038 ARMul_UndefInstr (state, instr); 4039 break; 4040 } 4041 UNDEF_LSRBaseEQOffWb; 4042 UNDEF_LSRBaseEQDestWb; 4043 UNDEF_LSRPCBaseWb; 4044 UNDEF_LSRPCOffWb; 4045 temp = LHS + LSRegRHS; 4046 if (StoreByte (state, instr, temp)) 4047 LSBase = temp; 4048 break; 4049 4050 case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */ 4051 if (BIT (4)) 4052 { 4053 /* Check for the special breakpoint opcode. 4054 This value should correspond to the value defined 4055 as ARM_BE_BREAKPOINT in gdb/arm/tm-arm.h. */ 4056 if (BITS (0, 19) == 0xfdefe) 4057 { 4058 if (!ARMul_OSHandleSWI (state, SWI_Breakpoint)) 4059 ARMul_Abort (state, ARMul_SWIV); 4060 } 4061 #ifdef MODE32 4062 else if (state->is_v6 4063 && handle_v6_insn (state, instr)) 4064 break; 4065 #endif 4066 else 4067 ARMul_UndefInstr (state, instr); 4068 break; 4069 } 4070 UNDEF_LSRBaseEQOffWb; 4071 UNDEF_LSRBaseEQDestWb; 4072 UNDEF_LSRPCBaseWb; 4073 UNDEF_LSRPCOffWb; 4074 temp = LHS + LSRegRHS; 4075 if (LoadByte (state, instr, temp, LUNSIGNED)) 4076 LSBase = temp; 4077 break; 4078 4079 4080 /* Multiple Data Transfer Instructions. */ 4081 4082 case 0x80: /* Store, No WriteBack, Post Dec. */ 4083 STOREMULT (instr, LSBase - LSMNumRegs + 4L, 0L); 4084 break; 4085 4086 case 0x81: /* Load, No WriteBack, Post Dec. */ 4087 LOADMULT (instr, LSBase - LSMNumRegs + 4L, 0L); 4088 break; 4089 4090 case 0x82: /* Store, WriteBack, Post Dec. */ 4091 temp = LSBase - LSMNumRegs; 4092 STOREMULT (instr, temp + 4L, temp); 4093 break; 4094 4095 case 0x83: /* Load, WriteBack, Post Dec. */ 4096 temp = LSBase - LSMNumRegs; 4097 LOADMULT (instr, temp + 4L, temp); 4098 break; 4099 4100 case 0x84: /* Store, Flags, No WriteBack, Post Dec. */ 4101 STORESMULT (instr, LSBase - LSMNumRegs + 4L, 0L); 4102 break; 4103 4104 case 0x85: /* Load, Flags, No WriteBack, Post Dec. */ 4105 LOADSMULT (instr, LSBase - LSMNumRegs + 4L, 0L); 4106 break; 4107 4108 case 0x86: /* Store, Flags, WriteBack, Post Dec. */ 4109 temp = LSBase - LSMNumRegs; 4110 STORESMULT (instr, temp + 4L, temp); 4111 break; 4112 4113 case 0x87: /* Load, Flags, WriteBack, Post Dec. */ 4114 temp = LSBase - LSMNumRegs; 4115 LOADSMULT (instr, temp + 4L, temp); 4116 break; 4117 4118 case 0x88: /* Store, No WriteBack, Post Inc. */ 4119 STOREMULT (instr, LSBase, 0L); 4120 break; 4121 4122 case 0x89: /* Load, No WriteBack, Post Inc. */ 4123 LOADMULT (instr, LSBase, 0L); 4124 break; 4125 4126 case 0x8a: /* Store, WriteBack, Post Inc. */ 4127 temp = LSBase; 4128 STOREMULT (instr, temp, temp + LSMNumRegs); 4129 break; 4130 4131 case 0x8b: /* Load, WriteBack, Post Inc. */ 4132 temp = LSBase; 4133 LOADMULT (instr, temp, temp + LSMNumRegs); 4134 break; 4135 4136 case 0x8c: /* Store, Flags, No WriteBack, Post Inc. */ 4137 STORESMULT (instr, LSBase, 0L); 4138 break; 4139 4140 case 0x8d: /* Load, Flags, No WriteBack, Post Inc. */ 4141 LOADSMULT (instr, LSBase, 0L); 4142 break; 4143 4144 case 0x8e: /* Store, Flags, WriteBack, Post Inc. */ 4145 temp = LSBase; 4146 STORESMULT (instr, temp, temp + LSMNumRegs); 4147 break; 4148 4149 case 0x8f: /* Load, Flags, WriteBack, Post Inc. */ 4150 temp = LSBase; 4151 LOADSMULT (instr, temp, temp + LSMNumRegs); 4152 break; 4153 4154 case 0x90: /* Store, No WriteBack, Pre Dec. */ 4155 STOREMULT (instr, LSBase - LSMNumRegs, 0L); 4156 break; 4157 4158 case 0x91: /* Load, No WriteBack, Pre Dec. */ 4159 LOADMULT (instr, LSBase - LSMNumRegs, 0L); 4160 break; 4161 4162 case 0x92: /* Store, WriteBack, Pre Dec. */ 4163 temp = LSBase - LSMNumRegs; 4164 STOREMULT (instr, temp, temp); 4165 break; 4166 4167 case 0x93: /* Load, WriteBack, Pre Dec. */ 4168 temp = LSBase - LSMNumRegs; 4169 LOADMULT (instr, temp, temp); 4170 break; 4171 4172 case 0x94: /* Store, Flags, No WriteBack, Pre Dec. */ 4173 STORESMULT (instr, LSBase - LSMNumRegs, 0L); 4174 break; 4175 4176 case 0x95: /* Load, Flags, No WriteBack, Pre Dec. */ 4177 LOADSMULT (instr, LSBase - LSMNumRegs, 0L); 4178 break; 4179 4180 case 0x96: /* Store, Flags, WriteBack, Pre Dec. */ 4181 temp = LSBase - LSMNumRegs; 4182 STORESMULT (instr, temp, temp); 4183 break; 4184 4185 case 0x97: /* Load, Flags, WriteBack, Pre Dec. */ 4186 temp = LSBase - LSMNumRegs; 4187 LOADSMULT (instr, temp, temp); 4188 break; 4189 4190 case 0x98: /* Store, No WriteBack, Pre Inc. */ 4191 STOREMULT (instr, LSBase + 4L, 0L); 4192 break; 4193 4194 case 0x99: /* Load, No WriteBack, Pre Inc. */ 4195 LOADMULT (instr, LSBase + 4L, 0L); 4196 break; 4197 4198 case 0x9a: /* Store, WriteBack, Pre Inc. */ 4199 temp = LSBase; 4200 STOREMULT (instr, temp + 4L, temp + LSMNumRegs); 4201 break; 4202 4203 case 0x9b: /* Load, WriteBack, Pre Inc. */ 4204 temp = LSBase; 4205 LOADMULT (instr, temp + 4L, temp + LSMNumRegs); 4206 break; 4207 4208 case 0x9c: /* Store, Flags, No WriteBack, Pre Inc. */ 4209 STORESMULT (instr, LSBase + 4L, 0L); 4210 break; 4211 4212 case 0x9d: /* Load, Flags, No WriteBack, Pre Inc. */ 4213 LOADSMULT (instr, LSBase + 4L, 0L); 4214 break; 4215 4216 case 0x9e: /* Store, Flags, WriteBack, Pre Inc. */ 4217 temp = LSBase; 4218 STORESMULT (instr, temp + 4L, temp + LSMNumRegs); 4219 break; 4220 4221 case 0x9f: /* Load, Flags, WriteBack, Pre Inc. */ 4222 temp = LSBase; 4223 LOADSMULT (instr, temp + 4L, temp + LSMNumRegs); 4224 break; 4225 4226 4227 /* Branch forward. */ 4228 case 0xa0: 4229 case 0xa1: 4230 case 0xa2: 4231 case 0xa3: 4232 case 0xa4: 4233 case 0xa5: 4234 case 0xa6: 4235 case 0xa7: 4236 state->Reg[15] = pc + 8 + POSBRANCH; 4237 FLUSHPIPE; 4238 break; 4239 4240 4241 /* Branch backward. */ 4242 case 0xa8: 4243 case 0xa9: 4244 case 0xaa: 4245 case 0xab: 4246 case 0xac: 4247 case 0xad: 4248 case 0xae: 4249 case 0xaf: 4250 state->Reg[15] = pc + 8 + NEGBRANCH; 4251 FLUSHPIPE; 4252 break; 4253 4254 /* Branch and Link forward. */ 4255 case 0xb0: 4256 case 0xb1: 4257 case 0xb2: 4258 case 0xb3: 4259 case 0xb4: 4260 case 0xb5: 4261 case 0xb6: 4262 case 0xb7: 4263 /* Put PC into Link. */ 4264 #ifdef MODE32 4265 state->Reg[14] = pc + 4; 4266 #else 4267 state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE; 4268 #endif 4269 state->Reg[15] = pc + 8 + POSBRANCH; 4270 FLUSHPIPE; 4271 if (trace_funcs) 4272 fprintf (stderr, " pc changed to %x\n", state->Reg[15]); 4273 break; 4274 4275 /* Branch and Link backward. */ 4276 case 0xb8: 4277 case 0xb9: 4278 case 0xba: 4279 case 0xbb: 4280 case 0xbc: 4281 case 0xbd: 4282 case 0xbe: 4283 case 0xbf: 4284 /* Put PC into Link. */ 4285 #ifdef MODE32 4286 state->Reg[14] = pc + 4; 4287 #else 4288 state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE; 4289 #endif 4290 state->Reg[15] = pc + 8 + NEGBRANCH; 4291 FLUSHPIPE; 4292 if (trace_funcs) 4293 fprintf (stderr, " pc changed to %x\n", state->Reg[15]); 4294 break; 4295 4296 /* Co-Processor Data Transfers. */ 4297 case 0xc4: 4298 if (state->is_v5) 4299 { 4300 if (CPNum == 10 || CPNum == 11) 4301 handle_VFP_move (state, instr); 4302 /* Reading from R15 is UNPREDICTABLE. */ 4303 else if (BITS (12, 15) == 15 || BITS (16, 19) == 15) 4304 ARMul_UndefInstr (state, instr); 4305 /* Is access to coprocessor 0 allowed ? */ 4306 else if (! CP_ACCESS_ALLOWED (state, CPNum)) 4307 ARMul_UndefInstr (state, instr); 4308 /* Special treatment for XScale coprocessors. */ 4309 else if (state->is_XScale) 4310 { 4311 /* Only opcode 0 is supported. */ 4312 if (BITS (4, 7) != 0x00) 4313 ARMul_UndefInstr (state, instr); 4314 /* Only coporcessor 0 is supported. */ 4315 else if (CPNum != 0x00) 4316 ARMul_UndefInstr (state, instr); 4317 /* Only accumulator 0 is supported. */ 4318 else if (BITS (0, 3) != 0x00) 4319 ARMul_UndefInstr (state, instr); 4320 else 4321 { 4322 /* XScale MAR insn. Move two registers into accumulator. */ 4323 state->Accumulator = state->Reg[BITS (12, 15)]; 4324 state->Accumulator += (ARMdword) state->Reg[BITS (16, 19)] << 32; 4325 } 4326 } 4327 else 4328 /* FIXME: Not sure what to do for other v5 processors. */ 4329 ARMul_UndefInstr (state, instr); 4330 break; 4331 } 4332 /* Drop through. */ 4333 4334 case 0xc0: /* Store , No WriteBack , Post Dec. */ 4335 ARMul_STC (state, instr, LHS); 4336 break; 4337 4338 case 0xc5: 4339 if (state->is_v5) 4340 { 4341 if (CPNum == 10 || CPNum == 11) 4342 handle_VFP_move (state, instr); 4343 /* Writes to R15 are UNPREDICATABLE. */ 4344 else if (DESTReg == 15 || LHSReg == 15) 4345 ARMul_UndefInstr (state, instr); 4346 /* Is access to the coprocessor allowed ? */ 4347 else if (! CP_ACCESS_ALLOWED (state, CPNum)) 4348 ARMul_UndefInstr (state, instr); 4349 /* Special handling for XScale coprcoessors. */ 4350 else if (state->is_XScale) 4351 { 4352 /* Only opcode 0 is supported. */ 4353 if (BITS (4, 7) != 0x00) 4354 ARMul_UndefInstr (state, instr); 4355 /* Only coprocessor 0 is supported. */ 4356 else if (CPNum != 0x00) 4357 ARMul_UndefInstr (state, instr); 4358 /* Only accumulator 0 is supported. */ 4359 else if (BITS (0, 3) != 0x00) 4360 ARMul_UndefInstr (state, instr); 4361 else 4362 { 4363 /* XScale MRA insn. Move accumulator into two registers. */ 4364 ARMword t1 = (state->Accumulator >> 32) & 255; 4365 4366 if (t1 & 128) 4367 t1 -= 256; 4368 4369 state->Reg[BITS (12, 15)] = state->Accumulator; 4370 state->Reg[BITS (16, 19)] = t1; 4371 break; 4372 } 4373 } 4374 else 4375 /* FIXME: Not sure what to do for other v5 processors. */ 4376 ARMul_UndefInstr (state, instr); 4377 break; 4378 } 4379 /* Drop through. */ 4380 4381 case 0xc1: /* Load , No WriteBack , Post Dec. */ 4382 ARMul_LDC (state, instr, LHS); 4383 break; 4384 4385 case 0xc2: 4386 case 0xc6: /* Store , WriteBack , Post Dec. */ 4387 lhs = LHS; 4388 state->Base = lhs - LSCOff; 4389 ARMul_STC (state, instr, lhs); 4390 break; 4391 4392 case 0xc3: 4393 case 0xc7: /* Load , WriteBack , Post Dec. */ 4394 lhs = LHS; 4395 state->Base = lhs - LSCOff; 4396 ARMul_LDC (state, instr, lhs); 4397 break; 4398 4399 case 0xc8: 4400 case 0xcc: /* Store , No WriteBack , Post Inc. */ 4401 ARMul_STC (state, instr, LHS); 4402 break; 4403 4404 case 0xc9: 4405 case 0xcd: /* Load , No WriteBack , Post Inc. */ 4406 ARMul_LDC (state, instr, LHS); 4407 break; 4408 4409 case 0xca: 4410 case 0xce: /* Store , WriteBack , Post Inc. */ 4411 lhs = LHS; 4412 state->Base = lhs + LSCOff; 4413 ARMul_STC (state, instr, LHS); 4414 break; 4415 4416 case 0xcb: 4417 case 0xcf: /* Load , WriteBack , Post Inc. */ 4418 lhs = LHS; 4419 state->Base = lhs + LSCOff; 4420 ARMul_LDC (state, instr, LHS); 4421 break; 4422 4423 case 0xd0: 4424 case 0xd4: /* Store , No WriteBack , Pre Dec. */ 4425 ARMul_STC (state, instr, LHS - LSCOff); 4426 break; 4427 4428 case 0xd1: 4429 case 0xd5: /* Load , No WriteBack , Pre Dec. */ 4430 ARMul_LDC (state, instr, LHS - LSCOff); 4431 break; 4432 4433 case 0xd2: 4434 case 0xd6: /* Store , WriteBack , Pre Dec. */ 4435 lhs = LHS - LSCOff; 4436 state->Base = lhs; 4437 ARMul_STC (state, instr, lhs); 4438 break; 4439 4440 case 0xd3: 4441 case 0xd7: /* Load , WriteBack , Pre Dec. */ 4442 lhs = LHS - LSCOff; 4443 state->Base = lhs; 4444 ARMul_LDC (state, instr, lhs); 4445 break; 4446 4447 case 0xd8: 4448 case 0xdc: /* Store , No WriteBack , Pre Inc. */ 4449 ARMul_STC (state, instr, LHS + LSCOff); 4450 break; 4451 4452 case 0xd9: 4453 case 0xdd: /* Load , No WriteBack , Pre Inc. */ 4454 ARMul_LDC (state, instr, LHS + LSCOff); 4455 break; 4456 4457 case 0xda: 4458 case 0xde: /* Store , WriteBack , Pre Inc. */ 4459 lhs = LHS + LSCOff; 4460 state->Base = lhs; 4461 ARMul_STC (state, instr, lhs); 4462 break; 4463 4464 case 0xdb: 4465 case 0xdf: /* Load , WriteBack , Pre Inc. */ 4466 lhs = LHS + LSCOff; 4467 state->Base = lhs; 4468 ARMul_LDC (state, instr, lhs); 4469 break; 4470 4471 4472 /* Co-Processor Register Transfers (MCR) and Data Ops. */ 4473 4474 case 0xe2: 4475 if (! CP_ACCESS_ALLOWED (state, CPNum)) 4476 { 4477 ARMul_UndefInstr (state, instr); 4478 break; 4479 } 4480 if (state->is_XScale) 4481 switch (BITS (18, 19)) 4482 { 4483 case 0x0: 4484 if (BITS (4, 11) == 1 && BITS (16, 17) == 0) 4485 { 4486 /* XScale MIA instruction. Signed multiplication of 4487 two 32 bit values and addition to 40 bit accumulator. */ 4488 ARMsdword Rm = state->Reg[MULLHSReg]; 4489 ARMsdword Rs = state->Reg[MULACCReg]; 4490 4491 if (Rm & (1 << 31)) 4492 Rm -= 1ULL << 32; 4493 if (Rs & (1 << 31)) 4494 Rs -= 1ULL << 32; 4495 state->Accumulator += Rm * Rs; 4496 goto donext; 4497 } 4498 break; 4499 4500 case 0x2: 4501 if (BITS (4, 11) == 1 && BITS (16, 17) == 0) 4502 { 4503 /* XScale MIAPH instruction. */ 4504 ARMword t1 = state->Reg[MULLHSReg] >> 16; 4505 ARMword t2 = state->Reg[MULACCReg] >> 16; 4506 ARMword t3 = state->Reg[MULLHSReg] & 0xffff; 4507 ARMword t4 = state->Reg[MULACCReg] & 0xffff; 4508 ARMsdword t5; 4509 4510 if (t1 & (1 << 15)) 4511 t1 -= 1 << 16; 4512 if (t2 & (1 << 15)) 4513 t2 -= 1 << 16; 4514 if (t3 & (1 << 15)) 4515 t3 -= 1 << 16; 4516 if (t4 & (1 << 15)) 4517 t4 -= 1 << 16; 4518 t1 *= t2; 4519 t5 = t1; 4520 if (t5 & (1 << 31)) 4521 t5 -= 1ULL << 32; 4522 state->Accumulator += t5; 4523 t3 *= t4; 4524 t5 = t3; 4525 if (t5 & (1 << 31)) 4526 t5 -= 1ULL << 32; 4527 state->Accumulator += t5; 4528 goto donext; 4529 } 4530 break; 4531 4532 case 0x3: 4533 if (BITS (4, 11) == 1) 4534 { 4535 /* XScale MIAxy instruction. */ 4536 ARMword t1; 4537 ARMword t2; 4538 ARMsdword t5; 4539 4540 if (BIT (17)) 4541 t1 = state->Reg[MULLHSReg] >> 16; 4542 else 4543 t1 = state->Reg[MULLHSReg] & 0xffff; 4544 4545 if (BIT (16)) 4546 t2 = state->Reg[MULACCReg] >> 16; 4547 else 4548 t2 = state->Reg[MULACCReg] & 0xffff; 4549 4550 if (t1 & (1 << 15)) 4551 t1 -= 1 << 16; 4552 if (t2 & (1 << 15)) 4553 t2 -= 1 << 16; 4554 t1 *= t2; 4555 t5 = t1; 4556 if (t5 & (1 << 31)) 4557 t5 -= 1ULL << 32; 4558 state->Accumulator += t5; 4559 goto donext; 4560 } 4561 break; 4562 4563 default: 4564 break; 4565 } 4566 /* Drop through. */ 4567 4568 case 0xe0: 4569 case 0xe4: 4570 case 0xe6: 4571 case 0xe8: 4572 case 0xea: 4573 case 0xec: 4574 case 0xee: 4575 if (BIT (4)) 4576 { 4577 if (CPNum == 10 || CPNum == 11) 4578 handle_VFP_move (state, instr); 4579 /* MCR. */ 4580 else if (DESTReg == 15) 4581 { 4582 UNDEF_MCRPC; 4583 #ifdef MODE32 4584 ARMul_MCR (state, instr, state->Reg[15] + isize); 4585 #else 4586 ARMul_MCR (state, instr, ECC | ER15INT | EMODE | 4587 ((state->Reg[15] + isize) & R15PCBITS)); 4588 #endif 4589 } 4590 else 4591 ARMul_MCR (state, instr, DEST); 4592 } 4593 else 4594 /* CDP Part 1. */ 4595 ARMul_CDP (state, instr); 4596 break; 4597 4598 4599 /* Co-Processor Register Transfers (MRC) and Data Ops. */ 4600 case 0xe1: 4601 case 0xe3: 4602 case 0xe5: 4603 case 0xe7: 4604 case 0xe9: 4605 case 0xeb: 4606 case 0xed: 4607 case 0xef: 4608 if (BIT (4)) 4609 { 4610 if (CPNum == 10 || CPNum == 11) 4611 { 4612 switch (BITS (20, 27)) 4613 { 4614 case 0xEF: 4615 if (BITS (16, 19) == 0x1 4616 && BITS (0, 11) == 0xA10) 4617 { 4618 /* VMRS */ 4619 if (DESTReg == 15) 4620 { 4621 ARMul_SetCPSR (state, (state->FPSCR & 0xF0000000) 4622 | (ARMul_GetCPSR (state) & 0x0FFFFFFF)); 4623 4624 if (trace) 4625 fprintf (stderr, " VFP: VMRS: set flags to %c%c%c%c\n", 4626 ARMul_GetCPSR (state) & NBIT ? 'N' : '-', 4627 ARMul_GetCPSR (state) & ZBIT ? 'Z' : '-', 4628 ARMul_GetCPSR (state) & CBIT ? 'C' : '-', 4629 ARMul_GetCPSR (state) & VBIT ? 'V' : '-'); 4630 } 4631 else 4632 { 4633 state->Reg[DESTReg] = state->FPSCR; 4634 4635 if (trace) 4636 fprintf (stderr, " VFP: VMRS: r%d = %x\n", DESTReg, state->Reg[DESTReg]); 4637 } 4638 } 4639 else 4640 fprintf (stderr, "SIM: VFP: Unimplemented: Compare op\n"); 4641 break; 4642 4643 case 0xE0: 4644 case 0xE1: 4645 /* VMOV reg <-> single precision. */ 4646 if (BITS (0,6) != 0x10 || BITS (8,11) != 0xA) 4647 fprintf (stderr, "SIM: VFP: Unimplemented: move op\n"); 4648 else if (BIT (20)) 4649 state->Reg[BITS (12, 15)] = VFP_uword (BITS (16, 19) << 1 | BIT (7)); 4650 else 4651 VFP_uword (BITS (16, 19) << 1 | BIT (7)) = state->Reg[BITS (12, 15)]; 4652 break; 4653 4654 default: 4655 fprintf (stderr, "SIM: VFP: Unimplemented: CDP op\n"); 4656 break; 4657 } 4658 } 4659 else 4660 { 4661 /* MRC */ 4662 temp = ARMul_MRC (state, instr); 4663 if (DESTReg == 15) 4664 { 4665 ASSIGNN ((temp & NBIT) != 0); 4666 ASSIGNZ ((temp & ZBIT) != 0); 4667 ASSIGNC ((temp & CBIT) != 0); 4668 ASSIGNV ((temp & VBIT) != 0); 4669 } 4670 else 4671 DEST = temp; 4672 } 4673 } 4674 else 4675 /* CDP Part 2. */ 4676 ARMul_CDP (state, instr); 4677 break; 4678 4679 4680 /* SWI instruction. */ 4681 case 0xf0: 4682 case 0xf1: 4683 case 0xf2: 4684 case 0xf3: 4685 case 0xf4: 4686 case 0xf5: 4687 case 0xf6: 4688 case 0xf7: 4689 case 0xf8: 4690 case 0xf9: 4691 case 0xfa: 4692 case 0xfb: 4693 case 0xfc: 4694 case 0xfd: 4695 case 0xfe: 4696 case 0xff: 4697 if (instr == ARMul_ABORTWORD && state->AbortAddr == pc) 4698 { 4699 /* A prefetch abort. */ 4700 XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc); 4701 ARMul_Abort (state, ARMul_PrefetchAbortV); 4702 break; 4703 } 4704 4705 if (!ARMul_OSHandleSWI (state, BITS (0, 23))) 4706 ARMul_Abort (state, ARMul_SWIV); 4707 4708 break; 4709 } 4710 } 4711 4712 #ifdef MODET 4713 donext: 4714 #endif 4715 4716 if (state->Emulate == ONCE) 4717 state->Emulate = STOP; 4718 /* If we have changed mode, allow the PC to advance before stopping. */ 4719 else if (state->Emulate == CHANGEMODE) 4720 continue; 4721 else if (state->Emulate != RUN) 4722 break; 4723 } 4724 while (!stop_simulator); 4725 4726 state->decoded = decoded; 4727 state->loaded = loaded; 4728 state->pc = pc; 4729 4730 return pc; 4731 } 4732 4733 /* This routine evaluates most Data Processing register RHS's with the S 4734 bit clear. It is intended to be called from the macro DPRegRHS, which 4735 filters the common case of an unshifted register with in line code. */ 4736 4737 static ARMword 4738 GetDPRegRHS (ARMul_State * state, ARMword instr) 4739 { 4740 ARMword shamt, base; 4741 4742 base = RHSReg; 4743 if (BIT (4)) 4744 { 4745 /* Shift amount in a register. */ 4746 UNDEF_Shift; 4747 INCPC; 4748 #ifndef MODE32 4749 if (base == 15) 4750 base = ECC | ER15INT | R15PC | EMODE; 4751 else 4752 #endif 4753 base = state->Reg[base]; 4754 ARMul_Icycles (state, 1, 0L); 4755 shamt = state->Reg[BITS (8, 11)] & 0xff; 4756 switch ((int) BITS (5, 6)) 4757 { 4758 case LSL: 4759 if (shamt == 0) 4760 return (base); 4761 else if (shamt >= 32) 4762 return (0); 4763 else 4764 return (base << shamt); 4765 case LSR: 4766 if (shamt == 0) 4767 return (base); 4768 else if (shamt >= 32) 4769 return (0); 4770 else 4771 return (base >> shamt); 4772 case ASR: 4773 if (shamt == 0) 4774 return (base); 4775 else if (shamt >= 32) 4776 return ((ARMword) ((ARMsword) base >> 31L)); 4777 else 4778 return ((ARMword) ((ARMsword) base >> (int) shamt)); 4779 case ROR: 4780 shamt &= 0x1f; 4781 if (shamt == 0) 4782 return (base); 4783 else 4784 return ((base << (32 - shamt)) | (base >> shamt)); 4785 } 4786 } 4787 else 4788 { 4789 /* Shift amount is a constant. */ 4790 #ifndef MODE32 4791 if (base == 15) 4792 base = ECC | ER15INT | R15PC | EMODE; 4793 else 4794 #endif 4795 base = state->Reg[base]; 4796 shamt = BITS (7, 11); 4797 switch ((int) BITS (5, 6)) 4798 { 4799 case LSL: 4800 return (base << shamt); 4801 case LSR: 4802 if (shamt == 0) 4803 return (0); 4804 else 4805 return (base >> shamt); 4806 case ASR: 4807 if (shamt == 0) 4808 return ((ARMword) ((ARMsword) base >> 31L)); 4809 else 4810 return ((ARMword) ((ARMsword) base >> (int) shamt)); 4811 case ROR: 4812 if (shamt == 0) 4813 /* It's an RRX. */ 4814 return ((base >> 1) | (CFLAG << 31)); 4815 else 4816 return ((base << (32 - shamt)) | (base >> shamt)); 4817 } 4818 } 4819 4820 return 0; 4821 } 4822 4823 /* This routine evaluates most Logical Data Processing register RHS's 4824 with the S bit set. It is intended to be called from the macro 4825 DPSRegRHS, which filters the common case of an unshifted register 4826 with in line code. */ 4827 4828 static ARMword 4829 GetDPSRegRHS (ARMul_State * state, ARMword instr) 4830 { 4831 ARMword shamt, base; 4832 4833 base = RHSReg; 4834 if (BIT (4)) 4835 { 4836 /* Shift amount in a register. */ 4837 UNDEF_Shift; 4838 INCPC; 4839 #ifndef MODE32 4840 if (base == 15) 4841 base = ECC | ER15INT | R15PC | EMODE; 4842 else 4843 #endif 4844 base = state->Reg[base]; 4845 ARMul_Icycles (state, 1, 0L); 4846 shamt = state->Reg[BITS (8, 11)] & 0xff; 4847 switch ((int) BITS (5, 6)) 4848 { 4849 case LSL: 4850 if (shamt == 0) 4851 return (base); 4852 else if (shamt == 32) 4853 { 4854 ASSIGNC (base & 1); 4855 return (0); 4856 } 4857 else if (shamt > 32) 4858 { 4859 CLEARC; 4860 return (0); 4861 } 4862 else 4863 { 4864 ASSIGNC ((base >> (32 - shamt)) & 1); 4865 return (base << shamt); 4866 } 4867 case LSR: 4868 if (shamt == 0) 4869 return (base); 4870 else if (shamt == 32) 4871 { 4872 ASSIGNC (base >> 31); 4873 return (0); 4874 } 4875 else if (shamt > 32) 4876 { 4877 CLEARC; 4878 return (0); 4879 } 4880 else 4881 { 4882 ASSIGNC ((base >> (shamt - 1)) & 1); 4883 return (base >> shamt); 4884 } 4885 case ASR: 4886 if (shamt == 0) 4887 return (base); 4888 else if (shamt >= 32) 4889 { 4890 ASSIGNC (base >> 31L); 4891 return ((ARMword) ((ARMsword) base >> 31L)); 4892 } 4893 else 4894 { 4895 ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1); 4896 return ((ARMword) ((ARMsword) base >> (int) shamt)); 4897 } 4898 case ROR: 4899 if (shamt == 0) 4900 return (base); 4901 shamt &= 0x1f; 4902 if (shamt == 0) 4903 { 4904 ASSIGNC (base >> 31); 4905 return (base); 4906 } 4907 else 4908 { 4909 ASSIGNC ((base >> (shamt - 1)) & 1); 4910 return ((base << (32 - shamt)) | (base >> shamt)); 4911 } 4912 } 4913 } 4914 else 4915 { 4916 /* Shift amount is a constant. */ 4917 #ifndef MODE32 4918 if (base == 15) 4919 base = ECC | ER15INT | R15PC | EMODE; 4920 else 4921 #endif 4922 base = state->Reg[base]; 4923 shamt = BITS (7, 11); 4924 4925 switch ((int) BITS (5, 6)) 4926 { 4927 case LSL: 4928 ASSIGNC ((base >> (32 - shamt)) & 1); 4929 return (base << shamt); 4930 case LSR: 4931 if (shamt == 0) 4932 { 4933 ASSIGNC (base >> 31); 4934 return (0); 4935 } 4936 else 4937 { 4938 ASSIGNC ((base >> (shamt - 1)) & 1); 4939 return (base >> shamt); 4940 } 4941 case ASR: 4942 if (shamt == 0) 4943 { 4944 ASSIGNC (base >> 31L); 4945 return ((ARMword) ((ARMsword) base >> 31L)); 4946 } 4947 else 4948 { 4949 ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1); 4950 return ((ARMword) ((ARMsword) base >> (int) shamt)); 4951 } 4952 case ROR: 4953 if (shamt == 0) 4954 { 4955 /* It's an RRX. */ 4956 shamt = CFLAG; 4957 ASSIGNC (base & 1); 4958 return ((base >> 1) | (shamt << 31)); 4959 } 4960 else 4961 { 4962 ASSIGNC ((base >> (shamt - 1)) & 1); 4963 return ((base << (32 - shamt)) | (base >> shamt)); 4964 } 4965 } 4966 } 4967 4968 return 0; 4969 } 4970 4971 /* This routine handles writes to register 15 when the S bit is not set. */ 4972 4973 static void 4974 WriteR15 (ARMul_State * state, ARMword src) 4975 { 4976 /* The ARM documentation states that the two least significant bits 4977 are discarded when setting PC, except in the cases handled by 4978 WriteR15Branch() below. It's probably an oversight: in THUMB 4979 mode, the second least significant bit should probably not be 4980 discarded. */ 4981 #ifdef MODET 4982 if (TFLAG) 4983 src &= 0xfffffffe; 4984 else 4985 #endif 4986 src &= 0xfffffffc; 4987 4988 #ifdef MODE32 4989 state->Reg[15] = src & PCBITS; 4990 #else 4991 state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE; 4992 ARMul_R15Altered (state); 4993 #endif 4994 4995 FLUSHPIPE; 4996 if (trace_funcs) 4997 fprintf (stderr, " pc changed to %x\n", state->Reg[15]); 4998 } 4999 5000 /* This routine handles writes to register 15 when the S bit is set. */ 5001 5002 static void 5003 WriteSR15 (ARMul_State * state, ARMword src) 5004 { 5005 #ifdef MODE32 5006 if (state->Bank > 0) 5007 { 5008 state->Cpsr = state->Spsr[state->Bank]; 5009 ARMul_CPSRAltered (state); 5010 } 5011 #ifdef MODET 5012 if (TFLAG) 5013 src &= 0xfffffffe; 5014 else 5015 #endif 5016 src &= 0xfffffffc; 5017 state->Reg[15] = src & PCBITS; 5018 #else 5019 #ifdef MODET 5020 if (TFLAG) 5021 /* ARMul_R15Altered would have to support it. */ 5022 abort (); 5023 else 5024 #endif 5025 src &= 0xfffffffc; 5026 5027 if (state->Bank == USERBANK) 5028 state->Reg[15] = (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE; 5029 else 5030 state->Reg[15] = src; 5031 5032 ARMul_R15Altered (state); 5033 #endif 5034 FLUSHPIPE; 5035 if (trace_funcs) 5036 fprintf (stderr, " pc changed to %x\n", state->Reg[15]); 5037 } 5038 5039 /* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM 5040 will switch to Thumb mode if the least significant bit is set. */ 5041 5042 static void 5043 WriteR15Branch (ARMul_State * state, ARMword src) 5044 { 5045 #ifdef MODET 5046 if (src & 1) 5047 { 5048 /* Thumb bit. */ 5049 SETT; 5050 state->Reg[15] = src & 0xfffffffe; 5051 } 5052 else 5053 { 5054 CLEART; 5055 state->Reg[15] = src & 0xfffffffc; 5056 } 5057 FLUSHPIPE; 5058 if (trace_funcs) 5059 fprintf (stderr, " pc changed to %x\n", state->Reg[15]); 5060 #else 5061 WriteR15 (state, src); 5062 #endif 5063 } 5064 5065 /* Before ARM_v5 LDR and LDM of pc did not change mode. */ 5066 5067 static void 5068 WriteR15Load (ARMul_State * state, ARMword src) 5069 { 5070 if (state->is_v5) 5071 WriteR15Branch (state, src); 5072 else 5073 WriteR15 (state, src); 5074 } 5075 5076 /* This routine evaluates most Load and Store register RHS's. It is 5077 intended to be called from the macro LSRegRHS, which filters the 5078 common case of an unshifted register with in line code. */ 5079 5080 static ARMword 5081 GetLSRegRHS (ARMul_State * state, ARMword instr) 5082 { 5083 ARMword shamt, base; 5084 5085 base = RHSReg; 5086 #ifndef MODE32 5087 if (base == 15) 5088 /* Now forbidden, but ... */ 5089 base = ECC | ER15INT | R15PC | EMODE; 5090 else 5091 #endif 5092 base = state->Reg[base]; 5093 5094 shamt = BITS (7, 11); 5095 switch ((int) BITS (5, 6)) 5096 { 5097 case LSL: 5098 return (base << shamt); 5099 case LSR: 5100 if (shamt == 0) 5101 return (0); 5102 else 5103 return (base >> shamt); 5104 case ASR: 5105 if (shamt == 0) 5106 return ((ARMword) ((ARMsword) base >> 31L)); 5107 else 5108 return ((ARMword) ((ARMsword) base >> (int) shamt)); 5109 case ROR: 5110 if (shamt == 0) 5111 /* It's an RRX. */ 5112 return ((base >> 1) | (CFLAG << 31)); 5113 else 5114 return ((base << (32 - shamt)) | (base >> shamt)); 5115 default: 5116 break; 5117 } 5118 return 0; 5119 } 5120 5121 /* This routine evaluates the ARM7T halfword and signed transfer RHS's. */ 5122 5123 static ARMword 5124 GetLS7RHS (ARMul_State * state, ARMword instr) 5125 { 5126 if (BIT (22) == 0) 5127 { 5128 /* Register. */ 5129 #ifndef MODE32 5130 if (RHSReg == 15) 5131 /* Now forbidden, but ... */ 5132 return ECC | ER15INT | R15PC | EMODE; 5133 #endif 5134 return state->Reg[RHSReg]; 5135 } 5136 5137 /* Immediate. */ 5138 return BITS (0, 3) | (BITS (8, 11) << 4); 5139 } 5140 5141 /* This function does the work of loading a word for a LDR instruction. */ 5142 5143 static unsigned 5144 LoadWord (ARMul_State * state, ARMword instr, ARMword address) 5145 { 5146 ARMword dest; 5147 5148 BUSUSEDINCPCS; 5149 #ifndef MODE32 5150 if (ADDREXCEPT (address)) 5151 INTERNALABORT (address); 5152 #endif 5153 5154 dest = ARMul_LoadWordN (state, address); 5155 5156 if (state->Aborted) 5157 { 5158 TAKEABORT; 5159 return state->lateabtSig; 5160 } 5161 if (address & 3) 5162 dest = ARMul_Align (state, address, dest); 5163 WRITEDESTB (dest); 5164 ARMul_Icycles (state, 1, 0L); 5165 5166 return (DESTReg != LHSReg); 5167 } 5168 5169 #ifdef MODET 5170 /* This function does the work of loading a halfword. */ 5171 5172 static unsigned 5173 LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address, 5174 int signextend) 5175 { 5176 ARMword dest; 5177 5178 BUSUSEDINCPCS; 5179 #ifndef MODE32 5180 if (ADDREXCEPT (address)) 5181 INTERNALABORT (address); 5182 #endif 5183 dest = ARMul_LoadHalfWord (state, address); 5184 if (state->Aborted) 5185 { 5186 TAKEABORT; 5187 return state->lateabtSig; 5188 } 5189 UNDEF_LSRBPC; 5190 if (signextend) 5191 if (dest & 1 << (16 - 1)) 5192 dest = (dest & ((1 << 16) - 1)) - (1 << 16); 5193 5194 WRITEDEST (dest); 5195 ARMul_Icycles (state, 1, 0L); 5196 return (DESTReg != LHSReg); 5197 } 5198 5199 #endif /* MODET */ 5200 5201 /* This function does the work of loading a byte for a LDRB instruction. */ 5202 5203 static unsigned 5204 LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend) 5205 { 5206 ARMword dest; 5207 5208 BUSUSEDINCPCS; 5209 #ifndef MODE32 5210 if (ADDREXCEPT (address)) 5211 INTERNALABORT (address); 5212 #endif 5213 dest = ARMul_LoadByte (state, address); 5214 if (state->Aborted) 5215 { 5216 TAKEABORT; 5217 return state->lateabtSig; 5218 } 5219 UNDEF_LSRBPC; 5220 if (signextend) 5221 if (dest & 1 << (8 - 1)) 5222 dest = (dest & ((1 << 8) - 1)) - (1 << 8); 5223 5224 WRITEDEST (dest); 5225 ARMul_Icycles (state, 1, 0L); 5226 5227 return (DESTReg != LHSReg); 5228 } 5229 5230 /* This function does the work of loading two words for a LDRD instruction. */ 5231 5232 static void 5233 Handle_Load_Double (ARMul_State * state, ARMword instr) 5234 { 5235 ARMword dest_reg; 5236 ARMword addr_reg; 5237 ARMword write_back = BIT (21); 5238 ARMword immediate = BIT (22); 5239 ARMword add_to_base = BIT (23); 5240 ARMword pre_indexed = BIT (24); 5241 ARMword offset; 5242 ARMword addr; 5243 ARMword sum; 5244 ARMword base; 5245 ARMword value1; 5246 ARMword value2; 5247 5248 BUSUSEDINCPCS; 5249 5250 /* If the writeback bit is set, the pre-index bit must be clear. */ 5251 if (write_back && ! pre_indexed) 5252 { 5253 ARMul_UndefInstr (state, instr); 5254 return; 5255 } 5256 5257 /* Extract the base address register. */ 5258 addr_reg = LHSReg; 5259 5260 /* Extract the destination register and check it. */ 5261 dest_reg = DESTReg; 5262 5263 /* Destination register must be even. */ 5264 if ((dest_reg & 1) 5265 /* Destination register cannot be LR. */ 5266 || (dest_reg == 14)) 5267 { 5268 ARMul_UndefInstr (state, instr); 5269 return; 5270 } 5271 5272 /* Compute the base address. */ 5273 base = state->Reg[addr_reg]; 5274 5275 /* Compute the offset. */ 5276 offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg]; 5277 5278 /* Compute the sum of the two. */ 5279 if (add_to_base) 5280 sum = base + offset; 5281 else 5282 sum = base - offset; 5283 5284 /* If this is a pre-indexed mode use the sum. */ 5285 if (pre_indexed) 5286 addr = sum; 5287 else 5288 addr = base; 5289 5290 if (state->is_v6 && (addr & 0x3) == 0) 5291 /* Word alignment is enough for v6. */ 5292 ; 5293 /* The address must be aligned on a 8 byte boundary. */ 5294 else if (addr & 0x7) 5295 { 5296 #ifdef ABORTS 5297 ARMul_DATAABORT (addr); 5298 #else 5299 ARMul_UndefInstr (state, instr); 5300 #endif 5301 return; 5302 } 5303 5304 /* For pre indexed or post indexed addressing modes, 5305 check that the destination registers do not overlap 5306 the address registers. */ 5307 if ((! pre_indexed || write_back) 5308 && ( addr_reg == dest_reg 5309 || addr_reg == dest_reg + 1)) 5310 { 5311 ARMul_UndefInstr (state, instr); 5312 return; 5313 } 5314 5315 /* Load the words. */ 5316 value1 = ARMul_LoadWordN (state, addr); 5317 value2 = ARMul_LoadWordN (state, addr + 4); 5318 5319 /* Check for data aborts. */ 5320 if (state->Aborted) 5321 { 5322 TAKEABORT; 5323 return; 5324 } 5325 5326 ARMul_Icycles (state, 2, 0L); 5327 5328 /* Store the values. */ 5329 state->Reg[dest_reg] = value1; 5330 state->Reg[dest_reg + 1] = value2; 5331 5332 /* Do the post addressing and writeback. */ 5333 if (! pre_indexed) 5334 addr = sum; 5335 5336 if (! pre_indexed || write_back) 5337 state->Reg[addr_reg] = addr; 5338 } 5339 5340 /* This function does the work of storing two words for a STRD instruction. */ 5341 5342 static void 5343 Handle_Store_Double (ARMul_State * state, ARMword instr) 5344 { 5345 ARMword src_reg; 5346 ARMword addr_reg; 5347 ARMword write_back = BIT (21); 5348 ARMword immediate = BIT (22); 5349 ARMword add_to_base = BIT (23); 5350 ARMword pre_indexed = BIT (24); 5351 ARMword offset; 5352 ARMword addr; 5353 ARMword sum; 5354 ARMword base; 5355 5356 BUSUSEDINCPCS; 5357 5358 /* If the writeback bit is set, the pre-index bit must be clear. */ 5359 if (write_back && ! pre_indexed) 5360 { 5361 ARMul_UndefInstr (state, instr); 5362 return; 5363 } 5364 5365 /* Extract the base address register. */ 5366 addr_reg = LHSReg; 5367 5368 /* Base register cannot be PC. */ 5369 if (addr_reg == 15) 5370 { 5371 ARMul_UndefInstr (state, instr); 5372 return; 5373 } 5374 5375 /* Extract the source register. */ 5376 src_reg = DESTReg; 5377 5378 /* Source register must be even. */ 5379 if (src_reg & 1) 5380 { 5381 ARMul_UndefInstr (state, instr); 5382 return; 5383 } 5384 5385 /* Compute the base address. */ 5386 base = state->Reg[addr_reg]; 5387 5388 /* Compute the offset. */ 5389 offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg]; 5390 5391 /* Compute the sum of the two. */ 5392 if (add_to_base) 5393 sum = base + offset; 5394 else 5395 sum = base - offset; 5396 5397 /* If this is a pre-indexed mode use the sum. */ 5398 if (pre_indexed) 5399 addr = sum; 5400 else 5401 addr = base; 5402 5403 /* The address must be aligned on a 8 byte boundary. */ 5404 if (addr & 0x7) 5405 { 5406 #ifdef ABORTS 5407 ARMul_DATAABORT (addr); 5408 #else 5409 ARMul_UndefInstr (state, instr); 5410 #endif 5411 return; 5412 } 5413 5414 /* For pre indexed or post indexed addressing modes, 5415 check that the destination registers do not overlap 5416 the address registers. */ 5417 if ((! pre_indexed || write_back) 5418 && ( addr_reg == src_reg 5419 || addr_reg == src_reg + 1)) 5420 { 5421 ARMul_UndefInstr (state, instr); 5422 return; 5423 } 5424 5425 /* Load the words. */ 5426 ARMul_StoreWordN (state, addr, state->Reg[src_reg]); 5427 ARMul_StoreWordN (state, addr + 4, state->Reg[src_reg + 1]); 5428 5429 if (state->Aborted) 5430 { 5431 TAKEABORT; 5432 return; 5433 } 5434 5435 /* Do the post addressing and writeback. */ 5436 if (! pre_indexed) 5437 addr = sum; 5438 5439 if (! pre_indexed || write_back) 5440 state->Reg[addr_reg] = addr; 5441 } 5442 5443 /* This function does the work of storing a word from a STR instruction. */ 5444 5445 static unsigned 5446 StoreWord (ARMul_State * state, ARMword instr, ARMword address) 5447 { 5448 BUSUSEDINCPCN; 5449 #ifndef MODE32 5450 if (DESTReg == 15) 5451 state->Reg[15] = ECC | ER15INT | R15PC | EMODE; 5452 #endif 5453 #ifdef MODE32 5454 ARMul_StoreWordN (state, address, DEST); 5455 #else 5456 if (VECTORACCESS (address) || ADDREXCEPT (address)) 5457 { 5458 INTERNALABORT (address); 5459 (void) ARMul_LoadWordN (state, address); 5460 } 5461 else 5462 ARMul_StoreWordN (state, address, DEST); 5463 #endif 5464 if (state->Aborted) 5465 { 5466 TAKEABORT; 5467 return state->lateabtSig; 5468 } 5469 return TRUE; 5470 } 5471 5472 #ifdef MODET 5473 /* This function does the work of storing a byte for a STRH instruction. */ 5474 5475 static unsigned 5476 StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address) 5477 { 5478 BUSUSEDINCPCN; 5479 5480 #ifndef MODE32 5481 if (DESTReg == 15) 5482 state->Reg[15] = ECC | ER15INT | R15PC | EMODE; 5483 #endif 5484 5485 #ifdef MODE32 5486 ARMul_StoreHalfWord (state, address, DEST); 5487 #else 5488 if (VECTORACCESS (address) || ADDREXCEPT (address)) 5489 { 5490 INTERNALABORT (address); 5491 (void) ARMul_LoadHalfWord (state, address); 5492 } 5493 else 5494 ARMul_StoreHalfWord (state, address, DEST); 5495 #endif 5496 5497 if (state->Aborted) 5498 { 5499 TAKEABORT; 5500 return state->lateabtSig; 5501 } 5502 return TRUE; 5503 } 5504 5505 #endif /* MODET */ 5506 5507 /* This function does the work of storing a byte for a STRB instruction. */ 5508 5509 static unsigned 5510 StoreByte (ARMul_State * state, ARMword instr, ARMword address) 5511 { 5512 BUSUSEDINCPCN; 5513 #ifndef MODE32 5514 if (DESTReg == 15) 5515 state->Reg[15] = ECC | ER15INT | R15PC | EMODE; 5516 #endif 5517 #ifdef MODE32 5518 ARMul_StoreByte (state, address, DEST); 5519 #else 5520 if (VECTORACCESS (address) || ADDREXCEPT (address)) 5521 { 5522 INTERNALABORT (address); 5523 (void) ARMul_LoadByte (state, address); 5524 } 5525 else 5526 ARMul_StoreByte (state, address, DEST); 5527 #endif 5528 if (state->Aborted) 5529 { 5530 TAKEABORT; 5531 return state->lateabtSig; 5532 } 5533 UNDEF_LSRBPC; 5534 return TRUE; 5535 } 5536 5537 /* This function does the work of loading the registers listed in an LDM 5538 instruction, when the S bit is clear. The code here is always increment 5539 after, it's up to the caller to get the input address correct and to 5540 handle base register modification. */ 5541 5542 static void 5543 LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase) 5544 { 5545 ARMword dest, temp; 5546 5547 UNDEF_LSMNoRegs; 5548 UNDEF_LSMPCBase; 5549 UNDEF_LSMBaseInListWb; 5550 BUSUSEDINCPCS; 5551 #ifndef MODE32 5552 if (ADDREXCEPT (address)) 5553 INTERNALABORT (address); 5554 #endif 5555 if (BIT (21) && LHSReg != 15) 5556 LSBase = WBBase; 5557 5558 /* N cycle first. */ 5559 for (temp = 0; !BIT (temp); temp++) 5560 ; 5561 5562 dest = ARMul_LoadWordN (state, address); 5563 5564 if (!state->abortSig && !state->Aborted) 5565 state->Reg[temp++] = dest; 5566 else if (!state->Aborted) 5567 { 5568 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); 5569 state->Aborted = ARMul_DataAbortV; 5570 } 5571 5572 /* S cycles from here on. */ 5573 for (; temp < 16; temp ++) 5574 if (BIT (temp)) 5575 { 5576 /* Load this register. */ 5577 address += 4; 5578 dest = ARMul_LoadWordS (state, address); 5579 5580 if (!state->abortSig && !state->Aborted) 5581 state->Reg[temp] = dest; 5582 else if (!state->Aborted) 5583 { 5584 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); 5585 state->Aborted = ARMul_DataAbortV; 5586 } 5587 } 5588 5589 if (BIT (15) && !state->Aborted) 5590 /* PC is in the reg list. */ 5591 WriteR15Load (state, PC); 5592 5593 /* To write back the final register. */ 5594 ARMul_Icycles (state, 1, 0L); 5595 5596 if (state->Aborted) 5597 { 5598 if (BIT (21) && LHSReg != 15) 5599 LSBase = WBBase; 5600 TAKEABORT; 5601 } 5602 } 5603 5604 /* This function does the work of loading the registers listed in an LDM 5605 instruction, when the S bit is set. The code here is always increment 5606 after, it's up to the caller to get the input address correct and to 5607 handle base register modification. */ 5608 5609 static void 5610 LoadSMult (ARMul_State * state, 5611 ARMword instr, 5612 ARMword address, 5613 ARMword WBBase) 5614 { 5615 ARMword dest, temp; 5616 5617 UNDEF_LSMNoRegs; 5618 UNDEF_LSMPCBase; 5619 UNDEF_LSMBaseInListWb; 5620 5621 BUSUSEDINCPCS; 5622 5623 #ifndef MODE32 5624 if (ADDREXCEPT (address)) 5625 INTERNALABORT (address); 5626 #endif 5627 5628 if (BIT (21) && LHSReg != 15) 5629 LSBase = WBBase; 5630 5631 if (!BIT (15) && state->Bank != USERBANK) 5632 { 5633 /* Temporary reg bank switch. */ 5634 (void) ARMul_SwitchMode (state, state->Mode, USER26MODE); 5635 UNDEF_LSMUserBankWb; 5636 } 5637 5638 /* N cycle first. */ 5639 for (temp = 0; !BIT (temp); temp ++) 5640 ; 5641 5642 dest = ARMul_LoadWordN (state, address); 5643 5644 if (!state->abortSig) 5645 state->Reg[temp++] = dest; 5646 else if (!state->Aborted) 5647 { 5648 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); 5649 state->Aborted = ARMul_DataAbortV; 5650 } 5651 5652 /* S cycles from here on. */ 5653 for (; temp < 16; temp++) 5654 if (BIT (temp)) 5655 { 5656 /* Load this register. */ 5657 address += 4; 5658 dest = ARMul_LoadWordS (state, address); 5659 5660 if (!state->abortSig && !state->Aborted) 5661 state->Reg[temp] = dest; 5662 else if (!state->Aborted) 5663 { 5664 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); 5665 state->Aborted = ARMul_DataAbortV; 5666 } 5667 } 5668 5669 if (BIT (15) && !state->Aborted) 5670 { 5671 /* PC is in the reg list. */ 5672 #ifdef MODE32 5673 if (state->Mode != USER26MODE && state->Mode != USER32MODE) 5674 { 5675 state->Cpsr = GETSPSR (state->Bank); 5676 ARMul_CPSRAltered (state); 5677 } 5678 5679 WriteR15 (state, PC); 5680 #else 5681 if (state->Mode == USER26MODE || state->Mode == USER32MODE) 5682 { 5683 /* Protect bits in user mode. */ 5684 ASSIGNN ((state->Reg[15] & NBIT) != 0); 5685 ASSIGNZ ((state->Reg[15] & ZBIT) != 0); 5686 ASSIGNC ((state->Reg[15] & CBIT) != 0); 5687 ASSIGNV ((state->Reg[15] & VBIT) != 0); 5688 } 5689 else 5690 ARMul_R15Altered (state); 5691 5692 FLUSHPIPE; 5693 #endif 5694 } 5695 5696 if (!BIT (15) && state->Mode != USER26MODE && state->Mode != USER32MODE) 5697 /* Restore the correct bank. */ 5698 (void) ARMul_SwitchMode (state, USER26MODE, state->Mode); 5699 5700 /* To write back the final register. */ 5701 ARMul_Icycles (state, 1, 0L); 5702 5703 if (state->Aborted) 5704 { 5705 if (BIT (21) && LHSReg != 15) 5706 LSBase = WBBase; 5707 5708 TAKEABORT; 5709 } 5710 } 5711 5712 /* This function does the work of storing the registers listed in an STM 5713 instruction, when the S bit is clear. The code here is always increment 5714 after, it's up to the caller to get the input address correct and to 5715 handle base register modification. */ 5716 5717 static void 5718 StoreMult (ARMul_State * state, 5719 ARMword instr, 5720 ARMword address, 5721 ARMword WBBase) 5722 { 5723 ARMword temp; 5724 5725 UNDEF_LSMNoRegs; 5726 UNDEF_LSMPCBase; 5727 UNDEF_LSMBaseInListWb; 5728 5729 if (!TFLAG) 5730 /* N-cycle, increment the PC and update the NextInstr state. */ 5731 BUSUSEDINCPCN; 5732 5733 #ifndef MODE32 5734 if (VECTORACCESS (address) || ADDREXCEPT (address)) 5735 INTERNALABORT (address); 5736 5737 if (BIT (15)) 5738 PATCHR15; 5739 #endif 5740 5741 /* N cycle first. */ 5742 for (temp = 0; !BIT (temp); temp ++) 5743 ; 5744 5745 #ifdef MODE32 5746 ARMul_StoreWordN (state, address, state->Reg[temp++]); 5747 #else 5748 if (state->Aborted) 5749 { 5750 (void) ARMul_LoadWordN (state, address); 5751 5752 /* Fake the Stores as Loads. */ 5753 for (; temp < 16; temp++) 5754 if (BIT (temp)) 5755 { 5756 /* Save this register. */ 5757 address += 4; 5758 (void) ARMul_LoadWordS (state, address); 5759 } 5760 5761 if (BIT (21) && LHSReg != 15) 5762 LSBase = WBBase; 5763 TAKEABORT; 5764 return; 5765 } 5766 else 5767 ARMul_StoreWordN (state, address, state->Reg[temp++]); 5768 #endif 5769 5770 if (state->abortSig && !state->Aborted) 5771 { 5772 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); 5773 state->Aborted = ARMul_DataAbortV; 5774 } 5775 5776 if (BIT (21) && LHSReg != 15) 5777 LSBase = WBBase; 5778 5779 /* S cycles from here on. */ 5780 for (; temp < 16; temp ++) 5781 if (BIT (temp)) 5782 { 5783 /* Save this register. */ 5784 address += 4; 5785 5786 ARMul_StoreWordS (state, address, state->Reg[temp]); 5787 5788 if (state->abortSig && !state->Aborted) 5789 { 5790 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); 5791 state->Aborted = ARMul_DataAbortV; 5792 } 5793 } 5794 5795 if (state->Aborted) 5796 TAKEABORT; 5797 } 5798 5799 /* This function does the work of storing the registers listed in an STM 5800 instruction when the S bit is set. The code here is always increment 5801 after, it's up to the caller to get the input address correct and to 5802 handle base register modification. */ 5803 5804 static void 5805 StoreSMult (ARMul_State * state, 5806 ARMword instr, 5807 ARMword address, 5808 ARMword WBBase) 5809 { 5810 ARMword temp; 5811 5812 UNDEF_LSMNoRegs; 5813 UNDEF_LSMPCBase; 5814 UNDEF_LSMBaseInListWb; 5815 5816 BUSUSEDINCPCN; 5817 5818 #ifndef MODE32 5819 if (VECTORACCESS (address) || ADDREXCEPT (address)) 5820 INTERNALABORT (address); 5821 5822 if (BIT (15)) 5823 PATCHR15; 5824 #endif 5825 5826 if (state->Bank != USERBANK) 5827 { 5828 /* Force User Bank. */ 5829 (void) ARMul_SwitchMode (state, state->Mode, USER26MODE); 5830 UNDEF_LSMUserBankWb; 5831 } 5832 5833 for (temp = 0; !BIT (temp); temp++) 5834 ; /* N cycle first. */ 5835 5836 #ifdef MODE32 5837 ARMul_StoreWordN (state, address, state->Reg[temp++]); 5838 #else 5839 if (state->Aborted) 5840 { 5841 (void) ARMul_LoadWordN (state, address); 5842 5843 for (; temp < 16; temp++) 5844 /* Fake the Stores as Loads. */ 5845 if (BIT (temp)) 5846 { 5847 /* Save this register. */ 5848 address += 4; 5849 5850 (void) ARMul_LoadWordS (state, address); 5851 } 5852 5853 if (BIT (21) && LHSReg != 15) 5854 LSBase = WBBase; 5855 5856 TAKEABORT; 5857 return; 5858 } 5859 else 5860 ARMul_StoreWordN (state, address, state->Reg[temp++]); 5861 #endif 5862 5863 if (state->abortSig && !state->Aborted) 5864 { 5865 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); 5866 state->Aborted = ARMul_DataAbortV; 5867 } 5868 5869 /* S cycles from here on. */ 5870 for (; temp < 16; temp++) 5871 if (BIT (temp)) 5872 { 5873 /* Save this register. */ 5874 address += 4; 5875 5876 ARMul_StoreWordS (state, address, state->Reg[temp]); 5877 5878 if (state->abortSig && !state->Aborted) 5879 { 5880 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); 5881 state->Aborted = ARMul_DataAbortV; 5882 } 5883 } 5884 5885 if (state->Mode != USER26MODE && state->Mode != USER32MODE) 5886 /* Restore the correct bank. */ 5887 (void) ARMul_SwitchMode (state, USER26MODE, state->Mode); 5888 5889 if (BIT (21) && LHSReg != 15) 5890 LSBase = WBBase; 5891 5892 if (state->Aborted) 5893 TAKEABORT; 5894 } 5895 5896 /* This function does the work of adding two 32bit values 5897 together, and calculating if a carry has occurred. */ 5898 5899 static ARMword 5900 Add32 (ARMword a1, ARMword a2, int *carry) 5901 { 5902 ARMword result = (a1 + a2); 5903 unsigned int uresult = (unsigned int) result; 5904 unsigned int ua1 = (unsigned int) a1; 5905 5906 /* If (result == RdLo) and (state->Reg[nRdLo] == 0), 5907 or (result > RdLo) then we have no carry. */ 5908 if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1)) 5909 *carry = 1; 5910 else 5911 *carry = 0; 5912 5913 return result; 5914 } 5915 5916 /* This function does the work of multiplying 5917 two 32bit values to give a 64bit result. */ 5918 5919 static unsigned 5920 Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc) 5921 { 5922 /* Operand register numbers. */ 5923 int nRdHi, nRdLo, nRs, nRm; 5924 ARMword RdHi = 0, RdLo = 0, Rm; 5925 /* Cycle count. */ 5926 int scount; 5927 5928 nRdHi = BITS (16, 19); 5929 nRdLo = BITS (12, 15); 5930 nRs = BITS (8, 11); 5931 nRm = BITS (0, 3); 5932 5933 /* Needed to calculate the cycle count. */ 5934 Rm = state->Reg[nRm]; 5935 5936 /* Check for illegal operand combinations first. */ 5937 if ( nRdHi != 15 5938 && nRdLo != 15 5939 && nRs != 15 5940 && nRm != 15 5941 && nRdHi != nRdLo) 5942 { 5943 /* Intermediate results. */ 5944 ARMword lo, mid1, mid2, hi; 5945 int carry; 5946 ARMword Rs = state->Reg[nRs]; 5947 int sign = 0; 5948 5949 #ifdef MODE32 5950 if (state->is_v6) 5951 ; 5952 else 5953 #endif 5954 if (nRdHi == nRm || nRdLo == nRm) 5955 fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS: %d %d %d\n", 5956 nRdHi, nRdLo, nRm); 5957 5958 if (msigned) 5959 { 5960 /* Compute sign of result and adjust operands if necessary. */ 5961 sign = (Rm ^ Rs) & 0x80000000; 5962 5963 if (((ARMsword) Rm) < 0) 5964 Rm = -Rm; 5965 5966 if (((ARMsword) Rs) < 0) 5967 Rs = -Rs; 5968 } 5969 5970 /* We can split the 32x32 into four 16x16 operations. This 5971 ensures that we do not lose precision on 32bit only hosts. */ 5972 lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF)); 5973 mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF)); 5974 mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF)); 5975 hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF)); 5976 5977 /* We now need to add all of these results together, taking 5978 care to propogate the carries from the additions. */ 5979 RdLo = Add32 (lo, (mid1 << 16), &carry); 5980 RdHi = carry; 5981 RdLo = Add32 (RdLo, (mid2 << 16), &carry); 5982 RdHi += 5983 (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi); 5984 5985 if (sign) 5986 { 5987 /* Negate result if necessary. */ 5988 RdLo = ~RdLo; 5989 RdHi = ~RdHi; 5990 if (RdLo == 0xFFFFFFFF) 5991 { 5992 RdLo = 0; 5993 RdHi += 1; 5994 } 5995 else 5996 RdLo += 1; 5997 } 5998 5999 state->Reg[nRdLo] = RdLo; 6000 state->Reg[nRdHi] = RdHi; 6001 } 6002 else 6003 fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS\n"); 6004 6005 if (scc) 6006 /* Ensure that both RdHi and RdLo are used to compute Z, 6007 but don't let RdLo's sign bit make it to N. */ 6008 ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF)); 6009 6010 /* The cycle count depends on whether the instruction is a signed or 6011 unsigned multiply, and what bits are clear in the multiplier. */ 6012 if (msigned && (Rm & ((unsigned) 1 << 31))) 6013 /* Invert the bits to make the check against zero. */ 6014 Rm = ~Rm; 6015 6016 if ((Rm & 0xFFFFFF00) == 0) 6017 scount = 1; 6018 else if ((Rm & 0xFFFF0000) == 0) 6019 scount = 2; 6020 else if ((Rm & 0xFF000000) == 0) 6021 scount = 3; 6022 else 6023 scount = 4; 6024 6025 return 2 + scount; 6026 } 6027 6028 /* This function does the work of multiplying two 32bit 6029 values and adding a 64bit value to give a 64bit result. */ 6030 6031 static unsigned 6032 MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc) 6033 { 6034 unsigned scount; 6035 ARMword RdLo, RdHi; 6036 int nRdHi, nRdLo; 6037 int carry = 0; 6038 6039 nRdHi = BITS (16, 19); 6040 nRdLo = BITS (12, 15); 6041 6042 RdHi = state->Reg[nRdHi]; 6043 RdLo = state->Reg[nRdLo]; 6044 6045 scount = Multiply64 (state, instr, msigned, LDEFAULT); 6046 6047 RdLo = Add32 (RdLo, state->Reg[nRdLo], &carry); 6048 RdHi = (RdHi + state->Reg[nRdHi]) + carry; 6049 6050 state->Reg[nRdLo] = RdLo; 6051 state->Reg[nRdHi] = RdHi; 6052 6053 if (scc) 6054 /* Ensure that both RdHi and RdLo are used to compute Z, 6055 but don't let RdLo's sign bit make it to N. */ 6056 ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF)); 6057 6058 /* Extra cycle for addition. */ 6059 return scount + 1; 6060 } 6061