OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 RUNTIME_VM_CONSTANTS_ARM64_H_ | 5 #ifndef RUNTIME_VM_CONSTANTS_ARM64_H_ |
6 #define RUNTIME_VM_CONSTANTS_ARM64_H_ | 6 #define RUNTIME_VM_CONSTANTS_ARM64_H_ |
7 | 7 |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 | 9 |
10 namespace dart { | 10 namespace dart { |
11 | 11 |
12 enum Register { | 12 enum Register { |
13 R0 = 0, | 13 R0 = 0, |
14 R1 = 1, | 14 R1 = 1, |
15 R2 = 2, | 15 R2 = 2, |
16 R3 = 3, | 16 R3 = 3, |
17 R4 = 4, | 17 R4 = 4, |
18 R5 = 5, | 18 R5 = 5, |
19 R6 = 6, | 19 R6 = 6, |
20 R7 = 7, | 20 R7 = 7, |
21 R8 = 8, | 21 R8 = 8, |
22 R9 = 9, | 22 R9 = 9, |
23 R10 = 10, | 23 R10 = 10, |
24 R11 = 11, | 24 R11 = 11, |
25 R12 = 12, | 25 R12 = 12, |
26 R13 = 13, | 26 R13 = 13, |
27 R14 = 14, | 27 R14 = 14, |
28 R15 = 15, // SP in Dart code. | 28 R15 = 15, // SP in Dart code. |
29 R16 = 16, // IP0 aka TMP | 29 R16 = 16, // IP0 aka TMP |
30 R17 = 17, // IP1 aka TMP2 | 30 R17 = 17, // IP1 aka TMP2 |
31 R18 = 18, // "platform register" on iOS. | 31 R18 = 18, // "platform register" on iOS. |
32 R19 = 19, | 32 R19 = 19, |
(...skipping 20 matching lines...) Expand all Loading... |
53 // Aliases. | 53 // Aliases. |
54 IP0 = R16, | 54 IP0 = R16, |
55 IP1 = R17, | 55 IP1 = R17, |
56 SP = R15, | 56 SP = R15, |
57 FP = R29, | 57 FP = R29, |
58 LR = R30, | 58 LR = R30, |
59 }; | 59 }; |
60 | 60 |
61 | 61 |
62 enum VRegister { | 62 enum VRegister { |
63 V0 = 0, | 63 V0 = 0, |
64 V1 = 1, | 64 V1 = 1, |
65 V2 = 2, | 65 V2 = 2, |
66 V3 = 3, | 66 V3 = 3, |
67 V4 = 4, | 67 V4 = 4, |
68 V5 = 5, | 68 V5 = 5, |
69 V6 = 6, | 69 V6 = 6, |
70 V7 = 7, | 70 V7 = 7, |
71 V8 = 8, | 71 V8 = 8, |
72 V9 = 9, | 72 V9 = 9, |
73 V10 = 10, | 73 V10 = 10, |
74 V11 = 11, | 74 V11 = 11, |
75 V12 = 12, | 75 V12 = 12, |
76 V13 = 13, | 76 V13 = 13, |
77 V14 = 14, | 77 V14 = 14, |
78 V15 = 15, | 78 V15 = 15, |
79 V16 = 16, | 79 V16 = 16, |
80 V17 = 17, | 80 V17 = 17, |
81 V18 = 18, | 81 V18 = 18, |
82 V19 = 19, | 82 V19 = 19, |
(...skipping 19 matching lines...) Expand all Loading... |
102 // Architecture independent aliases. | 102 // Architecture independent aliases. |
103 typedef VRegister FpuRegister; | 103 typedef VRegister FpuRegister; |
104 const FpuRegister FpuTMP = VTMP; | 104 const FpuRegister FpuTMP = VTMP; |
105 const int kNumberOfFpuRegisters = kNumberOfVRegisters; | 105 const int kNumberOfFpuRegisters = kNumberOfVRegisters; |
106 const FpuRegister kNoFpuRegister = kNoVRegister; | 106 const FpuRegister kNoFpuRegister = kNoVRegister; |
107 | 107 |
108 // Register aliases. | 108 // Register aliases. |
109 const Register TMP = R16; // Used as scratch register by assembler. | 109 const Register TMP = R16; // Used as scratch register by assembler. |
110 const Register TMP2 = R17; | 110 const Register TMP2 = R17; |
111 const Register CTX = R28; // Location of current context at method entry. | 111 const Register CTX = R28; // Location of current context at method entry. |
112 const Register PP = R27; // Caches object pool pointer in generated code. | 112 const Register PP = R27; // Caches object pool pointer in generated code. |
113 const Register CODE_REG = R24; | 113 const Register CODE_REG = R24; |
114 const Register FPREG = FP; // Frame pointer register. | 114 const Register FPREG = FP; // Frame pointer register. |
115 const Register SPREG = R15; // Stack pointer register. | 115 const Register SPREG = R15; // Stack pointer register. |
116 const Register LRREG = LR; // Link register. | 116 const Register LRREG = LR; // Link register. |
117 const Register ICREG = R5; // IC data register. | 117 const Register ICREG = R5; // IC data register. |
118 const Register ARGS_DESC_REG = R4; // Arguments descriptor register. | 118 const Register ARGS_DESC_REG = R4; // Arguments descriptor register. |
119 const Register THR = R26; // Caches current thread in generated code. | 119 const Register THR = R26; // Caches current thread in generated code. |
120 const Register CALLEE_SAVED_TEMP = R19; | 120 const Register CALLEE_SAVED_TEMP = R19; |
121 const Register CALLEE_SAVED_TEMP2 = R20; | 121 const Register CALLEE_SAVED_TEMP2 = R20; |
122 | 122 |
123 // Exception object is passed in this register to the catch handlers when an | 123 // Exception object is passed in this register to the catch handlers when an |
124 // exception is thrown. | 124 // exception is thrown. |
125 const Register kExceptionObjectReg = R0; | 125 const Register kExceptionObjectReg = R0; |
126 | 126 |
127 // Stack trace object is passed in this register to the catch handlers when | 127 // Stack trace object is passed in this register to the catch handlers when |
128 // an exception is thrown. | 128 // an exception is thrown. |
129 const Register kStackTraceObjectReg = R1; | 129 const Register kStackTraceObjectReg = R1; |
130 | 130 |
131 // Masks, sizes, etc. | 131 // Masks, sizes, etc. |
132 const int kXRegSizeInBits = 64; | 132 const int kXRegSizeInBits = 64; |
133 const int kWRegSizeInBits = 32; | 133 const int kWRegSizeInBits = 32; |
134 const int64_t kXRegMask = 0xffffffffffffffffL; | 134 const int64_t kXRegMask = 0xffffffffffffffffL; |
135 const int64_t kWRegMask = 0x00000000ffffffffL; | 135 const int64_t kWRegMask = 0x00000000ffffffffL; |
136 | 136 |
137 // List of registers used in load/store multiple. | 137 // List of registers used in load/store multiple. |
138 typedef uint32_t RegList; | 138 typedef uint32_t RegList; |
139 const RegList kAllCpuRegistersList = 0xFFFF; | 139 const RegList kAllCpuRegistersList = 0xFFFF; |
140 | 140 |
141 | 141 |
142 // C++ ABI call registers. | 142 // C++ ABI call registers. |
143 const RegList kAbiArgumentCpuRegs = | 143 const RegList kAbiArgumentCpuRegs = (1 << R0) | (1 << R1) | (1 << R2) | |
144 (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) | | 144 (1 << R3) | (1 << R4) | (1 << R5) | |
145 (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7); | 145 (1 << R6) | (1 << R7); |
146 const RegList kAbiPreservedCpuRegs = | 146 const RegList kAbiPreservedCpuRegs = |
147 (1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) | | 147 (1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) | (1 << R23) | |
148 (1 << R23) | (1 << R24) | (1 << R25) | (1 << R26) | | 148 (1 << R24) | (1 << R25) | (1 << R26) | (1 << R27) | (1 << R28); |
149 (1 << R27) | (1 << R28); | |
150 const Register kAbiFirstPreservedCpuReg = R19; | 149 const Register kAbiFirstPreservedCpuReg = R19; |
151 const Register kAbiLastPreservedCpuReg = R28; | 150 const Register kAbiLastPreservedCpuReg = R28; |
152 const int kAbiPreservedCpuRegCount = 10; | 151 const int kAbiPreservedCpuRegCount = 10; |
153 const VRegister kAbiFirstPreservedFpuReg = V8; | 152 const VRegister kAbiFirstPreservedFpuReg = V8; |
154 const VRegister kAbiLastPreservedFpuReg = V15; | 153 const VRegister kAbiLastPreservedFpuReg = V15; |
155 const int kAbiPreservedFpuRegCount = 8; | 154 const int kAbiPreservedFpuRegCount = 8; |
156 | 155 |
157 const intptr_t kReservedCpuRegisters = | 156 const intptr_t kReservedCpuRegisters = |
158 (1 << SPREG) | // Dart SP | 157 (1 << SPREG) | // Dart SP |
159 (1 << FPREG) | | 158 (1 << FPREG) | (1 << TMP) | (1 << TMP2) | (1 << PP) | (1 << THR) | |
160 (1 << TMP) | | 159 (1 << LR) | (1 << R31) | // C++ SP |
161 (1 << TMP2) | | 160 (1 << CTX) | (1 << R18); // iOS platform register. |
162 (1 << PP) | | 161 // TODO(rmacnak): Only reserve on Mac & iOS. |
163 (1 << THR) | | |
164 (1 << LR) | | |
165 (1 << R31) | // C++ SP | |
166 (1 << CTX) | | |
167 (1 << R18); // iOS platform register. | |
168 // TODO(rmacnak): Only reserve on Mac & iOS. | |
169 // CPU registers available to Dart allocator. | 162 // CPU registers available to Dart allocator. |
170 const RegList kDartAvailableCpuRegs = | 163 const RegList kDartAvailableCpuRegs = |
171 kAllCpuRegistersList & ~kReservedCpuRegisters; | 164 kAllCpuRegistersList & ~kReservedCpuRegisters; |
172 // Registers available to Dart that are not preserved by runtime calls. | 165 // Registers available to Dart that are not preserved by runtime calls. |
173 const RegList kDartVolatileCpuRegs = | 166 const RegList kDartVolatileCpuRegs = |
174 kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs; | 167 kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs; |
175 const Register kDartFirstVolatileCpuReg = R0; | 168 const Register kDartFirstVolatileCpuReg = R0; |
176 const Register kDartLastVolatileCpuReg = R14; | 169 const Register kDartLastVolatileCpuReg = R14; |
177 const int kDartVolatileCpuRegCount = 15; | 170 const int kDartVolatileCpuRegCount = 15; |
178 const int kDartVolatileFpuRegCount = 24; | 171 const int kDartVolatileFpuRegCount = 24; |
179 | 172 |
180 static inline Register ConcreteRegister(Register r) { | 173 static inline Register ConcreteRegister(Register r) { |
181 return ((r == ZR) || (r == CSP)) ? R31 : r; | 174 return ((r == ZR) || (r == CSP)) ? R31 : r; |
182 } | 175 } |
183 | 176 |
184 // Values for the condition field as defined in section A3.2. | 177 // Values for the condition field as defined in section A3.2. |
185 enum Condition { | 178 enum Condition { |
186 kNoCondition = -1, | 179 kNoCondition = -1, |
187 EQ = 0, // equal | 180 EQ = 0, // equal |
188 NE = 1, // not equal | 181 NE = 1, // not equal |
189 CS = 2, // carry set/unsigned higher or same | 182 CS = 2, // carry set/unsigned higher or same |
190 CC = 3, // carry clear/unsigned lower | 183 CC = 3, // carry clear/unsigned lower |
191 MI = 4, // minus/negative | 184 MI = 4, // minus/negative |
192 PL = 5, // plus/positive or zero | 185 PL = 5, // plus/positive or zero |
193 VS = 6, // overflow | 186 VS = 6, // overflow |
194 VC = 7, // no overflow | 187 VC = 7, // no overflow |
195 HI = 8, // unsigned higher | 188 HI = 8, // unsigned higher |
196 LS = 9, // unsigned lower or same | 189 LS = 9, // unsigned lower or same |
197 GE = 10, // signed greater than or equal | 190 GE = 10, // signed greater than or equal |
198 LT = 11, // signed less than | 191 LT = 11, // signed less than |
199 GT = 12, // signed greater than | 192 GT = 12, // signed greater than |
200 LE = 13, // signed less than or equal | 193 LE = 13, // signed less than or equal |
201 AL = 14, // always (unconditional) | 194 AL = 14, // always (unconditional) |
202 NV = 15, // special condition (refer to section C1.2.3) | 195 NV = 15, // special condition (refer to section C1.2.3) |
203 kMaxCondition = 16, | 196 kMaxCondition = 16, |
204 }; | 197 }; |
205 | 198 |
206 static inline Condition InvertCondition(Condition c) { | 199 static inline Condition InvertCondition(Condition c) { |
207 const int32_t i = static_cast<int32_t>(c) ^ 0x1; | 200 const int32_t i = static_cast<int32_t>(c) ^ 0x1; |
208 return static_cast<Condition>(i); | 201 return static_cast<Condition>(i); |
209 } | 202 } |
210 | 203 |
211 enum Bits { | 204 enum Bits { |
212 B0 = (1 << 0), B1 = (1 << 1), B2 = (1 << 2), B3 = (1 << 3), | 205 B0 = (1 << 0), |
213 B4 = (1 << 4), B5 = (1 << 5), B6 = (1 << 6), B7 = (1 << 7), | 206 B1 = (1 << 1), |
214 B8 = (1 << 8), B9 = (1 << 9), B10 = (1 << 10), B11 = (1 << 11), | 207 B2 = (1 << 2), |
215 B12 = (1 << 12), B13 = (1 << 13), B14 = (1 << 14), B15 = (1 << 15), | 208 B3 = (1 << 3), |
216 B16 = (1 << 16), B17 = (1 << 17), B18 = (1 << 18), B19 = (1 << 19), | 209 B4 = (1 << 4), |
217 B20 = (1 << 20), B21 = (1 << 21), B22 = (1 << 22), B23 = (1 << 23), | 210 B5 = (1 << 5), |
218 B24 = (1 << 24), B25 = (1 << 25), B26 = (1 << 26), B27 = (1 << 27), | 211 B6 = (1 << 6), |
219 B28 = (1 << 28), B29 = (1 << 29), B30 = (1 << 30), B31 = (1 << 31), | 212 B7 = (1 << 7), |
| 213 B8 = (1 << 8), |
| 214 B9 = (1 << 9), |
| 215 B10 = (1 << 10), |
| 216 B11 = (1 << 11), |
| 217 B12 = (1 << 12), |
| 218 B13 = (1 << 13), |
| 219 B14 = (1 << 14), |
| 220 B15 = (1 << 15), |
| 221 B16 = (1 << 16), |
| 222 B17 = (1 << 17), |
| 223 B18 = (1 << 18), |
| 224 B19 = (1 << 19), |
| 225 B20 = (1 << 20), |
| 226 B21 = (1 << 21), |
| 227 B22 = (1 << 22), |
| 228 B23 = (1 << 23), |
| 229 B24 = (1 << 24), |
| 230 B25 = (1 << 25), |
| 231 B26 = (1 << 26), |
| 232 B27 = (1 << 27), |
| 233 B28 = (1 << 28), |
| 234 B29 = (1 << 29), |
| 235 B30 = (1 << 30), |
| 236 B31 = (1 << 31), |
220 }; | 237 }; |
221 | 238 |
222 enum OperandSize { | 239 enum OperandSize { |
223 kByte, | 240 kByte, |
224 kUnsignedByte, | 241 kUnsignedByte, |
225 kHalfword, | 242 kHalfword, |
226 kUnsignedHalfword, | 243 kUnsignedHalfword, |
227 kWord, | 244 kWord, |
228 kUnsignedWord, | 245 kUnsignedWord, |
229 kDoubleWord, | 246 kDoubleWord, |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 SVC = ExceptionGenFixed | B0, | 341 SVC = ExceptionGenFixed | B0, |
325 BRK = ExceptionGenFixed | B21, | 342 BRK = ExceptionGenFixed | B21, |
326 HLT = ExceptionGenFixed | B22, | 343 HLT = ExceptionGenFixed | B22, |
327 }; | 344 }; |
328 | 345 |
329 // C3.2.4 | 346 // C3.2.4 |
330 enum SystemOp { | 347 enum SystemOp { |
331 SystemMask = 0xffc00000, | 348 SystemMask = 0xffc00000, |
332 SystemFixed = CompareBranchFixed | B31 | B30 | B24, | 349 SystemFixed = CompareBranchFixed | B31 | B30 | B24, |
333 HINT = SystemFixed | B17 | B16 | B13 | B4 | B3 | B2 | B1 | B0, | 350 HINT = SystemFixed | B17 | B16 | B13 | B4 | B3 | B2 | B1 | B0, |
334 CLREX = SystemFixed | B17 | B16 | B13 | B12 | B11 | B10 | B9 | B8 | | 351 CLREX = SystemFixed | B17 | B16 | B13 | B12 | B11 | B10 | B9 | B8 | B6 | B4 | |
335 B6 | B4 | B3 | B2 | B1 | B0, | 352 B3 | |
| 353 B2 | |
| 354 B1 | |
| 355 B0, |
336 }; | 356 }; |
337 | 357 |
338 // C3.2.5 | 358 // C3.2.5 |
339 enum TestAndBranchOp { | 359 enum TestAndBranchOp { |
340 TestAndBranchMask = 0x7e000000, | 360 TestAndBranchMask = 0x7e000000, |
341 TestAndBranchFixed = CompareBranchFixed | B29 | B25, | 361 TestAndBranchFixed = CompareBranchFixed | B29 | B25, |
342 TBZ = TestAndBranchFixed, | 362 TBZ = TestAndBranchFixed, |
343 TBNZ = TestAndBranchFixed | B24, | 363 TBNZ = TestAndBranchFixed | B24, |
344 }; | 364 }; |
345 | 365 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 // C.3.6.17 | 567 // C.3.6.17 |
548 enum SIMDTwoRegOp { | 568 enum SIMDTwoRegOp { |
549 SIMDTwoRegMask = 0x9f3e0c00, | 569 SIMDTwoRegMask = 0x9f3e0c00, |
550 SIMDTwoRegFixed = DPSimd1Fixed | B21 | B11, | 570 SIMDTwoRegFixed = DPSimd1Fixed | B21 | B11, |
551 VNOT = SIMDTwoRegFixed | B30 | B29 | B14 | B12, | 571 VNOT = SIMDTwoRegFixed | B30 | B29 | B14 | B12, |
552 VABSS = SIMDTwoRegFixed | B30 | B23 | B15 | B14 | B13 | B12, | 572 VABSS = SIMDTwoRegFixed | B30 | B23 | B15 | B14 | B13 | B12, |
553 VNEGS = SIMDTwoRegFixed | B30 | B29 | B23 | B15 | B14 | B13 | B12, | 573 VNEGS = SIMDTwoRegFixed | B30 | B29 | B23 | B15 | B14 | B13 | B12, |
554 VABSD = SIMDTwoRegFixed | B30 | B23 | B22 | B15 | B14 | B13 | B12, | 574 VABSD = SIMDTwoRegFixed | B30 | B23 | B22 | B15 | B14 | B13 | B12, |
555 VNEGD = SIMDTwoRegFixed | B30 | B29 | B23 | B22 | B15 | B14 | B13 | B12, | 575 VNEGD = SIMDTwoRegFixed | B30 | B29 | B23 | B22 | B15 | B14 | B13 | B12, |
556 VSQRTS = SIMDTwoRegFixed | B30 | B29 | B23 | B16 | B15 | B14 | B13 | B12, | 576 VSQRTS = SIMDTwoRegFixed | B30 | B29 | B23 | B16 | B15 | B14 | B13 | B12, |
557 VSQRTD = SIMDTwoRegFixed | B30 | B29 | B23 | B22 | 577 VSQRTD = |
558 | B16 | B15 | B14 | B13 | B12, | 578 SIMDTwoRegFixed | B30 | B29 | B23 | B22 | B16 | B15 | B14 | B13 | B12, |
559 VRECPES = SIMDTwoRegFixed | B30 | B23 | B16 | B15 | B14 | B12, | 579 VRECPES = SIMDTwoRegFixed | B30 | B23 | B16 | B15 | B14 | B12, |
560 VRSQRTES = SIMDTwoRegFixed | B30 | B29 | B23 | B16 | B15 | B14 | B12, | 580 VRSQRTES = SIMDTwoRegFixed | B30 | B29 | B23 | B16 | B15 | B14 | B12, |
561 }; | 581 }; |
562 | 582 |
563 // C.3.6.22 | 583 // C.3.6.22 |
564 enum FPCompareOp { | 584 enum FPCompareOp { |
565 FPCompareMask = 0xffa0fc07, | 585 FPCompareMask = 0xffa0fc07, |
566 FPCompareFixed = FPFixed | B21 | B13, | 586 FPCompareFixed = FPFixed | B21 | B13, |
567 FCMPD = FPCompareFixed | B22, | 587 FCMPD = FPCompareFixed | B22, |
568 FCMPZD = FPCompareFixed | B22 | B3, | 588 FCMPZD = FPCompareFixed | B22 | B3, |
(...skipping 29 matching lines...) Expand all Loading... |
598 FMOVDI = FPImmFixed | B22, | 618 FMOVDI = FPImmFixed | B22, |
599 }; | 619 }; |
600 | 620 |
601 // C3.6.30 | 621 // C3.6.30 |
602 enum FPIntCvtOp { | 622 enum FPIntCvtOp { |
603 FPIntCvtMask = 0x5f20fc00, | 623 FPIntCvtMask = 0x5f20fc00, |
604 FPIntCvtFixed = FPFixed | B21, | 624 FPIntCvtFixed = FPFixed | B21, |
605 FMOVRD = FPIntCvtFixed | B22 | B18 | B17, | 625 FMOVRD = FPIntCvtFixed | B22 | B18 | B17, |
606 FMOVDR = FPIntCvtFixed | B22 | B18 | B17 | B16, | 626 FMOVDR = FPIntCvtFixed | B22 | B18 | B17 | B16, |
607 FCVTZDS = FPIntCvtFixed | B22 | B20 | B19, | 627 FCVTZDS = FPIntCvtFixed | B22 | B20 | B19, |
608 SCVTFD = FPIntCvtFixed | B22 | B17, | 628 SCVTFD = FPIntCvtFixed | B22 | B17, |
609 }; | 629 }; |
610 | 630 |
611 | 631 |
612 #define APPLY_OP_LIST(_V) \ | 632 #define APPLY_OP_LIST(_V) \ |
613 _V(DPImmediate) \ | 633 _V(DPImmediate) \ |
614 _V(CompareBranch) \ | 634 _V(CompareBranch) \ |
615 _V(LoadStore) \ | 635 _V(LoadStore) \ |
616 _V(DPRegister) \ | 636 _V(DPRegister) \ |
617 _V(DPSimd1) \ | 637 _V(DPSimd1) \ |
618 _V(DPSimd2) \ | 638 _V(DPSimd2) \ |
619 _V(FP) \ | 639 _V(FP) \ |
620 _V(CompareAndBranch) \ | 640 _V(CompareAndBranch) \ |
621 _V(ConditionalBranch) \ | 641 _V(ConditionalBranch) \ |
622 _V(ExceptionGen) \ | 642 _V(ExceptionGen) \ |
623 _V(System) \ | 643 _V(System) \ |
624 _V(TestAndBranch) \ | 644 _V(TestAndBranch) \ |
625 _V(UnconditionalBranch) \ | 645 _V(UnconditionalBranch) \ |
626 _V(UnconditionalBranchReg) \ | 646 _V(UnconditionalBranchReg) \ |
627 _V(LoadStoreReg) \ | 647 _V(LoadStoreReg) \ |
628 _V(LoadStoreRegPair) \ | 648 _V(LoadStoreRegPair) \ |
629 _V(LoadRegLiteral) \ | 649 _V(LoadRegLiteral) \ |
630 _V(LoadStoreExclusive) \ | 650 _V(LoadStoreExclusive) \ |
631 _V(AddSubImm) \ | 651 _V(AddSubImm) \ |
632 _V(LogicalImm) \ | 652 _V(LogicalImm) \ |
633 _V(MoveWide) \ | 653 _V(MoveWide) \ |
634 _V(PCRel) \ | 654 _V(PCRel) \ |
635 _V(AddSubShiftExt) \ | 655 _V(AddSubShiftExt) \ |
636 _V(AddSubWithCarry) \ | 656 _V(AddSubWithCarry) \ |
637 _V(ConditionalSelect) \ | 657 _V(ConditionalSelect) \ |
638 _V(MiscDP1Source) \ | 658 _V(MiscDP1Source) \ |
639 _V(MiscDP2Source) \ | 659 _V(MiscDP2Source) \ |
640 _V(MiscDP3Source) \ | 660 _V(MiscDP3Source) \ |
641 _V(LogicalShift) \ | 661 _V(LogicalShift) \ |
642 _V(SIMDCopy) \ | 662 _V(SIMDCopy) \ |
643 _V(SIMDThreeSame) \ | 663 _V(SIMDThreeSame) \ |
644 _V(SIMDTwoReg) \ | 664 _V(SIMDTwoReg) \ |
645 _V(FPCompare) \ | 665 _V(FPCompare) \ |
646 _V(FPOneSource) \ | 666 _V(FPOneSource) \ |
647 _V(FPTwoSource) \ | 667 _V(FPTwoSource) \ |
648 _V(FPImm) \ | 668 _V(FPImm) \ |
649 _V(FPIntCvt) \ | 669 _V(FPIntCvt) |
650 | 670 |
651 | 671 |
652 enum Shift { | 672 enum Shift { |
653 kNoShift = -1, | 673 kNoShift = -1, |
654 LSL = 0, // Logical shift left | 674 LSL = 0, // Logical shift left |
655 LSR = 1, // Logical shift right | 675 LSR = 1, // Logical shift right |
656 ASR = 2, // Arithmetic shift right | 676 ASR = 2, // Arithmetic shift right |
657 ROR = 3, // Rotate right | 677 ROR = 3, // Rotate right |
658 kMaxShift = 4, | 678 kMaxShift = 4, |
659 }; | 679 }; |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 | 798 |
779 // Hint Fields. | 799 // Hint Fields. |
780 kHintCRmShift = 8, | 800 kHintCRmShift = 8, |
781 kHintCRmBits = 4, | 801 kHintCRmBits = 4, |
782 kHintOp2Shift = 5, | 802 kHintOp2Shift = 5, |
783 kHintOp2Bits = 3, | 803 kHintOp2Bits = 3, |
784 }; | 804 }; |
785 | 805 |
786 | 806 |
787 // Helper functions for decoding logical immediates. | 807 // Helper functions for decoding logical immediates. |
788 static inline uint64_t RotateRight( | 808 static inline uint64_t RotateRight(uint64_t value, |
789 uint64_t value, uint8_t rotate, uint8_t width) { | 809 uint8_t rotate, |
| 810 uint8_t width) { |
790 ASSERT(width <= 64); | 811 ASSERT(width <= 64); |
791 rotate &= 63; | 812 rotate &= 63; |
792 return ((value & ((1UL << rotate) - 1UL)) << (width - rotate)) | | 813 return ((value & ((1UL << rotate) - 1UL)) << (width - rotate)) | |
793 (value >> rotate); | 814 (value >> rotate); |
794 } | 815 } |
795 | 816 |
796 static inline uint64_t RepeatBitsAcrossReg( | 817 static inline uint64_t RepeatBitsAcrossReg(uint8_t reg_size, |
797 uint8_t reg_size, uint64_t value, uint8_t width) { | 818 uint64_t value, |
| 819 uint8_t width) { |
798 ASSERT((width == 2) || (width == 4) || (width == 8) || (width == 16) || | 820 ASSERT((width == 2) || (width == 4) || (width == 8) || (width == 16) || |
799 (width == 32)); | 821 (width == 32)); |
800 ASSERT((reg_size == kWRegSizeInBits) || (reg_size == kXRegSizeInBits)); | 822 ASSERT((reg_size == kWRegSizeInBits) || (reg_size == kXRegSizeInBits)); |
801 uint64_t result = value & ((1UL << width) - 1UL); | 823 uint64_t result = value & ((1UL << width) - 1UL); |
802 for (unsigned i = width; i < reg_size; i *= 2) { | 824 for (unsigned i = width; i < reg_size; i *= 2) { |
803 result |= (result << i); | 825 result |= (result << i); |
804 } | 826 } |
805 return result; | 827 return result; |
806 } | 828 } |
807 | 829 |
808 // The class Instr enables access to individual fields defined in the ARM | 830 // The class Instr enables access to individual fields defined in the ARM |
809 // architecture instruction set encoding as described in figure A3-1. | 831 // architecture instruction set encoding as described in figure A3-1. |
810 // | 832 // |
811 // Example: Test whether the instruction at ptr sets the condition code bits. | 833 // Example: Test whether the instruction at ptr sets the condition code bits. |
812 // | 834 // |
813 // bool InstructionSetsConditionCodes(byte* ptr) { | 835 // bool InstructionSetsConditionCodes(byte* ptr) { |
814 // Instr* instr = Instr::At(ptr); | 836 // Instr* instr = Instr::At(ptr); |
815 // int type = instr->TypeField(); | 837 // int type = instr->TypeField(); |
816 // return ((type == 0) || (type == 1)) && instr->HasS(); | 838 // return ((type == 0) || (type == 1)) && instr->HasS(); |
817 // } | 839 // } |
818 // | 840 // |
819 class Instr { | 841 class Instr { |
820 public: | 842 public: |
821 enum { | 843 enum { kInstrSize = 4, kInstrSizeLog2 = 2, kPCReadOffset = 8 }; |
822 kInstrSize = 4, | |
823 kInstrSizeLog2 = 2, | |
824 kPCReadOffset = 8 | |
825 }; | |
826 | 844 |
827 static const int32_t kNopInstruction = HINT; // hint #0 === nop. | 845 static const int32_t kNopInstruction = HINT; // hint #0 === nop. |
828 | 846 |
829 // Reserved brk and hlt instruction codes. | 847 // Reserved brk and hlt instruction codes. |
830 static const int32_t kBreakPointCode = 0xdeb0; // For breakpoint. | 848 static const int32_t kBreakPointCode = 0xdeb0; // For breakpoint. |
831 static const int32_t kStopMessageCode = 0xdeb1; // For Stop(message). | 849 static const int32_t kStopMessageCode = 0xdeb1; // For Stop(message). |
832 static const int32_t kSimulatorBreakCode = 0xdeb2; // For breakpoint in sim. | 850 static const int32_t kSimulatorBreakCode = 0xdeb2; // For breakpoint in sim. |
833 static const int32_t kSimulatorRedirectCode = 0xca11; // For redirection. | 851 static const int32_t kSimulatorRedirectCode = 0xca11; // For redirection. |
834 | 852 |
835 // Breakpoint instruction filling assembler code buffers in debug mode. | 853 // Breakpoint instruction filling assembler code buffers in debug mode. |
836 static const int32_t kBreakPointInstruction = // brk(0xdeb0). | 854 static const int32_t kBreakPointInstruction = // brk(0xdeb0). |
837 BRK | (kBreakPointCode << kImm16Shift); | 855 BRK | (kBreakPointCode << kImm16Shift); |
838 | 856 |
839 // Breakpoint instruction used by the simulator. | 857 // Breakpoint instruction used by the simulator. |
840 // Should be distinct from kBreakPointInstruction and from a typical user | 858 // Should be distinct from kBreakPointInstruction and from a typical user |
841 // breakpoint inserted in generated code for debugging, e.g. brk(0). | 859 // breakpoint inserted in generated code for debugging, e.g. brk(0). |
842 static const int32_t kSimulatorBreakpointInstruction = | 860 static const int32_t kSimulatorBreakpointInstruction = |
843 HLT | (kSimulatorBreakCode << kImm16Shift); | 861 HLT | (kSimulatorBreakCode << kImm16Shift); |
844 | 862 |
845 // Runtime call redirection instruction used by the simulator. | 863 // Runtime call redirection instruction used by the simulator. |
846 static const int32_t kSimulatorRedirectInstruction = | 864 static const int32_t kSimulatorRedirectInstruction = |
847 HLT | (kSimulatorRedirectCode << kImm16Shift); | 865 HLT | (kSimulatorRedirectCode << kImm16Shift); |
848 | 866 |
849 // Read one particular bit out of the instruction bits. | 867 // Read one particular bit out of the instruction bits. |
850 inline int Bit(int nr) const { | 868 inline int Bit(int nr) const { return (InstructionBits() >> nr) & 1; } |
851 return (InstructionBits() >> nr) & 1; | |
852 } | |
853 | 869 |
854 // Read a bit field out of the instruction bits. | 870 // Read a bit field out of the instruction bits. |
855 inline int Bits(int shift, int count) const { | 871 inline int Bits(int shift, int count) const { |
856 return (InstructionBits() >> shift) & ((1 << count) - 1); | 872 return (InstructionBits() >> shift) & ((1 << count) - 1); |
857 } | 873 } |
858 | 874 |
859 // Get the raw instruction bits. | 875 // Get the raw instruction bits. |
860 inline int32_t InstructionBits() const { | 876 inline int32_t InstructionBits() const { |
861 return *reinterpret_cast<const int32_t*>(this); | 877 return *reinterpret_cast<const int32_t*>(this); |
862 } | 878 } |
863 | 879 |
864 // Set the raw instruction bits to value. | 880 // Set the raw instruction bits to value. |
865 inline void SetInstructionBits(int32_t value) { | 881 inline void SetInstructionBits(int32_t value) { |
866 *reinterpret_cast<int32_t*>(this) = value; | 882 *reinterpret_cast<int32_t*>(this) = value; |
867 } | 883 } |
868 | 884 |
869 inline void SetMoveWideBits( | 885 inline void SetMoveWideBits(MoveWideOp op, |
870 MoveWideOp op, Register rd, uint16_t imm, int hw, OperandSize sz) { | 886 Register rd, |
| 887 uint16_t imm, |
| 888 int hw, |
| 889 OperandSize sz) { |
871 ASSERT((hw >= 0) && (hw <= 3)); | 890 ASSERT((hw >= 0) && (hw <= 3)); |
872 ASSERT((sz == kDoubleWord) || (sz == kWord)); | 891 ASSERT((sz == kDoubleWord) || (sz == kWord)); |
873 const int32_t size = (sz == kDoubleWord) ? B31 : 0; | 892 const int32_t size = (sz == kDoubleWord) ? B31 : 0; |
874 SetInstructionBits( | 893 SetInstructionBits(op | size | (static_cast<int32_t>(rd) << kRdShift) | |
875 op | size | | 894 (static_cast<int32_t>(hw) << kHWShift) | |
876 (static_cast<int32_t>(rd) << kRdShift) | | 895 (static_cast<int32_t>(imm) << kImm16Shift)); |
877 (static_cast<int32_t>(hw) << kHWShift) | | |
878 (static_cast<int32_t>(imm) << kImm16Shift)); | |
879 } | 896 } |
880 | 897 |
881 inline void SetUnconditionalBranchRegBits( | 898 inline void SetUnconditionalBranchRegBits(UnconditionalBranchRegOp op, |
882 UnconditionalBranchRegOp op, Register rn) { | 899 Register rn) { |
883 SetInstructionBits( | 900 SetInstructionBits(op | (static_cast<int32_t>(rn) << kRnShift)); |
884 op | | |
885 (static_cast<int32_t>(rn) << kRnShift)); | |
886 } | 901 } |
887 | 902 |
888 inline void SetImm12Bits(int32_t orig, int32_t imm12) { | 903 inline void SetImm12Bits(int32_t orig, int32_t imm12) { |
889 ASSERT((imm12 & 0xfffff000) == 0); | 904 ASSERT((imm12 & 0xfffff000) == 0); |
890 SetInstructionBits((orig & ~kImm12Mask) | (imm12 << kImm12Shift)); | 905 SetInstructionBits((orig & ~kImm12Mask) | (imm12 << kImm12Shift)); |
891 } | 906 } |
892 | 907 |
893 inline int NField() const { return Bit(22); } | 908 inline int NField() const { return Bit(22); } |
894 inline int SField() const { return Bit(kSShift); } | 909 inline int SField() const { return Bit(kSShift); } |
895 inline int SFField() const { return Bit(kSFShift); } | 910 inline int SFField() const { return Bit(kSFShift); } |
896 inline int SzField() const { return Bits(kSzShift, kSzBits); } | 911 inline int SzField() const { return Bits(kSzShift, kSzBits); } |
897 inline Register RdField() const { return static_cast<Register>( | 912 inline Register RdField() const { |
898 Bits(kRdShift, kRdBits)); } | 913 return static_cast<Register>(Bits(kRdShift, kRdBits)); |
899 inline Register RnField() const { return static_cast<Register>( | 914 } |
900 Bits(kRnShift, kRnBits)); } | 915 inline Register RnField() const { |
901 inline Register RaField() const { return static_cast<Register>( | 916 return static_cast<Register>(Bits(kRnShift, kRnBits)); |
902 Bits(kRaShift, kRaBits)); } | 917 } |
903 inline Register RmField() const { return static_cast<Register>( | 918 inline Register RaField() const { |
904 Bits(kRmShift, kRmBits)); } | 919 return static_cast<Register>(Bits(kRaShift, kRaBits)); |
905 inline Register RtField() const { return static_cast<Register>( | 920 } |
906 Bits(kRtShift, kRtBits)); } | 921 inline Register RmField() const { |
907 inline Register Rt2Field() const { return static_cast<Register>( | 922 return static_cast<Register>(Bits(kRmShift, kRmBits)); |
908 Bits(kRt2Shift, kRt2Bits)); } | 923 } |
909 inline Register RsField() const { return static_cast<Register>( | 924 inline Register RtField() const { |
910 Bits(kRsShift, kRsBits)); } | 925 return static_cast<Register>(Bits(kRtShift, kRtBits)); |
| 926 } |
| 927 inline Register Rt2Field() const { |
| 928 return static_cast<Register>(Bits(kRt2Shift, kRt2Bits)); |
| 929 } |
| 930 inline Register RsField() const { |
| 931 return static_cast<Register>(Bits(kRsShift, kRsBits)); |
| 932 } |
911 | 933 |
912 inline VRegister VdField() const { return static_cast<VRegister>( | 934 inline VRegister VdField() const { |
913 Bits(kVdShift, kVdBits)); } | 935 return static_cast<VRegister>(Bits(kVdShift, kVdBits)); |
914 inline VRegister VnField() const { return static_cast<VRegister>( | 936 } |
915 Bits(kVnShift, kVnBits)); } | 937 inline VRegister VnField() const { |
916 inline VRegister VmField() const { return static_cast<VRegister>( | 938 return static_cast<VRegister>(Bits(kVnShift, kVnBits)); |
917 Bits(kVmShift, kVmBits)); } | 939 } |
918 inline VRegister VtField() const { return static_cast<VRegister>( | 940 inline VRegister VmField() const { |
919 Bits(kVtShift, kVtBits)); } | 941 return static_cast<VRegister>(Bits(kVmShift, kVmBits)); |
| 942 } |
| 943 inline VRegister VtField() const { |
| 944 return static_cast<VRegister>(Bits(kVtShift, kVtBits)); |
| 945 } |
920 | 946 |
921 // Immediates | 947 // Immediates |
922 inline int Imm3Field() const { return Bits(kImm3Shift, kImm3Bits); } | 948 inline int Imm3Field() const { return Bits(kImm3Shift, kImm3Bits); } |
923 inline int Imm6Field() const { return Bits(kImm6Shift, kImm6Bits); } | 949 inline int Imm6Field() const { return Bits(kImm6Shift, kImm6Bits); } |
924 inline int Imm7Field() const { return Bits(kImm7Shift, kImm7Bits); } | 950 inline int Imm7Field() const { return Bits(kImm7Shift, kImm7Bits); } |
925 // Sign-extended Imm7Field() | 951 // Sign-extended Imm7Field() |
926 inline int64_t SImm7Field() const { | 952 inline int64_t SImm7Field() const { |
927 return (static_cast<int32_t>(Imm7Field()) << 25) >> 25; } | 953 return (static_cast<int32_t>(Imm7Field()) << 25) >> 25; |
| 954 } |
928 inline int Imm8Field() const { return Bits(kImm8Shift, kImm8Bits); } | 955 inline int Imm8Field() const { return Bits(kImm8Shift, kImm8Bits); } |
929 inline int Imm9Field() const { return Bits(kImm9Shift, kImm9Bits); } | 956 inline int Imm9Field() const { return Bits(kImm9Shift, kImm9Bits); } |
930 // Sign-extended Imm9Field() | 957 // Sign-extended Imm9Field() |
931 inline int64_t SImm9Field() const { | 958 inline int64_t SImm9Field() const { |
932 return (static_cast<int32_t>(Imm9Field()) << 23) >> 23; } | 959 return (static_cast<int32_t>(Imm9Field()) << 23) >> 23; |
| 960 } |
933 | 961 |
934 inline int Imm12Field() const { return Bits(kImm12Shift, kImm12Bits); } | 962 inline int Imm12Field() const { return Bits(kImm12Shift, kImm12Bits); } |
935 inline int Imm12ShiftField() const { | 963 inline int Imm12ShiftField() const { |
936 return Bits(kImm12ShiftShift, kImm12ShiftBits); } | 964 return Bits(kImm12ShiftShift, kImm12ShiftBits); |
| 965 } |
937 | 966 |
938 inline int Imm16Field() const { return Bits(kImm16Shift, kImm16Bits); } | 967 inline int Imm16Field() const { return Bits(kImm16Shift, kImm16Bits); } |
939 inline int HWField() const { return Bits(kHWShift, kHWBits); } | 968 inline int HWField() const { return Bits(kHWShift, kHWBits); } |
940 | 969 |
941 inline int ImmRField() const { return Bits(kImmRShift, kImmRBits); } | 970 inline int ImmRField() const { return Bits(kImmRShift, kImmRBits); } |
942 inline int ImmSField() const { return Bits(kImmSShift, kImmSBits); } | 971 inline int ImmSField() const { return Bits(kImmSShift, kImmSBits); } |
943 | 972 |
944 inline int Imm14Field() const { return Bits(kImm14Shift, kImm14Bits); } | 973 inline int Imm14Field() const { return Bits(kImm14Shift, kImm14Bits); } |
945 inline int64_t SImm14Field() const { | 974 inline int64_t SImm14Field() const { |
946 return (static_cast<int32_t>(Imm14Field()) << 18) >> 18; } | 975 return (static_cast<int32_t>(Imm14Field()) << 18) >> 18; |
| 976 } |
947 inline int Imm19Field() const { return Bits(kImm19Shift, kImm19Bits); } | 977 inline int Imm19Field() const { return Bits(kImm19Shift, kImm19Bits); } |
948 inline int64_t SImm19Field() const { | 978 inline int64_t SImm19Field() const { |
949 return (static_cast<int32_t>(Imm19Field()) << 13) >> 13; } | 979 return (static_cast<int32_t>(Imm19Field()) << 13) >> 13; |
| 980 } |
950 inline int Imm26Field() const { return Bits(kImm26Shift, kImm26Bits); } | 981 inline int Imm26Field() const { return Bits(kImm26Shift, kImm26Bits); } |
951 inline int64_t SImm26Field() const { | 982 inline int64_t SImm26Field() const { |
952 return (static_cast<int32_t>(Imm26Field()) << 6) >> 6; } | 983 return (static_cast<int32_t>(Imm26Field()) << 6) >> 6; |
| 984 } |
953 | 985 |
954 inline Condition ConditionField() const { | 986 inline Condition ConditionField() const { |
955 return static_cast<Condition>(Bits(kCondShift, kCondBits)); | 987 return static_cast<Condition>(Bits(kCondShift, kCondBits)); |
956 } | 988 } |
957 inline Condition SelectConditionField() const { | 989 inline Condition SelectConditionField() const { |
958 return static_cast<Condition>(Bits(kSelCondShift, kSelCondBits)); | 990 return static_cast<Condition>(Bits(kSelCondShift, kSelCondBits)); |
959 } | 991 } |
960 | 992 |
961 // Shift and Extend. | 993 // Shift and Extend. |
962 inline bool IsShift() const { | 994 inline bool IsShift() const { |
963 return IsLogicalShiftOp() || (Bit(kAddShiftExtendShift) == 0); | 995 return IsLogicalShiftOp() || (Bit(kAddShiftExtendShift) == 0); |
964 } | 996 } |
965 inline bool IsExtend() const { | 997 inline bool IsExtend() const { |
966 return !IsLogicalShiftOp() && (Bit(kAddShiftExtendShift) == 1); | 998 return !IsLogicalShiftOp() && (Bit(kAddShiftExtendShift) == 1); |
967 } | 999 } |
968 inline Shift ShiftTypeField() const { | 1000 inline Shift ShiftTypeField() const { |
969 return static_cast<Shift>(Bits(kShiftTypeShift, kShiftTypeBits)); } | 1001 return static_cast<Shift>(Bits(kShiftTypeShift, kShiftTypeBits)); |
| 1002 } |
970 inline Extend ExtendTypeField() const { | 1003 inline Extend ExtendTypeField() const { |
971 return static_cast<Extend>(Bits(kExtendTypeShift, kExtendTypeBits)); } | 1004 return static_cast<Extend>(Bits(kExtendTypeShift, kExtendTypeBits)); |
| 1005 } |
972 inline int ShiftAmountField() const { return Imm6Field(); } | 1006 inline int ShiftAmountField() const { return Imm6Field(); } |
973 inline int ExtShiftAmountField() const { return Imm3Field(); } | 1007 inline int ExtShiftAmountField() const { return Imm3Field(); } |
974 | 1008 |
975 // Instruction identification. | 1009 // Instruction identification. |
976 #define IS_OP(op) \ | 1010 #define IS_OP(op) \ |
977 inline bool Is##op##Op() const { \ | 1011 inline bool Is##op##Op() const { \ |
978 return ((InstructionBits() & op##Mask) == (op##Fixed & op##Mask)); } | 1012 return ((InstructionBits() & op##Mask) == (op##Fixed & op##Mask)); \ |
| 1013 } |
979 APPLY_OP_LIST(IS_OP) | 1014 APPLY_OP_LIST(IS_OP) |
980 #undef IS_OP | 1015 #undef IS_OP |
981 | 1016 |
982 inline bool HasS() const { return (SField() == 1); } | 1017 inline bool HasS() const { return (SField() == 1); } |
983 | 1018 |
984 // Indicate whether Rd can be the CSP or ZR. This does not check that the | 1019 // Indicate whether Rd can be the CSP or ZR. This does not check that the |
985 // instruction actually has an Rd field. | 1020 // instruction actually has an Rd field. |
986 R31Type RdMode() const { | 1021 R31Type RdMode() const { |
987 // The following instructions use CSP as Rd: | 1022 // The following instructions use CSP as Rd: |
988 // Add/sub (immediate) when not setting the flags. | 1023 // Add/sub (immediate) when not setting the flags. |
989 // Add/sub (extended) when not setting the flags. | 1024 // Add/sub (extended) when not setting the flags. |
990 // Logical (immediate) when not setting the flags. | 1025 // Logical (immediate) when not setting the flags. |
(...skipping 18 matching lines...) Expand all Loading... |
1009 } | 1044 } |
1010 | 1045 |
1011 // Indicate whether Rn can be CSP or ZR. This does not check that the | 1046 // Indicate whether Rn can be CSP or ZR. This does not check that the |
1012 // instruction actually has an Rn field. | 1047 // instruction actually has an Rn field. |
1013 R31Type RnMode() const { | 1048 R31Type RnMode() const { |
1014 // The following instructions use CSP as Rn: | 1049 // The following instructions use CSP as Rn: |
1015 // All loads and stores. | 1050 // All loads and stores. |
1016 // Add/sub (immediate). | 1051 // Add/sub (immediate). |
1017 // Add/sub (extended). | 1052 // Add/sub (extended). |
1018 // Otherwise, r31 is ZR. | 1053 // Otherwise, r31 is ZR. |
1019 if (IsLoadStoreOp() || | 1054 if (IsLoadStoreOp() || IsAddSubImmOp() || |
1020 IsAddSubImmOp() || | |
1021 (IsAddSubShiftExtOp() && IsExtend())) { | 1055 (IsAddSubShiftExtOp() && IsExtend())) { |
1022 return R31IsSP; | 1056 return R31IsSP; |
1023 } | 1057 } |
1024 return R31IsZR; | 1058 return R31IsZR; |
1025 } | 1059 } |
1026 | 1060 |
1027 // Logical immediates can't encode zero, so a return value of zero is used to | 1061 // Logical immediates can't encode zero, so a return value of zero is used to |
1028 // indicate a failure case. Specifically, where the constraints on imm_s are | 1062 // indicate a failure case. Specifically, where the constraints on imm_s are |
1029 // not met. | 1063 // not met. |
1030 uint64_t ImmLogical() { | 1064 uint64_t ImmLogical() { |
1031 const uint8_t reg_size = | 1065 const uint8_t reg_size = SFField() == 1 ? kXRegSizeInBits : kWRegSizeInBits; |
1032 SFField() == 1 ? kXRegSizeInBits : kWRegSizeInBits; | |
1033 const int64_t n = NField(); | 1066 const int64_t n = NField(); |
1034 const int64_t imm_s = ImmSField(); | 1067 const int64_t imm_s = ImmSField(); |
1035 const int64_t imm_r = ImmRField(); | 1068 const int64_t imm_r = ImmRField(); |
1036 | 1069 |
1037 // An integer is constructed from the n, imm_s and imm_r bits according to | 1070 // An integer is constructed from the n, imm_s and imm_r bits according to |
1038 // the following table: | 1071 // the following table: |
1039 // | 1072 // |
1040 // N imms immr size S R | 1073 // N imms immr size S R |
1041 // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr) | 1074 // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr) |
1042 // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr) | 1075 // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr) |
(...skipping 17 matching lines...) Expand all Loading... |
1060 if ((imm_s >> 1) == 0x1F) { | 1093 if ((imm_s >> 1) == 0x1F) { |
1061 return 0; | 1094 return 0; |
1062 } | 1095 } |
1063 for (int width = 0x20; width >= 0x2; width >>= 1) { | 1096 for (int width = 0x20; width >= 0x2; width >>= 1) { |
1064 if ((imm_s & width) == 0) { | 1097 if ((imm_s & width) == 0) { |
1065 int mask = width - 1; | 1098 int mask = width - 1; |
1066 if ((imm_s & mask) == mask) { | 1099 if ((imm_s & mask) == mask) { |
1067 return 0; | 1100 return 0; |
1068 } | 1101 } |
1069 uint64_t bits = (1UL << ((imm_s & mask) + 1)) - 1; | 1102 uint64_t bits = (1UL << ((imm_s & mask) + 1)) - 1; |
1070 return RepeatBitsAcrossReg(reg_size, | 1103 return RepeatBitsAcrossReg( |
1071 RotateRight(bits, imm_r & mask, width), | 1104 reg_size, RotateRight(bits, imm_r & mask, width), width); |
1072 width); | |
1073 } | 1105 } |
1074 } | 1106 } |
1075 } | 1107 } |
1076 UNREACHABLE(); | 1108 UNREACHABLE(); |
1077 return 0; | 1109 return 0; |
1078 } | 1110 } |
1079 | 1111 |
1080 static int64_t VFPExpandImm(uint8_t imm8) { | 1112 static int64_t VFPExpandImm(uint8_t imm8) { |
1081 const int64_t sign = | 1113 const int64_t sign = static_cast<int64_t>((imm8 & 0x80) >> 7) << 63; |
1082 static_cast<int64_t>((imm8 & 0x80) >> 7) << 63; | 1114 const int64_t hi_exp = static_cast<int64_t>(!((imm8 & 0x40) >> 6)) << 62; |
1083 const int64_t hi_exp = | 1115 const int64_t mid_exp = (((imm8 & 0x40) >> 6) == 0) ? 0 : (0xffLL << 54); |
1084 static_cast<int64_t>(!((imm8 & 0x40) >> 6)) << 62; | 1116 const int64_t low_exp = static_cast<int64_t>((imm8 & 0x30) >> 4) << 52; |
1085 const int64_t mid_exp = | 1117 const int64_t frac = static_cast<int64_t>(imm8 & 0x0f) << 48; |
1086 (((imm8 & 0x40) >> 6) == 0) ? 0 : (0xffLL << 54); | |
1087 const int64_t low_exp = | |
1088 static_cast<int64_t>((imm8 & 0x30) >> 4) << 52; | |
1089 const int64_t frac = | |
1090 static_cast<int64_t>(imm8 & 0x0f) << 48; | |
1091 return sign | hi_exp | mid_exp | low_exp | frac; | 1118 return sign | hi_exp | mid_exp | low_exp | frac; |
1092 } | 1119 } |
1093 | 1120 |
1094 // Instructions are read out of a code stream. The only way to get a | 1121 // Instructions are read out of a code stream. The only way to get a |
1095 // reference to an instruction is to convert a pointer. There is no way | 1122 // reference to an instruction is to convert a pointer. There is no way |
1096 // to allocate or create instances of class Instr. | 1123 // to allocate or create instances of class Instr. |
1097 // Use the At(pc) function to create references to Instr. | 1124 // Use the At(pc) function to create references to Instr. |
1098 static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); } | 1125 static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); } |
1099 | 1126 |
1100 private: | 1127 private: |
1101 DISALLOW_ALLOCATION(); | 1128 DISALLOW_ALLOCATION(); |
1102 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr); | 1129 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr); |
1103 }; | 1130 }; |
1104 | 1131 |
1105 } // namespace dart | 1132 } // namespace dart |
1106 | 1133 |
1107 #endif // RUNTIME_VM_CONSTANTS_ARM64_H_ | 1134 #endif // RUNTIME_VM_CONSTANTS_ARM64_H_ |
OLD | NEW |