| 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" |
| 11 #include "vm/instructions.h" | 11 #include "vm/instructions.h" |
| 12 #include "vm/locations.h" | 12 #include "vm/locations.h" |
| 13 #include "vm/memory_region.h" | 13 #include "vm/memory_region.h" |
| 14 #include "vm/runtime_entry.h" | 14 #include "vm/runtime_entry.h" |
| 15 #include "vm/stack_frame.h" | 15 #include "vm/stack_frame.h" |
| 16 #include "vm/stub_code.h" | 16 #include "vm/stub_code.h" |
| 17 | 17 |
| 18 namespace dart { | 18 namespace dart { |
| 19 | 19 |
| 20 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 20 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| 21 DECLARE_FLAG(bool, inline_alloc); | 21 DECLARE_FLAG(bool, inline_alloc); |
| 22 | 22 |
| 23 | 23 |
| 24 Assembler::Assembler(bool use_far_branches) | 24 Assembler::Assembler(bool use_far_branches) |
| 25 : buffer_(), | 25 : buffer_(), |
| 26 prologue_offset_(-1), | 26 prologue_offset_(-1), |
| 27 comments_(), | 27 comments_(), |
| 28 constant_pool_allowed_(true) { | 28 constant_pool_allowed_(false) { |
| 29 // Far branching mode is only needed and implemented for MIPS and ARM. | 29 // Far branching mode is only needed and implemented for MIPS and ARM. |
| 30 ASSERT(!use_far_branches); | 30 ASSERT(!use_far_branches); |
| 31 } | 31 } |
| 32 | 32 |
| 33 | 33 |
| 34 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { | 34 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { |
| 35 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); | 35 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); |
| 36 } | 36 } |
| 37 | 37 |
| 38 | 38 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 56 void Assembler::call(Label* label) { | 56 void Assembler::call(Label* label) { |
| 57 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 57 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 58 static const int kSize = 5; | 58 static const int kSize = 5; |
| 59 EmitUint8(0xE8); | 59 EmitUint8(0xE8); |
| 60 EmitLabel(label, kSize); | 60 EmitLabel(label, kSize); |
| 61 } | 61 } |
| 62 | 62 |
| 63 | 63 |
| 64 void Assembler::LoadExternalLabel(Register dst, | 64 void Assembler::LoadExternalLabel(Register dst, |
| 65 const ExternalLabel* label, | 65 const ExternalLabel* label, |
| 66 Patchability patchable, | 66 Patchability patchable) { |
| 67 Register pp) { | |
| 68 const int32_t offset = ObjectPool::element_offset( | 67 const int32_t offset = ObjectPool::element_offset( |
| 69 object_pool_wrapper_.FindExternalLabel(label, patchable)); | 68 object_pool_wrapper_.FindExternalLabel(label, patchable)); |
| 70 LoadWordFromPoolOffset(dst, pp, offset - kHeapObjectTag); | 69 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag); |
| 71 } | 70 } |
| 72 | 71 |
| 73 | 72 |
| 74 void Assembler::call(const ExternalLabel* label) { | 73 void Assembler::call(const ExternalLabel* label) { |
| 75 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. | 74 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. |
| 76 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 75 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 77 EmitRegisterREX(TMP, REX_W); | 76 EmitRegisterREX(TMP, REX_W); |
| 78 EmitUint8(0xB8 | (TMP & 7)); | 77 EmitUint8(0xB8 | (TMP & 7)); |
| 79 EmitInt64(label->address()); | 78 EmitInt64(label->address()); |
| 80 } | 79 } |
| 81 call(TMP); | 80 call(TMP); |
| 82 } | 81 } |
| 83 | 82 |
| 84 | 83 |
| 85 void Assembler::CallPatchable(const ExternalLabel* label) { | 84 void Assembler::CallPatchable(const ExternalLabel* label) { |
| 86 ASSERT(constant_pool_allowed()); | 85 ASSERT(constant_pool_allowed()); |
| 87 intptr_t call_start = buffer_.GetPosition(); | 86 intptr_t call_start = buffer_.GetPosition(); |
| 88 const int32_t offset = ObjectPool::element_offset( | 87 const int32_t offset = ObjectPool::element_offset( |
| 89 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); | 88 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); |
| 90 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); | 89 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); |
| 91 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); | 90 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); |
| 92 } | 91 } |
| 93 | 92 |
| 94 | 93 |
| 95 void Assembler::Call(const ExternalLabel* label, Register pp) { | 94 void Assembler::Call(const ExternalLabel* label) { |
| 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::pushq(Register reg) { | 102 void Assembler::pushq(Register reg) { |
| 103 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 103 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 104 EmitRegisterREX(reg, REX_NONE); | 104 EmitRegisterREX(reg, REX_NONE); |
| 105 EmitUint8(0x50 | (reg & 7)); | 105 EmitUint8(0x50 | (reg & 7)); |
| 106 } | 106 } |
| 107 | 107 |
| 108 | 108 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 119 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 119 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 120 EmitUint8(0x68); | 120 EmitUint8(0x68); |
| 121 EmitImmediate(imm); | 121 EmitImmediate(imm); |
| 122 } else { | 122 } else { |
| 123 movq(TMP, imm); | 123 movq(TMP, imm); |
| 124 pushq(TMP); | 124 pushq(TMP); |
| 125 } | 125 } |
| 126 } | 126 } |
| 127 | 127 |
| 128 | 128 |
| 129 void Assembler::PushImmediate(const Immediate& imm, Register pp) { | 129 void Assembler::PushImmediate(const Immediate& imm) { |
| 130 if (CanLoadImmediateFromPool(imm, pp)) { | 130 if (imm.is_int32()) { |
| 131 LoadImmediate(TMP, imm, pp); | 131 pushq(imm); |
| 132 } else { |
| 133 LoadImmediate(TMP, imm); |
| 132 pushq(TMP); | 134 pushq(TMP); |
| 133 } else { | |
| 134 pushq(imm); | |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 | 137 |
| 138 | 138 |
| 139 void Assembler::popq(Register reg) { | 139 void Assembler::popq(Register reg) { |
| 140 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 140 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 141 EmitRegisterREX(reg, REX_NONE); | 141 EmitRegisterREX(reg, REX_NONE); |
| 142 EmitUint8(0x58 | (reg & 7)); | 142 EmitUint8(0x58 | (reg & 7)); |
| 143 } | 143 } |
| 144 | 144 |
| (...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 | 775 |
| 776 void Assembler::notps(XmmRegister dst) { | 776 void Assembler::notps(XmmRegister dst) { |
| 777 static const struct ALIGN16 { | 777 static const struct ALIGN16 { |
| 778 uint32_t a; | 778 uint32_t a; |
| 779 uint32_t b; | 779 uint32_t b; |
| 780 uint32_t c; | 780 uint32_t c; |
| 781 uint32_t d; | 781 uint32_t d; |
| 782 } float_not_constant = | 782 } float_not_constant = |
| 783 { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; | 783 { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; |
| 784 LoadImmediate( | 784 LoadImmediate( |
| 785 TMP, Immediate(reinterpret_cast<intptr_t>(&float_not_constant)), PP); | 785 TMP, Immediate(reinterpret_cast<intptr_t>(&float_not_constant))); |
| 786 xorps(dst, Address(TMP, 0)); | 786 xorps(dst, Address(TMP, 0)); |
| 787 } | 787 } |
| 788 | 788 |
| 789 | 789 |
| 790 void Assembler::negateps(XmmRegister dst) { | 790 void Assembler::negateps(XmmRegister dst) { |
| 791 static const struct ALIGN16 { | 791 static const struct ALIGN16 { |
| 792 uint32_t a; | 792 uint32_t a; |
| 793 uint32_t b; | 793 uint32_t b; |
| 794 uint32_t c; | 794 uint32_t c; |
| 795 uint32_t d; | 795 uint32_t d; |
| 796 } float_negate_constant = | 796 } float_negate_constant = |
| 797 { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; | 797 { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; |
| 798 LoadImmediate( | 798 LoadImmediate( |
| 799 TMP, Immediate(reinterpret_cast<intptr_t>(&float_negate_constant)), PP); | 799 TMP, Immediate(reinterpret_cast<intptr_t>(&float_negate_constant))); |
| 800 xorps(dst, Address(TMP, 0)); | 800 xorps(dst, Address(TMP, 0)); |
| 801 } | 801 } |
| 802 | 802 |
| 803 | 803 |
| 804 void Assembler::absps(XmmRegister dst) { | 804 void Assembler::absps(XmmRegister dst) { |
| 805 static const struct ALIGN16 { | 805 static const struct ALIGN16 { |
| 806 uint32_t a; | 806 uint32_t a; |
| 807 uint32_t b; | 807 uint32_t b; |
| 808 uint32_t c; | 808 uint32_t c; |
| 809 uint32_t d; | 809 uint32_t d; |
| 810 } float_absolute_constant = | 810 } float_absolute_constant = |
| 811 { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; | 811 { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; |
| 812 LoadImmediate( | 812 LoadImmediate( |
| 813 TMP, Immediate(reinterpret_cast<intptr_t>(&float_absolute_constant)), PP); | 813 TMP, Immediate(reinterpret_cast<intptr_t>(&float_absolute_constant))); |
| 814 andps(dst, Address(TMP, 0)); | 814 andps(dst, Address(TMP, 0)); |
| 815 } | 815 } |
| 816 | 816 |
| 817 | 817 |
| 818 void Assembler::zerowps(XmmRegister dst) { | 818 void Assembler::zerowps(XmmRegister dst) { |
| 819 static const struct ALIGN16 { | 819 static const struct ALIGN16 { |
| 820 uint32_t a; | 820 uint32_t a; |
| 821 uint32_t b; | 821 uint32_t b; |
| 822 uint32_t c; | 822 uint32_t c; |
| 823 uint32_t d; | 823 uint32_t d; |
| 824 } float_zerow_constant = | 824 } float_zerow_constant = |
| 825 { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; | 825 { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; |
| 826 LoadImmediate( | 826 LoadImmediate( |
| 827 TMP, Immediate(reinterpret_cast<intptr_t>(&float_zerow_constant)), PP); | 827 TMP, Immediate(reinterpret_cast<intptr_t>(&float_zerow_constant))); |
| 828 andps(dst, Address(TMP, 0)); | 828 andps(dst, Address(TMP, 0)); |
| 829 } | 829 } |
| 830 | 830 |
| 831 | 831 |
| 832 void Assembler::cmppseq(XmmRegister dst, XmmRegister src) { | 832 void Assembler::cmppseq(XmmRegister dst, XmmRegister src) { |
| 833 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 833 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 834 EmitREX_RB(dst, src); | 834 EmitREX_RB(dst, src); |
| 835 EmitUint8(0x0F); | 835 EmitUint8(0x0F); |
| 836 EmitUint8(0xC2); | 836 EmitUint8(0xC2); |
| 837 EmitXmmRegisterOperand(dst & 7, src); | 837 EmitXmmRegisterOperand(dst & 7, src); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 } | 1005 } |
| 1006 | 1006 |
| 1007 | 1007 |
| 1008 void Assembler::negatepd(XmmRegister dst) { | 1008 void Assembler::negatepd(XmmRegister dst) { |
| 1009 static const struct ALIGN16 { | 1009 static const struct ALIGN16 { |
| 1010 uint64_t a; | 1010 uint64_t a; |
| 1011 uint64_t b; | 1011 uint64_t b; |
| 1012 } double_negate_constant = | 1012 } double_negate_constant = |
| 1013 { 0x8000000000000000LL, 0x8000000000000000LL }; | 1013 { 0x8000000000000000LL, 0x8000000000000000LL }; |
| 1014 LoadImmediate( | 1014 LoadImmediate( |
| 1015 TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)), PP); | 1015 TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant))); |
| 1016 xorpd(dst, Address(TMP, 0)); | 1016 xorpd(dst, Address(TMP, 0)); |
| 1017 } | 1017 } |
| 1018 | 1018 |
| 1019 | 1019 |
| 1020 void Assembler::subpd(XmmRegister dst, XmmRegister src) { | 1020 void Assembler::subpd(XmmRegister dst, XmmRegister src) { |
| 1021 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1021 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1022 ASSERT(src <= XMM15); | 1022 ASSERT(src <= XMM15); |
| 1023 ASSERT(dst <= XMM15); | 1023 ASSERT(dst <= XMM15); |
| 1024 EmitUint8(0x66); | 1024 EmitUint8(0x66); |
| 1025 EmitREX_RB(dst, src); | 1025 EmitREX_RB(dst, src); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1053 } | 1053 } |
| 1054 | 1054 |
| 1055 | 1055 |
| 1056 void Assembler::abspd(XmmRegister dst) { | 1056 void Assembler::abspd(XmmRegister dst) { |
| 1057 static const struct ALIGN16 { | 1057 static const struct ALIGN16 { |
| 1058 uint64_t a; | 1058 uint64_t a; |
| 1059 uint64_t b; | 1059 uint64_t b; |
| 1060 } double_absolute_const = | 1060 } double_absolute_const = |
| 1061 { 0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL }; | 1061 { 0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL }; |
| 1062 LoadImmediate( | 1062 LoadImmediate( |
| 1063 TMP, Immediate(reinterpret_cast<intptr_t>(&double_absolute_const)), PP); | 1063 TMP, Immediate(reinterpret_cast<intptr_t>(&double_absolute_const))); |
| 1064 andpd(dst, Address(TMP, 0)); | 1064 andpd(dst, Address(TMP, 0)); |
| 1065 } | 1065 } |
| 1066 | 1066 |
| 1067 | 1067 |
| 1068 void Assembler::minpd(XmmRegister dst, XmmRegister src) { | 1068 void Assembler::minpd(XmmRegister dst, XmmRegister src) { |
| 1069 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1069 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1070 ASSERT(src <= XMM15); | 1070 ASSERT(src <= XMM15); |
| 1071 ASSERT(dst <= XMM15); | 1071 ASSERT(dst <= XMM15); |
| 1072 EmitUint8(0x66); | 1072 EmitUint8(0x66); |
| 1073 EmitREX_RB(dst, src); | 1073 EmitREX_RB(dst, src); |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1466 } | 1466 } |
| 1467 } | 1467 } |
| 1468 | 1468 |
| 1469 | 1469 |
| 1470 void Assembler::cmpq(Register reg, const Immediate& imm) { | 1470 void Assembler::cmpq(Register reg, const Immediate& imm) { |
| 1471 if (imm.is_int32()) { | 1471 if (imm.is_int32()) { |
| 1472 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1472 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1473 EmitRegisterREX(reg, REX_W); | 1473 EmitRegisterREX(reg, REX_W); |
| 1474 EmitComplex(7, Operand(reg), imm); | 1474 EmitComplex(7, Operand(reg), imm); |
| 1475 } else { | 1475 } else { |
| 1476 ASSERT(reg != TMP); |
| 1476 movq(TMP, imm); | 1477 movq(TMP, imm); |
| 1477 cmpq(reg, TMP); | 1478 cmpq(reg, TMP); |
| 1478 } | 1479 } |
| 1479 } | 1480 } |
| 1480 | 1481 |
| 1481 | 1482 |
| 1482 void Assembler::cmpq(Register reg0, Register reg1) { | 1483 void Assembler::cmpq(Register reg0, Register reg1) { |
| 1483 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1484 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1484 Operand operand(reg1); | 1485 Operand operand(reg1); |
| 1485 EmitOperandREX(reg0, operand, REX_W); | 1486 EmitOperandREX(reg0, operand, REX_W); |
| 1486 EmitUint8(0x3B); | 1487 EmitUint8(0x3B); |
| 1487 EmitOperand(reg0 & 7, operand); | 1488 EmitOperand(reg0 & 7, operand); |
| 1488 } | 1489 } |
| 1489 | 1490 |
| 1490 | 1491 |
| 1491 void Assembler::cmpq(Register reg, const Address& address) { | 1492 void Assembler::cmpq(Register reg, const Address& address) { |
| 1492 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1493 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1493 EmitOperandREX(reg, address, REX_W); | 1494 EmitOperandREX(reg, address, REX_W); |
| 1494 EmitUint8(0x3B); | 1495 EmitUint8(0x3B); |
| 1495 EmitOperand(reg & 7, address); | 1496 EmitOperand(reg & 7, address); |
| 1496 } | 1497 } |
| 1497 | 1498 |
| 1498 | 1499 |
| 1499 void Assembler::CompareImmediate(Register reg, const Immediate& imm, | 1500 void Assembler::CompareImmediate(Register reg, const Immediate& imm) { |
| 1500 Register pp) { | 1501 if (imm.is_int32()) { |
| 1501 if (CanLoadImmediateFromPool(imm, pp)) { | 1502 cmpq(reg, imm); |
| 1502 LoadImmediate(TMP, imm, pp); | 1503 } else { |
| 1504 ASSERT(reg != TMP); |
| 1505 LoadImmediate(TMP, imm); |
| 1503 cmpq(reg, TMP); | 1506 cmpq(reg, TMP); |
| 1504 } else { | |
| 1505 cmpq(reg, imm); | |
| 1506 } | 1507 } |
| 1507 } | 1508 } |
| 1508 | 1509 |
| 1509 | 1510 |
| 1510 void Assembler::CompareImmediate(const Address& address, const Immediate& imm, | 1511 void Assembler::CompareImmediate(const Address& address, const Immediate& imm) { |
| 1511 Register pp) { | 1512 if (imm.is_int32()) { |
| 1512 if (CanLoadImmediateFromPool(imm, pp)) { | 1513 cmpq(address, imm); |
| 1513 LoadImmediate(TMP, imm, pp); | 1514 } else { |
| 1515 LoadImmediate(TMP, imm); |
| 1514 cmpq(address, TMP); | 1516 cmpq(address, TMP); |
| 1515 } else { | |
| 1516 cmpq(address, imm); | |
| 1517 } | 1517 } |
| 1518 } | 1518 } |
| 1519 | 1519 |
| 1520 | 1520 |
| 1521 void Assembler::testl(Register reg1, Register reg2) { | 1521 void Assembler::testl(Register reg1, Register reg2) { |
| 1522 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1522 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1523 Operand operand(reg2); | 1523 Operand operand(reg2); |
| 1524 EmitOperandREX(reg1, operand, REX_NONE); | 1524 EmitOperandREX(reg1, operand, REX_NONE); |
| 1525 EmitUint8(0x85); | 1525 EmitUint8(0x85); |
| 1526 EmitOperand(reg1 & 7, operand); | 1526 EmitOperand(reg1 & 7, operand); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1601 } else { | 1601 } else { |
| 1602 EmitRegisterREX(reg, REX_W); | 1602 EmitRegisterREX(reg, REX_W); |
| 1603 EmitUint8(0xF7); | 1603 EmitUint8(0xF7); |
| 1604 EmitUint8(0xC0 | (reg & 7)); | 1604 EmitUint8(0xC0 | (reg & 7)); |
| 1605 } | 1605 } |
| 1606 EmitImmediate(imm); | 1606 EmitImmediate(imm); |
| 1607 } | 1607 } |
| 1608 } | 1608 } |
| 1609 | 1609 |
| 1610 | 1610 |
| 1611 void Assembler::TestImmediate(Register dst, const Immediate& imm, Register pp) { | 1611 void Assembler::TestImmediate(Register dst, const Immediate& imm) { |
| 1612 if (CanLoadImmediateFromPool(imm, pp)) { | 1612 if (imm.is_int32()) { |
| 1613 testq(dst, imm); |
| 1614 } else { |
| 1613 ASSERT(dst != TMP); | 1615 ASSERT(dst != TMP); |
| 1614 LoadImmediate(TMP, imm, pp); | 1616 LoadImmediate(TMP, imm); |
| 1615 testq(dst, TMP); | 1617 testq(dst, TMP); |
| 1616 } else { | |
| 1617 testq(dst, imm); | |
| 1618 } | 1618 } |
| 1619 } | 1619 } |
| 1620 | 1620 |
| 1621 | 1621 |
| 1622 void Assembler::andl(Register dst, Register src) { | 1622 void Assembler::andl(Register dst, Register src) { |
| 1623 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1623 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1624 Operand operand(src); | 1624 Operand operand(src); |
| 1625 EmitOperandREX(dst, operand, REX_NONE); | 1625 EmitOperandREX(dst, operand, REX_NONE); |
| 1626 EmitUint8(0x23); | 1626 EmitUint8(0x23); |
| 1627 EmitOperand(dst & 7, operand); | 1627 EmitOperand(dst & 7, operand); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1684 EmitOperand(dst & 7, address); | 1684 EmitOperand(dst & 7, address); |
| 1685 } | 1685 } |
| 1686 | 1686 |
| 1687 | 1687 |
| 1688 void Assembler::andq(Register dst, const Immediate& imm) { | 1688 void Assembler::andq(Register dst, const Immediate& imm) { |
| 1689 if (imm.is_int32()) { | 1689 if (imm.is_int32()) { |
| 1690 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1690 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1691 EmitRegisterREX(dst, REX_W); | 1691 EmitRegisterREX(dst, REX_W); |
| 1692 EmitComplex(4, Operand(dst), imm); | 1692 EmitComplex(4, Operand(dst), imm); |
| 1693 } else { | 1693 } else { |
| 1694 ASSERT(dst != TMP); |
| 1694 movq(TMP, imm); | 1695 movq(TMP, imm); |
| 1695 andq(dst, TMP); | 1696 andq(dst, TMP); |
| 1696 } | 1697 } |
| 1697 } | 1698 } |
| 1698 | 1699 |
| 1699 | 1700 |
| 1700 void Assembler::AndImmediate(Register dst, const Immediate& imm, Register pp) { | 1701 void Assembler::AndImmediate(Register dst, const Immediate& imm) { |
| 1701 if (CanLoadImmediateFromPool(imm, pp)) { | 1702 if (imm.is_int32()) { |
| 1703 andq(dst, imm); |
| 1704 } else { |
| 1702 ASSERT(dst != TMP); | 1705 ASSERT(dst != TMP); |
| 1703 LoadImmediate(TMP, imm, pp); | 1706 LoadImmediate(TMP, imm); |
| 1704 andq(dst, TMP); | 1707 andq(dst, TMP); |
| 1705 } else { | |
| 1706 andq(dst, imm); | |
| 1707 } | 1708 } |
| 1708 } | 1709 } |
| 1709 | 1710 |
| 1710 | 1711 |
| 1711 void Assembler::orq(Register dst, Register src) { | 1712 void Assembler::orq(Register dst, Register src) { |
| 1712 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1713 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1713 Operand operand(src); | 1714 Operand operand(src); |
| 1714 EmitOperandREX(dst, operand, REX_W); | 1715 EmitOperandREX(dst, operand, REX_W); |
| 1715 EmitUint8(0x0B); | 1716 EmitUint8(0x0B); |
| 1716 EmitOperand(dst & 7, operand); | 1717 EmitOperand(dst & 7, operand); |
| 1717 } | 1718 } |
| 1718 | 1719 |
| 1719 | 1720 |
| 1720 void Assembler::orq(Register dst, const Address& address) { | 1721 void Assembler::orq(Register dst, const Address& address) { |
| 1721 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1722 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1722 EmitOperandREX(dst, address, REX_W); | 1723 EmitOperandREX(dst, address, REX_W); |
| 1723 EmitUint8(0x0B); | 1724 EmitUint8(0x0B); |
| 1724 EmitOperand(dst & 7, address); | 1725 EmitOperand(dst & 7, address); |
| 1725 } | 1726 } |
| 1726 | 1727 |
| 1727 | 1728 |
| 1728 void Assembler::orq(Register dst, const Immediate& imm) { | 1729 void Assembler::orq(Register dst, const Immediate& imm) { |
| 1729 if (imm.is_int32()) { | 1730 if (imm.is_int32()) { |
| 1730 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1731 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1731 EmitRegisterREX(dst, REX_W); | 1732 EmitRegisterREX(dst, REX_W); |
| 1732 EmitComplex(1, Operand(dst), imm); | 1733 EmitComplex(1, Operand(dst), imm); |
| 1733 } else { | 1734 } else { |
| 1735 ASSERT(dst != TMP); |
| 1734 movq(TMP, imm); | 1736 movq(TMP, imm); |
| 1735 orq(dst, TMP); | 1737 orq(dst, TMP); |
| 1736 } | 1738 } |
| 1737 } | 1739 } |
| 1738 | 1740 |
| 1739 | 1741 |
| 1740 void Assembler::OrImmediate(Register dst, const Immediate& imm, Register pp) { | 1742 void Assembler::OrImmediate(Register dst, const Immediate& imm) { |
| 1741 if (CanLoadImmediateFromPool(imm, pp)) { | 1743 if (imm.is_int32()) { |
| 1744 orq(dst, imm); |
| 1745 } else { |
| 1742 ASSERT(dst != TMP); | 1746 ASSERT(dst != TMP); |
| 1743 LoadImmediate(TMP, imm, pp); | 1747 LoadImmediate(TMP, imm); |
| 1744 orq(dst, TMP); | 1748 orq(dst, TMP); |
| 1745 } else { | |
| 1746 orq(dst, imm); | |
| 1747 } | 1749 } |
| 1748 } | 1750 } |
| 1749 | 1751 |
| 1750 | 1752 |
| 1751 void Assembler::xorq(Register dst, Register src) { | 1753 void Assembler::xorq(Register dst, Register src) { |
| 1752 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1754 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1753 Operand operand(src); | 1755 Operand operand(src); |
| 1754 EmitOperandREX(dst, operand, REX_W); | 1756 EmitOperandREX(dst, operand, REX_W); |
| 1755 EmitUint8(0x33); | 1757 EmitUint8(0x33); |
| 1756 EmitOperand(dst & 7, operand); | 1758 EmitOperand(dst & 7, operand); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1772 EmitOperand(src & 7, dst); | 1774 EmitOperand(src & 7, dst); |
| 1773 } | 1775 } |
| 1774 | 1776 |
| 1775 | 1777 |
| 1776 void Assembler::xorq(Register dst, const Immediate& imm) { | 1778 void Assembler::xorq(Register dst, const Immediate& imm) { |
| 1777 if (imm.is_int32()) { | 1779 if (imm.is_int32()) { |
| 1778 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1780 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1779 EmitRegisterREX(dst, REX_W); | 1781 EmitRegisterREX(dst, REX_W); |
| 1780 EmitComplex(6, Operand(dst), imm); | 1782 EmitComplex(6, Operand(dst), imm); |
| 1781 } else { | 1783 } else { |
| 1784 ASSERT(dst != TMP); |
| 1782 movq(TMP, imm); | 1785 movq(TMP, imm); |
| 1783 xorq(dst, TMP); | 1786 xorq(dst, TMP); |
| 1784 } | 1787 } |
| 1785 } | 1788 } |
| 1786 | 1789 |
| 1787 | 1790 |
| 1788 void Assembler::XorImmediate(Register dst, const Immediate& imm, Register pp) { | 1791 void Assembler::XorImmediate(Register dst, const Immediate& imm) { |
| 1789 if (CanLoadImmediateFromPool(imm, pp)) { | 1792 if (imm.is_int32()) { |
| 1793 xorq(dst, imm); |
| 1794 } else { |
| 1790 ASSERT(dst != TMP); | 1795 ASSERT(dst != TMP); |
| 1791 LoadImmediate(TMP, imm, pp); | 1796 LoadImmediate(TMP, imm); |
| 1792 xorq(dst, TMP); | 1797 xorq(dst, TMP); |
| 1793 } else { | |
| 1794 xorq(dst, imm); | |
| 1795 } | 1798 } |
| 1796 } | 1799 } |
| 1797 | 1800 |
| 1798 | 1801 |
| 1799 void Assembler::addl(Register dst, Register src) { | 1802 void Assembler::addl(Register dst, Register src) { |
| 1800 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1803 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1801 Operand operand(src); | 1804 Operand operand(src); |
| 1802 EmitOperandREX(dst, operand, REX_NONE); | 1805 EmitOperandREX(dst, operand, REX_NONE); |
| 1803 EmitUint8(0x03); | 1806 EmitUint8(0x03); |
| 1804 EmitOperand(dst & 7, operand); | 1807 EmitOperand(dst & 7, operand); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1870 EmitOperand(dst & 7, address); | 1873 EmitOperand(dst & 7, address); |
| 1871 } | 1874 } |
| 1872 | 1875 |
| 1873 | 1876 |
| 1874 void Assembler::addq(Register dst, const Immediate& imm) { | 1877 void Assembler::addq(Register dst, const Immediate& imm) { |
| 1875 if (imm.is_int32()) { | 1878 if (imm.is_int32()) { |
| 1876 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1879 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1877 EmitRegisterREX(dst, REX_W); | 1880 EmitRegisterREX(dst, REX_W); |
| 1878 EmitComplex(0, Operand(dst), imm); | 1881 EmitComplex(0, Operand(dst), imm); |
| 1879 } else { | 1882 } else { |
| 1883 ASSERT(dst != TMP); |
| 1880 movq(TMP, imm); | 1884 movq(TMP, imm); |
| 1881 addq(dst, TMP); | 1885 addq(dst, TMP); |
| 1882 } | 1886 } |
| 1883 } | 1887 } |
| 1884 | 1888 |
| 1885 | 1889 |
| 1886 void Assembler::addq(const Address& address, const Immediate& imm) { | 1890 void Assembler::addq(const Address& address, const Immediate& imm) { |
| 1887 if (imm.is_int32()) { | 1891 if (imm.is_int32()) { |
| 1888 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1892 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1889 EmitOperandREX(0, address, REX_W); | 1893 EmitOperandREX(0, address, REX_W); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1911 EmitOperand(dst & 7, operand); | 1915 EmitOperand(dst & 7, operand); |
| 1912 } | 1916 } |
| 1913 | 1917 |
| 1914 | 1918 |
| 1915 void Assembler::adcq(Register dst, const Immediate& imm) { | 1919 void Assembler::adcq(Register dst, const Immediate& imm) { |
| 1916 if (imm.is_int32()) { | 1920 if (imm.is_int32()) { |
| 1917 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1921 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1918 EmitRegisterREX(dst, REX_W); | 1922 EmitRegisterREX(dst, REX_W); |
| 1919 EmitComplex(2, Operand(dst), imm); | 1923 EmitComplex(2, Operand(dst), imm); |
| 1920 } else { | 1924 } else { |
| 1925 ASSERT(dst != TMP); |
| 1921 movq(TMP, imm); | 1926 movq(TMP, imm); |
| 1922 adcq(dst, TMP); | 1927 adcq(dst, TMP); |
| 1923 } | 1928 } |
| 1924 } | 1929 } |
| 1925 | 1930 |
| 1926 | 1931 |
| 1927 void Assembler::adcq(Register dst, const Address& address) { | 1932 void Assembler::adcq(Register dst, const Address& address) { |
| 1928 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1933 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1929 EmitOperandREX(dst, address, REX_W); | 1934 EmitOperandREX(dst, address, REX_W); |
| 1930 EmitUint8(0x13); | 1935 EmitUint8(0x13); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2067 | 2072 |
| 2068 void Assembler::imulq(Register reg, const Immediate& imm) { | 2073 void Assembler::imulq(Register reg, const Immediate& imm) { |
| 2069 if (imm.is_int32()) { | 2074 if (imm.is_int32()) { |
| 2070 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2075 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2071 Operand operand(reg); | 2076 Operand operand(reg); |
| 2072 EmitOperandREX(reg, operand, REX_W); | 2077 EmitOperandREX(reg, operand, REX_W); |
| 2073 EmitUint8(0x69); | 2078 EmitUint8(0x69); |
| 2074 EmitOperand(reg & 7, Operand(reg)); | 2079 EmitOperand(reg & 7, Operand(reg)); |
| 2075 EmitImmediate(imm); | 2080 EmitImmediate(imm); |
| 2076 } else { | 2081 } else { |
| 2082 ASSERT(reg != TMP); |
| 2077 movq(TMP, imm); | 2083 movq(TMP, imm); |
| 2078 imulq(reg, TMP); | 2084 imulq(reg, TMP); |
| 2079 } | 2085 } |
| 2080 } | 2086 } |
| 2081 | 2087 |
| 2082 | 2088 |
| 2083 void Assembler::MulImmediate(Register reg, const Immediate& imm, Register pp) { | 2089 void Assembler::MulImmediate(Register reg, const Immediate& imm) { |
| 2084 if (CanLoadImmediateFromPool(imm, pp)) { | 2090 if (imm.is_int32()) { |
| 2091 imulq(reg, imm); |
| 2092 } else { |
| 2085 ASSERT(reg != TMP); | 2093 ASSERT(reg != TMP); |
| 2086 LoadImmediate(TMP, imm, pp); | 2094 LoadImmediate(TMP, imm); |
| 2087 imulq(reg, TMP); | 2095 imulq(reg, TMP); |
| 2088 } else { | |
| 2089 imulq(reg, imm); | |
| 2090 } | 2096 } |
| 2091 } | 2097 } |
| 2092 | 2098 |
| 2093 | 2099 |
| 2094 void Assembler::imulq(Register dst, const Address& address) { | 2100 void Assembler::imulq(Register dst, const Address& address) { |
| 2095 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2101 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2096 EmitOperandREX(dst, address, REX_W); | 2102 EmitOperandREX(dst, address, REX_W); |
| 2097 EmitUint8(0x0F); | 2103 EmitUint8(0x0F); |
| 2098 EmitUint8(0xAF); | 2104 EmitUint8(0xAF); |
| 2099 EmitOperand(dst & 7, address); | 2105 EmitOperand(dst & 7, address); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2116 EmitOperand(dst & 7, operand); | 2122 EmitOperand(dst & 7, operand); |
| 2117 } | 2123 } |
| 2118 | 2124 |
| 2119 | 2125 |
| 2120 void Assembler::subq(Register reg, const Immediate& imm) { | 2126 void Assembler::subq(Register reg, const Immediate& imm) { |
| 2121 if (imm.is_int32()) { | 2127 if (imm.is_int32()) { |
| 2122 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2128 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2123 EmitRegisterREX(reg, REX_W); | 2129 EmitRegisterREX(reg, REX_W); |
| 2124 EmitComplex(5, Operand(reg), imm); | 2130 EmitComplex(5, Operand(reg), imm); |
| 2125 } else { | 2131 } else { |
| 2132 ASSERT(reg != TMP); |
| 2126 movq(TMP, imm); | 2133 movq(TMP, imm); |
| 2127 subq(reg, TMP); | 2134 subq(reg, TMP); |
| 2128 } | 2135 } |
| 2129 } | 2136 } |
| 2130 | 2137 |
| 2131 | 2138 |
| 2132 void Assembler::subq(Register reg, const Address& address) { | 2139 void Assembler::subq(Register reg, const Address& address) { |
| 2133 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2140 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2134 EmitOperandREX(reg, address, REX_W); | 2141 EmitOperandREX(reg, address, REX_W); |
| 2135 EmitUint8(0x2B); | 2142 EmitUint8(0x2B); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2165 EmitOperand(dst & 7, operand); | 2172 EmitOperand(dst & 7, operand); |
| 2166 } | 2173 } |
| 2167 | 2174 |
| 2168 | 2175 |
| 2169 void Assembler::sbbq(Register dst, const Immediate& imm) { | 2176 void Assembler::sbbq(Register dst, const Immediate& imm) { |
| 2170 if (imm.is_int32()) { | 2177 if (imm.is_int32()) { |
| 2171 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2178 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2172 EmitRegisterREX(dst, REX_W); | 2179 EmitRegisterREX(dst, REX_W); |
| 2173 EmitComplex(3, Operand(dst), imm); | 2180 EmitComplex(3, Operand(dst), imm); |
| 2174 } else { | 2181 } else { |
| 2182 ASSERT(dst != TMP); |
| 2175 movq(TMP, imm); | 2183 movq(TMP, imm); |
| 2176 sbbq(dst, TMP); | 2184 sbbq(dst, TMP); |
| 2177 } | 2185 } |
| 2178 } | 2186 } |
| 2179 | 2187 |
| 2180 | 2188 |
| 2181 void Assembler::sbbq(Register dst, const Address& address) { | 2189 void Assembler::sbbq(Register dst, const Address& address) { |
| 2182 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2190 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2183 EmitOperandREX(dst, address, REX_W); | 2191 EmitOperandREX(dst, address, REX_W); |
| 2184 EmitUint8(0x1B); | 2192 EmitUint8(0x1B); |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2592 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2600 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2593 EmitRegisterREX(TMP, REX_W); | 2601 EmitRegisterREX(TMP, REX_W); |
| 2594 EmitUint8(0xB8 | (TMP & 7)); | 2602 EmitUint8(0xB8 | (TMP & 7)); |
| 2595 EmitInt64(label->address()); | 2603 EmitInt64(label->address()); |
| 2596 } | 2604 } |
| 2597 jmp(TMP); | 2605 jmp(TMP); |
| 2598 } | 2606 } |
| 2599 | 2607 |
| 2600 | 2608 |
| 2601 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { | 2609 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { |
| 2602 ASSERT(constant_pool_allowed()); | 2610 ASSERT((pp != PP) || constant_pool_allowed()); |
| 2603 intptr_t call_start = buffer_.GetPosition(); | 2611 intptr_t call_start = buffer_.GetPosition(); |
| 2604 const int32_t offset = ObjectPool::element_offset( | 2612 const int32_t offset = ObjectPool::element_offset( |
| 2605 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); | 2613 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); |
| 2606 // Patchable jumps always use a 32-bit immediate encoding. | 2614 // Patchable jumps always use a 32-bit immediate encoding. |
| 2607 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); | 2615 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); |
| 2608 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); | 2616 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); |
| 2609 } | 2617 } |
| 2610 | 2618 |
| 2611 | 2619 |
| 2612 void Assembler::Jmp(const ExternalLabel* label, Register pp) { | 2620 void Assembler::Jmp(const ExternalLabel* label, Register pp) { |
| 2621 ASSERT((pp != PP) || constant_pool_allowed()); |
| 2613 const int32_t offset = ObjectPool::element_offset( | 2622 const int32_t offset = ObjectPool::element_offset( |
| 2614 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable)); | 2623 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable)); |
| 2615 jmp(Address(pp, offset - kHeapObjectTag)); | 2624 jmp(Address(pp, offset - kHeapObjectTag)); |
| 2616 } | 2625 } |
| 2617 | 2626 |
| 2618 | 2627 |
| 2619 void Assembler::lock() { | 2628 void Assembler::lock() { |
| 2620 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2629 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2621 EmitUint8(0xF0); | 2630 EmitUint8(0xF0); |
| 2622 } | 2631 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2657 movq(to, from); | 2666 movq(to, from); |
| 2658 } | 2667 } |
| 2659 } | 2668 } |
| 2660 | 2669 |
| 2661 | 2670 |
| 2662 void Assembler::PopRegister(Register r) { | 2671 void Assembler::PopRegister(Register r) { |
| 2663 popq(r); | 2672 popq(r); |
| 2664 } | 2673 } |
| 2665 | 2674 |
| 2666 | 2675 |
| 2667 void Assembler::AddImmediate(Register reg, const Immediate& imm, Register pp) { | 2676 void Assembler::AddImmediate(Register reg, const Immediate& imm) { |
| 2668 const int64_t value = imm.value(); | 2677 const int64_t value = imm.value(); |
| 2669 if (value == 0) { | 2678 if (value == 0) { |
| 2670 return; | 2679 return; |
| 2671 } | 2680 } |
| 2672 if ((value > 0) || (value == kMinInt64)) { | 2681 if ((value > 0) || (value == kMinInt64)) { |
| 2673 if (value == 1) { | 2682 if (value == 1) { |
| 2674 incq(reg); | 2683 incq(reg); |
| 2675 } else { | 2684 } else { |
| 2676 if (CanLoadImmediateFromPool(imm, pp)) { | 2685 if (imm.is_int32()) { |
| 2686 addq(reg, imm); |
| 2687 } else { |
| 2677 ASSERT(reg != TMP); | 2688 ASSERT(reg != TMP); |
| 2678 LoadImmediate(TMP, imm, pp); | 2689 LoadImmediate(TMP, imm); |
| 2679 addq(reg, TMP); | 2690 addq(reg, TMP); |
| 2680 } else { | |
| 2681 addq(reg, imm); | |
| 2682 } | 2691 } |
| 2683 } | 2692 } |
| 2684 } else { | 2693 } else { |
| 2685 SubImmediate(reg, Immediate(-value), pp); | 2694 SubImmediate(reg, Immediate(-value)); |
| 2686 } | 2695 } |
| 2687 } | 2696 } |
| 2688 | 2697 |
| 2689 | 2698 |
| 2690 void Assembler::AddImmediate(const Address& address, const Immediate& imm, | 2699 void Assembler::AddImmediate(const Address& address, const Immediate& imm) { |
| 2691 Register pp) { | |
| 2692 const int64_t value = imm.value(); | 2700 const int64_t value = imm.value(); |
| 2693 if (value == 0) { | 2701 if (value == 0) { |
| 2694 return; | 2702 return; |
| 2695 } | 2703 } |
| 2696 if ((value > 0) || (value == kMinInt64)) { | 2704 if ((value > 0) || (value == kMinInt64)) { |
| 2697 if (value == 1) { | 2705 if (value == 1) { |
| 2698 incq(address); | 2706 incq(address); |
| 2699 } else { | 2707 } else { |
| 2700 if (CanLoadImmediateFromPool(imm, pp)) { | 2708 if (imm.is_int32()) { |
| 2701 LoadImmediate(TMP, imm, pp); | 2709 addq(address, imm); |
| 2710 } else { |
| 2711 LoadImmediate(TMP, imm); |
| 2702 addq(address, TMP); | 2712 addq(address, TMP); |
| 2703 } else { | |
| 2704 addq(address, imm); | |
| 2705 } | 2713 } |
| 2706 } | 2714 } |
| 2707 } else { | 2715 } else { |
| 2708 SubImmediate(address, Immediate(-value), pp); | 2716 SubImmediate(address, Immediate(-value)); |
| 2709 } | 2717 } |
| 2710 } | 2718 } |
| 2711 | 2719 |
| 2712 | 2720 |
| 2713 void Assembler::SubImmediate(Register reg, const Immediate& imm, Register pp) { | 2721 void Assembler::SubImmediate(Register reg, const Immediate& imm) { |
| 2714 const int64_t value = imm.value(); | 2722 const int64_t value = imm.value(); |
| 2715 if (value == 0) { | 2723 if (value == 0) { |
| 2716 return; | 2724 return; |
| 2717 } | 2725 } |
| 2718 if ((value > 0) || (value == kMinInt64)) { | 2726 if ((value > 0) || (value == kMinInt64)) { |
| 2719 if (value == 1) { | 2727 if (value == 1) { |
| 2720 decq(reg); | 2728 decq(reg); |
| 2721 } else { | 2729 } else { |
| 2722 if (CanLoadImmediateFromPool(imm, pp)) { | 2730 if (imm.is_int32()) { |
| 2731 subq(reg, imm); |
| 2732 } else { |
| 2723 ASSERT(reg != TMP); | 2733 ASSERT(reg != TMP); |
| 2724 LoadImmediate(TMP, imm, pp); | 2734 LoadImmediate(TMP, imm); |
| 2725 subq(reg, TMP); | 2735 subq(reg, TMP); |
| 2726 } else { | |
| 2727 subq(reg, imm); | |
| 2728 } | 2736 } |
| 2729 } | 2737 } |
| 2730 } else { | 2738 } else { |
| 2731 AddImmediate(reg, Immediate(-value), pp); | 2739 AddImmediate(reg, Immediate(-value)); |
| 2732 } | 2740 } |
| 2733 } | 2741 } |
| 2734 | 2742 |
| 2735 | 2743 |
| 2736 void Assembler::SubImmediate(const Address& address, const Immediate& imm, | 2744 void Assembler::SubImmediate(const Address& address, const Immediate& imm) { |
| 2737 Register pp) { | |
| 2738 const int64_t value = imm.value(); | 2745 const int64_t value = imm.value(); |
| 2739 if (value == 0) { | 2746 if (value == 0) { |
| 2740 return; | 2747 return; |
| 2741 } | 2748 } |
| 2742 if ((value > 0) || (value == kMinInt64)) { | 2749 if ((value > 0) || (value == kMinInt64)) { |
| 2743 if (value == 1) { | 2750 if (value == 1) { |
| 2744 decq(address); | 2751 decq(address); |
| 2745 } else { | 2752 } else { |
| 2746 if (CanLoadImmediateFromPool(imm, pp)) { | 2753 if (imm.is_int32()) { |
| 2747 LoadImmediate(TMP, imm, pp); | 2754 subq(address, imm); |
| 2755 } else { |
| 2756 LoadImmediate(TMP, imm); |
| 2748 subq(address, TMP); | 2757 subq(address, TMP); |
| 2749 } else { | |
| 2750 subq(address, imm); | |
| 2751 } | 2758 } |
| 2752 } | 2759 } |
| 2753 } else { | 2760 } else { |
| 2754 AddImmediate(address, Immediate(-value), pp); | 2761 AddImmediate(address, Immediate(-value)); |
| 2755 } | 2762 } |
| 2756 } | 2763 } |
| 2757 | 2764 |
| 2758 | 2765 |
| 2759 void Assembler::Drop(intptr_t stack_elements, Register tmp) { | 2766 void Assembler::Drop(intptr_t stack_elements, Register tmp) { |
| 2760 ASSERT(stack_elements >= 0); | 2767 ASSERT(stack_elements >= 0); |
| 2761 if (stack_elements <= 4) { | 2768 if (stack_elements <= 4) { |
| 2762 for (intptr_t i = 0; i < stack_elements; i++) { | 2769 for (intptr_t i = 0; i < stack_elements; i++) { |
| 2763 popq(tmp); | 2770 popq(tmp); |
| 2764 } | 2771 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2780 // If the raw smi does not fit into a 32-bit signed int, then we'll keep | 2787 // If the raw smi does not fit into a 32-bit signed int, then we'll keep |
| 2781 // the raw value in the object pool. | 2788 // the raw value in the object pool. |
| 2782 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); | 2789 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); |
| 2783 } | 2790 } |
| 2784 ASSERT(object.IsNotTemporaryScopedHandle()); | 2791 ASSERT(object.IsNotTemporaryScopedHandle()); |
| 2785 ASSERT(object.IsOld()); | 2792 ASSERT(object.IsOld()); |
| 2786 return true; | 2793 return true; |
| 2787 } | 2794 } |
| 2788 | 2795 |
| 2789 | 2796 |
| 2790 void Assembler::LoadWordFromPoolOffset(Register dst, Register pp, | 2797 void Assembler::LoadWordFromPoolOffset(Register dst, int32_t offset) { |
| 2791 int32_t offset) { | 2798 ASSERT(constant_pool_allowed()); |
| 2799 ASSERT(dst != PP); |
| 2792 // This sequence must be of fixed size. AddressBaseImm32 | 2800 // This sequence must be of fixed size. AddressBaseImm32 |
| 2793 // forces the address operand to use a fixed-size imm32 encoding. | 2801 // forces the address operand to use a fixed-size imm32 encoding. |
| 2794 movq(dst, Address::AddressBaseImm32(pp, offset)); | 2802 movq(dst, Address::AddressBaseImm32(PP, offset)); |
| 2795 } | 2803 } |
| 2796 | 2804 |
| 2797 | 2805 |
| 2798 void Assembler::LoadIsolate(Register dst) { | 2806 void Assembler::LoadIsolate(Register dst) { |
| 2799 movq(dst, Address(THR, Thread::isolate_offset())); | 2807 movq(dst, Address(THR, Thread::isolate_offset())); |
| 2800 } | 2808 } |
| 2801 | 2809 |
| 2802 | 2810 |
| 2803 void Assembler::LoadObjectHelper(Register dst, | 2811 void Assembler::LoadObjectHelper(Register dst, |
| 2804 const Object& object, | 2812 const Object& object, |
| 2805 Register pp, | |
| 2806 bool is_unique) { | 2813 bool is_unique) { |
| 2807 if (Thread::CanLoadFromThread(object)) { | 2814 if (Thread::CanLoadFromThread(object)) { |
| 2808 movq(dst, Address(THR, Thread::OffsetFromThread(object))); | 2815 movq(dst, Address(THR, Thread::OffsetFromThread(object))); |
| 2809 } else if (CanLoadFromObjectPool(object)) { | 2816 } else if (CanLoadFromObjectPool(object)) { |
| 2810 const int32_t offset = ObjectPool::element_offset( | 2817 const int32_t offset = ObjectPool::element_offset( |
| 2811 is_unique ? object_pool_wrapper_.AddObject(object) | 2818 is_unique ? object_pool_wrapper_.AddObject(object) |
| 2812 : object_pool_wrapper_.FindObject(object)); | 2819 : object_pool_wrapper_.FindObject(object)); |
| 2813 LoadWordFromPoolOffset(dst, pp, offset - kHeapObjectTag); | 2820 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag); |
| 2814 } else { | 2821 } else { |
| 2815 ASSERT(object.IsSmi() || object.InVMHeap()); | 2822 ASSERT(object.IsSmi() || object.InVMHeap()); |
| 2816 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); | 2823 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); |
| 2817 } | 2824 } |
| 2818 } | 2825 } |
| 2819 | 2826 |
| 2820 | 2827 |
| 2821 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { | 2828 void Assembler::LoadFunctionFromCalleePool(Register dst, |
| 2822 LoadObjectHelper(dst, object, pp, false); | 2829 const Function& function, |
| 2830 Register new_pp) { |
| 2831 ASSERT(!constant_pool_allowed()); |
| 2832 ASSERT(new_pp != PP); |
| 2833 const int32_t offset = |
| 2834 ObjectPool::element_offset(object_pool_wrapper_.FindObject(function)); |
| 2835 movq(dst, Address::AddressBaseImm32(new_pp, offset - kHeapObjectTag)); |
| 2823 } | 2836 } |
| 2824 | 2837 |
| 2825 | 2838 |
| 2826 void Assembler::LoadUniqueObject(Register dst, | 2839 void Assembler::LoadObject(Register dst, const Object& object) { |
| 2827 const Object& object, | 2840 LoadObjectHelper(dst, object, false); |
| 2828 Register pp) { | |
| 2829 LoadObjectHelper(dst, object, pp, true); | |
| 2830 } | 2841 } |
| 2831 | 2842 |
| 2832 | 2843 |
| 2833 void Assembler::StoreObject(const Address& dst, const Object& object, | 2844 void Assembler::LoadUniqueObject(Register dst, const Object& object) { |
| 2834 Register pp) { | 2845 LoadObjectHelper(dst, object, true); |
| 2846 } |
| 2847 |
| 2848 |
| 2849 void Assembler::StoreObject(const Address& dst, const Object& object) { |
| 2835 if (Thread::CanLoadFromThread(object)) { | 2850 if (Thread::CanLoadFromThread(object)) { |
| 2836 movq(TMP, Address(THR, Thread::OffsetFromThread(object))); | 2851 movq(TMP, Address(THR, Thread::OffsetFromThread(object))); |
| 2837 movq(dst, TMP); | 2852 movq(dst, TMP); |
| 2838 } else if (CanLoadFromObjectPool(object)) { | 2853 } else if (CanLoadFromObjectPool(object)) { |
| 2839 LoadObject(TMP, object, pp); | 2854 LoadObject(TMP, object); |
| 2840 movq(dst, TMP); | 2855 movq(dst, TMP); |
| 2841 } else { | 2856 } else { |
| 2842 MoveImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); | 2857 MoveImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); |
| 2843 } | 2858 } |
| 2844 } | 2859 } |
| 2845 | 2860 |
| 2846 | 2861 |
| 2847 void Assembler::PushObject(const Object& object, Register pp) { | 2862 void Assembler::PushObject(const Object& object) { |
| 2848 if (Thread::CanLoadFromThread(object)) { | 2863 if (Thread::CanLoadFromThread(object)) { |
| 2849 pushq(Address(THR, Thread::OffsetFromThread(object))); | 2864 pushq(Address(THR, Thread::OffsetFromThread(object))); |
| 2850 } else if (CanLoadFromObjectPool(object)) { | 2865 } else if (CanLoadFromObjectPool(object)) { |
| 2851 LoadObject(TMP, object, pp); | 2866 LoadObject(TMP, object); |
| 2852 pushq(TMP); | 2867 pushq(TMP); |
| 2853 } else { | 2868 } else { |
| 2854 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())), pp); | 2869 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw()))); |
| 2855 } | 2870 } |
| 2856 } | 2871 } |
| 2857 | 2872 |
| 2858 | 2873 |
| 2859 void Assembler::CompareObject(Register reg, const Object& object, Register pp) { | 2874 void Assembler::CompareObject(Register reg, const Object& object) { |
| 2860 if (Thread::CanLoadFromThread(object)) { | 2875 if (Thread::CanLoadFromThread(object)) { |
| 2861 cmpq(reg, Address(THR, Thread::OffsetFromThread(object))); | 2876 cmpq(reg, Address(THR, Thread::OffsetFromThread(object))); |
| 2862 } else if (CanLoadFromObjectPool(object)) { | 2877 } else if (CanLoadFromObjectPool(object)) { |
| 2863 const int32_t offset = | 2878 const int32_t offset = |
| 2864 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); | 2879 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); |
| 2865 cmpq(reg, Address(pp, offset-kHeapObjectTag)); | 2880 cmpq(reg, Address(PP, offset-kHeapObjectTag)); |
| 2866 } else { | 2881 } else { |
| 2867 CompareImmediate( | 2882 CompareImmediate( |
| 2868 reg, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); | 2883 reg, Immediate(reinterpret_cast<int64_t>(object.raw()))); |
| 2869 } | 2884 } |
| 2870 } | 2885 } |
| 2871 | 2886 |
| 2872 | 2887 |
| 2873 intptr_t Assembler::FindImmediate(int64_t imm) { | 2888 intptr_t Assembler::FindImmediate(int64_t imm) { |
| 2874 return object_pool_wrapper_.FindImmediate(imm); | 2889 return object_pool_wrapper_.FindImmediate(imm); |
| 2875 } | 2890 } |
| 2876 | 2891 |
| 2877 | 2892 |
| 2878 bool Assembler::CanLoadImmediateFromPool(const Immediate& imm, Register pp) { | 2893 void Assembler::LoadImmediate(Register reg, const Immediate& imm) { |
| 2879 if (!constant_pool_allowed()) { | 2894 if (imm.is_int32() || !constant_pool_allowed()) { |
| 2880 return false; | 2895 movq(reg, imm); |
| 2881 } | 2896 } else { |
| 2882 return !imm.is_int32() && (pp != kNoRegister); | |
| 2883 } | |
| 2884 | |
| 2885 | |
| 2886 void Assembler::LoadImmediate(Register reg, const Immediate& imm, Register pp) { | |
| 2887 if (CanLoadImmediateFromPool(imm, pp)) { | |
| 2888 int32_t offset = ObjectPool::element_offset(FindImmediate(imm.value())); | 2897 int32_t offset = ObjectPool::element_offset(FindImmediate(imm.value())); |
| 2889 LoadWordFromPoolOffset(reg, pp, offset - kHeapObjectTag); | 2898 LoadWordFromPoolOffset(reg, offset - kHeapObjectTag); |
| 2890 } else { | |
| 2891 movq(reg, imm); | |
| 2892 } | 2899 } |
| 2893 } | 2900 } |
| 2894 | 2901 |
| 2895 | 2902 |
| 2896 void Assembler::MoveImmediate(const Address& dst, const Immediate& imm, | 2903 void Assembler::MoveImmediate(const Address& dst, const Immediate& imm) { |
| 2897 Register pp) { | 2904 if (imm.is_int32()) { |
| 2898 if (CanLoadImmediateFromPool(imm, pp)) { | 2905 movq(dst, imm); |
| 2899 LoadImmediate(TMP, imm, pp); | 2906 } else { |
| 2907 LoadImmediate(TMP, imm); |
| 2900 movq(dst, TMP); | 2908 movq(dst, TMP); |
| 2901 } else { | |
| 2902 movq(dst, imm); | |
| 2903 } | 2909 } |
| 2904 } | 2910 } |
| 2905 | 2911 |
| 2906 | 2912 |
| 2907 // Destroys the value register. | 2913 // Destroys the value register. |
| 2908 void Assembler::StoreIntoObjectFilterNoSmi(Register object, | 2914 void Assembler::StoreIntoObjectFilterNoSmi(Register object, |
| 2909 Register value, | 2915 Register value, |
| 2910 Label* no_update) { | 2916 Label* no_update) { |
| 2911 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && | 2917 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && |
| 2912 (kOldObjectAlignmentOffset == 0)); | 2918 (kOldObjectAlignmentOffset == 0)); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3078 Bind(&done); | 3084 Bind(&done); |
| 3079 popq(value); | 3085 popq(value); |
| 3080 #endif // defined(DEBUG) | 3086 #endif // defined(DEBUG) |
| 3081 // No store buffer update. | 3087 // No store buffer update. |
| 3082 } | 3088 } |
| 3083 | 3089 |
| 3084 | 3090 |
| 3085 void Assembler::StoreIntoObjectNoBarrier(Register object, | 3091 void Assembler::StoreIntoObjectNoBarrier(Register object, |
| 3086 const Address& dest, | 3092 const Address& dest, |
| 3087 const Object& value, | 3093 const Object& value, |
| 3088 Register pp, | |
| 3089 FieldContent old_content) { | 3094 FieldContent old_content) { |
| 3090 VerifyHeapWord(dest, old_content); | 3095 VerifyHeapWord(dest, old_content); |
| 3091 if (VerifiedMemory::enabled()) { | 3096 if (VerifiedMemory::enabled()) { |
| 3092 Register temp = (pp == RCX) ? RDX : RCX; | 3097 const Register temp = RCX; |
| 3093 pushq(temp); | 3098 pushq(temp); |
| 3094 leaq(temp, dest); | 3099 leaq(temp, dest); |
| 3095 StoreObject(Address(temp, 0), value, pp); | 3100 StoreObject(Address(temp, 0), value); |
| 3096 StoreObject(Address(temp, VerifiedMemory::offset()), value, pp); | 3101 StoreObject(Address(temp, VerifiedMemory::offset()), value); |
| 3097 popq(temp); | 3102 popq(temp); |
| 3098 } else { | 3103 } else { |
| 3099 StoreObject(dest, value, pp); | 3104 StoreObject(dest, value); |
| 3100 } | 3105 } |
| 3101 // TODO(koda): Use 'object', verify that generational barrier's not needed. | 3106 // TODO(koda): Use 'object', verify that generational barrier's not needed. |
| 3102 } | 3107 } |
| 3103 | 3108 |
| 3104 | 3109 |
| 3105 void Assembler::StoreIntoSmiField(const Address& dest, Register value) { | 3110 void Assembler::StoreIntoSmiField(const Address& dest, Register value) { |
| 3106 #if defined(DEBUG) | 3111 #if defined(DEBUG) |
| 3107 Label done; | 3112 Label done; |
| 3108 testq(value, Immediate(kHeapObjectTag)); | 3113 testq(value, Immediate(kHeapObjectTag)); |
| 3109 j(ZERO, &done); | 3114 j(ZERO, &done); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3146 } | 3151 } |
| 3147 | 3152 |
| 3148 | 3153 |
| 3149 void Assembler::DoubleNegate(XmmRegister d) { | 3154 void Assembler::DoubleNegate(XmmRegister d) { |
| 3150 static const struct ALIGN16 { | 3155 static const struct ALIGN16 { |
| 3151 uint64_t a; | 3156 uint64_t a; |
| 3152 uint64_t b; | 3157 uint64_t b; |
| 3153 } double_negate_constant = | 3158 } double_negate_constant = |
| 3154 {0x8000000000000000LL, 0x8000000000000000LL}; | 3159 {0x8000000000000000LL, 0x8000000000000000LL}; |
| 3155 LoadImmediate( | 3160 LoadImmediate( |
| 3156 TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)), PP); | 3161 TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant))); |
| 3157 xorpd(d, Address(TMP, 0)); | 3162 xorpd(d, Address(TMP, 0)); |
| 3158 } | 3163 } |
| 3159 | 3164 |
| 3160 | 3165 |
| 3161 void Assembler::DoubleAbs(XmmRegister reg) { | 3166 void Assembler::DoubleAbs(XmmRegister reg) { |
| 3162 static const struct ALIGN16 { | 3167 static const struct ALIGN16 { |
| 3163 uint64_t a; | 3168 uint64_t a; |
| 3164 uint64_t b; | 3169 uint64_t b; |
| 3165 } double_abs_constant = | 3170 } double_abs_constant = |
| 3166 {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}; | 3171 {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}; |
| 3167 LoadImmediate(TMP, | 3172 LoadImmediate(TMP, |
| 3168 Immediate(reinterpret_cast<intptr_t>(&double_abs_constant)), PP); | 3173 Immediate(reinterpret_cast<intptr_t>(&double_abs_constant))); |
| 3169 andpd(reg, Address(TMP, 0)); | 3174 andpd(reg, Address(TMP, 0)); |
| 3170 } | 3175 } |
| 3171 | 3176 |
| 3172 | 3177 |
| 3173 void Assembler::Stop(const char* message, bool fixed_length_encoding) { | 3178 void Assembler::Stop(const char* message, bool fixed_length_encoding) { |
| 3174 int64_t message_address = reinterpret_cast<int64_t>(message); | 3179 int64_t message_address = reinterpret_cast<int64_t>(message); |
| 3175 if (FLAG_print_stop_message) { | 3180 if (FLAG_print_stop_message) { |
| 3176 pushq(TMP); // Preserve TMP register. | 3181 pushq(TMP); // Preserve TMP register. |
| 3177 pushq(RDI); // Preserve RDI register. | 3182 pushq(RDI); // Preserve RDI register. |
| 3178 if (fixed_length_encoding) { | 3183 if (fixed_length_encoding) { |
| 3179 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 3184 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 3180 EmitRegisterREX(RDI, REX_W); | 3185 EmitRegisterREX(RDI, REX_W); |
| 3181 EmitUint8(0xB8 | (RDI & 7)); | 3186 EmitUint8(0xB8 | (RDI & 7)); |
| 3182 EmitInt64(message_address); | 3187 EmitInt64(message_address); |
| 3183 } else { | 3188 } else { |
| 3184 LoadImmediate(RDI, Immediate(message_address), PP); | 3189 LoadImmediate(RDI, Immediate(message_address)); |
| 3185 } | 3190 } |
| 3186 call(&StubCode::PrintStopMessageLabel()); | 3191 call(&StubCode::PrintStopMessageLabel()); |
| 3187 popq(RDI); // Restore RDI register. | 3192 popq(RDI); // Restore RDI register. |
| 3188 popq(TMP); // Restore TMP register. | 3193 popq(TMP); // Restore TMP register. |
| 3189 } else { | 3194 } else { |
| 3190 // Emit the lower half and the higher half of the message address as | 3195 // Emit the lower half and the higher half of the message address as |
| 3191 // immediate operands in the test rax instructions. | 3196 // immediate operands in the test rax instructions. |
| 3192 testl(RAX, Immediate(Utils::Low32Bits(message_address))); | 3197 testl(RAX, Immediate(Utils::Low32Bits(message_address))); |
| 3193 testl(RAX, Immediate(Utils::High32Bits(message_address))); | 3198 testl(RAX, Immediate(Utils::High32Bits(message_address))); |
| 3194 } | 3199 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3252 if (OS::ActivationFrameAlignment() > 1) { | 3257 if (OS::ActivationFrameAlignment() > 1) { |
| 3253 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 3258 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 3254 } | 3259 } |
| 3255 } | 3260 } |
| 3256 | 3261 |
| 3257 | 3262 |
| 3258 void Assembler::PushRegisters(intptr_t cpu_register_set, | 3263 void Assembler::PushRegisters(intptr_t cpu_register_set, |
| 3259 intptr_t xmm_register_set) { | 3264 intptr_t xmm_register_set) { |
| 3260 const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set); | 3265 const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set); |
| 3261 if (xmm_regs_count > 0) { | 3266 if (xmm_regs_count > 0) { |
| 3262 AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize), PP); | 3267 AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize)); |
| 3263 // Store XMM registers with the lowest register number at the lowest | 3268 // Store XMM registers with the lowest register number at the lowest |
| 3264 // address. | 3269 // address. |
| 3265 intptr_t offset = 0; | 3270 intptr_t offset = 0; |
| 3266 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { | 3271 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { |
| 3267 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); | 3272 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); |
| 3268 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) { | 3273 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) { |
| 3269 movups(Address(RSP, offset), xmm_reg); | 3274 movups(Address(RSP, offset), xmm_reg); |
| 3270 offset += kFpuRegisterSize; | 3275 offset += kFpuRegisterSize; |
| 3271 } | 3276 } |
| 3272 } | 3277 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3301 // XMM registers have the lowest register number at the lowest address. | 3306 // XMM registers have the lowest register number at the lowest address. |
| 3302 intptr_t offset = 0; | 3307 intptr_t offset = 0; |
| 3303 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { | 3308 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { |
| 3304 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); | 3309 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); |
| 3305 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) { | 3310 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) { |
| 3306 movups(xmm_reg, Address(RSP, offset)); | 3311 movups(xmm_reg, Address(RSP, offset)); |
| 3307 offset += kFpuRegisterSize; | 3312 offset += kFpuRegisterSize; |
| 3308 } | 3313 } |
| 3309 } | 3314 } |
| 3310 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize)); | 3315 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize)); |
| 3311 AddImmediate(RSP, Immediate(offset), PP); | 3316 AddImmediate(RSP, Immediate(offset)); |
| 3312 } | 3317 } |
| 3313 } | 3318 } |
| 3314 | 3319 |
| 3315 | 3320 |
| 3316 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { | 3321 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { |
| 3317 EnterFrame(0); | 3322 EnterFrame(0); |
| 3318 | 3323 |
| 3319 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch. | 3324 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch. |
| 3320 PushRegisters(CallingConventions::kVolatileCpuRegisters, | 3325 PushRegisters(CallingConventions::kVolatileCpuRegisters, |
| 3321 CallingConventions::kVolatileXmmRegisters); | 3326 CallingConventions::kVolatileXmmRegisters); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3371 | 3376 |
| 3372 void Assembler::LoadPoolPointer(Register pp) { | 3377 void Assembler::LoadPoolPointer(Register pp) { |
| 3373 // Load new pool pointer. | 3378 // Load new pool pointer. |
| 3374 const intptr_t kRIPRelativeMovqSize = 7; | 3379 const intptr_t kRIPRelativeMovqSize = 7; |
| 3375 const intptr_t entry_to_rip_offset = CodeSize() + kRIPRelativeMovqSize; | 3380 const intptr_t entry_to_rip_offset = CodeSize() + kRIPRelativeMovqSize; |
| 3376 const intptr_t object_pool_pc_dist = | 3381 const intptr_t object_pool_pc_dist = |
| 3377 Instructions::HeaderSize() - Instructions::object_pool_offset(); | 3382 Instructions::HeaderSize() - Instructions::object_pool_offset(); |
| 3378 movq(pp, Address::AddressRIPRelative( | 3383 movq(pp, Address::AddressRIPRelative( |
| 3379 -entry_to_rip_offset - object_pool_pc_dist)); | 3384 -entry_to_rip_offset - object_pool_pc_dist)); |
| 3380 ASSERT(CodeSize() == entry_to_rip_offset); | 3385 ASSERT(CodeSize() == entry_to_rip_offset); |
| 3386 set_constant_pool_allowed(pp == PP); |
| 3381 } | 3387 } |
| 3382 | 3388 |
| 3383 | 3389 |
| 3384 void Assembler::EnterDartFrameWithInfo(intptr_t frame_size, | 3390 void Assembler::EnterDartFrameWithInfo(intptr_t frame_size, |
| 3385 Register new_pp, | 3391 Register new_pp, |
| 3386 Register pc_marker_override) { | 3392 Register pc_marker_override) { |
| 3393 ASSERT(!constant_pool_allowed()); |
| 3387 EnterFrame(0); | 3394 EnterFrame(0); |
| 3388 pushq(pc_marker_override); | 3395 pushq(pc_marker_override); |
| 3389 pushq(PP); | 3396 pushq(PP); |
| 3390 movq(PP, new_pp); | 3397 movq(PP, new_pp); |
| 3398 set_constant_pool_allowed(true); |
| 3391 if (frame_size != 0) { | 3399 if (frame_size != 0) { |
| 3392 subq(RSP, Immediate(frame_size)); | 3400 subq(RSP, Immediate(frame_size)); |
| 3393 } | 3401 } |
| 3394 } | 3402 } |
| 3395 | 3403 |
| 3396 | 3404 |
| 3397 void Assembler::LeaveDartFrame() { | 3405 void Assembler::LeaveDartFrame() { |
| 3406 // LeaveDartFrame is called from stubs (pp disallowed) and from Dart code (pp |
| 3407 // allowed), so there is no point in checking the current value of |
| 3408 // constant_pool_allowed(). |
| 3409 set_constant_pool_allowed(false); |
| 3398 // Restore caller's PP register that was pushed in EnterDartFrame. | 3410 // Restore caller's PP register that was pushed in EnterDartFrame. |
| 3399 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); | 3411 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); |
| 3400 LeaveFrame(); | 3412 LeaveFrame(); |
| 3401 } | 3413 } |
| 3402 | 3414 |
| 3403 | 3415 |
| 3404 // On entry to a function compiled for OSR, the caller's frame pointer, the | 3416 // On entry to a function compiled for OSR, the caller's frame pointer, the |
| 3405 // stack locals, and any copied parameters are already in place. The frame | 3417 // stack locals, and any copied parameters are already in place. The frame |
| 3406 // pointer is already set up. The PC marker is not correct for the | 3418 // pointer is already set up. The PC marker is not correct for the |
| 3407 // optimized function and there may be extra space for spill slots to | 3419 // optimized function and there may be extra space for spill slots to |
| 3408 // allocate. | 3420 // allocate. |
| 3409 void Assembler::EnterOsrFrame(intptr_t extra_size, | 3421 void Assembler::EnterOsrFrame(intptr_t extra_size, |
| 3410 Register new_pp, | 3422 Register new_pp, |
| 3411 Register pc_marker_override) { | 3423 Register pc_marker_override) { |
| 3424 ASSERT(!constant_pool_allowed()); |
| 3412 if (prologue_offset_ == -1) { | 3425 if (prologue_offset_ == -1) { |
| 3413 Comment("PrologueOffset = %" Pd "", CodeSize()); | 3426 Comment("PrologueOffset = %" Pd "", CodeSize()); |
| 3414 prologue_offset_ = CodeSize(); | 3427 prologue_offset_ = CodeSize(); |
| 3415 } | 3428 } |
| 3416 movq(Address(RBP, kPcMarkerSlotFromFp * kWordSize), pc_marker_override); | 3429 movq(Address(RBP, kPcMarkerSlotFromFp * kWordSize), pc_marker_override); |
| 3417 movq(PP, new_pp); | 3430 movq(PP, new_pp); |
| 3431 set_constant_pool_allowed(true); |
| 3418 if (extra_size != 0) { | 3432 if (extra_size != 0) { |
| 3419 subq(RSP, Immediate(extra_size)); | 3433 subq(RSP, Immediate(extra_size)); |
| 3420 } | 3434 } |
| 3421 } | 3435 } |
| 3422 | 3436 |
| 3423 | 3437 |
| 3424 void Assembler::EnterStubFrame() { | 3438 void Assembler::EnterStubFrame() { |
| 3439 set_constant_pool_allowed(false); |
| 3425 EnterFrame(0); | 3440 EnterFrame(0); |
| 3426 pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames. | 3441 pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames. |
| 3427 pushq(PP); // Save caller's pool pointer | 3442 pushq(PP); // Save caller's pool pointer |
| 3428 LoadPoolPointer(PP); | 3443 LoadPoolPointer(); |
| 3429 } | 3444 } |
| 3430 | 3445 |
| 3431 | 3446 |
| 3432 void Assembler::LeaveStubFrame() { | 3447 void Assembler::LeaveStubFrame() { |
| 3448 set_constant_pool_allowed(false); |
| 3433 // Restore caller's PP register that was pushed in EnterStubFrame. | 3449 // Restore caller's PP register that was pushed in EnterStubFrame. |
| 3434 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); | 3450 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); |
| 3435 LeaveFrame(); | 3451 LeaveFrame(); |
| 3436 } | 3452 } |
| 3437 | 3453 |
| 3438 | 3454 |
| 3439 void Assembler::MaybeTraceAllocation(intptr_t cid, | 3455 void Assembler::MaybeTraceAllocation(intptr_t cid, |
| 3440 Label* trace, | 3456 Label* trace, |
| 3441 bool near_jump, | 3457 bool near_jump, |
| 3442 bool inline_isolate) { | 3458 bool inline_isolate) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3514 UpdateAllocationStats(cid, space, inline_isolate); | 3530 UpdateAllocationStats(cid, space, inline_isolate); |
| 3515 Register temp_reg = TMP; | 3531 Register temp_reg = TMP; |
| 3516 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew); | 3532 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew); |
| 3517 addq(Address(temp_reg, size_offset), Immediate(size_in_bytes)); | 3533 addq(Address(temp_reg, size_offset), Immediate(size_in_bytes)); |
| 3518 } | 3534 } |
| 3519 | 3535 |
| 3520 | 3536 |
| 3521 void Assembler::TryAllocate(const Class& cls, | 3537 void Assembler::TryAllocate(const Class& cls, |
| 3522 Label* failure, | 3538 Label* failure, |
| 3523 bool near_jump, | 3539 bool near_jump, |
| 3524 Register instance_reg, | 3540 Register instance_reg) { |
| 3525 Register pp) { | |
| 3526 ASSERT(failure != NULL); | 3541 ASSERT(failure != NULL); |
| 3527 if (FLAG_inline_alloc) { | 3542 if (FLAG_inline_alloc) { |
| 3528 // If this allocation is traced, program will jump to failure path | 3543 // If this allocation is traced, program will jump to failure path |
| 3529 // (i.e. the allocation stub) which will allocate the object and trace the | 3544 // (i.e. the allocation stub) which will allocate the object and trace the |
| 3530 // allocation call site. | 3545 // allocation call site. |
| 3531 MaybeTraceAllocation(cls.id(), failure, near_jump); | 3546 MaybeTraceAllocation(cls.id(), failure, near_jump); |
| 3532 Heap* heap = Isolate::Current()->heap(); | 3547 Heap* heap = Isolate::Current()->heap(); |
| 3533 const intptr_t instance_size = cls.instance_size(); | 3548 const intptr_t instance_size = cls.instance_size(); |
| 3534 Heap::Space space = heap->SpaceForAllocation(cls.id()); | 3549 Heap::Space space = heap->SpaceForAllocation(cls.id()); |
| 3535 LoadImmediate(TMP, Immediate(heap->TopAddress(space)), pp); | 3550 LoadImmediate(TMP, Immediate(heap->TopAddress(space))); |
| 3536 movq(instance_reg, Address(TMP, 0)); | 3551 movq(instance_reg, Address(TMP, 0)); |
| 3537 AddImmediate(instance_reg, Immediate(instance_size), pp); | 3552 AddImmediate(instance_reg, Immediate(instance_size)); |
| 3538 // instance_reg: potential next object start. | 3553 // instance_reg: potential next object start. |
| 3539 LoadImmediate(TMP, Immediate(heap->EndAddress(space)), pp); | 3554 LoadImmediate(TMP, Immediate(heap->EndAddress(space))); |
| 3540 cmpq(instance_reg, Address(TMP, 0)); | 3555 cmpq(instance_reg, Address(TMP, 0)); |
| 3541 j(ABOVE_EQUAL, failure, near_jump); | 3556 j(ABOVE_EQUAL, failure, near_jump); |
| 3542 // Successfully allocated the object, now update top to point to | 3557 // Successfully allocated the object, now update top to point to |
| 3543 // next object start and store the class in the class field of object. | 3558 // next object start and store the class in the class field of object. |
| 3544 LoadImmediate(TMP, Immediate(heap->TopAddress(space)), pp); | 3559 LoadImmediate(TMP, Immediate(heap->TopAddress(space))); |
| 3545 movq(Address(TMP, 0), instance_reg); | 3560 movq(Address(TMP, 0), instance_reg); |
| 3546 UpdateAllocationStats(cls.id(), space); | 3561 UpdateAllocationStats(cls.id(), space); |
| 3547 ASSERT(instance_size >= kHeapObjectTag); | 3562 ASSERT(instance_size >= kHeapObjectTag); |
| 3548 AddImmediate(instance_reg, Immediate(kHeapObjectTag - instance_size), pp); | 3563 AddImmediate(instance_reg, Immediate(kHeapObjectTag - instance_size)); |
| 3549 uword tags = 0; | 3564 uword tags = 0; |
| 3550 tags = RawObject::SizeTag::update(instance_size, tags); | 3565 tags = RawObject::SizeTag::update(instance_size, tags); |
| 3551 ASSERT(cls.id() != kIllegalCid); | 3566 ASSERT(cls.id() != kIllegalCid); |
| 3552 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 3567 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 3553 MoveImmediate(FieldAddress(instance_reg, Object::tags_offset()), | 3568 MoveImmediate(FieldAddress(instance_reg, Object::tags_offset()), |
| 3554 Immediate(tags), pp); | 3569 Immediate(tags)); |
| 3555 } else { | 3570 } else { |
| 3556 jmp(failure); | 3571 jmp(failure); |
| 3557 } | 3572 } |
| 3558 } | 3573 } |
| 3559 | 3574 |
| 3560 | 3575 |
| 3561 void Assembler::TryAllocateArray(intptr_t cid, | 3576 void Assembler::TryAllocateArray(intptr_t cid, |
| 3562 intptr_t instance_size, | 3577 intptr_t instance_size, |
| 3563 Label* failure, | 3578 Label* failure, |
| 3564 bool near_jump, | 3579 bool near_jump, |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3744 void Assembler::LoadClassId(Register result, Register object) { | 3759 void Assembler::LoadClassId(Register result, Register object) { |
| 3745 ASSERT(RawObject::kClassIdTagPos == kBitsPerInt32); | 3760 ASSERT(RawObject::kClassIdTagPos == kBitsPerInt32); |
| 3746 ASSERT(RawObject::kClassIdTagSize == kBitsPerInt32); | 3761 ASSERT(RawObject::kClassIdTagSize == kBitsPerInt32); |
| 3747 ASSERT(sizeof(classid_t) == sizeof(uint32_t)); | 3762 ASSERT(sizeof(classid_t) == sizeof(uint32_t)); |
| 3748 const intptr_t class_id_offset = Object::tags_offset() + | 3763 const intptr_t class_id_offset = Object::tags_offset() + |
| 3749 RawObject::kClassIdTagPos / kBitsPerByte; | 3764 RawObject::kClassIdTagPos / kBitsPerByte; |
| 3750 movl(result, FieldAddress(object, class_id_offset)); | 3765 movl(result, FieldAddress(object, class_id_offset)); |
| 3751 } | 3766 } |
| 3752 | 3767 |
| 3753 | 3768 |
| 3754 void Assembler::LoadClassById(Register result, Register class_id, Register pp) { | 3769 void Assembler::LoadClassById(Register result, Register class_id) { |
| 3755 ASSERT(result != class_id); | 3770 ASSERT(result != class_id); |
| 3756 LoadIsolate(result); | 3771 LoadIsolate(result); |
| 3757 const intptr_t offset = | 3772 const intptr_t offset = |
| 3758 Isolate::class_table_offset() + ClassTable::table_offset(); | 3773 Isolate::class_table_offset() + ClassTable::table_offset(); |
| 3759 movq(result, Address(result, offset)); | 3774 movq(result, Address(result, offset)); |
| 3760 movq(result, Address(result, class_id, TIMES_8, 0)); | 3775 movq(result, Address(result, class_id, TIMES_8, 0)); |
| 3761 } | 3776 } |
| 3762 | 3777 |
| 3763 | 3778 |
| 3764 void Assembler::LoadClass(Register result, Register object, Register pp) { | 3779 void Assembler::LoadClass(Register result, Register object) { |
| 3765 LoadClassId(TMP, object); | 3780 LoadClassId(TMP, object); |
| 3766 LoadClassById(result, TMP, pp); | 3781 LoadClassById(result, TMP); |
| 3767 } | 3782 } |
| 3768 | 3783 |
| 3769 | 3784 |
| 3770 void Assembler::CompareClassId(Register object, intptr_t class_id) { | 3785 void Assembler::CompareClassId(Register object, intptr_t class_id) { |
| 3771 LoadClassId(TMP, object); | 3786 LoadClassId(TMP, object); |
| 3772 cmpl(TMP, Immediate(class_id)); | 3787 cmpl(TMP, Immediate(class_id)); |
| 3773 } | 3788 } |
| 3774 | 3789 |
| 3775 | 3790 |
| 3776 void Assembler::SmiUntagOrCheckClass(Register object, | 3791 void Assembler::SmiUntagOrCheckClass(Register object, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3791 movl(TMP, Address(object, TIMES_2, class_id_offset)); | 3806 movl(TMP, Address(object, TIMES_2, class_id_offset)); |
| 3792 cmpl(TMP, Immediate(class_id)); | 3807 cmpl(TMP, Immediate(class_id)); |
| 3793 } | 3808 } |
| 3794 | 3809 |
| 3795 | 3810 |
| 3796 void Assembler::LoadClassIdMayBeSmi(Register result, Register object) { | 3811 void Assembler::LoadClassIdMayBeSmi(Register result, Register object) { |
| 3797 ASSERT(result != object); | 3812 ASSERT(result != object); |
| 3798 | 3813 |
| 3799 // Load up a null object. We only need it so we can use LoadClassId on it in | 3814 // Load up a null object. We only need it so we can use LoadClassId on it in |
| 3800 // the case that object is a Smi. | 3815 // the case that object is a Smi. |
| 3801 LoadObject(result, Object::null_object(), PP); | 3816 LoadObject(result, Object::null_object()); |
| 3802 // Check if the object is a Smi. | 3817 // Check if the object is a Smi. |
| 3803 testq(object, Immediate(kSmiTagMask)); | 3818 testq(object, Immediate(kSmiTagMask)); |
| 3804 // If the object *is* a Smi, use the null object instead. | 3819 // If the object *is* a Smi, use the null object instead. |
| 3805 cmoveq(object, result); | 3820 cmoveq(object, result); |
| 3806 // Loads either the cid of the object if it isn't a Smi, or the cid of null | 3821 // Loads either the cid of the object if it isn't a Smi, or the cid of null |
| 3807 // if it is a Smi, which will be ignored. | 3822 // if it is a Smi, which will be ignored. |
| 3808 LoadClassId(result, object); | 3823 LoadClassId(result, object); |
| 3809 | 3824 |
| 3810 movq(object, Immediate(kSmiCid)); | 3825 movq(object, Immediate(kSmiCid)); |
| 3811 // If object is a Smi, move the Smi cid into result. o/w leave alone. | 3826 // If object is a Smi, move the Smi cid into result. o/w leave alone. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3931 | 3946 |
| 3932 | 3947 |
| 3933 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3948 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3934 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3949 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 3935 return xmm_reg_names[reg]; | 3950 return xmm_reg_names[reg]; |
| 3936 } | 3951 } |
| 3937 | 3952 |
| 3938 } // namespace dart | 3953 } // namespace dart |
| 3939 | 3954 |
| 3940 #endif // defined TARGET_ARCH_X64 | 3955 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |