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 |