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