| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_CONSTANTS_ARM_H_ | 5 #ifndef VM_CONSTANTS_ARM_H_ |
| 6 #define VM_CONSTANTS_ARM_H_ | 6 #define VM_CONSTANTS_ARM_H_ |
| 7 | 7 |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 | 9 |
| 10 namespace dart { | 10 namespace dart { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 D29 = 29, | 122 D29 = 29, |
| 123 D30 = 30, | 123 D30 = 30, |
| 124 D31 = 31, | 124 D31 = 31, |
| 125 kNumberOfDRegisters = 32, | 125 kNumberOfDRegisters = 32, |
| 126 #endif | 126 #endif |
| 127 kNumberOfOverlappingDRegisters = 16, | 127 kNumberOfOverlappingDRegisters = 16, |
| 128 kNoDRegister = -1, | 128 kNoDRegister = -1, |
| 129 }; | 129 }; |
| 130 | 130 |
| 131 | 131 |
| 132 enum QRegister { |
| 133 Q0 = 0, |
| 134 Q1 = 1, |
| 135 Q2 = 2, |
| 136 Q3 = 3, |
| 137 Q4 = 4, |
| 138 Q5 = 5, |
| 139 Q6 = 6, |
| 140 Q7 = 7, |
| 141 #ifdef VFPv3_D16 |
| 142 kNumberOfQRegisters = 8, |
| 143 #else |
| 144 Q8 = 8, |
| 145 Q9 = 9, |
| 146 Q10 = 10, |
| 147 Q11 = 11, |
| 148 Q12 = 12, |
| 149 Q13 = 13, |
| 150 Q14 = 14, |
| 151 Q15 = 15, |
| 152 kNumberOfQRegisters = 16, |
| 153 #endif |
| 154 kNoQRegister = -1, |
| 155 }; |
| 156 |
| 157 |
| 158 static inline DRegister EvenDRegisterOf(QRegister q) { |
| 159 return static_cast<DRegister>(q * 2); |
| 160 } |
| 161 |
| 162 static inline DRegister OddDRegisterOf(QRegister q) { |
| 163 return static_cast<DRegister>((q * 2) + 1); |
| 164 } |
| 165 |
| 166 |
| 132 // Register aliases for floating point scratch registers. | 167 // Register aliases for floating point scratch registers. |
| 133 const DRegister DTMP = D15; // Overlaps with STMP. | 168 const QRegister QTMP = Q7; // Overlaps with DTMP, STMP. |
| 134 const SRegister STMP = S30; | 169 const DRegister DTMP = D14; // Overlaps with STMP. |
| 170 const SRegister STMP = S28; |
| 135 | 171 |
| 136 // Architecture independent aliases. | 172 // Architecture independent aliases. |
| 137 typedef DRegister FpuRegister; | 173 typedef QRegister FpuRegister; |
| 138 const FpuRegister FpuTMP = DTMP; | 174 const FpuRegister FpuTMP = QTMP; |
| 139 const int kNumberOfFpuRegisters = kNumberOfDRegisters; | 175 const int kNumberOfFpuRegisters = kNumberOfQRegisters; |
| 140 const FpuRegister kNoFpuRegister = kNoDRegister; | 176 const FpuRegister kNoFpuRegister = kNoQRegister; |
| 141 | 177 |
| 142 // Register aliases. | 178 // Register aliases. |
| 143 const Register TMP = IP; // Used as scratch register by assembler. | 179 const Register TMP = IP; // Used as scratch register by assembler. |
| 144 const Register CTX = R9; // Caches current context in generated code. | 180 const Register CTX = R9; // Caches current context in generated code. |
| 145 const Register PP = R10; // Caches object pool pointer in generated code. | 181 const Register PP = R10; // Caches object pool pointer in generated code. |
| 146 const Register SPREG = SP; // Stack pointer register. | 182 const Register SPREG = SP; // Stack pointer register. |
| 147 const Register FPREG = FP; // Frame pointer register. | 183 const Register FPREG = FP; // Frame pointer register. |
| 148 | 184 |
| 149 // Exception object is passed in this register to the catch handlers when an | 185 // Exception object is passed in this register to the catch handlers when an |
| 150 // exception is thrown. | 186 // exception is thrown. |
| 151 const Register kExceptionObjectReg = R0; | 187 const Register kExceptionObjectReg = R0; |
| 152 | 188 |
| 153 // Stack trace object is passed in this register to the catch handlers when | 189 // Stack trace object is passed in this register to the catch handlers when |
| 154 // an exception is thrown. | 190 // an exception is thrown. |
| 155 const Register kStackTraceObjectReg = R1; | 191 const Register kStackTraceObjectReg = R1; |
| 156 | 192 |
| 157 | 193 |
| 158 // List of registers used in load/store multiple. | 194 // List of registers used in load/store multiple. |
| 159 typedef uint16_t RegList; | 195 typedef uint16_t RegList; |
| 160 const RegList kAllCpuRegistersList = 0xFFFF; | 196 const RegList kAllCpuRegistersList = 0xFFFF; |
| 161 | 197 |
| 162 | 198 |
| 163 // C++ ABI call registers. | 199 // C++ ABI call registers. |
| 164 const RegList kAbiArgumentCpuRegs = | 200 const RegList kAbiArgumentCpuRegs = |
| 165 (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3); | 201 (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3); |
| 166 const RegList kAbiPreservedCpuRegs = | 202 const RegList kAbiPreservedCpuRegs = |
| 167 (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) | | 203 (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) | |
| 168 (1 << R8) | (1 << R9) | (1 << R10); | 204 (1 << R8) | (1 << R9) | (1 << R10); |
| 169 const int kAbiPreservedCpuRegCount = 7; | 205 const int kAbiPreservedCpuRegCount = 7; |
| 170 const DRegister kAbiFirstPreservedFpuReg = D8; | 206 const QRegister kAbiFirstPreservedFpuReg = Q4; |
| 171 const DRegister kAbiLastPreservedFpuReg = | 207 const QRegister kAbiLastPreservedFpuReg = |
| 172 static_cast<DRegister>(kNumberOfDRegisters - 1); | 208 static_cast<QRegister>(kNumberOfQRegisters - 1); |
| 173 | 209 |
| 174 // CPU registers available to Dart allocator. | 210 // CPU registers available to Dart allocator. |
| 175 const RegList kDartAvailableCpuRegs = | 211 const RegList kDartAvailableCpuRegs = |
| 176 (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) | | 212 (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) | |
| 177 (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) | (1 << R8); | 213 (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) | (1 << R8); |
| 178 | 214 |
| 179 // Registers available to Dart that are not preserved by runtime calls. | 215 // Registers available to Dart that are not preserved by runtime calls. |
| 180 const RegList kDartVolatileCpuRegs = | 216 const RegList kDartVolatileCpuRegs = |
| 181 kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs; | 217 kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs; |
| 182 const int kDartVolatileCpuRegCount = 4; | 218 const int kDartVolatileCpuRegCount = 4; |
| 183 const DRegister kDartFirstVolatileFpuReg = D0; | 219 const QRegister kDartFirstVolatileFpuReg = Q0; |
| 184 const DRegister kDartLastVolatileFpuReg = D7; | 220 const QRegister kDartLastVolatileFpuReg = Q3; |
| 185 const int kDartVolatileFpuRegCount = 8; | 221 const int kDartVolatileFpuRegCount = 4; |
| 186 | 222 |
| 187 | 223 |
| 188 // Values for the condition field as defined in section A3.2. | 224 // Values for the condition field as defined in section A3.2. |
| 189 enum Condition { | 225 enum Condition { |
| 190 kNoCondition = -1, | 226 kNoCondition = -1, |
| 191 EQ = 0, // equal | 227 EQ = 0, // equal |
| 192 NE = 1, // not equal | 228 NE = 1, // not equal |
| 193 CS = 2, // carry set/unsigned higher or same | 229 CS = 2, // carry set/unsigned higher or same |
| 194 CC = 3, // carry clear/unsigned lower | 230 CC = 3, // carry clear/unsigned lower |
| 195 MI = 4, // minus/negative | 231 MI = 4, // minus/negative |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 } | 554 } |
| 519 inline DRegister DnField() const { | 555 inline DRegister DnField() const { |
| 520 return static_cast<DRegister>(Bits(kRnShift, kRnBits) + (Bit(7) << 4)); | 556 return static_cast<DRegister>(Bits(kRnShift, kRnBits) + (Bit(7) << 4)); |
| 521 } | 557 } |
| 522 inline DRegister DdField() const { | 558 inline DRegister DdField() const { |
| 523 return static_cast<DRegister>(Bits(kRdShift, kRdBits) + (Bit(22) << 4)); | 559 return static_cast<DRegister>(Bits(kRdShift, kRdBits) + (Bit(22) << 4)); |
| 524 } | 560 } |
| 525 inline DRegister DmField() const { | 561 inline DRegister DmField() const { |
| 526 return static_cast<DRegister>(Bits(kRmShift, kRmBits) + (Bit(5) << 4)); | 562 return static_cast<DRegister>(Bits(kRmShift, kRmBits) + (Bit(5) << 4)); |
| 527 } | 563 } |
| 564 inline QRegister QnField() const { |
| 565 const intptr_t bits = Bits(kRnShift, kRnBits) + (Bit(7) << 4); |
| 566 return static_cast<QRegister>(bits >> 1); |
| 567 } |
| 568 inline QRegister QdField() const { |
| 569 const intptr_t bits = Bits(kRdShift, kRdBits) + (Bit(22) << 4); |
| 570 return static_cast<QRegister>(bits >> 1); |
| 571 } |
| 572 inline QRegister QmField() const { |
| 573 const intptr_t bits = Bits(kRmShift, kRmBits) + (Bit(5) << 4); |
| 574 return static_cast<QRegister>(bits >> 1); |
| 575 } |
| 528 | 576 |
| 529 inline bool IsDivision() const { | 577 inline bool IsDivision() const { |
| 530 ASSERT(ConditionField() != kSpecialCondition); | 578 ASSERT(ConditionField() != kSpecialCondition); |
| 531 ASSERT(TypeField() == 3); | 579 ASSERT(TypeField() == 3); |
| 532 return ((Bit(4) == 1) && (Bits(5, 3) == 0) && | 580 return ((Bit(4) == 1) && (Bits(5, 3) == 0) && |
| 533 (Bit(20) == 1) && (Bits(22, 3) == 4)); | 581 (Bit(20) == 1) && (Bits(22, 3) == 4)); |
| 534 } | 582 } |
| 535 | 583 |
| 536 // Test for VFP data processing or single transfer instructions of type 7. | 584 // Test for VFP data processing or single transfer instructions of type 7. |
| 537 inline bool IsVFPDataProcessingOrSingleTransfer() const { | 585 inline bool IsVFPDataProcessingOrSingleTransfer() const { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 558 } | 606 } |
| 559 | 607 |
| 560 // Test for VFP multiple load and store instructions of type 6. | 608 // Test for VFP multiple load and store instructions of type 6. |
| 561 inline bool IsVFPMultipleLoadStore() const { | 609 inline bool IsVFPMultipleLoadStore() const { |
| 562 ASSERT(ConditionField() != kSpecialCondition); | 610 ASSERT(ConditionField() != kSpecialCondition); |
| 563 ASSERT(TypeField() == 6); | 611 ASSERT(TypeField() == 6); |
| 564 int32_t puw = (PUField() << 1) | Bit(21); // don't care about D bit | 612 int32_t puw = (PUField() << 1) | Bit(21); // don't care about D bit |
| 565 return (Bits(9, 3) == 5) && ((puw == 2) || (puw == 3) || (puw == 5)); | 613 return (Bits(9, 3) == 5) && ((puw == 2) || (puw == 3) || (puw == 5)); |
| 566 } | 614 } |
| 567 | 615 |
| 616 inline bool IsSIMDDataProcessing() const { |
| 617 ASSERT(ConditionField() == kSpecialCondition); |
| 618 return (Bits(25, 3) == 1); |
| 619 } |
| 620 |
| 621 inline bool IsSIMDLoadStore() const { |
| 622 ASSERT(ConditionField() == kSpecialCondition); |
| 623 return (Bits(24, 4) == 4) && (Bit(20) == 0); |
| 624 } |
| 625 |
| 568 // Special accessors that test for existence of a value. | 626 // Special accessors that test for existence of a value. |
| 569 inline bool HasS() const { return SField() == 1; } | 627 inline bool HasS() const { return SField() == 1; } |
| 570 inline bool HasB() const { return BField() == 1; } | 628 inline bool HasB() const { return BField() == 1; } |
| 571 inline bool HasW() const { return WField() == 1; } | 629 inline bool HasW() const { return WField() == 1; } |
| 572 inline bool HasL() const { return LField() == 1; } | 630 inline bool HasL() const { return LField() == 1; } |
| 573 inline bool HasSign() const { return SignField() == 1; } | 631 inline bool HasSign() const { return SignField() == 1; } |
| 574 inline bool HasH() const { return HField() == 1; } | 632 inline bool HasH() const { return HField() == 1; } |
| 575 inline bool HasLink() const { return LinkField() == 1; } | 633 inline bool HasLink() const { return LinkField() == 1; } |
| 576 | 634 |
| 577 // Instructions are read out of a code stream. The only way to get a | 635 // Instructions are read out of a code stream. The only way to get a |
| 578 // reference to an instruction is to convert a pointer. There is no way | 636 // reference to an instruction is to convert a pointer. There is no way |
| 579 // to allocate or create instances of class Instr. | 637 // to allocate or create instances of class Instr. |
| 580 // Use the At(pc) function to create references to Instr. | 638 // Use the At(pc) function to create references to Instr. |
| 581 static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); } | 639 static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); } |
| 582 | 640 |
| 583 private: | 641 private: |
| 584 DISALLOW_ALLOCATION(); | 642 DISALLOW_ALLOCATION(); |
| 585 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr); | 643 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr); |
| 586 }; | 644 }; |
| 587 | 645 |
| 588 } // namespace dart | 646 } // namespace dart |
| 589 | 647 |
| 590 #endif // VM_CONSTANTS_ARM_H_ | 648 #endif // VM_CONSTANTS_ARM_H_ |
| OLD | NEW |