types.hh revision 12732:c8b4f25eea9b
1/* 2 * Copyright (c) 2010, 2012-2013, 2017 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2007-2008 The Florida State University 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Stephen Hines 41 */ 42 43#ifndef __ARCH_ARM_TYPES_HH__ 44#define __ARCH_ARM_TYPES_HH__ 45 46#include "arch/generic/types.hh" 47#include "base/bitunion.hh" 48#include "base/logging.hh" 49#include "base/types.hh" 50#include "debug/Decoder.hh" 51 52namespace ArmISA 53{ 54 typedef uint32_t MachInst; 55 56 BitUnion8(ITSTATE) 57 /* Note that the split (cond, mask) below is not as in ARM ARM. 58 * But it is more convenient for simulation. The condition 59 * is always the concatenation of the top 3 bits and the next bit, 60 * which applies when one of the bottom 4 bits is set. 61 * Refer to predecoder.cc for the use case. 62 */ 63 Bitfield<7, 4> cond; 64 Bitfield<3, 0> mask; 65 // Bitfields for moving to/from CPSR 66 Bitfield<7, 2> top6; 67 Bitfield<1, 0> bottom2; 68 EndBitUnion(ITSTATE) 69 70 BitUnion64(ExtMachInst) 71 // Decoder state 72 Bitfield<63, 62> decoderFault; // See DecoderFault 73 74 // ITSTATE bits 75 Bitfield<55, 48> itstate; 76 Bitfield<55, 52> itstateCond; 77 Bitfield<51, 48> itstateMask; 78 79 // FPSCR fields 80 Bitfield<41, 40> fpscrStride; 81 Bitfield<39, 37> fpscrLen; 82 83 // Bitfields to select mode. 84 Bitfield<36> thumb; 85 Bitfield<35> bigThumb; 86 Bitfield<34> aarch64; 87 88 // Made up bitfields that make life easier. 89 Bitfield<33> sevenAndFour; 90 Bitfield<32> isMisc; 91 92 uint32_t instBits; 93 94 // All the different types of opcode fields. 95 Bitfield<27, 25> encoding; 96 Bitfield<25> useImm; 97 Bitfield<24, 21> opcode; 98 Bitfield<24, 20> mediaOpcode; 99 Bitfield<24> opcode24; 100 Bitfield<24, 23> opcode24_23; 101 Bitfield<23, 20> opcode23_20; 102 Bitfield<23, 21> opcode23_21; 103 Bitfield<20> opcode20; 104 Bitfield<22> opcode22; 105 Bitfield<19, 16> opcode19_16; 106 Bitfield<19> opcode19; 107 Bitfield<18> opcode18; 108 Bitfield<15, 12> opcode15_12; 109 Bitfield<15> opcode15; 110 Bitfield<7, 4> miscOpcode; 111 Bitfield<7,5> opc2; 112 Bitfield<7> opcode7; 113 Bitfield<6> opcode6; 114 Bitfield<4> opcode4; 115 116 Bitfield<31, 28> condCode; 117 Bitfield<20> sField; 118 Bitfield<19, 16> rn; 119 Bitfield<15, 12> rd; 120 Bitfield<15, 12> rt; 121 Bitfield<11, 7> shiftSize; 122 Bitfield<6, 5> shift; 123 Bitfield<3, 0> rm; 124 125 Bitfield<11, 8> rs; 126 127 SubBitUnion(puswl, 24, 20) 128 Bitfield<24> prepost; 129 Bitfield<23> up; 130 Bitfield<22> psruser; 131 Bitfield<21> writeback; 132 Bitfield<20> loadOp; 133 EndSubBitUnion(puswl) 134 135 Bitfield<24, 20> pubwl; 136 137 Bitfield<7, 0> imm; 138 139 Bitfield<11, 8> rotate; 140 141 Bitfield<11, 0> immed11_0; 142 Bitfield<7, 0> immed7_0; 143 144 Bitfield<11, 8> immedHi11_8; 145 Bitfield<3, 0> immedLo3_0; 146 147 Bitfield<15, 0> regList; 148 149 Bitfield<23, 0> offset; 150 151 Bitfield<23, 0> immed23_0; 152 153 Bitfield<11, 8> cpNum; 154 Bitfield<18, 16> fn; 155 Bitfield<14, 12> fd; 156 Bitfield<3> fpRegImm; 157 Bitfield<3, 0> fm; 158 Bitfield<2, 0> fpImm; 159 Bitfield<24, 20> punwl; 160 161 Bitfield<15, 8> m5Func; 162 163 // 16 bit thumb bitfields 164 Bitfield<15, 13> topcode15_13; 165 Bitfield<13, 11> topcode13_11; 166 Bitfield<12, 11> topcode12_11; 167 Bitfield<12, 10> topcode12_10; 168 Bitfield<11, 9> topcode11_9; 169 Bitfield<11, 8> topcode11_8; 170 Bitfield<10, 9> topcode10_9; 171 Bitfield<10, 8> topcode10_8; 172 Bitfield<9, 6> topcode9_6; 173 Bitfield<7> topcode7; 174 Bitfield<7, 6> topcode7_6; 175 Bitfield<7, 5> topcode7_5; 176 Bitfield<7, 4> topcode7_4; 177 Bitfield<3, 0> topcode3_0; 178 179 // 32 bit thumb bitfields 180 Bitfield<28, 27> htopcode12_11; 181 Bitfield<26, 25> htopcode10_9; 182 Bitfield<25> htopcode9; 183 Bitfield<25, 24> htopcode9_8; 184 Bitfield<25, 21> htopcode9_5; 185 Bitfield<25, 20> htopcode9_4; 186 Bitfield<24> htopcode8; 187 Bitfield<24, 23> htopcode8_7; 188 Bitfield<24, 22> htopcode8_6; 189 Bitfield<24, 21> htopcode8_5; 190 Bitfield<23> htopcode7; 191 Bitfield<23, 21> htopcode7_5; 192 Bitfield<22> htopcode6; 193 Bitfield<22, 21> htopcode6_5; 194 Bitfield<21, 20> htopcode5_4; 195 Bitfield<20> htopcode4; 196 197 Bitfield<19, 16> htrn; 198 Bitfield<20> hts; 199 200 Bitfield<15> ltopcode15; 201 Bitfield<11, 8> ltopcode11_8; 202 Bitfield<7, 6> ltopcode7_6; 203 Bitfield<7, 4> ltopcode7_4; 204 Bitfield<4> ltopcode4; 205 206 Bitfield<11, 8> ltrd; 207 Bitfield<11, 8> ltcoproc; 208 EndBitUnion(ExtMachInst) 209 210 class PCState : public GenericISA::UPCState<MachInst> 211 { 212 protected: 213 214 typedef GenericISA::UPCState<MachInst> Base; 215 216 enum FlagBits { 217 ThumbBit = (1 << 0), 218 JazelleBit = (1 << 1), 219 AArch64Bit = (1 << 2) 220 }; 221 uint8_t flags; 222 uint8_t nextFlags; 223 uint8_t _itstate; 224 uint8_t _nextItstate; 225 uint8_t _size; 226 public: 227 PCState() : flags(0), nextFlags(0), _itstate(0), _nextItstate(0), 228 _size(0) 229 {} 230 231 void 232 set(Addr val) 233 { 234 Base::set(val); 235 npc(val + (thumb() ? 2 : 4)); 236 } 237 238 PCState(Addr val) : flags(0), nextFlags(0), _itstate(0), 239 _nextItstate(0), _size(0) 240 { set(val); } 241 242 bool 243 thumb() const 244 { 245 return flags & ThumbBit; 246 } 247 248 void 249 thumb(bool val) 250 { 251 if (val) 252 flags |= ThumbBit; 253 else 254 flags &= ~ThumbBit; 255 } 256 257 bool 258 nextThumb() const 259 { 260 return nextFlags & ThumbBit; 261 } 262 263 void 264 nextThumb(bool val) 265 { 266 if (val) 267 nextFlags |= ThumbBit; 268 else 269 nextFlags &= ~ThumbBit; 270 } 271 272 void size(uint8_t s) { _size = s; } 273 uint8_t size() const { return _size; } 274 275 bool 276 branching() const 277 { 278 return ((this->pc() + this->size()) != this->npc()); 279 } 280 281 282 bool 283 jazelle() const 284 { 285 return flags & JazelleBit; 286 } 287 288 void 289 jazelle(bool val) 290 { 291 if (val) 292 flags |= JazelleBit; 293 else 294 flags &= ~JazelleBit; 295 } 296 297 bool 298 nextJazelle() const 299 { 300 return nextFlags & JazelleBit; 301 } 302 303 void 304 nextJazelle(bool val) 305 { 306 if (val) 307 nextFlags |= JazelleBit; 308 else 309 nextFlags &= ~JazelleBit; 310 } 311 312 bool 313 aarch64() const 314 { 315 return flags & AArch64Bit; 316 } 317 318 void 319 aarch64(bool val) 320 { 321 if (val) 322 flags |= AArch64Bit; 323 else 324 flags &= ~AArch64Bit; 325 } 326 327 bool 328 nextAArch64() const 329 { 330 return nextFlags & AArch64Bit; 331 } 332 333 void 334 nextAArch64(bool val) 335 { 336 if (val) 337 nextFlags |= AArch64Bit; 338 else 339 nextFlags &= ~AArch64Bit; 340 } 341 342 343 uint8_t 344 itstate() const 345 { 346 return _itstate; 347 } 348 349 void 350 itstate(uint8_t value) 351 { 352 _itstate = value; 353 } 354 355 uint8_t 356 nextItstate() const 357 { 358 return _nextItstate; 359 } 360 361 void 362 nextItstate(uint8_t value) 363 { 364 _nextItstate = value; 365 } 366 367 void 368 advance() 369 { 370 Base::advance(); 371 flags = nextFlags; 372 npc(pc() + (thumb() ? 2 : 4)); 373 374 if (_nextItstate) { 375 _itstate = _nextItstate; 376 _nextItstate = 0; 377 } else if (_itstate) { 378 ITSTATE it = _itstate; 379 uint8_t cond_mask = it.mask; 380 uint8_t thumb_cond = it.cond; 381 DPRINTF(Decoder, "Advancing ITSTATE from %#x,%#x.\n", 382 thumb_cond, cond_mask); 383 cond_mask <<= 1; 384 uint8_t new_bit = bits(cond_mask, 4); 385 cond_mask &= mask(4); 386 if (cond_mask == 0) 387 thumb_cond = 0; 388 else 389 replaceBits(thumb_cond, 0, new_bit); 390 DPRINTF(Decoder, "Advancing ITSTATE to %#x,%#x.\n", 391 thumb_cond, cond_mask); 392 it.mask = cond_mask; 393 it.cond = thumb_cond; 394 _itstate = it; 395 } 396 } 397 398 void 399 uEnd() 400 { 401 advance(); 402 upc(0); 403 nupc(1); 404 } 405 406 Addr 407 instPC() const 408 { 409 return pc() + (thumb() ? 4 : 8); 410 } 411 412 void 413 instNPC(Addr val) 414 { 415 // @todo: review this when AArch32/64 interprocessing is 416 // supported 417 if (aarch64()) 418 npc(val); // AArch64 doesn't force PC alignment, a PC 419 // Alignment Fault can be raised instead 420 else 421 npc(val &~ mask(nextThumb() ? 1 : 2)); 422 } 423 424 Addr 425 instNPC() const 426 { 427 return npc(); 428 } 429 430 // Perform an interworking branch. 431 void 432 instIWNPC(Addr val) 433 { 434 bool thumbEE = (thumb() && jazelle()); 435 436 Addr newPC = val; 437 if (thumbEE) { 438 if (bits(newPC, 0)) { 439 newPC = newPC & ~mask(1); 440 } // else we have a bad interworking address; do not call 441 // panic() since the instruction could be executed 442 // speculatively 443 } else { 444 if (bits(newPC, 0)) { 445 nextThumb(true); 446 newPC = newPC & ~mask(1); 447 } else if (!bits(newPC, 1)) { 448 nextThumb(false); 449 } else { 450 // This state is UNPREDICTABLE in the ARM architecture 451 // The easy thing to do is just mask off the bit and 452 // stay in the current mode, so we'll do that. 453 newPC &= ~mask(2); 454 } 455 } 456 npc(newPC); 457 } 458 459 // Perform an interworking branch in ARM mode, a regular branch 460 // otherwise. 461 void 462 instAIWNPC(Addr val) 463 { 464 if (!thumb() && !jazelle()) 465 instIWNPC(val); 466 else 467 instNPC(val); 468 } 469 470 bool 471 operator == (const PCState &opc) const 472 { 473 return Base::operator == (opc) && 474 flags == opc.flags && nextFlags == opc.nextFlags && 475 _itstate == opc._itstate && _nextItstate == opc._nextItstate; 476 } 477 478 bool 479 operator != (const PCState &opc) const 480 { 481 return !(*this == opc); 482 } 483 484 void 485 serialize(CheckpointOut &cp) const override 486 { 487 Base::serialize(cp); 488 SERIALIZE_SCALAR(flags); 489 SERIALIZE_SCALAR(_size); 490 SERIALIZE_SCALAR(nextFlags); 491 SERIALIZE_SCALAR(_itstate); 492 SERIALIZE_SCALAR(_nextItstate); 493 } 494 495 void 496 unserialize(CheckpointIn &cp) override 497 { 498 Base::unserialize(cp); 499 UNSERIALIZE_SCALAR(flags); 500 UNSERIALIZE_SCALAR(_size); 501 UNSERIALIZE_SCALAR(nextFlags); 502 UNSERIALIZE_SCALAR(_itstate); 503 UNSERIALIZE_SCALAR(_nextItstate); 504 } 505 }; 506 507 // Shift types for ARM instructions 508 enum ArmShiftType { 509 LSL = 0, 510 LSR, 511 ASR, 512 ROR 513 }; 514 515 // Extension types for ARM instructions 516 enum ArmExtendType { 517 UXTB = 0, 518 UXTH = 1, 519 UXTW = 2, 520 UXTX = 3, 521 SXTB = 4, 522 SXTH = 5, 523 SXTW = 6, 524 SXTX = 7 525 }; 526 527 typedef int RegContextParam; 528 typedef int RegContextVal; 529 530 //used in FP convert & round function 531 enum ConvertType{ 532 SINGLE_TO_DOUBLE, 533 SINGLE_TO_WORD, 534 SINGLE_TO_LONG, 535 536 DOUBLE_TO_SINGLE, 537 DOUBLE_TO_WORD, 538 DOUBLE_TO_LONG, 539 540 LONG_TO_SINGLE, 541 LONG_TO_DOUBLE, 542 LONG_TO_WORD, 543 LONG_TO_PS, 544 545 WORD_TO_SINGLE, 546 WORD_TO_DOUBLE, 547 WORD_TO_LONG, 548 WORD_TO_PS, 549 550 PL_TO_SINGLE, 551 PU_TO_SINGLE 552 }; 553 554 //used in FP convert & round function 555 enum RoundMode{ 556 RND_ZERO, 557 RND_DOWN, 558 RND_UP, 559 RND_NEAREST 560 }; 561 562 enum ExceptionLevel { 563 EL0 = 0, 564 EL1, 565 EL2, 566 EL3 567 }; 568 569 enum OperatingMode { 570 MODE_EL0T = 0x0, 571 MODE_EL1T = 0x4, 572 MODE_EL1H = 0x5, 573 MODE_EL2T = 0x8, 574 MODE_EL2H = 0x9, 575 MODE_EL3T = 0xC, 576 MODE_EL3H = 0xD, 577 MODE_USER = 16, 578 MODE_FIQ = 17, 579 MODE_IRQ = 18, 580 MODE_SVC = 19, 581 MODE_MON = 22, 582 MODE_ABORT = 23, 583 MODE_HYP = 26, 584 MODE_UNDEFINED = 27, 585 MODE_SYSTEM = 31, 586 MODE_MAXMODE = MODE_SYSTEM 587 }; 588 589 enum ExceptionClass { 590 EC_INVALID = -1, 591 EC_UNKNOWN = 0x0, 592 EC_TRAPPED_WFI_WFE = 0x1, 593 EC_TRAPPED_CP15_MCR_MRC = 0x3, 594 EC_TRAPPED_CP15_MCRR_MRRC = 0x4, 595 EC_TRAPPED_CP14_MCR_MRC = 0x5, 596 EC_TRAPPED_CP14_LDC_STC = 0x6, 597 EC_TRAPPED_HCPTR = 0x7, 598 EC_TRAPPED_SIMD_FP = 0x7, // AArch64 alias 599 EC_TRAPPED_CP10_MRC_VMRS = 0x8, 600 EC_TRAPPED_BXJ = 0xA, 601 EC_TRAPPED_CP14_MCRR_MRRC = 0xC, 602 EC_ILLEGAL_INST = 0xE, 603 EC_SVC_TO_HYP = 0x11, 604 EC_SVC = 0x11, // AArch64 alias 605 EC_HVC = 0x12, 606 EC_SMC_TO_HYP = 0x13, 607 EC_SMC = 0x13, // AArch64 alias 608 EC_SVC_64 = 0x15, 609 EC_HVC_64 = 0x16, 610 EC_SMC_64 = 0x17, 611 EC_TRAPPED_MSR_MRS_64 = 0x18, 612 EC_PREFETCH_ABORT_TO_HYP = 0x20, 613 EC_PREFETCH_ABORT_LOWER_EL = 0x20, // AArch64 alias 614 EC_PREFETCH_ABORT_FROM_HYP = 0x21, 615 EC_PREFETCH_ABORT_CURR_EL = 0x21, // AArch64 alias 616 EC_PC_ALIGNMENT = 0x22, 617 EC_DATA_ABORT_TO_HYP = 0x24, 618 EC_DATA_ABORT_LOWER_EL = 0x24, // AArch64 alias 619 EC_DATA_ABORT_FROM_HYP = 0x25, 620 EC_DATA_ABORT_CURR_EL = 0x25, // AArch64 alias 621 EC_STACK_PTR_ALIGNMENT = 0x26, 622 EC_FP_EXCEPTION = 0x28, 623 EC_FP_EXCEPTION_64 = 0x2C, 624 EC_SERROR = 0x2F, 625 EC_SOFTWARE_BREAKPOINT = 0x38, 626 EC_SOFTWARE_BREAKPOINT_64 = 0x3C, 627 }; 628 629 /** 630 * Instruction decoder fault codes in ExtMachInst. 631 */ 632 enum DecoderFault : std::uint8_t { 633 OK = 0x0, ///< No fault 634 UNALIGNED = 0x1, ///< Unaligned instruction fault 635 636 PANIC = 0x3, ///< Internal gem5 error 637 }; 638 639 BitUnion8(OperatingMode64) 640 Bitfield<0> spX; 641 Bitfield<3, 2> el; 642 Bitfield<4> width; 643 EndBitUnion(OperatingMode64) 644 645 static bool inline 646 opModeIs64(OperatingMode mode) 647 { 648 return ((OperatingMode64)(uint8_t)mode).width == 0; 649 } 650 651 static bool inline 652 opModeIsH(OperatingMode mode) 653 { 654 return (mode == MODE_EL1H || mode == MODE_EL2H || mode == MODE_EL3H); 655 } 656 657 static bool inline 658 opModeIsT(OperatingMode mode) 659 { 660 return (mode == MODE_EL0T || mode == MODE_EL1T || mode == MODE_EL2T || 661 mode == MODE_EL3T); 662 } 663 664 static ExceptionLevel inline 665 opModeToEL(OperatingMode mode) 666 { 667 bool aarch32 = ((mode >> 4) & 1) ? true : false; 668 if (aarch32) { 669 switch (mode) { 670 case MODE_USER: 671 return EL0; 672 case MODE_FIQ: 673 case MODE_IRQ: 674 case MODE_SVC: 675 case MODE_ABORT: 676 case MODE_UNDEFINED: 677 case MODE_SYSTEM: 678 return EL1; 679 case MODE_HYP: 680 return EL2; 681 case MODE_MON: 682 return EL3; 683 default: 684 panic("Invalid operating mode: %d", mode); 685 break; 686 } 687 } else { 688 // aarch64 689 return (ExceptionLevel) ((mode >> 2) & 3); 690 } 691 } 692 693 static inline bool 694 badMode(OperatingMode mode) 695 { 696 switch (mode) { 697 case MODE_EL0T: 698 case MODE_EL1T: 699 case MODE_EL1H: 700 case MODE_EL2T: 701 case MODE_EL2H: 702 case MODE_EL3T: 703 case MODE_EL3H: 704 case MODE_USER: 705 case MODE_FIQ: 706 case MODE_IRQ: 707 case MODE_SVC: 708 case MODE_MON: 709 case MODE_ABORT: 710 case MODE_HYP: 711 case MODE_UNDEFINED: 712 case MODE_SYSTEM: 713 return false; 714 default: 715 return true; 716 } 717 } 718 719 720 static inline bool 721 badMode32(OperatingMode mode) 722 { 723 switch (mode) { 724 case MODE_USER: 725 case MODE_FIQ: 726 case MODE_IRQ: 727 case MODE_SVC: 728 case MODE_MON: 729 case MODE_ABORT: 730 case MODE_HYP: 731 case MODE_UNDEFINED: 732 case MODE_SYSTEM: 733 return false; 734 default: 735 return true; 736 } 737 } 738 739} // namespace ArmISA 740 741#endif 742