| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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" // NOLINT | 5 #include "vm/globals.h" // NOLINT |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/heap.h" | 10 #include "vm/heap.h" |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 | 92 |
| 93 | 93 |
| 94 void Assembler::Call(const ExternalLabel* label) { | 94 void Assembler::Call(const ExternalLabel* label) { |
| 95 ASSERT(constant_pool_allowed()); | 95 ASSERT(constant_pool_allowed()); |
| 96 const int32_t offset = ObjectPool::element_offset( | 96 const int32_t offset = ObjectPool::element_offset( |
| 97 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable)); | 97 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable)); |
| 98 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); | 98 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); |
| 99 } | 99 } |
| 100 | 100 |
| 101 | 101 |
| 102 void Assembler::CallPatchable(const StubEntry& stub_entry) { |
| 103 const ExternalLabel label(stub_entry.EntryPoint()); |
| 104 CallPatchable(&label); |
| 105 } |
| 106 |
| 107 |
| 108 void Assembler::Call(const StubEntry& stub_entry) { |
| 109 const ExternalLabel label(stub_entry.EntryPoint()); |
| 110 Call(&label); |
| 111 } |
| 112 |
| 113 |
| 102 void Assembler::pushq(Register reg) { | 114 void Assembler::pushq(Register reg) { |
| 103 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 115 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 104 EmitRegisterREX(reg, REX_NONE); | 116 EmitRegisterREX(reg, REX_NONE); |
| 105 EmitUint8(0x50 | (reg & 7)); | 117 EmitUint8(0x50 | (reg & 7)); |
| 106 } | 118 } |
| 107 | 119 |
| 108 | 120 |
| 109 void Assembler::pushq(const Address& address) { | 121 void Assembler::pushq(const Address& address) { |
| 110 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 122 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 111 EmitOperandREX(6, address, REX_NONE); | 123 EmitOperandREX(6, address, REX_NONE); |
| (...skipping 2432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2544 void Assembler::J(Condition condition, const ExternalLabel* label, | 2556 void Assembler::J(Condition condition, const ExternalLabel* label, |
| 2545 Register pp) { | 2557 Register pp) { |
| 2546 Label no_jump; | 2558 Label no_jump; |
| 2547 // Negate condition. | 2559 // Negate condition. |
| 2548 j(static_cast<Condition>(condition ^ 1), &no_jump, Assembler::kNearJump); | 2560 j(static_cast<Condition>(condition ^ 1), &no_jump, Assembler::kNearJump); |
| 2549 Jmp(label, pp); | 2561 Jmp(label, pp); |
| 2550 Bind(&no_jump); | 2562 Bind(&no_jump); |
| 2551 } | 2563 } |
| 2552 | 2564 |
| 2553 | 2565 |
| 2566 void Assembler::J(Condition condition, const StubEntry& stub_entry, |
| 2567 Register pp) { |
| 2568 const ExternalLabel label(stub_entry.EntryPoint()); |
| 2569 J(condition, &label, pp); |
| 2570 } |
| 2571 |
| 2572 |
| 2554 void Assembler::jmp(Register reg) { | 2573 void Assembler::jmp(Register reg) { |
| 2555 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2574 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2556 Operand operand(reg); | 2575 Operand operand(reg); |
| 2557 EmitOperandREX(4, operand, REX_NONE); | 2576 EmitOperandREX(4, operand, REX_NONE); |
| 2558 EmitUint8(0xFF); | 2577 EmitUint8(0xFF); |
| 2559 EmitOperand(4, operand); | 2578 EmitOperand(4, operand); |
| 2560 } | 2579 } |
| 2561 | 2580 |
| 2562 | 2581 |
| 2563 void Assembler::jmp(const Address& dst) { | 2582 void Assembler::jmp(const Address& dst) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2599 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. | 2618 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. |
| 2600 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2619 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2601 EmitRegisterREX(TMP, REX_W); | 2620 EmitRegisterREX(TMP, REX_W); |
| 2602 EmitUint8(0xB8 | (TMP & 7)); | 2621 EmitUint8(0xB8 | (TMP & 7)); |
| 2603 EmitInt64(label->address()); | 2622 EmitInt64(label->address()); |
| 2604 } | 2623 } |
| 2605 jmp(TMP); | 2624 jmp(TMP); |
| 2606 } | 2625 } |
| 2607 | 2626 |
| 2608 | 2627 |
| 2628 void Assembler::jmp(const StubEntry& stub_entry) { |
| 2629 const ExternalLabel label(stub_entry.EntryPoint()); |
| 2630 jmp(&label); |
| 2631 } |
| 2632 |
| 2633 |
| 2609 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { | 2634 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { |
| 2610 ASSERT((pp != PP) || constant_pool_allowed()); | 2635 ASSERT((pp != PP) || constant_pool_allowed()); |
| 2611 intptr_t call_start = buffer_.GetPosition(); | 2636 intptr_t call_start = buffer_.GetPosition(); |
| 2612 const int32_t offset = ObjectPool::element_offset( | 2637 const int32_t offset = ObjectPool::element_offset( |
| 2613 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); | 2638 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); |
| 2614 // Patchable jumps always use a 32-bit immediate encoding. | 2639 // Patchable jumps always use a 32-bit immediate encoding. |
| 2615 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); | 2640 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); |
| 2616 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); | 2641 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); |
| 2617 } | 2642 } |
| 2618 | 2643 |
| 2619 | 2644 |
| 2645 void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) { |
| 2646 const ExternalLabel label(stub_entry.EntryPoint()); |
| 2647 JmpPatchable(&label, pp); |
| 2648 } |
| 2649 |
| 2650 |
| 2620 void Assembler::Jmp(const ExternalLabel* label, Register pp) { | 2651 void Assembler::Jmp(const ExternalLabel* label, Register pp) { |
| 2621 ASSERT((pp != PP) || constant_pool_allowed()); | 2652 ASSERT((pp != PP) || constant_pool_allowed()); |
| 2622 const int32_t offset = ObjectPool::element_offset( | 2653 const int32_t offset = ObjectPool::element_offset( |
| 2623 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable)); | 2654 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable)); |
| 2624 jmp(Address(pp, offset - kHeapObjectTag)); | 2655 jmp(Address(pp, offset - kHeapObjectTag)); |
| 2625 } | 2656 } |
| 2626 | 2657 |
| 2627 | 2658 |
| 2659 void Assembler::Jmp(const StubEntry& stub_entry, Register pp) { |
| 2660 const ExternalLabel label(stub_entry.EntryPoint()); |
| 2661 Jmp(&label, pp); |
| 2662 } |
| 2663 |
| 2664 |
| 2628 void Assembler::lock() { | 2665 void Assembler::lock() { |
| 2629 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2666 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2630 EmitUint8(0xF0); | 2667 EmitUint8(0xF0); |
| 2631 } | 2668 } |
| 2632 | 2669 |
| 2633 | 2670 |
| 2634 void Assembler::cmpxchgl(const Address& address, Register reg) { | 2671 void Assembler::cmpxchgl(const Address& address, Register reg) { |
| 2635 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2672 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2636 EmitOperandREX(reg, address, REX_NONE); | 2673 EmitOperandREX(reg, address, REX_NONE); |
| 2637 EmitUint8(0x0F); | 2674 EmitUint8(0x0F); |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3181 pushq(TMP); // Preserve TMP register. | 3218 pushq(TMP); // Preserve TMP register. |
| 3182 pushq(RDI); // Preserve RDI register. | 3219 pushq(RDI); // Preserve RDI register. |
| 3183 if (fixed_length_encoding) { | 3220 if (fixed_length_encoding) { |
| 3184 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 3221 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 3185 EmitRegisterREX(RDI, REX_W); | 3222 EmitRegisterREX(RDI, REX_W); |
| 3186 EmitUint8(0xB8 | (RDI & 7)); | 3223 EmitUint8(0xB8 | (RDI & 7)); |
| 3187 EmitInt64(message_address); | 3224 EmitInt64(message_address); |
| 3188 } else { | 3225 } else { |
| 3189 LoadImmediate(RDI, Immediate(message_address)); | 3226 LoadImmediate(RDI, Immediate(message_address)); |
| 3190 } | 3227 } |
| 3191 call(&StubCode::PrintStopMessageLabel()); | 3228 call(&StubCode::PrintStopMessage_entry()->label()); |
| 3192 popq(RDI); // Restore RDI register. | 3229 popq(RDI); // Restore RDI register. |
| 3193 popq(TMP); // Restore TMP register. | 3230 popq(TMP); // Restore TMP register. |
| 3194 } else { | 3231 } else { |
| 3195 // Emit the lower half and the higher half of the message address as | 3232 // Emit the lower half and the higher half of the message address as |
| 3196 // immediate operands in the test rax instructions. | 3233 // immediate operands in the test rax instructions. |
| 3197 testl(RAX, Immediate(Utils::Low32Bits(message_address))); | 3234 testl(RAX, Immediate(Utils::Low32Bits(message_address))); |
| 3198 testl(RAX, Immediate(Utils::High32Bits(message_address))); | 3235 testl(RAX, Immediate(Utils::High32Bits(message_address))); |
| 3199 } | 3236 } |
| 3200 // Emit the int3 instruction. | 3237 // Emit the int3 instruction. |
| 3201 int3(); // Execution can be resumed with the 'cont' command in gdb. | 3238 int3(); // Execution can be resumed with the 'cont' command in gdb. |
| (...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3943 | 3980 |
| 3944 | 3981 |
| 3945 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3982 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3946 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3983 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 3947 return xmm_reg_names[reg]; | 3984 return xmm_reg_names[reg]; |
| 3948 } | 3985 } |
| 3949 | 3986 |
| 3950 } // namespace dart | 3987 } // namespace dart |
| 3951 | 3988 |
| 3952 #endif // defined TARGET_ARCH_X64 | 3989 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |