Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(956)

Side by Side Diff: runtime/vm/instructions_arm64.cc

Issue 274043003: Adds debugger patching to arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/instructions_arm64.h ('k') | runtime/vm/instructions_arm64_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/constants_arm64.h" 9 #include "vm/constants_arm64.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 16 matching lines...) Expand all
27 27
28 Register reg; 28 Register reg;
29 ic_data_load_end_ = 29 ic_data_load_end_ =
30 InstructionPattern::DecodeLoadWordFromPool(end_ - Instr::kInstrSize, 30 InstructionPattern::DecodeLoadWordFromPool(end_ - Instr::kInstrSize,
31 &reg, 31 &reg,
32 &target_address_pool_index_); 32 &target_address_pool_index_);
33 ASSERT(reg == IP0); 33 ASSERT(reg == IP0);
34 } 34 }
35 35
36 36
37 intptr_t InstructionPattern::OffsetFromPPIndex(intptr_t index) {
38 return Array::element_offset(index);
39 }
40
41
37 // Decodes a load sequence ending at 'end' (the last instruction of the load 42 // Decodes a load sequence ending at 'end' (the last instruction of the load
38 // sequence is the instruction before the one at end). Returns a pointer to 43 // sequence is the instruction before the one at end). Returns a pointer to
39 // the first instruction in the sequence. Returns the register being loaded 44 // the first instruction in the sequence. Returns the register being loaded
40 // and the loaded object in the output parameters 'reg' and 'obj' 45 // and the loaded object in the output parameters 'reg' and 'obj'
41 // respectively. 46 // respectively.
42 uword InstructionPattern::DecodeLoadObject(uword end, 47 uword InstructionPattern::DecodeLoadObject(uword end,
43 const Array& object_pool, 48 const Array& object_pool,
44 Register* reg, 49 Register* reg,
45 Object* obj) { 50 Object* obj) {
46 // 1. LoadWordFromPool 51 // 1. LoadWordFromPool
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 // Decodes a load sequence ending at 'end' (the last instruction of the load 145 // Decodes a load sequence ending at 'end' (the last instruction of the load
141 // sequence is the instruction before the one at end). Returns a pointer to 146 // sequence is the instruction before the one at end). Returns a pointer to
142 // the first instruction in the sequence. Returns the register being loaded 147 // the first instruction in the sequence. Returns the register being loaded
143 // and the index in the pool being read from in the output parameters 'reg' 148 // and the index in the pool being read from in the output parameters 'reg'
144 // and 'index' respectively. 149 // and 'index' respectively.
145 uword InstructionPattern::DecodeLoadWordFromPool(uword end, 150 uword InstructionPattern::DecodeLoadWordFromPool(uword end,
146 Register* reg, 151 Register* reg,
147 intptr_t* index) { 152 intptr_t* index) {
148 // 1. ldr dst, [pp, offset] 153 // 1. ldr dst, [pp, offset]
149 // or 154 // or
150 // 2. movz dst, low_offset, 0 155 // 2. add dst, pp, #offset_hi12
156 // ldr dst [dst, #offset_lo12]
157 // or
158 // 3. movz dst, low_offset, 0
151 // movk dst, hi_offset, 1 (optional) 159 // movk dst, hi_offset, 1 (optional)
152 // ldr dst, [pp, dst] 160 // ldr dst, [pp, dst]
153 uword start = end - Instr::kInstrSize; 161 uword start = end - Instr::kInstrSize;
154 Instr* instr = Instr::At(start); 162 Instr* instr = Instr::At(start);
155 intptr_t offset = 0; 163 intptr_t offset = 0;
156 164
157 // Last instruction is always an ldr into a 64-bit X register. 165 // Last instruction is always an ldr into a 64-bit X register.
158 ASSERT(instr->IsLoadStoreRegOp() && (instr->Bit(22) == 1) && 166 ASSERT(instr->IsLoadStoreRegOp() && (instr->Bit(22) == 1) &&
159 (instr->Bits(30, 2) == 3)); 167 (instr->Bits(30, 2) == 3));
160 168
161 // Grab the destination register from the ldr instruction. 169 // Grab the destination register from the ldr instruction.
162 *reg = instr->RtField(); 170 *reg = instr->RtField();
163 171
164 if (instr->Bit(24) == 1) { 172 if (instr->Bit(24) == 1) {
165 // pp + scaled unsigned 12-bit immediate offset. 173 // base + scaled unsigned 12-bit immediate offset.
166 // Case 1. 174 // Case 1.
167 offset = instr->Imm12Field() << 3; 175 offset |= (instr->Imm12Field() << 3);
176 if (instr->RnField() == *reg) {
177 start -= Instr::kInstrSize;
178 instr = Instr::At(start);
179 ASSERT(instr->IsAddSubImmOp());
180 ASSERT(instr->RnField() == PP);
181 ASSERT(instr->RdField() == *reg);
182 offset |= (instr->Imm12Field() << 12);
183 }
168 } else { 184 } else {
169 ASSERT(instr->Bits(10, 2) == 2); 185 ASSERT(instr->Bits(10, 2) == 2);
170 // We have to look at the preceding one or two instructions to find the 186 // We have to look at the preceding one or two instructions to find the
171 // offset. 187 // offset.
172 188
173 start -= Instr::kInstrSize; 189 start -= Instr::kInstrSize;
174 instr = Instr::At(start); 190 instr = Instr::At(start);
175 ASSERT(instr->IsMoveWideOp()); 191 ASSERT(instr->IsMoveWideOp());
176 ASSERT(instr->RdField() == *reg); 192 ASSERT(instr->RdField() == *reg);
177 if (instr->Bits(29, 2) == 2) { // movz dst, low_offset, 0 193 if (instr->Bits(29, 2) == 2) { // movz dst, low_offset, 0
(...skipping 13 matching lines...) Expand all
191 ASSERT(instr->HWField() == 0); 207 ASSERT(instr->HWField() == 0);
192 offset |= instr->Imm16Field(); 208 offset |= instr->Imm16Field();
193 } 209 }
194 } 210 }
195 ASSERT(Utils::IsAligned(offset, 8)); 211 ASSERT(Utils::IsAligned(offset, 8));
196 *index = (offset - Array::data_offset()) / 8; 212 *index = (offset - Array::data_offset()) / 8;
197 return start; 213 return start;
198 } 214 }
199 215
200 216
217 // Encodes a load sequence ending at 'end'. Encodes a fixed length two
218 // instruction load from the pool pointer in PP using the destination
219 // register reg as a temporary for the base address.
220 // Assumes that the location has already been validated for patching.
221 void InstructionPattern::EncodeLoadWordFromPoolFixed(uword end,
222 int32_t offset) {
223 uword start = end - Instr::kInstrSize;
224 Instr* instr = Instr::At(start);
225 const int32_t upper12 = offset & 0x00fff000;
226 const int32_t lower12 = offset & 0x00000fff;
227 ASSERT((offset & 0xff000000) == 0); // Can't encode > 24 bits.
228 ASSERT(((lower12 >> 3) << 3) == lower12); // 8-byte aligned.
229 instr->SetImm12Bits(instr->InstructionBits(), lower12 >> 3);
230
231 start -= Instr::kInstrSize;
232 instr = Instr::At(start);
233 instr->SetImm12Bits(instr->InstructionBits(), upper12 >> 12);
234 instr->SetInstructionBits(instr->InstructionBits() | B22);
235 }
236
237
201 RawICData* CallPattern::IcData() { 238 RawICData* CallPattern::IcData() {
202 if (ic_data_.IsNull()) { 239 if (ic_data_.IsNull()) {
203 Register reg; 240 Register reg;
204 args_desc_load_end_ = 241 args_desc_load_end_ =
205 InstructionPattern::DecodeLoadObject(ic_data_load_end_, 242 InstructionPattern::DecodeLoadObject(ic_data_load_end_,
206 object_pool_, 243 object_pool_,
207 &reg, 244 &reg,
208 &ic_data_); 245 &ic_data_);
209 ASSERT(reg == R5); 246 ASSERT(reg == R5);
210 } 247 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 movz0->SetInstructionBits((movz0_bits & ~kImm16Mask) | (h0 << kImm16Shift)); 361 movz0->SetInstructionBits((movz0_bits & ~kImm16Mask) | (h0 << kImm16Shift));
325 movk1->SetInstructionBits((movk1_bits & ~kImm16Mask) | (h1 << kImm16Shift)); 362 movk1->SetInstructionBits((movk1_bits & ~kImm16Mask) | (h1 << kImm16Shift));
326 movk2->SetInstructionBits((movk2_bits & ~kImm16Mask) | (h2 << kImm16Shift)); 363 movk2->SetInstructionBits((movk2_bits & ~kImm16Mask) | (h2 << kImm16Shift));
327 movk3->SetInstructionBits((movk3_bits & ~kImm16Mask) | (h3 << kImm16Shift)); 364 movk3->SetInstructionBits((movk3_bits & ~kImm16Mask) | (h3 << kImm16Shift));
328 CPU::FlushICache(pc_, 4 * Instr::kInstrSize); 365 CPU::FlushICache(pc_, 4 * Instr::kInstrSize);
329 } 366 }
330 367
331 } // namespace dart 368 } // namespace dart
332 369
333 #endif // defined TARGET_ARCH_ARM64 370 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/instructions_arm64.h ('k') | runtime/vm/instructions_arm64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698