1 /* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator. 2 Copyright (C) 1994 Advanced RISC Machines Ltd. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, see <http://www.gnu.org/licenses/>. */ 16 17 #include "armdefs.h" 18 #include "armemu.h" 19 #include "ansidecl.h" 20 #include "libiberty.h" 21 #include <math.h> 22 23 /* Definitions for the support routines. */ 24 25 static ARMword ModeToBank (ARMword); 26 static void EnvokeList (ARMul_State *, unsigned long, unsigned long); 27 28 struct EventNode 29 { /* An event list node. */ 30 unsigned (*func) (ARMul_State *); /* The function to call. */ 31 struct EventNode *next; 32 }; 33 34 /* This routine returns the value of a register from a mode. */ 35 36 ARMword 37 ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg) 38 { 39 mode &= MODEBITS; 40 if (mode != state->Mode) 41 return (state->RegBank[ModeToBank ((ARMword) mode)][reg]); 42 else 43 return (state->Reg[reg]); 44 } 45 46 /* This routine sets the value of a register for a mode. */ 47 48 void 49 ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value) 50 { 51 mode &= MODEBITS; 52 if (mode != state->Mode) 53 state->RegBank[ModeToBank ((ARMword) mode)][reg] = value; 54 else 55 state->Reg[reg] = value; 56 } 57 58 /* This routine returns the value of the PC, mode independently. */ 59 60 ARMword 61 ARMul_GetPC (ARMul_State * state) 62 { 63 if (state->Mode > SVC26MODE) 64 return state->Reg[15]; 65 else 66 return R15PC; 67 } 68 69 /* This routine returns the value of the PC, mode independently. */ 70 71 ARMword 72 ARMul_GetNextPC (ARMul_State * state) 73 { 74 if (state->Mode > SVC26MODE) 75 return state->Reg[15] + isize; 76 else 77 return (state->Reg[15] + isize) & R15PCBITS; 78 } 79 80 /* This routine sets the value of the PC. */ 81 82 void 83 ARMul_SetPC (ARMul_State * state, ARMword value) 84 { 85 if (ARMul_MODE32BIT) 86 state->Reg[15] = value & PCBITS; 87 else 88 state->Reg[15] = R15CCINTMODE | (value & R15PCBITS); 89 FLUSHPIPE; 90 } 91 92 /* This routine returns the value of register 15, mode independently. */ 93 94 ARMword 95 ARMul_GetR15 (ARMul_State * state) 96 { 97 if (state->Mode > SVC26MODE) 98 return (state->Reg[15]); 99 else 100 return (R15PC | ECC | ER15INT | EMODE); 101 } 102 103 /* This routine sets the value of Register 15. */ 104 105 void 106 ARMul_SetR15 (ARMul_State * state, ARMword value) 107 { 108 if (ARMul_MODE32BIT) 109 state->Reg[15] = value & PCBITS; 110 else 111 { 112 state->Reg[15] = value; 113 ARMul_R15Altered (state); 114 } 115 FLUSHPIPE; 116 } 117 118 /* This routine returns the value of the CPSR. */ 119 120 ARMword 121 ARMul_GetCPSR (ARMul_State * state) 122 { 123 return (CPSR | state->Cpsr); 124 } 125 126 /* This routine sets the value of the CPSR. */ 127 128 void 129 ARMul_SetCPSR (ARMul_State * state, ARMword value) 130 { 131 state->Cpsr = value; 132 ARMul_CPSRAltered (state); 133 } 134 135 /* This routine does all the nasty bits involved in a write to the CPSR, 136 including updating the register bank, given a MSR instruction. */ 137 138 void 139 ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs) 140 { 141 state->Cpsr = ARMul_GetCPSR (state); 142 143 if (state->Mode != USER26MODE 144 && state->Mode != USER32MODE) 145 { 146 /* In user mode, only write flags. */ 147 if (BIT (16)) 148 SETPSR_C (state->Cpsr, rhs); 149 if (BIT (17)) 150 SETPSR_X (state->Cpsr, rhs); 151 if (BIT (18)) 152 SETPSR_S (state->Cpsr, rhs); 153 } 154 if (BIT (19)) 155 SETPSR_F (state->Cpsr, rhs); 156 ARMul_CPSRAltered (state); 157 } 158 159 /* Get an SPSR from the specified mode. */ 160 161 ARMword 162 ARMul_GetSPSR (ARMul_State * state, ARMword mode) 163 { 164 ARMword bank = ModeToBank (mode & MODEBITS); 165 166 if (! BANK_CAN_ACCESS_SPSR (bank)) 167 return ARMul_GetCPSR (state); 168 169 return state->Spsr[bank]; 170 } 171 172 /* This routine does a write to an SPSR. */ 173 174 void 175 ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value) 176 { 177 ARMword bank = ModeToBank (mode & MODEBITS); 178 179 if (BANK_CAN_ACCESS_SPSR (bank)) 180 state->Spsr[bank] = value; 181 } 182 183 /* This routine does a write to the current SPSR, given an MSR instruction. */ 184 185 void 186 ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs) 187 { 188 if (BANK_CAN_ACCESS_SPSR (state->Bank)) 189 { 190 if (BIT (16)) 191 SETPSR_C (state->Spsr[state->Bank], rhs); 192 if (BIT (17)) 193 SETPSR_X (state->Spsr[state->Bank], rhs); 194 if (BIT (18)) 195 SETPSR_S (state->Spsr[state->Bank], rhs); 196 if (BIT (19)) 197 SETPSR_F (state->Spsr[state->Bank], rhs); 198 } 199 } 200 201 /* This routine updates the state of the emulator after the Cpsr has been 202 changed. Both the processor flags and register bank are updated. */ 203 204 void 205 ARMul_CPSRAltered (ARMul_State * state) 206 { 207 ARMword oldmode; 208 209 if (state->prog32Sig == LOW) 210 state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS); 211 212 oldmode = state->Mode; 213 214 if (state->Mode != (state->Cpsr & MODEBITS)) 215 { 216 state->Mode = 217 ARMul_SwitchMode (state, state->Mode, state->Cpsr & MODEBITS); 218 219 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 220 } 221 state->Cpsr &= ~MODEBITS; 222 223 ASSIGNINT (state->Cpsr & INTBITS); 224 state->Cpsr &= ~INTBITS; 225 ASSIGNN ((state->Cpsr & NBIT) != 0); 226 state->Cpsr &= ~NBIT; 227 ASSIGNZ ((state->Cpsr & ZBIT) != 0); 228 state->Cpsr &= ~ZBIT; 229 ASSIGNC ((state->Cpsr & CBIT) != 0); 230 state->Cpsr &= ~CBIT; 231 ASSIGNV ((state->Cpsr & VBIT) != 0); 232 state->Cpsr &= ~VBIT; 233 ASSIGNS ((state->Cpsr & SBIT) != 0); 234 state->Cpsr &= ~SBIT; 235 #ifdef MODET 236 ASSIGNT ((state->Cpsr & TBIT) != 0); 237 state->Cpsr &= ~TBIT; 238 #endif 239 240 if (oldmode > SVC26MODE) 241 { 242 if (state->Mode <= SVC26MODE) 243 { 244 state->Emulate = CHANGEMODE; 245 state->Reg[15] = ECC | ER15INT | EMODE | R15PC; 246 } 247 } 248 else 249 { 250 if (state->Mode > SVC26MODE) 251 { 252 state->Emulate = CHANGEMODE; 253 state->Reg[15] = R15PC; 254 } 255 else 256 state->Reg[15] = ECC | ER15INT | EMODE | R15PC; 257 } 258 } 259 260 /* This routine updates the state of the emulator after register 15 has 261 been changed. Both the processor flags and register bank are updated. 262 This routine should only be called from a 26 bit mode. */ 263 264 void 265 ARMul_R15Altered (ARMul_State * state) 266 { 267 if (state->Mode != R15MODE) 268 { 269 state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE); 270 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 271 } 272 273 if (state->Mode > SVC26MODE) 274 state->Emulate = CHANGEMODE; 275 276 ASSIGNR15INT (R15INT); 277 278 ASSIGNN ((state->Reg[15] & NBIT) != 0); 279 ASSIGNZ ((state->Reg[15] & ZBIT) != 0); 280 ASSIGNC ((state->Reg[15] & CBIT) != 0); 281 ASSIGNV ((state->Reg[15] & VBIT) != 0); 282 } 283 284 /* This routine controls the saving and restoring of registers across mode 285 changes. The regbank matrix is largely unused, only rows 13 and 14 are 286 used across all modes, 8 to 14 are used for FIQ, all others use the USER 287 column. It's easier this way. old and new parameter are modes numbers. 288 Notice the side effect of changing the Bank variable. */ 289 290 ARMword 291 ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode) 292 { 293 unsigned i; 294 ARMword oldbank; 295 ARMword newbank; 296 297 oldbank = ModeToBank (oldmode); 298 newbank = state->Bank = ModeToBank (newmode); 299 300 /* Do we really need to do it? */ 301 if (oldbank != newbank) 302 { 303 /* Save away the old registers. */ 304 switch (oldbank) 305 { 306 case USERBANK: 307 case IRQBANK: 308 case SVCBANK: 309 case ABORTBANK: 310 case UNDEFBANK: 311 if (newbank == FIQBANK) 312 for (i = 8; i < 13; i++) 313 state->RegBank[USERBANK][i] = state->Reg[i]; 314 state->RegBank[oldbank][13] = state->Reg[13]; 315 state->RegBank[oldbank][14] = state->Reg[14]; 316 break; 317 case FIQBANK: 318 for (i = 8; i < 15; i++) 319 state->RegBank[FIQBANK][i] = state->Reg[i]; 320 break; 321 case DUMMYBANK: 322 for (i = 8; i < 15; i++) 323 state->RegBank[DUMMYBANK][i] = 0; 324 break; 325 default: 326 abort (); 327 } 328 329 /* Restore the new registers. */ 330 switch (newbank) 331 { 332 case USERBANK: 333 case IRQBANK: 334 case SVCBANK: 335 case ABORTBANK: 336 case UNDEFBANK: 337 if (oldbank == FIQBANK) 338 for (i = 8; i < 13; i++) 339 state->Reg[i] = state->RegBank[USERBANK][i]; 340 state->Reg[13] = state->RegBank[newbank][13]; 341 state->Reg[14] = state->RegBank[newbank][14]; 342 break; 343 case FIQBANK: 344 for (i = 8; i < 15; i++) 345 state->Reg[i] = state->RegBank[FIQBANK][i]; 346 break; 347 case DUMMYBANK: 348 for (i = 8; i < 15; i++) 349 state->Reg[i] = 0; 350 break; 351 default: 352 abort (); 353 } 354 } 355 356 return newmode; 357 } 358 359 /* Given a processor mode, this routine returns the 360 register bank that will be accessed in that mode. */ 361 362 static ARMword 363 ModeToBank (ARMword mode) 364 { 365 static ARMword bankofmode[] = 366 { 367 USERBANK, FIQBANK, IRQBANK, SVCBANK, 368 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, 369 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, 370 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, 371 USERBANK, FIQBANK, IRQBANK, SVCBANK, 372 DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK, 373 DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK, 374 DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK 375 }; 376 377 if (mode >= ARRAY_SIZE (bankofmode)) 378 return DUMMYBANK; 379 380 return bankofmode[mode]; 381 } 382 383 /* Returns the register number of the nth register in a reg list. */ 384 385 unsigned 386 ARMul_NthReg (ARMword instr, unsigned number) 387 { 388 unsigned bit, upto; 389 390 for (bit = 0, upto = 0; upto <= number; bit ++) 391 if (BIT (bit)) 392 upto ++; 393 394 return (bit - 1); 395 } 396 397 /* Assigns the N and Z flags depending on the value of result. */ 398 399 void 400 ARMul_NegZero (ARMul_State * state, ARMword result) 401 { 402 if (NEG (result)) 403 { 404 SETN; 405 CLEARZ; 406 } 407 else if (result == 0) 408 { 409 CLEARN; 410 SETZ; 411 } 412 else 413 { 414 CLEARN; 415 CLEARZ; 416 } 417 } 418 419 /* Compute whether an addition of A and B, giving RESULT, overflowed. */ 420 421 int 422 AddOverflow (ARMword a, ARMword b, ARMword result) 423 { 424 return ((NEG (a) && NEG (b) && POS (result)) 425 || (POS (a) && POS (b) && NEG (result))); 426 } 427 428 /* Compute whether a subtraction of A and B, giving RESULT, overflowed. */ 429 430 int 431 SubOverflow (ARMword a, ARMword b, ARMword result) 432 { 433 return ((NEG (a) && POS (b) && POS (result)) 434 || (POS (a) && NEG (b) && NEG (result))); 435 } 436 437 /* Assigns the C flag after an addition of a and b to give result. */ 438 439 void 440 ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result) 441 { 442 ASSIGNC ((NEG (a) && NEG (b)) || 443 (NEG (a) && POS (result)) || (NEG (b) && POS (result))); 444 } 445 446 /* Assigns the V flag after an addition of a and b to give result. */ 447 448 void 449 ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) 450 { 451 ASSIGNV (AddOverflow (a, b, result)); 452 } 453 454 /* Assigns the C flag after an subtraction of a and b to give result. */ 455 456 void 457 ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result) 458 { 459 ASSIGNC ((NEG (a) && POS (b)) || 460 (NEG (a) && POS (result)) || (POS (b) && POS (result))); 461 } 462 463 /* Assigns the V flag after an subtraction of a and b to give result. */ 464 465 void 466 ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) 467 { 468 ASSIGNV (SubOverflow (a, b, result)); 469 } 470 471 static void 472 handle_VFP_xfer (ARMul_State * state, ARMword instr) 473 { 474 if (TOPBITS (28) == NV) 475 { 476 fprintf (stderr, "SIM: UNDEFINED VFP instruction\n"); 477 return; 478 } 479 480 if (BITS (25, 27) != 0x6) 481 { 482 fprintf (stderr, "SIM: ISE: VFP handler called incorrectly\n"); 483 return; 484 } 485 486 switch (BITS (20, 24)) 487 { 488 case 0x04: 489 case 0x05: 490 { 491 /* VMOV double precision to/from two ARM registers. */ 492 int vm = BITS (0, 3); 493 int rt1 = BITS (12, 15); 494 int rt2 = BITS (16, 19); 495 496 /* FIXME: UNPREDICTABLE if rt1 == 15 or rt2 == 15. */ 497 if (BIT (20)) 498 { 499 /* Transfer to ARM. */ 500 /* FIXME: UPPREDICTABLE if rt1 == rt2. */ 501 state->Reg[rt1] = VFP_dword (vm) & 0xffffffff; 502 state->Reg[rt2] = VFP_dword (vm) >> 32; 503 } 504 else 505 { 506 VFP_dword (vm) = state->Reg[rt2]; 507 VFP_dword (vm) <<= 32; 508 VFP_dword (vm) |= (state->Reg[rt1] & 0xffffffff); 509 } 510 return; 511 } 512 513 case 0x08: 514 case 0x0A: 515 case 0x0C: 516 case 0x0E: 517 { 518 /* VSTM with PUW=011 or PUW=010. */ 519 int n = BITS (16, 19); 520 int imm8 = BITS (0, 7); 521 522 ARMword address = state->Reg[n]; 523 if (BIT (21)) 524 state->Reg[n] = address + (imm8 << 2); 525 526 if (BIT (8)) 527 { 528 int src = (BIT (22) << 4) | BITS (12, 15); 529 imm8 >>= 1; 530 while (imm8--) 531 { 532 if (state->bigendSig) 533 { 534 ARMul_StoreWordN (state, address, VFP_dword (src) >> 32); 535 ARMul_StoreWordN (state, address + 4, VFP_dword (src)); 536 } 537 else 538 { 539 ARMul_StoreWordN (state, address, VFP_dword (src)); 540 ARMul_StoreWordN (state, address + 4, VFP_dword (src) >> 32); 541 } 542 address += 8; 543 src += 1; 544 } 545 } 546 else 547 { 548 int src = (BITS (12, 15) << 1) | BIT (22); 549 while (imm8--) 550 { 551 ARMul_StoreWordN (state, address, VFP_uword (src)); 552 address += 4; 553 src += 1; 554 } 555 } 556 } 557 return; 558 559 case 0x10: 560 case 0x14: 561 case 0x18: 562 case 0x1C: 563 { 564 /* VSTR */ 565 ARMword imm32 = BITS (0, 7) << 2; 566 int base = state->Reg[LHSReg]; 567 ARMword address; 568 int dest; 569 570 if (LHSReg == 15) 571 base = (base + 3) & ~3; 572 573 address = base + (BIT (23) ? imm32 : - imm32); 574 575 if (CPNum == 10) 576 { 577 dest = (DESTReg << 1) + BIT (22); 578 579 ARMul_StoreWordN (state, address, VFP_uword (dest)); 580 } 581 else 582 { 583 dest = (BIT (22) << 4) + DESTReg; 584 585 if (state->bigendSig) 586 { 587 ARMul_StoreWordN (state, address, VFP_dword (dest) >> 32); 588 ARMul_StoreWordN (state, address + 4, VFP_dword (dest)); 589 } 590 else 591 { 592 ARMul_StoreWordN (state, address, VFP_dword (dest)); 593 ARMul_StoreWordN (state, address + 4, VFP_dword (dest) >> 32); 594 } 595 } 596 } 597 return; 598 599 case 0x12: 600 case 0x16: 601 if (BITS (16, 19) == 13) 602 { 603 /* VPUSH */ 604 ARMword address = state->Reg[13] - (BITS (0, 7) << 2); 605 state->Reg[13] = address; 606 607 if (BIT (8)) 608 { 609 int dreg = (BIT (22) << 4) | BITS (12, 15); 610 int num = BITS (0, 7) >> 1; 611 while (num--) 612 { 613 if (state->bigendSig) 614 { 615 ARMul_StoreWordN (state, address, VFP_dword (dreg) >> 32); 616 ARMul_StoreWordN (state, address + 4, VFP_dword (dreg)); 617 } 618 else 619 { 620 ARMul_StoreWordN (state, address, VFP_dword (dreg)); 621 ARMul_StoreWordN (state, address + 4, VFP_dword (dreg) >> 32); 622 } 623 address += 8; 624 dreg += 1; 625 } 626 } 627 else 628 { 629 int sreg = (BITS (12, 15) << 1) | BIT (22); 630 int num = BITS (0, 7); 631 while (num--) 632 { 633 ARMul_StoreWordN (state, address, VFP_uword (sreg)); 634 address += 4; 635 sreg += 1; 636 } 637 } 638 } 639 else if (BITS (9, 11) != 0x5) 640 break; 641 else 642 { 643 /* VSTM PUW=101 */ 644 int n = BITS (16, 19); 645 int imm8 = BITS (0, 7); 646 ARMword address = state->Reg[n] - (imm8 << 2); 647 state->Reg[n] = address; 648 649 if (BIT (8)) 650 { 651 int src = (BIT (22) << 4) | BITS (12, 15); 652 653 imm8 >>= 1; 654 while (imm8--) 655 { 656 if (state->bigendSig) 657 { 658 ARMul_StoreWordN (state, address, VFP_dword (src) >> 32); 659 ARMul_StoreWordN (state, address + 4, VFP_dword (src)); 660 } 661 else 662 { 663 ARMul_StoreWordN (state, address, VFP_dword (src)); 664 ARMul_StoreWordN (state, address + 4, VFP_dword (src) >> 32); 665 } 666 address += 8; 667 src += 1; 668 } 669 } 670 else 671 { 672 int src = (BITS (12, 15) << 1) | BIT (22); 673 674 while (imm8--) 675 { 676 ARMul_StoreWordN (state, address, VFP_uword (src)); 677 address += 4; 678 src += 1; 679 } 680 } 681 } 682 return; 683 684 case 0x13: 685 case 0x17: 686 /* VLDM PUW=101 */ 687 case 0x09: 688 case 0x0D: 689 /* VLDM PUW=010 */ 690 { 691 int n = BITS (16, 19); 692 int imm8 = BITS (0, 7); 693 694 ARMword address = state->Reg[n]; 695 if (BIT (23) == 0) 696 address -= imm8 << 2; 697 if (BIT (21)) 698 state->Reg[n] = BIT (23) ? address + (imm8 << 2) : address; 699 700 if (BIT (8)) 701 { 702 int dest = (BIT (22) << 4) | BITS (12, 15); 703 imm8 >>= 1; 704 while (imm8--) 705 { 706 if (state->bigendSig) 707 { 708 VFP_dword (dest) = ARMul_LoadWordN (state, address); 709 VFP_dword (dest) <<= 32; 710 VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4); 711 } 712 else 713 { 714 VFP_dword (dest) = ARMul_LoadWordN (state, address + 4); 715 VFP_dword (dest) <<= 32; 716 VFP_dword (dest) |= ARMul_LoadWordN (state, address); 717 } 718 719 if (trace) 720 fprintf (stderr, " VFP: VLDM: D%d = %g\n", dest, VFP_dval (dest)); 721 722 address += 8; 723 dest += 1; 724 } 725 } 726 else 727 { 728 int dest = (BITS (12, 15) << 1) | BIT (22); 729 730 while (imm8--) 731 { 732 VFP_uword (dest) = ARMul_LoadWordN (state, address); 733 address += 4; 734 dest += 1; 735 } 736 } 737 } 738 return; 739 740 case 0x0B: 741 case 0x0F: 742 if (BITS (16, 19) == 13) 743 { 744 /* VPOP */ 745 ARMword address = state->Reg[13]; 746 state->Reg[13] = address + (BITS (0, 7) << 2); 747 748 if (BIT (8)) 749 { 750 int dest = (BIT (22) << 4) | BITS (12, 15); 751 int num = BITS (0, 7) >> 1; 752 753 while (num--) 754 { 755 if (state->bigendSig) 756 { 757 VFP_dword (dest) = ARMul_LoadWordN (state, address); 758 VFP_dword (dest) <<= 32; 759 VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4); 760 } 761 else 762 { 763 VFP_dword (dest) = ARMul_LoadWordN (state, address + 4); 764 VFP_dword (dest) <<= 32; 765 VFP_dword (dest) |= ARMul_LoadWordN (state, address); 766 } 767 768 if (trace) 769 fprintf (stderr, " VFP: VPOP: D%d = %g\n", dest, VFP_dval (dest)); 770 771 address += 8; 772 dest += 1; 773 } 774 } 775 else 776 { 777 int sreg = (BITS (12, 15) << 1) | BIT (22); 778 int num = BITS (0, 7); 779 780 while (num--) 781 { 782 VFP_uword (sreg) = ARMul_LoadWordN (state, address); 783 address += 4; 784 sreg += 1; 785 } 786 } 787 } 788 else if (BITS (9, 11) != 0x5) 789 break; 790 else 791 { 792 /* VLDM PUW=011 */ 793 int n = BITS (16, 19); 794 int imm8 = BITS (0, 7); 795 ARMword address = state->Reg[n]; 796 state->Reg[n] += imm8 << 2; 797 798 if (BIT (8)) 799 { 800 int dest = (BIT (22) << 4) | BITS (12, 15); 801 802 imm8 >>= 1; 803 while (imm8--) 804 { 805 if (state->bigendSig) 806 { 807 VFP_dword (dest) = ARMul_LoadWordN (state, address); 808 VFP_dword (dest) <<= 32; 809 VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4); 810 } 811 else 812 { 813 VFP_dword (dest) = ARMul_LoadWordN (state, address + 4); 814 VFP_dword (dest) <<= 32; 815 VFP_dword (dest) |= ARMul_LoadWordN (state, address); 816 } 817 818 if (trace) 819 fprintf (stderr, " VFP: VLDM: D%d = %g\n", dest, VFP_dval (dest)); 820 821 address += 8; 822 dest += 1; 823 } 824 } 825 else 826 { 827 int dest = (BITS (12, 15) << 1) | BIT (22); 828 while (imm8--) 829 { 830 VFP_uword (dest) = ARMul_LoadWordN (state, address); 831 address += 4; 832 dest += 1; 833 } 834 } 835 } 836 return; 837 838 case 0x11: 839 case 0x15: 840 case 0x19: 841 case 0x1D: 842 { 843 /* VLDR */ 844 ARMword imm32 = BITS (0, 7) << 2; 845 int base = state->Reg[LHSReg]; 846 ARMword address; 847 int dest; 848 849 if (LHSReg == 15) 850 base = (base + 3) & ~3; 851 852 address = base + (BIT (23) ? imm32 : - imm32); 853 854 if (CPNum == 10) 855 { 856 dest = (DESTReg << 1) + BIT (22); 857 858 VFP_uword (dest) = ARMul_LoadWordN (state, address); 859 } 860 else 861 { 862 dest = (BIT (22) << 4) + DESTReg; 863 864 if (state->bigendSig) 865 { 866 VFP_dword (dest) = ARMul_LoadWordN (state, address); 867 VFP_dword (dest) <<= 32; 868 VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4); 869 } 870 else 871 { 872 VFP_dword (dest) = ARMul_LoadWordN (state, address + 4); 873 VFP_dword (dest) <<= 32; 874 VFP_dword (dest) |= ARMul_LoadWordN (state, address); 875 } 876 877 if (trace) 878 fprintf (stderr, " VFP: VLDR: D%d = %g\n", dest, VFP_dval (dest)); 879 } 880 } 881 return; 882 } 883 884 fprintf (stderr, "SIM: VFP: Unimplemented: %0x\n", BITS (20, 24)); 885 } 886 887 /* This function does the work of generating the addresses used in an 888 LDC instruction. The code here is always post-indexed, it's up to the 889 caller to get the input address correct and to handle base register 890 modification. It also handles the Busy-Waiting. */ 891 892 void 893 ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address) 894 { 895 unsigned cpab; 896 ARMword data; 897 898 if (CPNum == 10 || CPNum == 11) 899 { 900 handle_VFP_xfer (state, instr); 901 return; 902 } 903 904 UNDEF_LSCPCBaseWb; 905 906 if (! CP_ACCESS_ALLOWED (state, CPNum)) 907 { 908 ARMul_UndefInstr (state, instr); 909 return; 910 } 911 912 if (ADDREXCEPT (address)) 913 INTERNALABORT (address); 914 915 cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0); 916 while (cpab == ARMul_BUSY) 917 { 918 ARMul_Icycles (state, 1, 0); 919 920 if (IntPending (state)) 921 { 922 cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT, instr, 0); 923 return; 924 } 925 else 926 cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr, 0); 927 } 928 if (cpab == ARMul_CANT) 929 { 930 CPTAKEABORT; 931 return; 932 } 933 934 cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0); 935 data = ARMul_LoadWordN (state, address); 936 BUSUSEDINCPCN; 937 938 if (BIT (21)) 939 LSBase = state->Base; 940 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data); 941 942 while (cpab == ARMul_INC) 943 { 944 address += 4; 945 data = ARMul_LoadWordN (state, address); 946 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data); 947 } 948 949 if (state->abortSig || state->Aborted) 950 TAKEABORT; 951 } 952 953 /* This function does the work of generating the addresses used in an 954 STC instruction. The code here is always post-indexed, it's up to the 955 caller to get the input address correct and to handle base register 956 modification. It also handles the Busy-Waiting. */ 957 958 void 959 ARMul_STC (ARMul_State * state, ARMword instr, ARMword address) 960 { 961 unsigned cpab; 962 ARMword data; 963 964 if (CPNum == 10 || CPNum == 11) 965 { 966 handle_VFP_xfer (state, instr); 967 return; 968 } 969 970 UNDEF_LSCPCBaseWb; 971 972 if (! CP_ACCESS_ALLOWED (state, CPNum)) 973 { 974 ARMul_UndefInstr (state, instr); 975 return; 976 } 977 978 if (ADDREXCEPT (address) || VECTORACCESS (address)) 979 INTERNALABORT (address); 980 981 cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data); 982 while (cpab == ARMul_BUSY) 983 { 984 ARMul_Icycles (state, 1, 0); 985 if (IntPending (state)) 986 { 987 cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT, instr, 0); 988 return; 989 } 990 else 991 cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr, &data); 992 } 993 994 if (cpab == ARMul_CANT) 995 { 996 CPTAKEABORT; 997 return; 998 } 999 #ifndef MODE32 1000 if (ADDREXCEPT (address) || VECTORACCESS (address)) 1001 INTERNALABORT (address); 1002 #endif 1003 BUSUSEDINCPCN; 1004 if (BIT (21)) 1005 LSBase = state->Base; 1006 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data); 1007 ARMul_StoreWordN (state, address, data); 1008 1009 while (cpab == ARMul_INC) 1010 { 1011 address += 4; 1012 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data); 1013 ARMul_StoreWordN (state, address, data); 1014 } 1015 1016 if (state->abortSig || state->Aborted) 1017 TAKEABORT; 1018 } 1019 1020 /* This function does the Busy-Waiting for an MCR instruction. */ 1021 1022 void 1023 ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source) 1024 { 1025 unsigned cpab; 1026 1027 if (! CP_ACCESS_ALLOWED (state, CPNum)) 1028 { 1029 ARMul_UndefInstr (state, instr); 1030 return; 1031 } 1032 1033 cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source); 1034 1035 while (cpab == ARMul_BUSY) 1036 { 1037 ARMul_Icycles (state, 1, 0); 1038 1039 if (IntPending (state)) 1040 { 1041 cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, instr, 0); 1042 return; 1043 } 1044 else 1045 cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, source); 1046 } 1047 1048 if (cpab == ARMul_CANT) 1049 ARMul_Abort (state, ARMul_UndefinedInstrV); 1050 else 1051 { 1052 BUSUSEDINCPCN; 1053 ARMul_Ccycles (state, 1, 0); 1054 } 1055 } 1056 1057 /* This function does the Busy-Waiting for an MRC instruction. */ 1058 1059 ARMword 1060 ARMul_MRC (ARMul_State * state, ARMword instr) 1061 { 1062 unsigned cpab; 1063 ARMword result = 0; 1064 1065 if (! CP_ACCESS_ALLOWED (state, CPNum)) 1066 { 1067 ARMul_UndefInstr (state, instr); 1068 return result; 1069 } 1070 1071 cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result); 1072 while (cpab == ARMul_BUSY) 1073 { 1074 ARMul_Icycles (state, 1, 0); 1075 if (IntPending (state)) 1076 { 1077 cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT, instr, 0); 1078 return (0); 1079 } 1080 else 1081 cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr, &result); 1082 } 1083 if (cpab == ARMul_CANT) 1084 { 1085 ARMul_Abort (state, ARMul_UndefinedInstrV); 1086 /* Parent will destroy the flags otherwise. */ 1087 result = ECC; 1088 } 1089 else 1090 { 1091 BUSUSEDINCPCN; 1092 ARMul_Ccycles (state, 1, 0); 1093 ARMul_Icycles (state, 1, 0); 1094 } 1095 1096 return result; 1097 } 1098 1099 static void 1100 handle_VFP_op (ARMul_State * state, ARMword instr) 1101 { 1102 int dest; 1103 int srcN; 1104 int srcM; 1105 1106 if (BITS (9, 11) != 0x5 || BIT (4) != 0) 1107 { 1108 fprintf (stderr, "SIM: VFP: Unimplemented: Float op: %08x\n", BITS (0,31)); 1109 return; 1110 } 1111 1112 if (BIT (8)) 1113 { 1114 dest = BITS(12,15) + (BIT (22) << 4); 1115 srcN = LHSReg + (BIT (7) << 4); 1116 srcM = BITS (0,3) + (BIT (5) << 4); 1117 } 1118 else 1119 { 1120 dest = (BITS(12,15) << 1) + BIT (22); 1121 srcN = (LHSReg << 1) + BIT (7); 1122 srcM = (BITS (0,3) << 1) + BIT (5); 1123 } 1124 1125 switch (BITS (20, 27)) 1126 { 1127 case 0xE0: 1128 case 0xE4: 1129 /* VMLA VMLS */ 1130 if (BIT (8)) 1131 { 1132 ARMdval val = VFP_dval (srcN) * VFP_dval (srcM); 1133 1134 if (BIT (6)) 1135 { 1136 if (trace) 1137 fprintf (stderr, " VFP: VMLS: %g = %g - %g * %g\n", 1138 VFP_dval (dest) - val, 1139 VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM)); 1140 VFP_dval (dest) -= val; 1141 } 1142 else 1143 { 1144 if (trace) 1145 fprintf (stderr, " VFP: VMLA: %g = %g + %g * %g\n", 1146 VFP_dval (dest) + val, 1147 VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM)); 1148 VFP_dval (dest) += val; 1149 } 1150 } 1151 else 1152 { 1153 ARMfval val = VFP_fval (srcN) * VFP_fval (srcM); 1154 1155 if (BIT (6)) 1156 { 1157 if (trace) 1158 fprintf (stderr, " VFP: VMLS: %g = %g - %g * %g\n", 1159 VFP_fval (dest) - val, 1160 VFP_fval (dest), VFP_fval (srcN), VFP_fval (srcM)); 1161 VFP_fval (dest) -= val; 1162 } 1163 else 1164 { 1165 if (trace) 1166 fprintf (stderr, " VFP: VMLA: %g = %g + %g * %g\n", 1167 VFP_fval (dest) + val, 1168 VFP_fval (dest), VFP_fval (srcN), VFP_fval (srcM)); 1169 VFP_fval (dest) += val; 1170 } 1171 } 1172 return; 1173 1174 case 0xE1: 1175 case 0xE5: 1176 if (BIT (8)) 1177 { 1178 ARMdval product = VFP_dval (srcN) * VFP_dval (srcM); 1179 1180 if (BIT (6)) 1181 { 1182 /* VNMLA */ 1183 if (trace) 1184 fprintf (stderr, " VFP: VNMLA: %g = -(%g + (%g * %g))\n", 1185 -(VFP_dval (dest) + product), 1186 VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM)); 1187 VFP_dval (dest) = -(product + VFP_dval (dest)); 1188 } 1189 else 1190 { 1191 /* VNMLS */ 1192 if (trace) 1193 fprintf (stderr, " VFP: VNMLS: %g = -(%g + (%g * %g))\n", 1194 -(VFP_dval (dest) + product), 1195 VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM)); 1196 VFP_dval (dest) = product - VFP_dval (dest); 1197 } 1198 } 1199 else 1200 { 1201 ARMfval product = VFP_fval (srcN) * VFP_fval (srcM); 1202 1203 if (BIT (6)) 1204 /* VNMLA */ 1205 VFP_fval (dest) = -(product + VFP_fval (dest)); 1206 else 1207 /* VNMLS */ 1208 VFP_fval (dest) = product - VFP_fval (dest); 1209 } 1210 return; 1211 1212 case 0xE2: 1213 case 0xE6: 1214 if (BIT (8)) 1215 { 1216 ARMdval product = VFP_dval (srcN) * VFP_dval (srcM); 1217 1218 if (BIT (6)) 1219 { 1220 if (trace) 1221 fprintf (stderr, " VFP: VMUL: %g = %g * %g\n", 1222 - product, VFP_dval (srcN), VFP_dval (srcM)); 1223 /* VNMUL */ 1224 VFP_dval (dest) = - product; 1225 } 1226 else 1227 { 1228 if (trace) 1229 fprintf (stderr, " VFP: VMUL: %g = %g * %g\n", 1230 product, VFP_dval (srcN), VFP_dval (srcM)); 1231 /* VMUL */ 1232 VFP_dval (dest) = product; 1233 } 1234 } 1235 else 1236 { 1237 ARMfval product = VFP_fval (srcN) * VFP_fval (srcM); 1238 1239 if (BIT (6)) 1240 { 1241 if (trace) 1242 fprintf (stderr, " VFP: VNMUL: %g = %g * %g\n", 1243 - product, VFP_fval (srcN), VFP_fval (srcM)); 1244 1245 VFP_fval (dest) = - product; 1246 } 1247 else 1248 { 1249 if (trace) 1250 fprintf (stderr, " VFP: VMUL: %g = %g * %g\n", 1251 product, VFP_fval (srcN), VFP_fval (srcM)); 1252 1253 VFP_fval (dest) = product; 1254 } 1255 } 1256 return; 1257 1258 case 0xE3: 1259 case 0xE7: 1260 if (BIT (6) == 0) 1261 { 1262 /* VADD */ 1263 if (BIT(8)) 1264 { 1265 if (trace) 1266 fprintf (stderr, " VFP: VADD %g = %g + %g\n", 1267 VFP_dval (srcN) + VFP_dval (srcM), 1268 VFP_dval (srcN), 1269 VFP_dval (srcM)); 1270 VFP_dval (dest) = VFP_dval (srcN) + VFP_dval (srcM); 1271 } 1272 else 1273 VFP_fval (dest) = VFP_fval (srcN) + VFP_fval (srcM); 1274 1275 } 1276 else 1277 { 1278 /* VSUB */ 1279 if (BIT(8)) 1280 { 1281 if (trace) 1282 fprintf (stderr, " VFP: VSUB %g = %g - %g\n", 1283 VFP_dval (srcN) - VFP_dval (srcM), 1284 VFP_dval (srcN), 1285 VFP_dval (srcM)); 1286 VFP_dval (dest) = VFP_dval (srcN) - VFP_dval (srcM); 1287 } 1288 else 1289 VFP_fval (dest) = VFP_fval (srcN) - VFP_fval (srcM); 1290 } 1291 return; 1292 1293 case 0xE8: 1294 case 0xEC: 1295 if (BIT (6) == 1) 1296 break; 1297 1298 /* VDIV */ 1299 if (BIT (8)) 1300 { 1301 ARMdval res = VFP_dval (srcN) / VFP_dval (srcM); 1302 if (trace) 1303 fprintf (stderr, " VFP: VDIV (64bit): %g = %g / %g\n", 1304 res, VFP_dval (srcN), VFP_dval (srcM)); 1305 VFP_dval (dest) = res; 1306 } 1307 else 1308 { 1309 if (trace) 1310 fprintf (stderr, " VFP: VDIV: %g = %g / %g\n", 1311 VFP_fval (srcN) / VFP_fval (srcM), 1312 VFP_fval (srcN), VFP_fval (srcM)); 1313 1314 VFP_fval (dest) = VFP_fval (srcN) / VFP_fval (srcM); 1315 } 1316 return; 1317 1318 case 0xEB: 1319 case 0xEF: 1320 if (BIT (6) != 1) 1321 break; 1322 1323 switch (BITS (16, 19)) 1324 { 1325 case 0x0: 1326 if (BIT (7) == 0) 1327 { 1328 if (BIT (8)) 1329 { 1330 /* VMOV.F64 <Dd>, <Dm>. */ 1331 VFP_dval (dest) = VFP_dval (srcM); 1332 if (trace) 1333 fprintf (stderr, " VFP: VMOV d%d, d%d: %g\n", dest, srcM, VFP_dval (srcM)); 1334 } 1335 else 1336 { 1337 /* VMOV.F32 <Sd>, <Sm>. */ 1338 VFP_fval (dest) = VFP_fval (srcM); 1339 if (trace) 1340 fprintf (stderr, " VFP: VMOV s%d, s%d: %g\n", dest, srcM, VFP_fval (srcM)); 1341 } 1342 } 1343 else 1344 { 1345 /* VABS */ 1346 if (BIT (8)) 1347 { 1348 ARMdval src = VFP_dval (srcM); 1349 1350 VFP_dval (dest) = fabs (src); 1351 if (trace) 1352 fprintf (stderr, " VFP: VABS (%g) = %g\n", src, VFP_dval (dest)); 1353 } 1354 else 1355 { 1356 ARMfval src = VFP_fval (srcM); 1357 1358 VFP_fval (dest) = fabsf (src); 1359 if (trace) 1360 fprintf (stderr, " VFP: VABS (%g) = %g\n", src, VFP_fval (dest)); 1361 } 1362 } 1363 return; 1364 1365 case 0x1: 1366 if (BIT (7) == 0) 1367 { 1368 /* VNEG */ 1369 if (BIT (8)) 1370 VFP_dval (dest) = - VFP_dval (srcM); 1371 else 1372 VFP_fval (dest) = - VFP_fval (srcM); 1373 } 1374 else 1375 { 1376 /* VSQRT */ 1377 if (BIT (8)) 1378 { 1379 if (trace) 1380 fprintf (stderr, " VFP: %g = root(%g)\n", 1381 sqrt (VFP_dval (srcM)), VFP_dval (srcM)); 1382 1383 VFP_dval (dest) = sqrt (VFP_dval (srcM)); 1384 } 1385 else 1386 { 1387 if (trace) 1388 fprintf (stderr, " VFP: %g = root(%g)\n", 1389 sqrtf (VFP_fval (srcM)), VFP_fval (srcM)); 1390 1391 VFP_fval (dest) = sqrtf (VFP_fval (srcM)); 1392 } 1393 } 1394 return; 1395 1396 case 0x4: 1397 case 0x5: 1398 /* VCMP, VCMPE */ 1399 if (BIT(8)) 1400 { 1401 ARMdval res = VFP_dval (dest); 1402 1403 if (BIT (16) == 0) 1404 { 1405 ARMdval src = VFP_dval (srcM); 1406 1407 if (isinf (res) && isinf (src)) 1408 { 1409 if (res > 0.0 && src > 0.0) 1410 res = 0.0; 1411 else if (res < 0.0 && src < 0.0) 1412 res = 0.0; 1413 /* else leave res alone. */ 1414 } 1415 else 1416 res -= src; 1417 } 1418 1419 /* FIXME: Add handling of signalling NaNs and the E bit. */ 1420 1421 state->FPSCR &= 0x0FFFFFFF; 1422 if (res < 0.0) 1423 state->FPSCR |= NBIT; 1424 else 1425 state->FPSCR |= CBIT; 1426 if (res == 0.0) 1427 state->FPSCR |= ZBIT; 1428 if (isnan (res)) 1429 state->FPSCR |= VBIT; 1430 1431 if (trace) 1432 fprintf (stderr, " VFP: VCMP (64bit) %g vs %g res %g, flags: %c%c%c%c\n", 1433 VFP_dval (dest), BIT (16) ? 0.0 : VFP_dval (srcM), res, 1434 state->FPSCR & NBIT ? 'N' : '-', 1435 state->FPSCR & ZBIT ? 'Z' : '-', 1436 state->FPSCR & CBIT ? 'C' : '-', 1437 state->FPSCR & VBIT ? 'V' : '-'); 1438 } 1439 else 1440 { 1441 ARMfval res = VFP_fval (dest); 1442 1443 if (BIT (16) == 0) 1444 { 1445 ARMfval src = VFP_fval (srcM); 1446 1447 if (isinf (res) && isinf (src)) 1448 { 1449 if (res > 0.0 && src > 0.0) 1450 res = 0.0; 1451 else if (res < 0.0 && src < 0.0) 1452 res = 0.0; 1453 /* else leave res alone. */ 1454 } 1455 else 1456 res -= src; 1457 } 1458 1459 /* FIXME: Add handling of signalling NaNs and the E bit. */ 1460 1461 state->FPSCR &= 0x0FFFFFFF; 1462 if (res < 0.0) 1463 state->FPSCR |= NBIT; 1464 else 1465 state->FPSCR |= CBIT; 1466 if (res == 0.0) 1467 state->FPSCR |= ZBIT; 1468 if (isnan (res)) 1469 state->FPSCR |= VBIT; 1470 1471 if (trace) 1472 fprintf (stderr, " VFP: VCMP (32bit) %g vs %g res %g, flags: %c%c%c%c\n", 1473 VFP_fval (dest), BIT (16) ? 0.0 : VFP_fval (srcM), res, 1474 state->FPSCR & NBIT ? 'N' : '-', 1475 state->FPSCR & ZBIT ? 'Z' : '-', 1476 state->FPSCR & CBIT ? 'C' : '-', 1477 state->FPSCR & VBIT ? 'V' : '-'); 1478 } 1479 return; 1480 1481 case 0x7: 1482 if (BIT (8)) 1483 { 1484 dest = (DESTReg << 1) + BIT (22); 1485 VFP_fval (dest) = VFP_dval (srcM); 1486 } 1487 else 1488 { 1489 dest = DESTReg + (BIT (22) << 4); 1490 VFP_dval (dest) = VFP_fval (srcM); 1491 } 1492 return; 1493 1494 case 0x8: 1495 case 0xC: 1496 case 0xD: 1497 /* VCVT integer <-> FP */ 1498 if (BIT (18)) 1499 { 1500 /* To integer. */ 1501 if (BIT (8)) 1502 { 1503 dest = (BITS(12,15) << 1) + BIT (22); 1504 if (BIT (16)) 1505 VFP_sword (dest) = VFP_dval (srcM); 1506 else 1507 VFP_uword (dest) = VFP_dval (srcM); 1508 } 1509 else 1510 { 1511 if (BIT (16)) 1512 VFP_sword (dest) = VFP_fval (srcM); 1513 else 1514 VFP_uword (dest) = VFP_fval (srcM); 1515 } 1516 } 1517 else 1518 { 1519 /* From integer. */ 1520 if (BIT (8)) 1521 { 1522 srcM = (BITS (0,3) << 1) + BIT (5); 1523 if (BIT (7)) 1524 VFP_dval (dest) = VFP_sword (srcM); 1525 else 1526 VFP_dval (dest) = VFP_uword (srcM); 1527 } 1528 else 1529 { 1530 if (BIT (7)) 1531 VFP_fval (dest) = VFP_sword (srcM); 1532 else 1533 VFP_fval (dest) = VFP_uword (srcM); 1534 } 1535 } 1536 return; 1537 } 1538 1539 fprintf (stderr, "SIM: VFP: Unimplemented: Float op3: %03x\n", BITS (16,27)); 1540 return; 1541 } 1542 1543 fprintf (stderr, "SIM: VFP: Unimplemented: Float op2: %02x\n", BITS (20, 27)); 1544 return; 1545 } 1546 1547 /* This function does the Busy-Waiting for an CDP instruction. */ 1548 1549 void 1550 ARMul_CDP (ARMul_State * state, ARMword instr) 1551 { 1552 unsigned cpab; 1553 1554 if (CPNum == 10 || CPNum == 11) 1555 { 1556 handle_VFP_op (state, instr); 1557 return; 1558 } 1559 1560 if (! CP_ACCESS_ALLOWED (state, CPNum)) 1561 { 1562 ARMul_UndefInstr (state, instr); 1563 return; 1564 } 1565 1566 cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr); 1567 while (cpab == ARMul_BUSY) 1568 { 1569 ARMul_Icycles (state, 1, 0); 1570 if (IntPending (state)) 1571 { 1572 cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT, instr); 1573 return; 1574 } 1575 else 1576 cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr); 1577 } 1578 if (cpab == ARMul_CANT) 1579 ARMul_Abort (state, ARMul_UndefinedInstrV); 1580 else 1581 BUSUSEDN; 1582 } 1583 1584 /* This function handles Undefined instructions, as CP isntruction. */ 1585 1586 void 1587 ARMul_UndefInstr (ARMul_State * state, ARMword instr ATTRIBUTE_UNUSED) 1588 { 1589 ARMul_Abort (state, ARMul_UndefinedInstrV); 1590 } 1591 1592 /* Return TRUE if an interrupt is pending, FALSE otherwise. */ 1593 1594 unsigned 1595 IntPending (ARMul_State * state) 1596 { 1597 if (state->Exception) 1598 { 1599 /* Any exceptions. */ 1600 if (state->NresetSig == LOW) 1601 { 1602 ARMul_Abort (state, ARMul_ResetV); 1603 return TRUE; 1604 } 1605 else if (!state->NfiqSig && !FFLAG) 1606 { 1607 ARMul_Abort (state, ARMul_FIQV); 1608 return TRUE; 1609 } 1610 else if (!state->NirqSig && !IFLAG) 1611 { 1612 ARMul_Abort (state, ARMul_IRQV); 1613 return TRUE; 1614 } 1615 } 1616 1617 return FALSE; 1618 } 1619 1620 /* Align a word access to a non word boundary. */ 1621 1622 ARMword 1623 ARMul_Align (ARMul_State *state ATTRIBUTE_UNUSED, ARMword address, ARMword data) 1624 { 1625 /* This code assumes the address is really unaligned, 1626 as a shift by 32 is undefined in C. */ 1627 1628 address = (address & 3) << 3; /* Get the word address. */ 1629 return ((data >> address) | (data << (32 - address))); /* rot right */ 1630 } 1631 1632 /* This routine is used to call another routine after a certain number of 1633 cycles have been executed. The first parameter is the number of cycles 1634 delay before the function is called, the second argument is a pointer 1635 to the function. A delay of zero doesn't work, just call the function. */ 1636 1637 void 1638 ARMul_ScheduleEvent (ARMul_State * state, unsigned long delay, 1639 unsigned (*what) (ARMul_State *)) 1640 { 1641 unsigned long when; 1642 struct EventNode *event; 1643 1644 if (state->EventSet++ == 0) 1645 state->Now = ARMul_Time (state); 1646 when = (state->Now + delay) % EVENTLISTSIZE; 1647 event = (struct EventNode *) malloc (sizeof (struct EventNode)); 1648 event->func = what; 1649 event->next = *(state->EventPtr + when); 1650 *(state->EventPtr + when) = event; 1651 } 1652 1653 /* This routine is called at the beginning of 1654 every cycle, to envoke scheduled events. */ 1655 1656 void 1657 ARMul_EnvokeEvent (ARMul_State * state) 1658 { 1659 static unsigned long then; 1660 1661 then = state->Now; 1662 state->Now = ARMul_Time (state) % EVENTLISTSIZE; 1663 if (then < state->Now) 1664 /* Schedule events. */ 1665 EnvokeList (state, then, state->Now); 1666 else if (then > state->Now) 1667 { 1668 /* Need to wrap around the list. */ 1669 EnvokeList (state, then, EVENTLISTSIZE - 1L); 1670 EnvokeList (state, 0L, state->Now); 1671 } 1672 } 1673 1674 /* Envokes all the entries in a range. */ 1675 1676 static void 1677 EnvokeList (ARMul_State * state, unsigned long from, unsigned long to) 1678 { 1679 for (; from <= to; from++) 1680 { 1681 struct EventNode *anevent; 1682 1683 anevent = *(state->EventPtr + from); 1684 while (anevent) 1685 { 1686 (anevent->func) (state); 1687 state->EventSet--; 1688 anevent = anevent->next; 1689 } 1690 *(state->EventPtr + from) = NULL; 1691 } 1692 } 1693 1694 /* This routine is returns the number of clock ticks since the last reset. */ 1695 1696 unsigned long 1697 ARMul_Time (ARMul_State * state) 1698 { 1699 return (state->NumScycles + state->NumNcycles + 1700 state->NumIcycles + state->NumCcycles + state->NumFcycles); 1701 } 1702