Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2096)

Side by Side Diff: runtime/vm/assembler_x64.cc

Issue 1268783003: Simplify constant pool usage in x64 code generator (by removing extra argument (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 1489
1490 1490
1491 void Assembler::cmpq(Register reg, const Address& address) { 1491 void Assembler::cmpq(Register reg, const Address& address) {
1492 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1492 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1493 EmitOperandREX(reg, address, REX_W); 1493 EmitOperandREX(reg, address, REX_W);
1494 EmitUint8(0x3B); 1494 EmitUint8(0x3B);
1495 EmitOperand(reg & 7, address); 1495 EmitOperand(reg & 7, address);
1496 } 1496 }
1497 1497
1498 1498
1499 void Assembler::CompareImmediate(Register reg, const Immediate& imm, 1499 void Assembler::CompareImmediate(Register reg, const Immediate& imm) {
1500 Register pp) { 1500 if (imm.is_int32()) {
1501 if (CanLoadImmediateFromPool(imm, pp)) { 1501 cmpq(reg, imm);
1502 LoadImmediate(TMP, imm, pp); 1502 } else {
1503 LoadImmediate(TMP, imm);
zra 2015/07/31 17:37:28 assert reg != TMP
regis 2015/07/31 19:33:59 Done here and at a bunch of other places.
1503 cmpq(reg, TMP); 1504 cmpq(reg, TMP);
1504 } else {
1505 cmpq(reg, imm);
1506 } 1505 }
1507 } 1506 }
1508 1507
1509 1508
1510 void Assembler::CompareImmediate(const Address& address, const Immediate& imm, 1509 void Assembler::CompareImmediate(const Address& address, const Immediate& imm) {
1511 Register pp) { 1510 if (imm.is_int32()) {
1512 if (CanLoadImmediateFromPool(imm, pp)) { 1511 cmpq(address, imm);
1513 LoadImmediate(TMP, imm, pp); 1512 } else {
1513 LoadImmediate(TMP, imm);
zra 2015/07/31 17:37:28 Could address refer to TMP?
regis 2015/07/31 19:33:59 Since I did not change this, we would know by now
1514 cmpq(address, TMP); 1514 cmpq(address, TMP);
1515 } else {
1516 cmpq(address, imm);
1517 } 1515 }
1518 } 1516 }
1519 1517
1520 1518
1521 void Assembler::testl(Register reg1, Register reg2) { 1519 void Assembler::testl(Register reg1, Register reg2) {
1522 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1520 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1523 Operand operand(reg2); 1521 Operand operand(reg2);
1524 EmitOperandREX(reg1, operand, REX_NONE); 1522 EmitOperandREX(reg1, operand, REX_NONE);
1525 EmitUint8(0x85); 1523 EmitUint8(0x85);
1526 EmitOperand(reg1 & 7, operand); 1524 EmitOperand(reg1 & 7, operand);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 } else { 1599 } else {
1602 EmitRegisterREX(reg, REX_W); 1600 EmitRegisterREX(reg, REX_W);
1603 EmitUint8(0xF7); 1601 EmitUint8(0xF7);
1604 EmitUint8(0xC0 | (reg & 7)); 1602 EmitUint8(0xC0 | (reg & 7));
1605 } 1603 }
1606 EmitImmediate(imm); 1604 EmitImmediate(imm);
1607 } 1605 }
1608 } 1606 }
1609 1607
1610 1608
1611 void Assembler::TestImmediate(Register dst, const Immediate& imm, Register pp) { 1609 void Assembler::TestImmediate(Register dst, const Immediate& imm) {
1612 if (CanLoadImmediateFromPool(imm, pp)) { 1610 if (imm.is_int32()) {
1611 testq(dst, imm);
1612 } else {
1613 ASSERT(dst != TMP); 1613 ASSERT(dst != TMP);
1614 LoadImmediate(TMP, imm, pp); 1614 LoadImmediate(TMP, imm);
1615 testq(dst, TMP); 1615 testq(dst, TMP);
1616 } else {
1617 testq(dst, imm);
1618 } 1616 }
1619 } 1617 }
1620 1618
1621 1619
1622 void Assembler::andl(Register dst, Register src) { 1620 void Assembler::andl(Register dst, Register src) {
1623 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1621 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1624 Operand operand(src); 1622 Operand operand(src);
1625 EmitOperandREX(dst, operand, REX_NONE); 1623 EmitOperandREX(dst, operand, REX_NONE);
1626 EmitUint8(0x23); 1624 EmitUint8(0x23);
1627 EmitOperand(dst & 7, operand); 1625 EmitOperand(dst & 7, operand);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1688 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1691 EmitRegisterREX(dst, REX_W); 1689 EmitRegisterREX(dst, REX_W);
1692 EmitComplex(4, Operand(dst), imm); 1690 EmitComplex(4, Operand(dst), imm);
1693 } else { 1691 } else {
1694 movq(TMP, imm); 1692 movq(TMP, imm);
1695 andq(dst, TMP); 1693 andq(dst, TMP);
1696 } 1694 }
1697 } 1695 }
1698 1696
1699 1697
1700 void Assembler::AndImmediate(Register dst, const Immediate& imm, Register pp) { 1698 void Assembler::AndImmediate(Register dst, const Immediate& imm) {
1701 if (CanLoadImmediateFromPool(imm, pp)) { 1699 if (imm.is_int32()) {
1700 andq(dst, imm);
1701 } else {
1702 ASSERT(dst != TMP); 1702 ASSERT(dst != TMP);
1703 LoadImmediate(TMP, imm, pp); 1703 LoadImmediate(TMP, imm);
1704 andq(dst, TMP); 1704 andq(dst, TMP);
1705 } else {
1706 andq(dst, imm);
1707 } 1705 }
1708 } 1706 }
1709 1707
1710 1708
1711 void Assembler::orq(Register dst, Register src) { 1709 void Assembler::orq(Register dst, Register src) {
1712 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1710 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1713 Operand operand(src); 1711 Operand operand(src);
1714 EmitOperandREX(dst, operand, REX_W); 1712 EmitOperandREX(dst, operand, REX_W);
1715 EmitUint8(0x0B); 1713 EmitUint8(0x0B);
1716 EmitOperand(dst & 7, operand); 1714 EmitOperand(dst & 7, operand);
(...skipping 13 matching lines...) Expand all
1730 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1728 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1731 EmitRegisterREX(dst, REX_W); 1729 EmitRegisterREX(dst, REX_W);
1732 EmitComplex(1, Operand(dst), imm); 1730 EmitComplex(1, Operand(dst), imm);
1733 } else { 1731 } else {
1734 movq(TMP, imm); 1732 movq(TMP, imm);
1735 orq(dst, TMP); 1733 orq(dst, TMP);
1736 } 1734 }
1737 } 1735 }
1738 1736
1739 1737
1740 void Assembler::OrImmediate(Register dst, const Immediate& imm, Register pp) { 1738 void Assembler::OrImmediate(Register dst, const Immediate& imm) {
1741 if (CanLoadImmediateFromPool(imm, pp)) { 1739 if (imm.is_int32()) {
1740 orq(dst, imm);
1741 } else {
1742 ASSERT(dst != TMP); 1742 ASSERT(dst != TMP);
1743 LoadImmediate(TMP, imm, pp); 1743 LoadImmediate(TMP, imm);
1744 orq(dst, TMP); 1744 orq(dst, TMP);
1745 } else {
1746 orq(dst, imm);
1747 } 1745 }
1748 } 1746 }
1749 1747
1750 1748
1751 void Assembler::xorq(Register dst, Register src) { 1749 void Assembler::xorq(Register dst, Register src) {
1752 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1750 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1753 Operand operand(src); 1751 Operand operand(src);
1754 EmitOperandREX(dst, operand, REX_W); 1752 EmitOperandREX(dst, operand, REX_W);
1755 EmitUint8(0x33); 1753 EmitUint8(0x33);
1756 EmitOperand(dst & 7, operand); 1754 EmitOperand(dst & 7, operand);
(...skipping 21 matching lines...) Expand all
1778 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1776 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1779 EmitRegisterREX(dst, REX_W); 1777 EmitRegisterREX(dst, REX_W);
1780 EmitComplex(6, Operand(dst), imm); 1778 EmitComplex(6, Operand(dst), imm);
1781 } else { 1779 } else {
1782 movq(TMP, imm); 1780 movq(TMP, imm);
1783 xorq(dst, TMP); 1781 xorq(dst, TMP);
1784 } 1782 }
1785 } 1783 }
1786 1784
1787 1785
1788 void Assembler::XorImmediate(Register dst, const Immediate& imm, Register pp) { 1786 void Assembler::XorImmediate(Register dst, const Immediate& imm) {
1789 if (CanLoadImmediateFromPool(imm, pp)) { 1787 if (imm.is_int32()) {
1788 xorq(dst, imm);
1789 } else {
1790 ASSERT(dst != TMP); 1790 ASSERT(dst != TMP);
1791 LoadImmediate(TMP, imm, pp); 1791 LoadImmediate(TMP, imm);
1792 xorq(dst, TMP); 1792 xorq(dst, TMP);
1793 } else {
1794 xorq(dst, imm);
1795 } 1793 }
1796 } 1794 }
1797 1795
1798 1796
1799 void Assembler::addl(Register dst, Register src) { 1797 void Assembler::addl(Register dst, Register src) {
1800 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1798 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1801 Operand operand(src); 1799 Operand operand(src);
1802 EmitOperandREX(dst, operand, REX_NONE); 1800 EmitOperandREX(dst, operand, REX_NONE);
1803 EmitUint8(0x03); 1801 EmitUint8(0x03);
1804 EmitOperand(dst & 7, operand); 1802 EmitOperand(dst & 7, operand);
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
2073 EmitUint8(0x69); 2071 EmitUint8(0x69);
2074 EmitOperand(reg & 7, Operand(reg)); 2072 EmitOperand(reg & 7, Operand(reg));
2075 EmitImmediate(imm); 2073 EmitImmediate(imm);
2076 } else { 2074 } else {
2077 movq(TMP, imm); 2075 movq(TMP, imm);
2078 imulq(reg, TMP); 2076 imulq(reg, TMP);
2079 } 2077 }
2080 } 2078 }
2081 2079
2082 2080
2083 void Assembler::MulImmediate(Register reg, const Immediate& imm, Register pp) { 2081 void Assembler::MulImmediate(Register reg, const Immediate& imm) {
2084 if (CanLoadImmediateFromPool(imm, pp)) { 2082 if (imm.is_int32()) {
2083 imulq(reg, imm);
2084 } else {
2085 ASSERT(reg != TMP); 2085 ASSERT(reg != TMP);
2086 LoadImmediate(TMP, imm, pp); 2086 LoadImmediate(TMP, imm);
2087 imulq(reg, TMP); 2087 imulq(reg, TMP);
2088 } else {
2089 imulq(reg, imm);
2090 } 2088 }
2091 } 2089 }
2092 2090
2093 2091
2094 void Assembler::imulq(Register dst, const Address& address) { 2092 void Assembler::imulq(Register dst, const Address& address) {
2095 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2093 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2096 EmitOperandREX(dst, address, REX_W); 2094 EmitOperandREX(dst, address, REX_W);
2097 EmitUint8(0x0F); 2095 EmitUint8(0x0F);
2098 EmitUint8(0xAF); 2096 EmitUint8(0xAF);
2099 EmitOperand(dst & 7, address); 2097 EmitOperand(dst & 7, address);
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
2592 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2590 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2593 EmitRegisterREX(TMP, REX_W); 2591 EmitRegisterREX(TMP, REX_W);
2594 EmitUint8(0xB8 | (TMP & 7)); 2592 EmitUint8(0xB8 | (TMP & 7));
2595 EmitInt64(label->address()); 2593 EmitInt64(label->address());
2596 } 2594 }
2597 jmp(TMP); 2595 jmp(TMP);
2598 } 2596 }
2599 2597
2600 2598
2601 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { 2599 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) {
2602 ASSERT(constant_pool_allowed()); 2600 ASSERT((pp != PP) || constant_pool_allowed());
2603 intptr_t call_start = buffer_.GetPosition(); 2601 intptr_t call_start = buffer_.GetPosition();
2604 const int32_t offset = ObjectPool::element_offset( 2602 const int32_t offset = ObjectPool::element_offset(
2605 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); 2603 object_pool_wrapper_.FindExternalLabel(label, kPatchable));
2606 // Patchable jumps always use a 32-bit immediate encoding. 2604 // Patchable jumps always use a 32-bit immediate encoding.
2607 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); 2605 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag));
2608 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); 2606 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes);
2609 } 2607 }
2610 2608
2611 2609
2612 void Assembler::Jmp(const ExternalLabel* label, Register pp) { 2610 void Assembler::Jmp(const ExternalLabel* label, Register pp) {
2611 ASSERT((pp != PP) || constant_pool_allowed());
2613 const int32_t offset = ObjectPool::element_offset( 2612 const int32_t offset = ObjectPool::element_offset(
2614 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable)); 2613 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable));
2615 jmp(Address(pp, offset - kHeapObjectTag)); 2614 jmp(Address(pp, offset - kHeapObjectTag));
2616 } 2615 }
2617 2616
2618 2617
2619 void Assembler::lock() { 2618 void Assembler::lock() {
2620 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2619 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2621 EmitUint8(0xF0); 2620 EmitUint8(0xF0);
2622 } 2621 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2657 movq(to, from); 2656 movq(to, from);
2658 } 2657 }
2659 } 2658 }
2660 2659
2661 2660
2662 void Assembler::PopRegister(Register r) { 2661 void Assembler::PopRegister(Register r) {
2663 popq(r); 2662 popq(r);
2664 } 2663 }
2665 2664
2666 2665
2667 void Assembler::AddImmediate(Register reg, const Immediate& imm, Register pp) { 2666 void Assembler::AddImmediate(Register reg, const Immediate& imm) {
2668 const int64_t value = imm.value(); 2667 const int64_t value = imm.value();
2669 if (value == 0) { 2668 if (value == 0) {
2670 return; 2669 return;
2671 } 2670 }
2672 if ((value > 0) || (value == kMinInt64)) { 2671 if ((value > 0) || (value == kMinInt64)) {
2673 if (value == 1) { 2672 if (value == 1) {
2674 incq(reg); 2673 incq(reg);
2675 } else { 2674 } else {
2676 if (CanLoadImmediateFromPool(imm, pp)) { 2675 if (imm.is_int32()) {
2676 addq(reg, imm);
2677 } else {
2677 ASSERT(reg != TMP); 2678 ASSERT(reg != TMP);
2678 LoadImmediate(TMP, imm, pp); 2679 LoadImmediate(TMP, imm);
2679 addq(reg, TMP); 2680 addq(reg, TMP);
2680 } else {
2681 addq(reg, imm);
2682 } 2681 }
2683 } 2682 }
2684 } else { 2683 } else {
2685 SubImmediate(reg, Immediate(-value), pp); 2684 SubImmediate(reg, Immediate(-value));
2686 } 2685 }
2687 } 2686 }
2688 2687
2689 2688
2690 void Assembler::AddImmediate(const Address& address, const Immediate& imm, 2689 void Assembler::AddImmediate(const Address& address, const Immediate& imm) {
2691 Register pp) {
2692 const int64_t value = imm.value(); 2690 const int64_t value = imm.value();
2693 if (value == 0) { 2691 if (value == 0) {
2694 return; 2692 return;
2695 } 2693 }
2696 if ((value > 0) || (value == kMinInt64)) { 2694 if ((value > 0) || (value == kMinInt64)) {
2697 if (value == 1) { 2695 if (value == 1) {
2698 incq(address); 2696 incq(address);
2699 } else { 2697 } else {
2700 if (CanLoadImmediateFromPool(imm, pp)) { 2698 if (imm.is_int32()) {
2701 LoadImmediate(TMP, imm, pp); 2699 addq(address, imm);
2700 } else {
2701 LoadImmediate(TMP, imm);
2702 addq(address, TMP); 2702 addq(address, TMP);
2703 } else {
2704 addq(address, imm);
2705 } 2703 }
2706 } 2704 }
2707 } else { 2705 } else {
2708 SubImmediate(address, Immediate(-value), pp); 2706 SubImmediate(address, Immediate(-value));
2709 } 2707 }
2710 } 2708 }
2711 2709
2712 2710
2713 void Assembler::SubImmediate(Register reg, const Immediate& imm, Register pp) { 2711 void Assembler::SubImmediate(Register reg, const Immediate& imm) {
2714 const int64_t value = imm.value(); 2712 const int64_t value = imm.value();
2715 if (value == 0) { 2713 if (value == 0) {
2716 return; 2714 return;
2717 } 2715 }
2718 if ((value > 0) || (value == kMinInt64)) { 2716 if ((value > 0) || (value == kMinInt64)) {
2719 if (value == 1) { 2717 if (value == 1) {
2720 decq(reg); 2718 decq(reg);
2721 } else { 2719 } else {
2722 if (CanLoadImmediateFromPool(imm, pp)) { 2720 if (imm.is_int32()) {
2721 subq(reg, imm);
2722 } else {
2723 ASSERT(reg != TMP); 2723 ASSERT(reg != TMP);
2724 LoadImmediate(TMP, imm, pp); 2724 LoadImmediate(TMP, imm);
2725 subq(reg, TMP); 2725 subq(reg, TMP);
2726 } else {
2727 subq(reg, imm);
2728 } 2726 }
2729 } 2727 }
2730 } else { 2728 } else {
2731 AddImmediate(reg, Immediate(-value), pp); 2729 AddImmediate(reg, Immediate(-value));
2732 } 2730 }
2733 } 2731 }
2734 2732
2735 2733
2736 void Assembler::SubImmediate(const Address& address, const Immediate& imm, 2734 void Assembler::SubImmediate(const Address& address, const Immediate& imm) {
2737 Register pp) {
2738 const int64_t value = imm.value(); 2735 const int64_t value = imm.value();
2739 if (value == 0) { 2736 if (value == 0) {
2740 return; 2737 return;
2741 } 2738 }
2742 if ((value > 0) || (value == kMinInt64)) { 2739 if ((value > 0) || (value == kMinInt64)) {
2743 if (value == 1) { 2740 if (value == 1) {
2744 decq(address); 2741 decq(address);
2745 } else { 2742 } else {
2746 if (CanLoadImmediateFromPool(imm, pp)) { 2743 if (imm.is_int32()) {
2747 LoadImmediate(TMP, imm, pp); 2744 subq(address, imm);
2745 } else {
2746 LoadImmediate(TMP, imm);
2748 subq(address, TMP); 2747 subq(address, TMP);
2749 } else {
2750 subq(address, imm);
2751 } 2748 }
2752 } 2749 }
2753 } else { 2750 } else {
2754 AddImmediate(address, Immediate(-value), pp); 2751 AddImmediate(address, Immediate(-value));
2755 } 2752 }
2756 } 2753 }
2757 2754
2758 2755
2759 void Assembler::Drop(intptr_t stack_elements, Register tmp) { 2756 void Assembler::Drop(intptr_t stack_elements, Register tmp) {
2760 ASSERT(stack_elements >= 0); 2757 ASSERT(stack_elements >= 0);
2761 if (stack_elements <= 4) { 2758 if (stack_elements <= 4) {
2762 for (intptr_t i = 0; i < stack_elements; i++) { 2759 for (intptr_t i = 0; i < stack_elements; i++) {
2763 popq(tmp); 2760 popq(tmp);
2764 } 2761 }
(...skipping 15 matching lines...) Expand all
2780 // If the raw smi does not fit into a 32-bit signed int, then we'll keep 2777 // 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. 2778 // the raw value in the object pool.
2782 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); 2779 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw()));
2783 } 2780 }
2784 ASSERT(object.IsNotTemporaryScopedHandle()); 2781 ASSERT(object.IsNotTemporaryScopedHandle());
2785 ASSERT(object.IsOld()); 2782 ASSERT(object.IsOld());
2786 return true; 2783 return true;
2787 } 2784 }
2788 2785
2789 2786
2790 void Assembler::LoadWordFromPoolOffset(Register dst, Register pp, 2787 void Assembler::LoadWordFromPoolOffset(Register dst, int32_t offset) {
2791 int32_t offset) { 2788 ASSERT(constant_pool_allowed());
2789 ASSERT(dst != PP);
2792 // This sequence must be of fixed size. AddressBaseImm32 2790 // This sequence must be of fixed size. AddressBaseImm32
2793 // forces the address operand to use a fixed-size imm32 encoding. 2791 // forces the address operand to use a fixed-size imm32 encoding.
2794 movq(dst, Address::AddressBaseImm32(pp, offset)); 2792 movq(dst, Address::AddressBaseImm32(PP, offset));
2795 } 2793 }
2796 2794
2797 2795
2798 void Assembler::LoadIsolate(Register dst) { 2796 void Assembler::LoadIsolate(Register dst) {
2799 movq(dst, Address(THR, Thread::isolate_offset())); 2797 movq(dst, Address(THR, Thread::isolate_offset()));
2800 } 2798 }
2801 2799
2802 2800
2803 void Assembler::LoadObjectHelper(Register dst, 2801 void Assembler::LoadObjectHelper(Register dst,
2804 const Object& object, 2802 const Object& object,
2805 Register pp,
2806 bool is_unique) { 2803 bool is_unique) {
2807 if (Thread::CanLoadFromThread(object)) { 2804 if (Thread::CanLoadFromThread(object)) {
2808 movq(dst, Address(THR, Thread::OffsetFromThread(object))); 2805 movq(dst, Address(THR, Thread::OffsetFromThread(object)));
2809 } else if (CanLoadFromObjectPool(object)) { 2806 } else if (CanLoadFromObjectPool(object)) {
2810 const int32_t offset = ObjectPool::element_offset( 2807 const int32_t offset = ObjectPool::element_offset(
2811 is_unique ? object_pool_wrapper_.AddObject(object) 2808 is_unique ? object_pool_wrapper_.AddObject(object)
2812 : object_pool_wrapper_.FindObject(object)); 2809 : object_pool_wrapper_.FindObject(object));
2813 LoadWordFromPoolOffset(dst, pp, offset - kHeapObjectTag); 2810 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag);
2814 } else { 2811 } else {
2815 ASSERT(object.IsSmi() || object.InVMHeap()); 2812 ASSERT(object.IsSmi() || object.InVMHeap());
2816 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); 2813 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
2817 } 2814 }
2818 } 2815 }
2819 2816
2820 2817
2821 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { 2818 void Assembler::LoadFunctionFromNewPool(Register dst,
zra 2015/07/31 17:37:28 Maybe FromCalleePool instead of FromNewPool.
regis 2015/07/31 19:33:59 Done.
2822 LoadObjectHelper(dst, object, pp, false); 2819 const Function& function,
2820 Register new_pp) {
2821 ASSERT(!constant_pool_allowed());
2822 ASSERT(new_pp != PP);
2823 const int32_t offset =
2824 ObjectPool::element_offset(object_pool_wrapper_.FindObject(function));
2825 movq(dst, Address::AddressBaseImm32(new_pp, offset - kHeapObjectTag));
2823 } 2826 }
2824 2827
2825 2828
2826 void Assembler::LoadUniqueObject(Register dst, 2829 void Assembler::LoadObject(Register dst, const Object& object) {
2827 const Object& object, 2830 LoadObjectHelper(dst, object, false);
2828 Register pp) {
2829 LoadObjectHelper(dst, object, pp, true);
2830 } 2831 }
2831 2832
2832 2833
2833 void Assembler::StoreObject(const Address& dst, const Object& object, 2834 void Assembler::LoadUniqueObject(Register dst, const Object& object) {
2834 Register pp) { 2835 LoadObjectHelper(dst, object, true);
2836 }
2837
2838
2839 void Assembler::StoreObject(const Address& dst, const Object& object) {
2835 if (Thread::CanLoadFromThread(object)) { 2840 if (Thread::CanLoadFromThread(object)) {
2836 movq(TMP, Address(THR, Thread::OffsetFromThread(object))); 2841 movq(TMP, Address(THR, Thread::OffsetFromThread(object)));
2837 movq(dst, TMP); 2842 movq(dst, TMP);
2838 } else if (CanLoadFromObjectPool(object)) { 2843 } else if (CanLoadFromObjectPool(object)) {
2839 LoadObject(TMP, object, pp); 2844 LoadObject(TMP, object);
2840 movq(dst, TMP); 2845 movq(dst, TMP);
2841 } else { 2846 } else {
2842 MoveImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); 2847 MoveImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
2843 } 2848 }
2844 } 2849 }
2845 2850
2846 2851
2847 void Assembler::PushObject(const Object& object, Register pp) { 2852 void Assembler::PushObject(const Object& object) {
2848 if (Thread::CanLoadFromThread(object)) { 2853 if (Thread::CanLoadFromThread(object)) {
2849 pushq(Address(THR, Thread::OffsetFromThread(object))); 2854 pushq(Address(THR, Thread::OffsetFromThread(object)));
2850 } else if (CanLoadFromObjectPool(object)) { 2855 } else if (CanLoadFromObjectPool(object)) {
2851 LoadObject(TMP, object, pp); 2856 LoadObject(TMP, object);
2852 pushq(TMP); 2857 pushq(TMP);
2853 } else { 2858 } else {
2854 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())), pp); 2859 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())));
2855 } 2860 }
2856 } 2861 }
2857 2862
2858 2863
2859 void Assembler::CompareObject(Register reg, const Object& object, Register pp) { 2864 void Assembler::CompareObject(Register reg, const Object& object) {
2860 if (Thread::CanLoadFromThread(object)) { 2865 if (Thread::CanLoadFromThread(object)) {
2861 cmpq(reg, Address(THR, Thread::OffsetFromThread(object))); 2866 cmpq(reg, Address(THR, Thread::OffsetFromThread(object)));
2862 } else if (CanLoadFromObjectPool(object)) { 2867 } else if (CanLoadFromObjectPool(object)) {
2863 const int32_t offset = 2868 const int32_t offset =
2864 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); 2869 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object));
2865 cmpq(reg, Address(pp, offset-kHeapObjectTag)); 2870 cmpq(reg, Address(PP, offset-kHeapObjectTag));
2866 } else { 2871 } else {
2867 CompareImmediate( 2872 CompareImmediate(
2868 reg, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); 2873 reg, Immediate(reinterpret_cast<int64_t>(object.raw())));
2869 } 2874 }
2870 } 2875 }
2871 2876
2872 2877
2873 intptr_t Assembler::FindImmediate(int64_t imm) { 2878 intptr_t Assembler::FindImmediate(int64_t imm) {
2874 return object_pool_wrapper_.FindImmediate(imm); 2879 return object_pool_wrapper_.FindImmediate(imm);
2875 } 2880 }
2876 2881
2877 2882
2878 bool Assembler::CanLoadImmediateFromPool(const Immediate& imm, Register pp) { 2883 void Assembler::LoadImmediate(Register reg, const Immediate& imm) {
2879 if (!constant_pool_allowed()) { 2884 if (imm.is_int32() || !constant_pool_allowed()) {
2880 return false; 2885 movq(reg, imm);
2881 } 2886 } 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())); 2887 int32_t offset = ObjectPool::element_offset(FindImmediate(imm.value()));
2889 LoadWordFromPoolOffset(reg, pp, offset - kHeapObjectTag); 2888 LoadWordFromPoolOffset(reg, offset - kHeapObjectTag);
2890 } else {
2891 movq(reg, imm);
2892 } 2889 }
2893 } 2890 }
2894 2891
2895 2892
2896 void Assembler::MoveImmediate(const Address& dst, const Immediate& imm, 2893 void Assembler::MoveImmediate(const Address& dst, const Immediate& imm) {
2897 Register pp) { 2894 if (imm.is_int32()) {
2898 if (CanLoadImmediateFromPool(imm, pp)) { 2895 movq(dst, imm);
2899 LoadImmediate(TMP, imm, pp); 2896 } else {
2897 LoadImmediate(TMP, imm);
2900 movq(dst, TMP); 2898 movq(dst, TMP);
2901 } else {
2902 movq(dst, imm);
2903 } 2899 }
2904 } 2900 }
2905 2901
2906 2902
2907 // Destroys the value register. 2903 // Destroys the value register.
2908 void Assembler::StoreIntoObjectFilterNoSmi(Register object, 2904 void Assembler::StoreIntoObjectFilterNoSmi(Register object,
2909 Register value, 2905 Register value,
2910 Label* no_update) { 2906 Label* no_update) {
2911 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && 2907 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
2912 (kOldObjectAlignmentOffset == 0)); 2908 (kOldObjectAlignmentOffset == 0));
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
3078 Bind(&done); 3074 Bind(&done);
3079 popq(value); 3075 popq(value);
3080 #endif // defined(DEBUG) 3076 #endif // defined(DEBUG)
3081 // No store buffer update. 3077 // No store buffer update.
3082 } 3078 }
3083 3079
3084 3080
3085 void Assembler::StoreIntoObjectNoBarrier(Register object, 3081 void Assembler::StoreIntoObjectNoBarrier(Register object,
3086 const Address& dest, 3082 const Address& dest,
3087 const Object& value, 3083 const Object& value,
3088 Register pp,
3089 FieldContent old_content) { 3084 FieldContent old_content) {
3090 VerifyHeapWord(dest, old_content); 3085 VerifyHeapWord(dest, old_content);
3091 if (VerifiedMemory::enabled()) { 3086 if (VerifiedMemory::enabled()) {
3092 Register temp = (pp == RCX) ? RDX : RCX; 3087 const Register temp = RCX;
3093 pushq(temp); 3088 pushq(temp);
3094 leaq(temp, dest); 3089 leaq(temp, dest);
3095 StoreObject(Address(temp, 0), value, pp); 3090 StoreObject(Address(temp, 0), value);
3096 StoreObject(Address(temp, VerifiedMemory::offset()), value, pp); 3091 StoreObject(Address(temp, VerifiedMemory::offset()), value);
3097 popq(temp); 3092 popq(temp);
3098 } else { 3093 } else {
3099 StoreObject(dest, value, pp); 3094 StoreObject(dest, value);
3100 } 3095 }
3101 // TODO(koda): Use 'object', verify that generational barrier's not needed. 3096 // TODO(koda): Use 'object', verify that generational barrier's not needed.
3102 } 3097 }
3103 3098
3104 3099
3105 void Assembler::StoreIntoSmiField(const Address& dest, Register value) { 3100 void Assembler::StoreIntoSmiField(const Address& dest, Register value) {
3106 #if defined(DEBUG) 3101 #if defined(DEBUG)
3107 Label done; 3102 Label done;
3108 testq(value, Immediate(kHeapObjectTag)); 3103 testq(value, Immediate(kHeapObjectTag));
3109 j(ZERO, &done); 3104 j(ZERO, &done);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3146 } 3141 }
3147 3142
3148 3143
3149 void Assembler::DoubleNegate(XmmRegister d) { 3144 void Assembler::DoubleNegate(XmmRegister d) {
3150 static const struct ALIGN16 { 3145 static const struct ALIGN16 {
3151 uint64_t a; 3146 uint64_t a;
3152 uint64_t b; 3147 uint64_t b;
3153 } double_negate_constant = 3148 } double_negate_constant =
3154 {0x8000000000000000LL, 0x8000000000000000LL}; 3149 {0x8000000000000000LL, 0x8000000000000000LL};
3155 LoadImmediate( 3150 LoadImmediate(
3156 TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)), PP); 3151 TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)));
3157 xorpd(d, Address(TMP, 0)); 3152 xorpd(d, Address(TMP, 0));
3158 } 3153 }
3159 3154
3160 3155
3161 void Assembler::DoubleAbs(XmmRegister reg) { 3156 void Assembler::DoubleAbs(XmmRegister reg) {
3162 static const struct ALIGN16 { 3157 static const struct ALIGN16 {
3163 uint64_t a; 3158 uint64_t a;
3164 uint64_t b; 3159 uint64_t b;
3165 } double_abs_constant = 3160 } double_abs_constant =
3166 {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}; 3161 {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
3167 LoadImmediate(TMP, 3162 LoadImmediate(TMP,
3168 Immediate(reinterpret_cast<intptr_t>(&double_abs_constant)), PP); 3163 Immediate(reinterpret_cast<intptr_t>(&double_abs_constant)));
3169 andpd(reg, Address(TMP, 0)); 3164 andpd(reg, Address(TMP, 0));
3170 } 3165 }
3171 3166
3172 3167
3173 void Assembler::Stop(const char* message, bool fixed_length_encoding) { 3168 void Assembler::Stop(const char* message, bool fixed_length_encoding) {
3174 int64_t message_address = reinterpret_cast<int64_t>(message); 3169 int64_t message_address = reinterpret_cast<int64_t>(message);
3175 if (FLAG_print_stop_message) { 3170 if (FLAG_print_stop_message) {
3176 pushq(TMP); // Preserve TMP register. 3171 pushq(TMP); // Preserve TMP register.
3177 pushq(RDI); // Preserve RDI register. 3172 pushq(RDI); // Preserve RDI register.
3178 if (fixed_length_encoding) { 3173 if (fixed_length_encoding) {
3179 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 3174 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
3180 EmitRegisterREX(RDI, REX_W); 3175 EmitRegisterREX(RDI, REX_W);
3181 EmitUint8(0xB8 | (RDI & 7)); 3176 EmitUint8(0xB8 | (RDI & 7));
3182 EmitInt64(message_address); 3177 EmitInt64(message_address);
3183 } else { 3178 } else {
3184 LoadImmediate(RDI, Immediate(message_address), PP); 3179 LoadImmediate(RDI, Immediate(message_address));
3185 } 3180 }
3186 call(&StubCode::PrintStopMessageLabel()); 3181 call(&StubCode::PrintStopMessageLabel());
3187 popq(RDI); // Restore RDI register. 3182 popq(RDI); // Restore RDI register.
3188 popq(TMP); // Restore TMP register. 3183 popq(TMP); // Restore TMP register.
3189 } else { 3184 } else {
3190 // Emit the lower half and the higher half of the message address as 3185 // Emit the lower half and the higher half of the message address as
3191 // immediate operands in the test rax instructions. 3186 // immediate operands in the test rax instructions.
3192 testl(RAX, Immediate(Utils::Low32Bits(message_address))); 3187 testl(RAX, Immediate(Utils::Low32Bits(message_address)));
3193 testl(RAX, Immediate(Utils::High32Bits(message_address))); 3188 testl(RAX, Immediate(Utils::High32Bits(message_address)));
3194 } 3189 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3252 if (OS::ActivationFrameAlignment() > 1) { 3247 if (OS::ActivationFrameAlignment() > 1) {
3253 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); 3248 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
3254 } 3249 }
3255 } 3250 }
3256 3251
3257 3252
3258 void Assembler::PushRegisters(intptr_t cpu_register_set, 3253 void Assembler::PushRegisters(intptr_t cpu_register_set,
3259 intptr_t xmm_register_set) { 3254 intptr_t xmm_register_set) {
3260 const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set); 3255 const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set);
3261 if (xmm_regs_count > 0) { 3256 if (xmm_regs_count > 0) {
3262 AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize), PP); 3257 AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize));
3263 // Store XMM registers with the lowest register number at the lowest 3258 // Store XMM registers with the lowest register number at the lowest
3264 // address. 3259 // address.
3265 intptr_t offset = 0; 3260 intptr_t offset = 0;
3266 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { 3261 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
3267 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); 3262 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
3268 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) { 3263 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) {
3269 movups(Address(RSP, offset), xmm_reg); 3264 movups(Address(RSP, offset), xmm_reg);
3270 offset += kFpuRegisterSize; 3265 offset += kFpuRegisterSize;
3271 } 3266 }
3272 } 3267 }
(...skipping 28 matching lines...) Expand all
3301 // XMM registers have the lowest register number at the lowest address. 3296 // XMM registers have the lowest register number at the lowest address.
3302 intptr_t offset = 0; 3297 intptr_t offset = 0;
3303 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { 3298 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
3304 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); 3299 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
3305 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) { 3300 if (RegisterSet::Contains(xmm_register_set, xmm_reg)) {
3306 movups(xmm_reg, Address(RSP, offset)); 3301 movups(xmm_reg, Address(RSP, offset));
3307 offset += kFpuRegisterSize; 3302 offset += kFpuRegisterSize;
3308 } 3303 }
3309 } 3304 }
3310 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize)); 3305 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize));
3311 AddImmediate(RSP, Immediate(offset), PP); 3306 AddImmediate(RSP, Immediate(offset));
3312 } 3307 }
3313 } 3308 }
3314 3309
3315 3310
3316 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { 3311 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
3317 EnterFrame(0); 3312 EnterFrame(0);
3318 3313
3319 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch. 3314 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
3320 PushRegisters(CallingConventions::kVolatileCpuRegisters, 3315 PushRegisters(CallingConventions::kVolatileCpuRegisters,
3321 CallingConventions::kVolatileXmmRegisters); 3316 CallingConventions::kVolatileXmmRegisters);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3371 3366
3372 void Assembler::LoadPoolPointer(Register pp) { 3367 void Assembler::LoadPoolPointer(Register pp) {
3373 // Load new pool pointer. 3368 // Load new pool pointer.
3374 const intptr_t kRIPRelativeMovqSize = 7; 3369 const intptr_t kRIPRelativeMovqSize = 7;
3375 const intptr_t entry_to_rip_offset = CodeSize() + kRIPRelativeMovqSize; 3370 const intptr_t entry_to_rip_offset = CodeSize() + kRIPRelativeMovqSize;
3376 const intptr_t object_pool_pc_dist = 3371 const intptr_t object_pool_pc_dist =
3377 Instructions::HeaderSize() - Instructions::object_pool_offset(); 3372 Instructions::HeaderSize() - Instructions::object_pool_offset();
3378 movq(pp, Address::AddressRIPRelative( 3373 movq(pp, Address::AddressRIPRelative(
3379 -entry_to_rip_offset - object_pool_pc_dist)); 3374 -entry_to_rip_offset - object_pool_pc_dist));
3380 ASSERT(CodeSize() == entry_to_rip_offset); 3375 ASSERT(CodeSize() == entry_to_rip_offset);
3376 set_constant_pool_allowed(pp == PP);
3381 } 3377 }
3382 3378
3383 3379
3384 void Assembler::EnterDartFrameWithInfo(intptr_t frame_size, 3380 void Assembler::EnterDartFrameWithInfo(intptr_t frame_size,
3385 Register new_pp, 3381 Register new_pp,
3386 Register pc_marker_override) { 3382 Register pc_marker_override) {
3383 ASSERT(!constant_pool_allowed());
3387 EnterFrame(0); 3384 EnterFrame(0);
3388 pushq(pc_marker_override); 3385 pushq(pc_marker_override);
3389 pushq(PP); 3386 pushq(PP);
3390 movq(PP, new_pp); 3387 movq(PP, new_pp);
3388 set_constant_pool_allowed(true);
3391 if (frame_size != 0) { 3389 if (frame_size != 0) {
3392 subq(RSP, Immediate(frame_size)); 3390 subq(RSP, Immediate(frame_size));
3393 } 3391 }
3394 } 3392 }
3395 3393
3396 3394
3397 void Assembler::LeaveDartFrame() { 3395 void Assembler::LeaveDartFrame() {
3396 // LeaveDartFrame is called from stubs (pp disallowed) and from Dart code (pp
3397 // allowed), so there is no point in checking the current value of
3398 // constant_pool_allowed().
3399 set_constant_pool_allowed(false);
3398 // Restore caller's PP register that was pushed in EnterDartFrame. 3400 // Restore caller's PP register that was pushed in EnterDartFrame.
3399 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); 3401 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize)));
3400 LeaveFrame(); 3402 LeaveFrame();
3401 } 3403 }
3402 3404
3403 3405
3404 // On entry to a function compiled for OSR, the caller's frame pointer, the 3406 // 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 3407 // 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 3408 // 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 3409 // optimized function and there may be extra space for spill slots to
3408 // allocate. 3410 // allocate.
3409 void Assembler::EnterOsrFrame(intptr_t extra_size, 3411 void Assembler::EnterOsrFrame(intptr_t extra_size,
3410 Register new_pp, 3412 Register new_pp,
3411 Register pc_marker_override) { 3413 Register pc_marker_override) {
3414 ASSERT(!constant_pool_allowed());
3412 if (prologue_offset_ == -1) { 3415 if (prologue_offset_ == -1) {
3413 Comment("PrologueOffset = %" Pd "", CodeSize()); 3416 Comment("PrologueOffset = %" Pd "", CodeSize());
3414 prologue_offset_ = CodeSize(); 3417 prologue_offset_ = CodeSize();
3415 } 3418 }
3416 movq(Address(RBP, kPcMarkerSlotFromFp * kWordSize), pc_marker_override); 3419 movq(Address(RBP, kPcMarkerSlotFromFp * kWordSize), pc_marker_override);
3417 movq(PP, new_pp); 3420 movq(PP, new_pp);
3421 set_constant_pool_allowed(true);
3418 if (extra_size != 0) { 3422 if (extra_size != 0) {
3419 subq(RSP, Immediate(extra_size)); 3423 subq(RSP, Immediate(extra_size));
3420 } 3424 }
3421 } 3425 }
3422 3426
3423 3427
3424 void Assembler::EnterStubFrame() { 3428 void Assembler::EnterStubFrame() {
3429 set_constant_pool_allowed(false);
3425 EnterFrame(0); 3430 EnterFrame(0);
3426 pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames. 3431 pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames.
3427 pushq(PP); // Save caller's pool pointer 3432 pushq(PP); // Save caller's pool pointer
3428 LoadPoolPointer(PP); 3433 LoadPoolPointer(PP);
3429 } 3434 }
3430 3435
3431 3436
3432 void Assembler::LeaveStubFrame() { 3437 void Assembler::LeaveStubFrame() {
3438 set_constant_pool_allowed(false);
3433 // Restore caller's PP register that was pushed in EnterStubFrame. 3439 // Restore caller's PP register that was pushed in EnterStubFrame.
3434 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); 3440 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize)));
3435 LeaveFrame(); 3441 LeaveFrame();
3436 } 3442 }
3437 3443
3438 3444
3439 void Assembler::MaybeTraceAllocation(intptr_t cid, 3445 void Assembler::MaybeTraceAllocation(intptr_t cid,
3440 Label* trace, 3446 Label* trace,
3441 bool near_jump, 3447 bool near_jump,
3442 bool inline_isolate) { 3448 bool inline_isolate) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
3514 UpdateAllocationStats(cid, space, inline_isolate); 3520 UpdateAllocationStats(cid, space, inline_isolate);
3515 Register temp_reg = TMP; 3521 Register temp_reg = TMP;
3516 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew); 3522 intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew);
3517 addq(Address(temp_reg, size_offset), Immediate(size_in_bytes)); 3523 addq(Address(temp_reg, size_offset), Immediate(size_in_bytes));
3518 } 3524 }
3519 3525
3520 3526
3521 void Assembler::TryAllocate(const Class& cls, 3527 void Assembler::TryAllocate(const Class& cls,
3522 Label* failure, 3528 Label* failure,
3523 bool near_jump, 3529 bool near_jump,
3524 Register instance_reg, 3530 Register instance_reg) {
3525 Register pp) {
3526 ASSERT(failure != NULL); 3531 ASSERT(failure != NULL);
3527 if (FLAG_inline_alloc) { 3532 if (FLAG_inline_alloc) {
3528 // If this allocation is traced, program will jump to failure path 3533 // 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 3534 // (i.e. the allocation stub) which will allocate the object and trace the
3530 // allocation call site. 3535 // allocation call site.
3531 MaybeTraceAllocation(cls.id(), failure, near_jump); 3536 MaybeTraceAllocation(cls.id(), failure, near_jump);
3532 Heap* heap = Isolate::Current()->heap(); 3537 Heap* heap = Isolate::Current()->heap();
3533 const intptr_t instance_size = cls.instance_size(); 3538 const intptr_t instance_size = cls.instance_size();
3534 Heap::Space space = heap->SpaceForAllocation(cls.id()); 3539 Heap::Space space = heap->SpaceForAllocation(cls.id());
3535 LoadImmediate(TMP, Immediate(heap->TopAddress(space)), pp); 3540 LoadImmediate(TMP, Immediate(heap->TopAddress(space)));
3536 movq(instance_reg, Address(TMP, 0)); 3541 movq(instance_reg, Address(TMP, 0));
3537 AddImmediate(instance_reg, Immediate(instance_size), pp); 3542 AddImmediate(instance_reg, Immediate(instance_size));
3538 // instance_reg: potential next object start. 3543 // instance_reg: potential next object start.
3539 LoadImmediate(TMP, Immediate(heap->EndAddress(space)), pp); 3544 LoadImmediate(TMP, Immediate(heap->EndAddress(space)));
3540 cmpq(instance_reg, Address(TMP, 0)); 3545 cmpq(instance_reg, Address(TMP, 0));
3541 j(ABOVE_EQUAL, failure, near_jump); 3546 j(ABOVE_EQUAL, failure, near_jump);
3542 // Successfully allocated the object, now update top to point to 3547 // Successfully allocated the object, now update top to point to
3543 // next object start and store the class in the class field of object. 3548 // next object start and store the class in the class field of object.
3544 LoadImmediate(TMP, Immediate(heap->TopAddress(space)), pp); 3549 LoadImmediate(TMP, Immediate(heap->TopAddress(space)));
3545 movq(Address(TMP, 0), instance_reg); 3550 movq(Address(TMP, 0), instance_reg);
3546 UpdateAllocationStats(cls.id(), space); 3551 UpdateAllocationStats(cls.id(), space);
3547 ASSERT(instance_size >= kHeapObjectTag); 3552 ASSERT(instance_size >= kHeapObjectTag);
3548 AddImmediate(instance_reg, Immediate(kHeapObjectTag - instance_size), pp); 3553 AddImmediate(instance_reg, Immediate(kHeapObjectTag - instance_size));
3549 uword tags = 0; 3554 uword tags = 0;
3550 tags = RawObject::SizeTag::update(instance_size, tags); 3555 tags = RawObject::SizeTag::update(instance_size, tags);
3551 ASSERT(cls.id() != kIllegalCid); 3556 ASSERT(cls.id() != kIllegalCid);
3552 tags = RawObject::ClassIdTag::update(cls.id(), tags); 3557 tags = RawObject::ClassIdTag::update(cls.id(), tags);
3553 MoveImmediate(FieldAddress(instance_reg, Object::tags_offset()), 3558 MoveImmediate(FieldAddress(instance_reg, Object::tags_offset()),
3554 Immediate(tags), pp); 3559 Immediate(tags));
3555 } else { 3560 } else {
3556 jmp(failure); 3561 jmp(failure);
3557 } 3562 }
3558 } 3563 }
3559 3564
3560 3565
3561 void Assembler::TryAllocateArray(intptr_t cid, 3566 void Assembler::TryAllocateArray(intptr_t cid,
3562 intptr_t instance_size, 3567 intptr_t instance_size,
3563 Label* failure, 3568 Label* failure,
3564 bool near_jump, 3569 bool near_jump,
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
3744 void Assembler::LoadClassId(Register result, Register object) { 3749 void Assembler::LoadClassId(Register result, Register object) {
3745 ASSERT(RawObject::kClassIdTagPos == kBitsPerInt32); 3750 ASSERT(RawObject::kClassIdTagPos == kBitsPerInt32);
3746 ASSERT(RawObject::kClassIdTagSize == kBitsPerInt32); 3751 ASSERT(RawObject::kClassIdTagSize == kBitsPerInt32);
3747 ASSERT(sizeof(classid_t) == sizeof(uint32_t)); 3752 ASSERT(sizeof(classid_t) == sizeof(uint32_t));
3748 const intptr_t class_id_offset = Object::tags_offset() + 3753 const intptr_t class_id_offset = Object::tags_offset() +
3749 RawObject::kClassIdTagPos / kBitsPerByte; 3754 RawObject::kClassIdTagPos / kBitsPerByte;
3750 movl(result, FieldAddress(object, class_id_offset)); 3755 movl(result, FieldAddress(object, class_id_offset));
3751 } 3756 }
3752 3757
3753 3758
3754 void Assembler::LoadClassById(Register result, Register class_id, Register pp) { 3759 void Assembler::LoadClassById(Register result, Register class_id) {
3755 ASSERT(result != class_id); 3760 ASSERT(result != class_id);
3756 LoadIsolate(result); 3761 LoadIsolate(result);
3757 const intptr_t offset = 3762 const intptr_t offset =
3758 Isolate::class_table_offset() + ClassTable::table_offset(); 3763 Isolate::class_table_offset() + ClassTable::table_offset();
3759 movq(result, Address(result, offset)); 3764 movq(result, Address(result, offset));
3760 movq(result, Address(result, class_id, TIMES_8, 0)); 3765 movq(result, Address(result, class_id, TIMES_8, 0));
3761 } 3766 }
3762 3767
3763 3768
3764 void Assembler::LoadClass(Register result, Register object, Register pp) { 3769 void Assembler::LoadClass(Register result, Register object) {
3765 LoadClassId(TMP, object); 3770 LoadClassId(TMP, object);
3766 LoadClassById(result, TMP, pp); 3771 LoadClassById(result, TMP);
3767 } 3772 }
3768 3773
3769 3774
3770 void Assembler::CompareClassId(Register object, intptr_t class_id) { 3775 void Assembler::CompareClassId(Register object, intptr_t class_id) {
3771 LoadClassId(TMP, object); 3776 LoadClassId(TMP, object);
3772 cmpl(TMP, Immediate(class_id)); 3777 cmpl(TMP, Immediate(class_id));
3773 } 3778 }
3774 3779
3775 3780
3776 void Assembler::SmiUntagOrCheckClass(Register object, 3781 void Assembler::SmiUntagOrCheckClass(Register object,
(...skipping 14 matching lines...) Expand all
3791 movl(TMP, Address(object, TIMES_2, class_id_offset)); 3796 movl(TMP, Address(object, TIMES_2, class_id_offset));
3792 cmpl(TMP, Immediate(class_id)); 3797 cmpl(TMP, Immediate(class_id));
3793 } 3798 }
3794 3799
3795 3800
3796 void Assembler::LoadClassIdMayBeSmi(Register result, Register object) { 3801 void Assembler::LoadClassIdMayBeSmi(Register result, Register object) {
3797 ASSERT(result != object); 3802 ASSERT(result != object);
3798 3803
3799 // Load up a null object. We only need it so we can use LoadClassId on it in 3804 // 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. 3805 // the case that object is a Smi.
3801 LoadObject(result, Object::null_object(), PP); 3806 LoadObject(result, Object::null_object());
3802 // Check if the object is a Smi. 3807 // Check if the object is a Smi.
3803 testq(object, Immediate(kSmiTagMask)); 3808 testq(object, Immediate(kSmiTagMask));
3804 // If the object *is* a Smi, use the null object instead. 3809 // If the object *is* a Smi, use the null object instead.
3805 cmoveq(object, result); 3810 cmoveq(object, result);
3806 // Loads either the cid of the object if it isn't a Smi, or the cid of null 3811 // 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. 3812 // if it is a Smi, which will be ignored.
3808 LoadClassId(result, object); 3813 LoadClassId(result, object);
3809 3814
3810 movq(object, Immediate(kSmiCid)); 3815 movq(object, Immediate(kSmiCid));
3811 // If object is a Smi, move the Smi cid into result. o/w leave alone. 3816 // 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
3931 3936
3932 3937
3933 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3938 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3934 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 3939 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
3935 return xmm_reg_names[reg]; 3940 return xmm_reg_names[reg];
3936 } 3941 }
3937 3942
3938 } // namespace dart 3943 } // namespace dart
3939 3944
3940 #endif // defined TARGET_ARCH_X64 3945 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698