| 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 |