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