| 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 VM_ASSEMBLER_ARM64_H_ | 5 #ifndef VM_ASSEMBLER_ARM64_H_ |
| 6 #define VM_ASSEMBLER_ARM64_H_ | 6 #define VM_ASSEMBLER_ARM64_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_arm64.h directly; use assembler.h instead. | 9 #error Do not include assembler_arm64.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 Unknown, | 92 Unknown, |
| 93 }; | 93 }; |
| 94 | 94 |
| 95 // Offset is in bytes. For the unsigned imm12 case, we unscale based on the | 95 // Offset is in bytes. For the unsigned imm12 case, we unscale based on the |
| 96 // operand size, and assert that offset is aligned accordingly. | 96 // operand size, and assert that offset is aligned accordingly. |
| 97 // For the smaller signed imm9 case, the offset is the number of bytes, but | 97 // For the smaller signed imm9 case, the offset is the number of bytes, but |
| 98 // is unscaled. | 98 // is unscaled. |
| 99 Address(Register rn, int32_t offset = 0, AddressType at = Offset, | 99 Address(Register rn, int32_t offset = 0, AddressType at = Offset, |
| 100 OperandSize sz = kDoubleWord) { | 100 OperandSize sz = kDoubleWord) { |
| 101 ASSERT((rn != R31) && (rn != ZR)); | 101 ASSERT((rn != R31) && (rn != ZR)); |
| 102 ASSERT(CanHoldOffset(offset, at, sz)); |
| 102 const Register crn = ConcreteRegister(rn); | 103 const Register crn = ConcreteRegister(rn); |
| 103 const int32_t scale = Log2OperandSizeBytes(sz); | 104 const int32_t scale = Log2OperandSizeBytes(sz); |
| 104 if (Utils::IsUint(12 + scale, offset) && (at == Offset)) { | 105 if ((at == Offset) && |
| 105 ASSERT(offset == ((offset >> scale) << scale)); | 106 Utils::IsUint(12 + scale, offset) && |
| 107 (offset == ((offset >> scale) << scale))) { |
| 106 encoding_ = | 108 encoding_ = |
| 107 B24 | | 109 B24 | |
| 108 ((offset >> scale) << kImm12Shift) | | 110 ((offset >> scale) << kImm12Shift) | |
| 109 (static_cast<int32_t>(crn) << kRnShift); | 111 (static_cast<int32_t>(crn) << kRnShift); |
| 112 } else if ((at == Offset) && |
| 113 Utils::IsInt(9, offset)) { |
| 114 encoding_ = |
| 115 ((offset & 0x1ff) << kImm9Shift) | |
| 116 (static_cast<int32_t>(crn) << kRnShift); |
| 110 } else { | 117 } else { |
| 111 ASSERT(Utils::IsInt(9, offset)); | 118 ASSERT(Utils::IsInt(9, offset)); |
| 112 ASSERT((at == PreIndex) || (at == PostIndex)); | 119 ASSERT((at == PreIndex) || (at == PostIndex)); |
| 113 int32_t idx = (at == PostIndex) ? B10 : (B11 | B10); | 120 int32_t idx = (at == PostIndex) ? B10 : (B11 | B10); |
| 114 encoding_ = | 121 encoding_ = |
| 115 idx | | 122 idx | |
| 116 ((offset & 0x1ff) << kImm9Shift) | | 123 ((offset & 0x1ff) << kImm9Shift) | |
| 117 (static_cast<int32_t>(crn) << kRnShift); | 124 (static_cast<int32_t>(crn) << kRnShift); |
| 118 } | 125 } |
| 119 type_ = at; | 126 type_ = at; |
| 120 base_ = crn; | 127 base_ = crn; |
| 121 } | 128 } |
| 122 | 129 |
| 123 static bool CanHoldOffset(int32_t offset, AddressType at = Offset, | 130 static bool CanHoldOffset(int32_t offset, AddressType at = Offset, |
| 124 OperandSize sz = kDoubleWord) { | 131 OperandSize sz = kDoubleWord) { |
| 125 if (at == Offset) { | 132 if (at == Offset) { |
| 126 // Fits in 12 bit unsigned and right alignment for sz. | 133 // Offset fits in 12 bit unsigned and has right alignment for sz, |
| 134 // or fits in 9 bit signed offset with no alignment restriction. |
| 127 const int32_t scale = Log2OperandSizeBytes(sz); | 135 const int32_t scale = Log2OperandSizeBytes(sz); |
| 128 return Utils::IsUint(12 + scale, offset) && | 136 return (Utils::IsUint(12 + scale, offset) && |
| 129 (offset == ((offset >> scale) << scale)); | 137 (offset == ((offset >> scale) << scale))) || |
| 138 (Utils::IsInt(9, offset)); |
| 130 } else if (at == PCOffset) { | 139 } else if (at == PCOffset) { |
| 131 return Utils::IsInt(21, offset) && | 140 return Utils::IsInt(21, offset) && |
| 132 (offset == ((offset >> 2) << 2)); | 141 (offset == ((offset >> 2) << 2)); |
| 133 } else { | 142 } else { |
| 134 ASSERT((at == PreIndex) || (at == PostIndex)); | 143 ASSERT((at == PreIndex) || (at == PostIndex)); |
| 135 return Utils::IsInt(9, offset); | 144 return Utils::IsInt(9, offset); |
| 136 } | 145 } |
| 137 } | 146 } |
| 138 | 147 |
| 139 // PC-relative load address. | 148 // PC-relative load address. |
| (...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 Emit(encoding); | 1002 Emit(encoding); |
| 994 } | 1003 } |
| 995 | 1004 |
| 996 DISALLOW_ALLOCATION(); | 1005 DISALLOW_ALLOCATION(); |
| 997 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1006 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 998 }; | 1007 }; |
| 999 | 1008 |
| 1000 } // namespace dart | 1009 } // namespace dart |
| 1001 | 1010 |
| 1002 #endif // VM_ASSEMBLER_ARM64_H_ | 1011 #endif // VM_ASSEMBLER_ARM64_H_ |
| OLD | NEW |