OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 #include "macro-assembler.h" | 32 #include "macro-assembler.h" |
33 #include "serialize.h" | 33 #include "serialize.h" |
34 | 34 |
35 namespace v8 { | 35 namespace v8 { |
36 namespace internal { | 36 namespace internal { |
37 | 37 |
38 // ----------------------------------------------------------------------------- | 38 // ----------------------------------------------------------------------------- |
39 // Implementation of CpuFeatures | 39 // Implementation of CpuFeatures |
40 | 40 |
41 // The required user mode extensions in X64 are (from AMD64 ABI Table A.1): | 41 CpuFeatures::CpuFeatures() |
42 // fpu, tsc, cx8, cmov, mmx, sse, sse2, fxsr, syscall | 42 : supported_(kDefaultCpuFeatures), |
43 uint64_t CpuFeatures::supported_ = kDefaultCpuFeatures; | 43 enabled_(0), |
44 uint64_t CpuFeatures::enabled_ = 0; | 44 found_by_runtime_probing_(0) { |
45 uint64_t CpuFeatures::found_by_runtime_probing_ = 0; | 45 } |
| 46 |
46 | 47 |
47 void CpuFeatures::Probe(bool portable) { | 48 void CpuFeatures::Probe(bool portable) { |
48 ASSERT(Heap::HasBeenSetup()); | 49 ASSERT(HEAP->HasBeenSetup()); |
49 supported_ = kDefaultCpuFeatures; | 50 supported_ = kDefaultCpuFeatures; |
50 if (portable && Serializer::enabled()) { | 51 if (portable && Serializer::enabled()) { |
51 supported_ |= OS::CpuFeaturesImpliedByPlatform(); | 52 supported_ |= OS::CpuFeaturesImpliedByPlatform(); |
52 return; // No features if we might serialize. | 53 return; // No features if we might serialize. |
53 } | 54 } |
54 | 55 |
55 Assembler assm(NULL, 0); | 56 Assembler assm(NULL, 0); |
56 Label cpuid, done; | 57 Label cpuid, done; |
57 #define __ assm. | 58 #define __ assm. |
58 // Save old rsp, since we are going to modify the stack. | 59 // Save old rsp, since we are going to modify the stack. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 __ movq(rsp, rbp); | 112 __ movq(rsp, rbp); |
112 __ pop(rbx); | 113 __ pop(rbx); |
113 __ pop(rcx); | 114 __ pop(rcx); |
114 __ popfq(); | 115 __ popfq(); |
115 __ pop(rbp); | 116 __ pop(rbp); |
116 __ ret(0); | 117 __ ret(0); |
117 #undef __ | 118 #undef __ |
118 | 119 |
119 CodeDesc desc; | 120 CodeDesc desc; |
120 assm.GetCode(&desc); | 121 assm.GetCode(&desc); |
121 MaybeObject* maybe_code = Heap::CreateCode(desc, | 122 Isolate* isolate = Isolate::Current(); |
122 Code::ComputeFlags(Code::STUB), | 123 MaybeObject* maybe_code = |
123 Handle<Object>()); | 124 isolate->heap()->CreateCode(desc, |
| 125 Code::ComputeFlags(Code::STUB), |
| 126 Handle<Object>()); |
124 Object* code; | 127 Object* code; |
125 if (!maybe_code->ToObject(&code)) return; | 128 if (!maybe_code->ToObject(&code)) return; |
126 if (!code->IsCode()) return; | 129 if (!code->IsCode()) return; |
127 PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG, | 130 PROFILE(isolate, |
| 131 CodeCreateEvent(Logger::BUILTIN_TAG, |
128 Code::cast(code), "CpuFeatures::Probe")); | 132 Code::cast(code), "CpuFeatures::Probe")); |
129 typedef uint64_t (*F0)(); | 133 typedef uint64_t (*F0)(); |
130 F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry()); | 134 F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry()); |
131 supported_ = probe(); | 135 supported_ = probe(); |
132 found_by_runtime_probing_ = supported_; | 136 found_by_runtime_probing_ = supported_; |
133 found_by_runtime_probing_ &= ~kDefaultCpuFeatures; | 137 found_by_runtime_probing_ &= ~kDefaultCpuFeatures; |
134 uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform(); | 138 uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform(); |
135 supported_ |= os_guarantees; | 139 supported_ |= os_guarantees; |
136 found_by_runtime_probing_ &= portable ? ~os_guarantees : 0; | 140 found_by_runtime_probing_ &= portable ? ~os_guarantees : 0; |
137 // SSE2 and CMOV must be available on an X64 CPU. | 141 // SSE2 and CMOV must be available on an X64 CPU. |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 } | 332 } |
329 | 333 |
330 | 334 |
331 // ----------------------------------------------------------------------------- | 335 // ----------------------------------------------------------------------------- |
332 // Implementation of Assembler. | 336 // Implementation of Assembler. |
333 | 337 |
334 #ifdef GENERATED_CODE_COVERAGE | 338 #ifdef GENERATED_CODE_COVERAGE |
335 static void InitCoverageLog(); | 339 static void InitCoverageLog(); |
336 #endif | 340 #endif |
337 | 341 |
338 byte* Assembler::spare_buffer_ = NULL; | |
339 | |
340 Assembler::Assembler(void* buffer, int buffer_size) | 342 Assembler::Assembler(void* buffer, int buffer_size) |
341 : code_targets_(100), | 343 : code_targets_(100), |
342 positions_recorder_(this), | 344 positions_recorder_(this), |
343 emit_debug_code_(FLAG_debug_code) { | 345 emit_debug_code_(FLAG_debug_code) { |
| 346 Isolate* isolate = Isolate::Current(); |
344 if (buffer == NULL) { | 347 if (buffer == NULL) { |
345 // Do our own buffer management. | 348 // Do our own buffer management. |
346 if (buffer_size <= kMinimalBufferSize) { | 349 if (buffer_size <= kMinimalBufferSize) { |
347 buffer_size = kMinimalBufferSize; | 350 buffer_size = kMinimalBufferSize; |
348 | 351 |
349 if (spare_buffer_ != NULL) { | 352 if (isolate->assembler_spare_buffer() != NULL) { |
350 buffer = spare_buffer_; | 353 buffer = isolate->assembler_spare_buffer(); |
351 spare_buffer_ = NULL; | 354 isolate->set_assembler_spare_buffer(NULL); |
352 } | 355 } |
353 } | 356 } |
354 if (buffer == NULL) { | 357 if (buffer == NULL) { |
355 buffer_ = NewArray<byte>(buffer_size); | 358 buffer_ = NewArray<byte>(buffer_size); |
356 } else { | 359 } else { |
357 buffer_ = static_cast<byte*>(buffer); | 360 buffer_ = static_cast<byte*>(buffer); |
358 } | 361 } |
359 buffer_size_ = buffer_size; | 362 buffer_size_ = buffer_size; |
360 own_buffer_ = true; | 363 own_buffer_ = true; |
361 } else { | 364 } else { |
(...skipping 20 matching lines...) Expand all Loading... |
382 | 385 |
383 last_pc_ = NULL; | 386 last_pc_ = NULL; |
384 | 387 |
385 #ifdef GENERATED_CODE_COVERAGE | 388 #ifdef GENERATED_CODE_COVERAGE |
386 InitCoverageLog(); | 389 InitCoverageLog(); |
387 #endif | 390 #endif |
388 } | 391 } |
389 | 392 |
390 | 393 |
391 Assembler::~Assembler() { | 394 Assembler::~Assembler() { |
| 395 Isolate* isolate = Isolate::Current(); |
392 if (own_buffer_) { | 396 if (own_buffer_) { |
393 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { | 397 if (isolate->assembler_spare_buffer() == NULL && |
394 spare_buffer_ = buffer_; | 398 buffer_size_ == kMinimalBufferSize) { |
| 399 isolate->set_assembler_spare_buffer(buffer_); |
395 } else { | 400 } else { |
396 DeleteArray(buffer_); | 401 DeleteArray(buffer_); |
397 } | 402 } |
398 } | 403 } |
399 } | 404 } |
400 | 405 |
401 | 406 |
402 void Assembler::GetCode(CodeDesc* desc) { | 407 void Assembler::GetCode(CodeDesc* desc) { |
403 // Finalize code (at this point overflow() may be true, but the gap ensures | 408 // Finalize code (at this point overflow() may be true, but the gap ensures |
404 // that we are still not overlapping instructions and relocation info). | 409 // that we are still not overlapping instructions and relocation info). |
405 ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap. | 410 ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap. |
406 // Setup code descriptor. | 411 // Setup code descriptor. |
407 desc->buffer = buffer_; | 412 desc->buffer = buffer_; |
408 desc->buffer_size = buffer_size_; | 413 desc->buffer_size = buffer_size_; |
409 desc->instr_size = pc_offset(); | 414 desc->instr_size = pc_offset(); |
410 ASSERT(desc->instr_size > 0); // Zero-size code objects upset the system. | 415 ASSERT(desc->instr_size > 0); // Zero-size code objects upset the system. |
411 desc->reloc_size = | 416 desc->reloc_size = |
412 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos()); | 417 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos()); |
413 desc->origin = this; | 418 desc->origin = this; |
414 | 419 |
415 Counters::reloc_info_size.Increment(desc->reloc_size); | 420 COUNTERS->reloc_info_size()->Increment(desc->reloc_size); |
416 } | 421 } |
417 | 422 |
418 | 423 |
419 void Assembler::Align(int m) { | 424 void Assembler::Align(int m) { |
420 ASSERT(IsPowerOf2(m)); | 425 ASSERT(IsPowerOf2(m)); |
421 int delta = (m - (pc_offset() & (m - 1))) & (m - 1); | 426 int delta = (m - (pc_offset() & (m - 1))) & (m - 1); |
422 while (delta >= 9) { | 427 while (delta >= 9) { |
423 nop(9); | 428 nop(9); |
424 delta -= 9; | 429 delta -= 9; |
425 } | 430 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 int disp = pc_offset() - branch_pos; | 474 int disp = pc_offset() - branch_pos; |
470 ASSERT(is_int8(disp)); | 475 ASSERT(is_int8(disp)); |
471 set_byte_at(branch_pos - sizeof(int8_t), disp); | 476 set_byte_at(branch_pos - sizeof(int8_t), disp); |
472 L->unresolved_branches_--; | 477 L->unresolved_branches_--; |
473 } | 478 } |
474 L->bind_to(pc_offset()); | 479 L->bind_to(pc_offset()); |
475 } | 480 } |
476 | 481 |
477 | 482 |
478 void Assembler::GrowBuffer() { | 483 void Assembler::GrowBuffer() { |
| 484 Isolate* isolate = Isolate::Current(); |
479 ASSERT(buffer_overflow()); | 485 ASSERT(buffer_overflow()); |
480 if (!own_buffer_) FATAL("external code buffer is too small"); | 486 if (!own_buffer_) FATAL("external code buffer is too small"); |
481 | 487 |
482 // Compute new buffer size. | 488 // Compute new buffer size. |
483 CodeDesc desc; // the new buffer | 489 CodeDesc desc; // the new buffer |
484 if (buffer_size_ < 4*KB) { | 490 if (buffer_size_ < 4*KB) { |
485 desc.buffer_size = 4*KB; | 491 desc.buffer_size = 4*KB; |
486 } else { | 492 } else { |
487 desc.buffer_size = 2*buffer_size_; | 493 desc.buffer_size = 2*buffer_size_; |
488 } | 494 } |
489 // Some internal data structures overflow for very large buffers, | 495 // Some internal data structures overflow for very large buffers, |
490 // they must ensure that kMaximalBufferSize is not too large. | 496 // they must ensure that kMaximalBufferSize is not too large. |
491 if ((desc.buffer_size > kMaximalBufferSize) || | 497 if ((desc.buffer_size > kMaximalBufferSize) || |
492 (desc.buffer_size > Heap::MaxOldGenerationSize())) { | 498 (desc.buffer_size > HEAP->MaxOldGenerationSize())) { |
493 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); | 499 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); |
494 } | 500 } |
495 | 501 |
496 // Setup new buffer. | 502 // Setup new buffer. |
497 desc.buffer = NewArray<byte>(desc.buffer_size); | 503 desc.buffer = NewArray<byte>(desc.buffer_size); |
498 desc.instr_size = pc_offset(); | 504 desc.instr_size = pc_offset(); |
499 desc.reloc_size = | 505 desc.reloc_size = |
500 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos())); | 506 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos())); |
501 | 507 |
502 // Clear the buffer in debug mode. Use 'int3' instructions to make | 508 // Clear the buffer in debug mode. Use 'int3' instructions to make |
503 // sure to get into problems if we ever run uninitialized code. | 509 // sure to get into problems if we ever run uninitialized code. |
504 #ifdef DEBUG | 510 #ifdef DEBUG |
505 memset(desc.buffer, 0xCC, desc.buffer_size); | 511 memset(desc.buffer, 0xCC, desc.buffer_size); |
506 #endif | 512 #endif |
507 | 513 |
508 // Copy the data. | 514 // Copy the data. |
509 intptr_t pc_delta = desc.buffer - buffer_; | 515 intptr_t pc_delta = desc.buffer - buffer_; |
510 intptr_t rc_delta = (desc.buffer + desc.buffer_size) - | 516 intptr_t rc_delta = (desc.buffer + desc.buffer_size) - |
511 (buffer_ + buffer_size_); | 517 (buffer_ + buffer_size_); |
512 memmove(desc.buffer, buffer_, desc.instr_size); | 518 memmove(desc.buffer, buffer_, desc.instr_size); |
513 memmove(rc_delta + reloc_info_writer.pos(), | 519 memmove(rc_delta + reloc_info_writer.pos(), |
514 reloc_info_writer.pos(), desc.reloc_size); | 520 reloc_info_writer.pos(), desc.reloc_size); |
515 | 521 |
516 // Switch buffers. | 522 // Switch buffers. |
517 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { | 523 if (isolate->assembler_spare_buffer() == NULL && |
518 spare_buffer_ = buffer_; | 524 buffer_size_ == kMinimalBufferSize) { |
| 525 isolate->set_assembler_spare_buffer(buffer_); |
519 } else { | 526 } else { |
520 DeleteArray(buffer_); | 527 DeleteArray(buffer_); |
521 } | 528 } |
522 buffer_ = desc.buffer; | 529 buffer_ = desc.buffer; |
523 buffer_size_ = desc.buffer_size; | 530 buffer_size_ = desc.buffer_size; |
524 pc_ += pc_delta; | 531 pc_ += pc_delta; |
525 if (last_pc_ != NULL) { | 532 if (last_pc_ != NULL) { |
526 last_pc_ += pc_delta; | 533 last_pc_ += pc_delta; |
527 } | 534 } |
528 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, | 535 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, |
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 void Assembler::cmpb_al(Immediate imm8) { | 1028 void Assembler::cmpb_al(Immediate imm8) { |
1022 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_)); | 1029 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_)); |
1023 EnsureSpace ensure_space(this); | 1030 EnsureSpace ensure_space(this); |
1024 last_pc_ = pc_; | 1031 last_pc_ = pc_; |
1025 emit(0x3c); | 1032 emit(0x3c); |
1026 emit(imm8.value_); | 1033 emit(imm8.value_); |
1027 } | 1034 } |
1028 | 1035 |
1029 | 1036 |
1030 void Assembler::cpuid() { | 1037 void Assembler::cpuid() { |
1031 ASSERT(CpuFeatures::IsEnabled(CPUID)); | 1038 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(CPUID)); |
1032 EnsureSpace ensure_space(this); | 1039 EnsureSpace ensure_space(this); |
1033 last_pc_ = pc_; | 1040 last_pc_ = pc_; |
1034 emit(0x0F); | 1041 emit(0x0F); |
1035 emit(0xA2); | 1042 emit(0xA2); |
1036 } | 1043 } |
1037 | 1044 |
1038 | 1045 |
1039 void Assembler::cqo() { | 1046 void Assembler::cqo() { |
1040 EnsureSpace ensure_space(this); | 1047 EnsureSpace ensure_space(this); |
1041 last_pc_ = pc_; | 1048 last_pc_ = pc_; |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1668 // (possibly using less that 8 bytes for the value). | 1675 // (possibly using less that 8 bytes for the value). |
1669 if (mode == RelocInfo::NONE) { | 1676 if (mode == RelocInfo::NONE) { |
1670 // There is no possible reason to store a heap pointer without relocation | 1677 // There is no possible reason to store a heap pointer without relocation |
1671 // info, so it must be a smi. | 1678 // info, so it must be a smi. |
1672 ASSERT(value->IsSmi()); | 1679 ASSERT(value->IsSmi()); |
1673 movq(dst, reinterpret_cast<int64_t>(*value), RelocInfo::NONE); | 1680 movq(dst, reinterpret_cast<int64_t>(*value), RelocInfo::NONE); |
1674 } else { | 1681 } else { |
1675 EnsureSpace ensure_space(this); | 1682 EnsureSpace ensure_space(this); |
1676 last_pc_ = pc_; | 1683 last_pc_ = pc_; |
1677 ASSERT(value->IsHeapObject()); | 1684 ASSERT(value->IsHeapObject()); |
1678 ASSERT(!Heap::InNewSpace(*value)); | 1685 ASSERT(!HEAP->InNewSpace(*value)); |
1679 emit_rex_64(dst); | 1686 emit_rex_64(dst); |
1680 emit(0xB8 | dst.low_bits()); | 1687 emit(0xB8 | dst.low_bits()); |
1681 emitq(reinterpret_cast<uintptr_t>(value.location()), mode); | 1688 emitq(reinterpret_cast<uintptr_t>(value.location()), mode); |
1682 } | 1689 } |
1683 } | 1690 } |
1684 | 1691 |
1685 | 1692 |
1686 void Assembler::movsxbq(Register dst, const Operand& src) { | 1693 void Assembler::movsxbq(Register dst, const Operand& src) { |
1687 EnsureSpace ensure_space(this); | 1694 EnsureSpace ensure_space(this); |
1688 last_pc_ = pc_; | 1695 last_pc_ = pc_; |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2372 void Assembler::fistp_s(const Operand& adr) { | 2379 void Assembler::fistp_s(const Operand& adr) { |
2373 EnsureSpace ensure_space(this); | 2380 EnsureSpace ensure_space(this); |
2374 last_pc_ = pc_; | 2381 last_pc_ = pc_; |
2375 emit_optional_rex_32(adr); | 2382 emit_optional_rex_32(adr); |
2376 emit(0xDB); | 2383 emit(0xDB); |
2377 emit_operand(3, adr); | 2384 emit_operand(3, adr); |
2378 } | 2385 } |
2379 | 2386 |
2380 | 2387 |
2381 void Assembler::fisttp_s(const Operand& adr) { | 2388 void Assembler::fisttp_s(const Operand& adr) { |
2382 ASSERT(CpuFeatures::IsEnabled(SSE3)); | 2389 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(SSE3)); |
2383 EnsureSpace ensure_space(this); | 2390 EnsureSpace ensure_space(this); |
2384 last_pc_ = pc_; | 2391 last_pc_ = pc_; |
2385 emit_optional_rex_32(adr); | 2392 emit_optional_rex_32(adr); |
2386 emit(0xDB); | 2393 emit(0xDB); |
2387 emit_operand(1, adr); | 2394 emit_operand(1, adr); |
2388 } | 2395 } |
2389 | 2396 |
2390 | 2397 |
2391 void Assembler::fisttp_d(const Operand& adr) { | 2398 void Assembler::fisttp_d(const Operand& adr) { |
2392 ASSERT(CpuFeatures::IsEnabled(SSE3)); | 2399 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(SSE3)); |
2393 EnsureSpace ensure_space(this); | 2400 EnsureSpace ensure_space(this); |
2394 last_pc_ = pc_; | 2401 last_pc_ = pc_; |
2395 emit_optional_rex_32(adr); | 2402 emit_optional_rex_32(adr); |
2396 emit(0xDD); | 2403 emit(0xDD); |
2397 emit_operand(1, adr); | 2404 emit_operand(1, adr); |
2398 } | 2405 } |
2399 | 2406 |
2400 | 2407 |
2401 void Assembler::fist_s(const Operand& adr) { | 2408 void Assembler::fist_s(const Operand& adr) { |
2402 EnsureSpace ensure_space(this); | 2409 EnsureSpace ensure_space(this); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2700 last_pc_ = pc_; | 2707 last_pc_ = pc_; |
2701 emit(0x66); | 2708 emit(0x66); |
2702 emit_rex_64(src, dst); | 2709 emit_rex_64(src, dst); |
2703 emit(0x0F); | 2710 emit(0x0F); |
2704 emit(0x7E); | 2711 emit(0x7E); |
2705 emit_sse_operand(src, dst); | 2712 emit_sse_operand(src, dst); |
2706 } | 2713 } |
2707 | 2714 |
2708 | 2715 |
2709 void Assembler::movdqa(const Operand& dst, XMMRegister src) { | 2716 void Assembler::movdqa(const Operand& dst, XMMRegister src) { |
2710 ASSERT(CpuFeatures::IsEnabled(SSE2)); | 2717 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(SSE2)); |
2711 EnsureSpace ensure_space(this); | 2718 EnsureSpace ensure_space(this); |
2712 last_pc_ = pc_; | 2719 last_pc_ = pc_; |
2713 emit(0x66); | 2720 emit(0x66); |
2714 emit_rex_64(src, dst); | 2721 emit_rex_64(src, dst); |
2715 emit(0x0F); | 2722 emit(0x0F); |
2716 emit(0x7F); | 2723 emit(0x7F); |
2717 emit_sse_operand(src, dst); | 2724 emit_sse_operand(src, dst); |
2718 } | 2725 } |
2719 | 2726 |
2720 | 2727 |
2721 void Assembler::movdqa(XMMRegister dst, const Operand& src) { | 2728 void Assembler::movdqa(XMMRegister dst, const Operand& src) { |
2722 ASSERT(CpuFeatures::IsEnabled(SSE2)); | 2729 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(SSE2)); |
2723 EnsureSpace ensure_space(this); | 2730 EnsureSpace ensure_space(this); |
2724 last_pc_ = pc_; | 2731 last_pc_ = pc_; |
2725 emit(0x66); | 2732 emit(0x66); |
2726 emit_rex_64(dst, src); | 2733 emit_rex_64(dst, src); |
2727 emit(0x0F); | 2734 emit(0x0F); |
2728 emit(0x6F); | 2735 emit(0x6F); |
2729 emit_sse_operand(dst, src); | 2736 emit_sse_operand(dst, src); |
2730 } | 2737 } |
2731 | 2738 |
2732 | 2739 |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3155 // specially coded on x64 means that it is a relative 32 bit address, as used | 3162 // specially coded on x64 means that it is a relative 32 bit address, as used |
3156 // by branch instructions. | 3163 // by branch instructions. |
3157 return (1 << rmode_) & kApplyMask; | 3164 return (1 << rmode_) & kApplyMask; |
3158 } | 3165 } |
3159 | 3166 |
3160 | 3167 |
3161 | 3168 |
3162 } } // namespace v8::internal | 3169 } } // namespace v8::internal |
3163 | 3170 |
3164 #endif // V8_TARGET_ARCH_X64 | 3171 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |