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