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