OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_X64_ASSEMBLER_X64_INL_H_ | 5 #ifndef V8_X64_ASSEMBLER_X64_INL_H_ |
6 #define V8_X64_ASSEMBLER_X64_INL_H_ | 6 #define V8_X64_ASSEMBLER_X64_INL_H_ |
7 | 7 |
8 #include "src/x64/assembler-x64.h" | 8 #include "src/x64/assembler-x64.h" |
9 | 9 |
10 #include "src/base/cpu.h" | 10 #include "src/base/cpu.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 | 50 |
51 void Assembler::emitw(uint16_t x) { | 51 void Assembler::emitw(uint16_t x) { |
52 Memory::uint16_at(pc_) = x; | 52 Memory::uint16_at(pc_) = x; |
53 pc_ += sizeof(uint16_t); | 53 pc_ += sizeof(uint16_t); |
54 } | 54 } |
55 | 55 |
56 | 56 |
57 void Assembler::emit_code_target(Handle<Code> target, | 57 void Assembler::emit_code_target(Handle<Code> target, |
58 RelocInfo::Mode rmode, | 58 RelocInfo::Mode rmode, |
59 TypeFeedbackId ast_id) { | 59 TypeFeedbackId ast_id) { |
60 ASSERT(RelocInfo::IsCodeTarget(rmode) || | 60 DCHECK(RelocInfo::IsCodeTarget(rmode) || |
61 rmode == RelocInfo::CODE_AGE_SEQUENCE); | 61 rmode == RelocInfo::CODE_AGE_SEQUENCE); |
62 if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) { | 62 if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) { |
63 RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, ast_id.ToInt()); | 63 RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, ast_id.ToInt()); |
64 } else { | 64 } else { |
65 RecordRelocInfo(rmode); | 65 RecordRelocInfo(rmode); |
66 } | 66 } |
67 int current = code_targets_.length(); | 67 int current = code_targets_.length(); |
68 if (current > 0 && code_targets_.last().is_identical_to(target)) { | 68 if (current > 0 && code_targets_.last().is_identical_to(target)) { |
69 // Optimization if we keep jumping to the same code target. | 69 // Optimization if we keep jumping to the same code target. |
70 emitl(current - 1); | 70 emitl(current - 1); |
71 } else { | 71 } else { |
72 code_targets_.Add(target); | 72 code_targets_.Add(target); |
73 emitl(current); | 73 emitl(current); |
74 } | 74 } |
75 } | 75 } |
76 | 76 |
77 | 77 |
78 void Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) { | 78 void Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) { |
79 ASSERT(RelocInfo::IsRuntimeEntry(rmode)); | 79 DCHECK(RelocInfo::IsRuntimeEntry(rmode)); |
80 RecordRelocInfo(rmode); | 80 RecordRelocInfo(rmode); |
81 emitl(static_cast<uint32_t>(entry - isolate()->code_range()->start())); | 81 emitl(static_cast<uint32_t>(entry - isolate()->code_range()->start())); |
82 } | 82 } |
83 | 83 |
84 | 84 |
85 void Assembler::emit_rex_64(Register reg, Register rm_reg) { | 85 void Assembler::emit_rex_64(Register reg, Register rm_reg) { |
86 emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit()); | 86 emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit()); |
87 } | 87 } |
88 | 88 |
89 | 89 |
(...skipping 11 matching lines...) Expand all Loading... |
101 emit(0x48 | reg.high_bit() << 2 | op.rex_); | 101 emit(0x48 | reg.high_bit() << 2 | op.rex_); |
102 } | 102 } |
103 | 103 |
104 | 104 |
105 void Assembler::emit_rex_64(XMMRegister reg, const Operand& op) { | 105 void Assembler::emit_rex_64(XMMRegister reg, const Operand& op) { |
106 emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_); | 106 emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_); |
107 } | 107 } |
108 | 108 |
109 | 109 |
110 void Assembler::emit_rex_64(Register rm_reg) { | 110 void Assembler::emit_rex_64(Register rm_reg) { |
111 ASSERT_EQ(rm_reg.code() & 0xf, rm_reg.code()); | 111 DCHECK_EQ(rm_reg.code() & 0xf, rm_reg.code()); |
112 emit(0x48 | rm_reg.high_bit()); | 112 emit(0x48 | rm_reg.high_bit()); |
113 } | 113 } |
114 | 114 |
115 | 115 |
116 void Assembler::emit_rex_64(const Operand& op) { | 116 void Assembler::emit_rex_64(const Operand& op) { |
117 emit(0x48 | op.rex_); | 117 emit(0x48 | op.rex_); |
118 } | 118 } |
119 | 119 |
120 | 120 |
121 void Assembler::emit_rex_32(Register reg, Register rm_reg) { | 121 void Assembler::emit_rex_32(Register reg, Register rm_reg) { |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 if (*pc_ == kCallOpcode) { | 232 if (*pc_ == kCallOpcode) { |
233 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 233 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
234 *p -= static_cast<int32_t>(delta); // Relocate entry. | 234 *p -= static_cast<int32_t>(delta); // Relocate entry. |
235 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | 235 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); |
236 } | 236 } |
237 } | 237 } |
238 } | 238 } |
239 | 239 |
240 | 240 |
241 Address RelocInfo::target_address() { | 241 Address RelocInfo::target_address() { |
242 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 242 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
243 return Assembler::target_address_at(pc_, host_); | 243 return Assembler::target_address_at(pc_, host_); |
244 } | 244 } |
245 | 245 |
246 | 246 |
247 Address RelocInfo::target_address_address() { | 247 Address RelocInfo::target_address_address() { |
248 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) | 248 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) |
249 || rmode_ == EMBEDDED_OBJECT | 249 || rmode_ == EMBEDDED_OBJECT |
250 || rmode_ == EXTERNAL_REFERENCE); | 250 || rmode_ == EXTERNAL_REFERENCE); |
251 return reinterpret_cast<Address>(pc_); | 251 return reinterpret_cast<Address>(pc_); |
252 } | 252 } |
253 | 253 |
254 | 254 |
255 Address RelocInfo::constant_pool_entry_address() { | 255 Address RelocInfo::constant_pool_entry_address() { |
256 UNREACHABLE(); | 256 UNREACHABLE(); |
257 return NULL; | 257 return NULL; |
258 } | 258 } |
259 | 259 |
260 | 260 |
261 int RelocInfo::target_address_size() { | 261 int RelocInfo::target_address_size() { |
262 if (IsCodedSpecially()) { | 262 if (IsCodedSpecially()) { |
263 return Assembler::kSpecialTargetSize; | 263 return Assembler::kSpecialTargetSize; |
264 } else { | 264 } else { |
265 return kPointerSize; | 265 return kPointerSize; |
266 } | 266 } |
267 } | 267 } |
268 | 268 |
269 | 269 |
270 void RelocInfo::set_target_address(Address target, | 270 void RelocInfo::set_target_address(Address target, |
271 WriteBarrierMode write_barrier_mode, | 271 WriteBarrierMode write_barrier_mode, |
272 ICacheFlushMode icache_flush_mode) { | 272 ICacheFlushMode icache_flush_mode) { |
273 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 273 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
274 Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode); | 274 Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode); |
275 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL && | 275 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL && |
276 IsCodeTarget(rmode_)) { | 276 IsCodeTarget(rmode_)) { |
277 Object* target_code = Code::GetCodeFromTargetAddress(target); | 277 Object* target_code = Code::GetCodeFromTargetAddress(target); |
278 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 278 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
279 host(), this, HeapObject::cast(target_code)); | 279 host(), this, HeapObject::cast(target_code)); |
280 } | 280 } |
281 } | 281 } |
282 | 282 |
283 | 283 |
284 Object* RelocInfo::target_object() { | 284 Object* RelocInfo::target_object() { |
285 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 285 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
286 return Memory::Object_at(pc_); | 286 return Memory::Object_at(pc_); |
287 } | 287 } |
288 | 288 |
289 | 289 |
290 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { | 290 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { |
291 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 291 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
292 if (rmode_ == EMBEDDED_OBJECT) { | 292 if (rmode_ == EMBEDDED_OBJECT) { |
293 return Memory::Object_Handle_at(pc_); | 293 return Memory::Object_Handle_at(pc_); |
294 } else { | 294 } else { |
295 return origin->code_target_object_handle_at(pc_); | 295 return origin->code_target_object_handle_at(pc_); |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 | 299 |
300 Address RelocInfo::target_reference() { | 300 Address RelocInfo::target_reference() { |
301 ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE); | 301 DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE); |
302 return Memory::Address_at(pc_); | 302 return Memory::Address_at(pc_); |
303 } | 303 } |
304 | 304 |
305 | 305 |
306 void RelocInfo::set_target_object(Object* target, | 306 void RelocInfo::set_target_object(Object* target, |
307 WriteBarrierMode write_barrier_mode, | 307 WriteBarrierMode write_barrier_mode, |
308 ICacheFlushMode icache_flush_mode) { | 308 ICacheFlushMode icache_flush_mode) { |
309 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 309 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
310 Memory::Object_at(pc_) = target; | 310 Memory::Object_at(pc_) = target; |
311 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 311 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
312 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 312 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
313 } | 313 } |
314 if (write_barrier_mode == UPDATE_WRITE_BARRIER && | 314 if (write_barrier_mode == UPDATE_WRITE_BARRIER && |
315 host() != NULL && | 315 host() != NULL && |
316 target->IsHeapObject()) { | 316 target->IsHeapObject()) { |
317 host()->GetHeap()->incremental_marking()->RecordWrite( | 317 host()->GetHeap()->incremental_marking()->RecordWrite( |
318 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); | 318 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); |
319 } | 319 } |
320 } | 320 } |
321 | 321 |
322 | 322 |
323 Address RelocInfo::target_runtime_entry(Assembler* origin) { | 323 Address RelocInfo::target_runtime_entry(Assembler* origin) { |
324 ASSERT(IsRuntimeEntry(rmode_)); | 324 DCHECK(IsRuntimeEntry(rmode_)); |
325 return origin->runtime_entry_at(pc_); | 325 return origin->runtime_entry_at(pc_); |
326 } | 326 } |
327 | 327 |
328 | 328 |
329 void RelocInfo::set_target_runtime_entry(Address target, | 329 void RelocInfo::set_target_runtime_entry(Address target, |
330 WriteBarrierMode write_barrier_mode, | 330 WriteBarrierMode write_barrier_mode, |
331 ICacheFlushMode icache_flush_mode) { | 331 ICacheFlushMode icache_flush_mode) { |
332 ASSERT(IsRuntimeEntry(rmode_)); | 332 DCHECK(IsRuntimeEntry(rmode_)); |
333 if (target_address() != target) { | 333 if (target_address() != target) { |
334 set_target_address(target, write_barrier_mode, icache_flush_mode); | 334 set_target_address(target, write_barrier_mode, icache_flush_mode); |
335 } | 335 } |
336 } | 336 } |
337 | 337 |
338 | 338 |
339 Handle<Cell> RelocInfo::target_cell_handle() { | 339 Handle<Cell> RelocInfo::target_cell_handle() { |
340 ASSERT(rmode_ == RelocInfo::CELL); | 340 DCHECK(rmode_ == RelocInfo::CELL); |
341 Address address = Memory::Address_at(pc_); | 341 Address address = Memory::Address_at(pc_); |
342 return Handle<Cell>(reinterpret_cast<Cell**>(address)); | 342 return Handle<Cell>(reinterpret_cast<Cell**>(address)); |
343 } | 343 } |
344 | 344 |
345 | 345 |
346 Cell* RelocInfo::target_cell() { | 346 Cell* RelocInfo::target_cell() { |
347 ASSERT(rmode_ == RelocInfo::CELL); | 347 DCHECK(rmode_ == RelocInfo::CELL); |
348 return Cell::FromValueAddress(Memory::Address_at(pc_)); | 348 return Cell::FromValueAddress(Memory::Address_at(pc_)); |
349 } | 349 } |
350 | 350 |
351 | 351 |
352 void RelocInfo::set_target_cell(Cell* cell, | 352 void RelocInfo::set_target_cell(Cell* cell, |
353 WriteBarrierMode write_barrier_mode, | 353 WriteBarrierMode write_barrier_mode, |
354 ICacheFlushMode icache_flush_mode) { | 354 ICacheFlushMode icache_flush_mode) { |
355 ASSERT(rmode_ == RelocInfo::CELL); | 355 DCHECK(rmode_ == RelocInfo::CELL); |
356 Address address = cell->address() + Cell::kValueOffset; | 356 Address address = cell->address() + Cell::kValueOffset; |
357 Memory::Address_at(pc_) = address; | 357 Memory::Address_at(pc_) = address; |
358 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 358 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
359 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 359 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
360 } | 360 } |
361 if (write_barrier_mode == UPDATE_WRITE_BARRIER && | 361 if (write_barrier_mode == UPDATE_WRITE_BARRIER && |
362 host() != NULL) { | 362 host() != NULL) { |
363 // TODO(1550) We are passing NULL as a slot because cell can never be on | 363 // TODO(1550) We are passing NULL as a slot because cell can never be on |
364 // evacuation candidate. | 364 // evacuation candidate. |
365 host()->GetHeap()->incremental_marking()->RecordWrite( | 365 host()->GetHeap()->incremental_marking()->RecordWrite( |
(...skipping 25 matching lines...) Expand all Loading... |
391 0xCC; | 391 0xCC; |
392 } | 392 } |
393 | 393 |
394 | 394 |
395 bool RelocInfo::IsPatchedDebugBreakSlotSequence() { | 395 bool RelocInfo::IsPatchedDebugBreakSlotSequence() { |
396 return !Assembler::IsNop(pc()); | 396 return !Assembler::IsNop(pc()); |
397 } | 397 } |
398 | 398 |
399 | 399 |
400 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { | 400 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { |
401 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 401 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
402 ASSERT(*pc_ == kCallOpcode); | 402 DCHECK(*pc_ == kCallOpcode); |
403 return origin->code_target_object_handle_at(pc_ + 1); | 403 return origin->code_target_object_handle_at(pc_ + 1); |
404 } | 404 } |
405 | 405 |
406 | 406 |
407 Code* RelocInfo::code_age_stub() { | 407 Code* RelocInfo::code_age_stub() { |
408 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 408 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
409 ASSERT(*pc_ == kCallOpcode); | 409 DCHECK(*pc_ == kCallOpcode); |
410 return Code::GetCodeFromTargetAddress( | 410 return Code::GetCodeFromTargetAddress( |
411 Assembler::target_address_at(pc_ + 1, host_)); | 411 Assembler::target_address_at(pc_ + 1, host_)); |
412 } | 412 } |
413 | 413 |
414 | 414 |
415 void RelocInfo::set_code_age_stub(Code* stub, | 415 void RelocInfo::set_code_age_stub(Code* stub, |
416 ICacheFlushMode icache_flush_mode) { | 416 ICacheFlushMode icache_flush_mode) { |
417 ASSERT(*pc_ == kCallOpcode); | 417 DCHECK(*pc_ == kCallOpcode); |
418 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 418 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
419 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), | 419 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), |
420 icache_flush_mode); | 420 icache_flush_mode); |
421 } | 421 } |
422 | 422 |
423 | 423 |
424 Address RelocInfo::call_address() { | 424 Address RelocInfo::call_address() { |
425 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 425 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
426 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 426 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
427 return Memory::Address_at( | 427 return Memory::Address_at( |
428 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset); | 428 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset); |
429 } | 429 } |
430 | 430 |
431 | 431 |
432 void RelocInfo::set_call_address(Address target) { | 432 void RelocInfo::set_call_address(Address target) { |
433 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 433 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
434 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 434 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
435 Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) = | 435 Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) = |
436 target; | 436 target; |
437 CpuFeatures::FlushICache( | 437 CpuFeatures::FlushICache( |
438 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset, sizeof(Address)); | 438 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset, sizeof(Address)); |
439 if (host() != NULL) { | 439 if (host() != NULL) { |
440 Object* target_code = Code::GetCodeFromTargetAddress(target); | 440 Object* target_code = Code::GetCodeFromTargetAddress(target); |
441 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 441 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
442 host(), this, HeapObject::cast(target_code)); | 442 host(), this, HeapObject::cast(target_code)); |
443 } | 443 } |
444 } | 444 } |
445 | 445 |
446 | 446 |
447 Object* RelocInfo::call_object() { | 447 Object* RelocInfo::call_object() { |
448 return *call_object_address(); | 448 return *call_object_address(); |
449 } | 449 } |
450 | 450 |
451 | 451 |
452 void RelocInfo::set_call_object(Object* target) { | 452 void RelocInfo::set_call_object(Object* target) { |
453 *call_object_address() = target; | 453 *call_object_address() = target; |
454 } | 454 } |
455 | 455 |
456 | 456 |
457 Object** RelocInfo::call_object_address() { | 457 Object** RelocInfo::call_object_address() { |
458 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 458 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
459 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 459 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
460 return reinterpret_cast<Object**>( | 460 return reinterpret_cast<Object**>( |
461 pc_ + Assembler::kPatchReturnSequenceAddressOffset); | 461 pc_ + Assembler::kPatchReturnSequenceAddressOffset); |
462 } | 462 } |
463 | 463 |
464 | 464 |
465 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { | 465 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { |
466 RelocInfo::Mode mode = rmode(); | 466 RelocInfo::Mode mode = rmode(); |
467 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 467 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
468 visitor->VisitEmbeddedPointer(this); | 468 visitor->VisitEmbeddedPointer(this); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 512 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
513 StaticVisitor::VisitRuntimeEntry(this); | 513 StaticVisitor::VisitRuntimeEntry(this); |
514 } | 514 } |
515 } | 515 } |
516 | 516 |
517 | 517 |
518 // ----------------------------------------------------------------------------- | 518 // ----------------------------------------------------------------------------- |
519 // Implementation of Operand | 519 // Implementation of Operand |
520 | 520 |
521 void Operand::set_modrm(int mod, Register rm_reg) { | 521 void Operand::set_modrm(int mod, Register rm_reg) { |
522 ASSERT(is_uint2(mod)); | 522 DCHECK(is_uint2(mod)); |
523 buf_[0] = mod << 6 | rm_reg.low_bits(); | 523 buf_[0] = mod << 6 | rm_reg.low_bits(); |
524 // Set REX.B to the high bit of rm.code(). | 524 // Set REX.B to the high bit of rm.code(). |
525 rex_ |= rm_reg.high_bit(); | 525 rex_ |= rm_reg.high_bit(); |
526 } | 526 } |
527 | 527 |
528 | 528 |
529 void Operand::set_sib(ScaleFactor scale, Register index, Register base) { | 529 void Operand::set_sib(ScaleFactor scale, Register index, Register base) { |
530 ASSERT(len_ == 1); | 530 DCHECK(len_ == 1); |
531 ASSERT(is_uint2(scale)); | 531 DCHECK(is_uint2(scale)); |
532 // Use SIB with no index register only for base rsp or r12. Otherwise we | 532 // Use SIB with no index register only for base rsp or r12. Otherwise we |
533 // would skip the SIB byte entirely. | 533 // would skip the SIB byte entirely. |
534 ASSERT(!index.is(rsp) || base.is(rsp) || base.is(r12)); | 534 DCHECK(!index.is(rsp) || base.is(rsp) || base.is(r12)); |
535 buf_[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits(); | 535 buf_[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits(); |
536 rex_ |= index.high_bit() << 1 | base.high_bit(); | 536 rex_ |= index.high_bit() << 1 | base.high_bit(); |
537 len_ = 2; | 537 len_ = 2; |
538 } | 538 } |
539 | 539 |
540 void Operand::set_disp8(int disp) { | 540 void Operand::set_disp8(int disp) { |
541 ASSERT(is_int8(disp)); | 541 DCHECK(is_int8(disp)); |
542 ASSERT(len_ == 1 || len_ == 2); | 542 DCHECK(len_ == 1 || len_ == 2); |
543 int8_t* p = reinterpret_cast<int8_t*>(&buf_[len_]); | 543 int8_t* p = reinterpret_cast<int8_t*>(&buf_[len_]); |
544 *p = disp; | 544 *p = disp; |
545 len_ += sizeof(int8_t); | 545 len_ += sizeof(int8_t); |
546 } | 546 } |
547 | 547 |
548 void Operand::set_disp32(int disp) { | 548 void Operand::set_disp32(int disp) { |
549 ASSERT(len_ == 1 || len_ == 2); | 549 DCHECK(len_ == 1 || len_ == 2); |
550 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); | 550 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); |
551 *p = disp; | 551 *p = disp; |
552 len_ += sizeof(int32_t); | 552 len_ += sizeof(int32_t); |
553 } | 553 } |
554 | 554 |
555 | 555 |
556 } } // namespace v8::internal | 556 } } // namespace v8::internal |
557 | 557 |
558 #endif // V8_X64_ASSEMBLER_X64_INL_H_ | 558 #endif // V8_X64_ASSEMBLER_X64_INL_H_ |
OLD | NEW |