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

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

Issue 25118002: Eliminates more large immediates from x64 code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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" 5 #include "vm/globals.h"
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/heap.h" 9 #include "vm/heap.h"
10 #include "vm/memory_region.h" 10 #include "vm/memory_region.h"
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 197 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
198 EmitUint8(0x68); 198 EmitUint8(0x68);
199 EmitImmediate(imm); 199 EmitImmediate(imm);
200 } else { 200 } else {
201 movq(TMP, imm); 201 movq(TMP, imm);
202 pushq(TMP); 202 pushq(TMP);
203 } 203 }
204 } 204 }
205 205
206 206
207 void Assembler::PushImmediate(const Immediate& imm, Register pp) {
208 if (imm.is_int32()) {
209 pushq(imm);
210 } else {
211 LoadImmediate(TMP, imm, pp);
212 pushq(TMP);
213 }
214 }
215
216
207 void Assembler::popq(Register reg) { 217 void Assembler::popq(Register reg) {
208 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 218 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
209 EmitRegisterREX(reg, REX_NONE); 219 EmitRegisterREX(reg, REX_NONE);
210 EmitUint8(0x58 | (reg & 7)); 220 EmitUint8(0x58 | (reg & 7));
211 } 221 }
212 222
213 223
214 void Assembler::popq(const Address& address) { 224 void Assembler::popq(const Address& address) {
215 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 225 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
216 EmitOperandREX(0, address, REX_NONE); 226 EmitOperandREX(0, address, REX_NONE);
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 } 816 }
807 817
808 void Assembler::notps(XmmRegister dst) { 818 void Assembler::notps(XmmRegister dst) {
809 static const struct ALIGN16 { 819 static const struct ALIGN16 {
810 uint32_t a; 820 uint32_t a;
811 uint32_t b; 821 uint32_t b;
812 uint32_t c; 822 uint32_t c;
813 uint32_t d; 823 uint32_t d;
814 } float_not_constant = 824 } float_not_constant =
815 { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; 825 { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
816 movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_not_constant))); 826 LoadImmediate(
827 TMP, Immediate(reinterpret_cast<intptr_t>(&float_not_constant)), PP);
817 xorps(dst, Address(TMP, 0)); 828 xorps(dst, Address(TMP, 0));
818 } 829 }
819 830
820 831
821 void Assembler::negateps(XmmRegister dst) { 832 void Assembler::negateps(XmmRegister dst) {
822 static const struct ALIGN16 { 833 static const struct ALIGN16 {
823 uint32_t a; 834 uint32_t a;
824 uint32_t b; 835 uint32_t b;
825 uint32_t c; 836 uint32_t c;
826 uint32_t d; 837 uint32_t d;
827 } float_negate_constant = 838 } float_negate_constant =
828 { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; 839 { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
829 movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_negate_constant))); 840 LoadImmediate(
841 TMP, Immediate(reinterpret_cast<intptr_t>(&float_negate_constant)), PP);
830 xorps(dst, Address(TMP, 0)); 842 xorps(dst, Address(TMP, 0));
831 } 843 }
832 844
833 845
834 void Assembler::absps(XmmRegister dst) { 846 void Assembler::absps(XmmRegister dst) {
835 static const struct ALIGN16 { 847 static const struct ALIGN16 {
836 uint32_t a; 848 uint32_t a;
837 uint32_t b; 849 uint32_t b;
838 uint32_t c; 850 uint32_t c;
839 uint32_t d; 851 uint32_t d;
840 } float_absolute_constant = 852 } float_absolute_constant =
841 { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; 853 { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
842 movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_absolute_constant))); 854 LoadImmediate(
855 TMP, Immediate(reinterpret_cast<intptr_t>(&float_absolute_constant)), PP);
843 andps(dst, Address(TMP, 0)); 856 andps(dst, Address(TMP, 0));
844 } 857 }
845 858
846 859
847 void Assembler::zerowps(XmmRegister dst) { 860 void Assembler::zerowps(XmmRegister dst) {
848 static const struct ALIGN16 { 861 static const struct ALIGN16 {
849 uint32_t a; 862 uint32_t a;
850 uint32_t b; 863 uint32_t b;
851 uint32_t c; 864 uint32_t c;
852 uint32_t d; 865 uint32_t d;
853 } float_zerow_constant = 866 } float_zerow_constant =
854 { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; 867 { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 };
855 movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_zerow_constant))); 868 LoadImmediate(
869 TMP, Immediate(reinterpret_cast<intptr_t>(&float_zerow_constant)), PP);
856 andps(dst, Address(TMP, 0)); 870 andps(dst, Address(TMP, 0));
857 } 871 }
858 872
859 873
860 void Assembler::cmppseq(XmmRegister dst, XmmRegister src) { 874 void Assembler::cmppseq(XmmRegister dst, XmmRegister src) {
861 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 875 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
862 EmitREX_RB(dst, src); 876 EmitREX_RB(dst, src);
863 EmitUint8(0x0F); 877 EmitUint8(0x0F);
864 EmitUint8(0xC2); 878 EmitUint8(0xC2);
865 EmitXmmRegisterOperand(dst & 7, src); 879 EmitXmmRegisterOperand(dst & 7, src);
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 1349
1336 1350
1337 void Assembler::cmpq(Register reg, const Address& address) { 1351 void Assembler::cmpq(Register reg, const Address& address) {
1338 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1352 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1339 EmitOperandREX(reg, address, REX_W); 1353 EmitOperandREX(reg, address, REX_W);
1340 EmitUint8(0x3B); 1354 EmitUint8(0x3B);
1341 EmitOperand(reg & 7, address); 1355 EmitOperand(reg & 7, address);
1342 } 1356 }
1343 1357
1344 1358
1359 void Assembler::CompareImmediate(Register reg, const Immediate& imm,
1360 Register pp) {
1361 if (imm.is_int32()) {
1362 cmpq(reg, imm);
1363 } else {
1364 LoadImmediate(TMP, imm, pp);
1365 cmpq(reg, TMP);
1366 }
1367 }
1368
1369
1370 void Assembler::CompareImmediate(const Address& address, const Immediate& imm,
1371 Register pp) {
1372 if (imm.is_int32()) {
1373 cmpq(address, imm);
1374 } else {
1375 LoadImmediate(TMP, imm, pp);
1376 cmpq(address, TMP);
1377 }
1378 }
1379
1380
1345 void Assembler::testl(Register reg1, Register reg2) { 1381 void Assembler::testl(Register reg1, Register reg2) {
1346 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1382 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1347 Operand operand(reg2); 1383 Operand operand(reg2);
1348 EmitOperandREX(reg1, operand, REX_NONE); 1384 EmitOperandREX(reg1, operand, REX_NONE);
1349 EmitUint8(0x85); 1385 EmitUint8(0x85);
1350 EmitOperand(reg1 & 7, operand); 1386 EmitOperand(reg1 & 7, operand);
1351 } 1387 }
1352 1388
1353 1389
1354 void Assembler::testl(Register reg, const Immediate& imm) { 1390 void Assembler::testl(Register reg, const Immediate& imm) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1521 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1486 EmitRegisterREX(dst, REX_W); 1522 EmitRegisterREX(dst, REX_W);
1487 EmitComplex(4, Operand(dst), imm); 1523 EmitComplex(4, Operand(dst), imm);
1488 } else { 1524 } else {
1489 movq(TMP, imm); 1525 movq(TMP, imm);
1490 andq(dst, TMP); 1526 andq(dst, TMP);
1491 } 1527 }
1492 } 1528 }
1493 1529
1494 1530
1531 void Assembler::AndImmediate(Register dst, const Immediate& imm, Register pp) {
1532 if (imm.is_int32()) {
1533 andq(dst, imm);
1534 } else {
1535 ASSERT(dst != TMP);
1536 LoadImmediate(TMP, imm, pp);
1537 andq(dst, TMP);
1538 }
1539 }
1540
1541
1495 void Assembler::orq(Register dst, Register src) { 1542 void Assembler::orq(Register dst, Register src) {
1496 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1543 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1497 Operand operand(src); 1544 Operand operand(src);
1498 EmitOperandREX(dst, operand, REX_W); 1545 EmitOperandREX(dst, operand, REX_W);
1499 EmitUint8(0x0B); 1546 EmitUint8(0x0B);
1500 EmitOperand(dst & 7, operand); 1547 EmitOperand(dst & 7, operand);
1501 } 1548 }
1502 1549
1503 1550
1504 void Assembler::orq(Register dst, const Address& address) { 1551 void Assembler::orq(Register dst, const Address& address) {
1505 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1552 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1506 EmitOperandREX(dst, address, REX_W); 1553 EmitOperandREX(dst, address, REX_W);
1507 EmitUint8(0x0B); 1554 EmitUint8(0x0B);
1508 EmitOperand(dst & 7, address); 1555 EmitOperand(dst & 7, address);
1509 } 1556 }
1510 1557
1511 1558
1512 void Assembler::orq(Register dst, const Immediate& imm) { 1559 void Assembler::orq(Register dst, const Immediate& imm) {
1513 if (imm.is_int32()) { 1560 if (imm.is_int32()) {
1514 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1561 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1515 EmitRegisterREX(dst, REX_W); 1562 EmitRegisterREX(dst, REX_W);
1516 EmitComplex(1, Operand(dst), imm); 1563 EmitComplex(1, Operand(dst), imm);
1517 } else { 1564 } else {
1518 movq(TMP, imm); 1565 movq(TMP, imm);
1519 orq(dst, TMP); 1566 orq(dst, TMP);
1520 } 1567 }
1521 } 1568 }
1522 1569
1523 1570
1571 void Assembler::OrImmediate(Register dst, const Immediate& imm, Register pp) {
1572 if (imm.is_int32()) {
1573 orq(dst, imm);
1574 } else {
1575 ASSERT(dst != TMP);
1576 LoadImmediate(TMP, imm, pp);
1577 orq(dst, TMP);
1578 }
1579 }
1580
1581
1524 void Assembler::xorq(Register dst, Register src) { 1582 void Assembler::xorq(Register dst, Register src) {
1525 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1583 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1526 Operand operand(src); 1584 Operand operand(src);
1527 EmitOperandREX(dst, operand, REX_W); 1585 EmitOperandREX(dst, operand, REX_W);
1528 EmitUint8(0x33); 1586 EmitUint8(0x33);
1529 EmitOperand(dst & 7, operand); 1587 EmitOperand(dst & 7, operand);
1530 } 1588 }
1531 1589
1532 1590
1533 void Assembler::xorq(Register dst, const Address& address) { 1591 void Assembler::xorq(Register dst, const Address& address) {
(...skipping 17 matching lines...) Expand all
1551 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1609 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1552 EmitRegisterREX(dst, REX_W); 1610 EmitRegisterREX(dst, REX_W);
1553 EmitComplex(6, Operand(dst), imm); 1611 EmitComplex(6, Operand(dst), imm);
1554 } else { 1612 } else {
1555 movq(TMP, imm); 1613 movq(TMP, imm);
1556 xorq(dst, TMP); 1614 xorq(dst, TMP);
1557 } 1615 }
1558 } 1616 }
1559 1617
1560 1618
1619 void Assembler::XorImmediate(Register dst, const Immediate& imm, Register pp) {
1620 if (imm.is_int32()) {
1621 xorq(dst, imm);
1622 } else {
1623 ASSERT(dst != TMP);
1624 LoadImmediate(TMP, imm, pp);
1625 xorq(dst, TMP);
1626 }
1627 }
1628
1629
1561 void Assembler::addl(Register dst, Register src) { 1630 void Assembler::addl(Register dst, Register src) {
1562 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1631 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1563 Operand operand(src); 1632 Operand operand(src);
1564 EmitOperandREX(dst, operand, REX_NONE); 1633 EmitOperandREX(dst, operand, REX_NONE);
1565 EmitUint8(0x03); 1634 EmitUint8(0x03);
1566 EmitOperand(dst & 7, operand); 1635 EmitOperand(dst & 7, operand);
1567 } 1636 }
1568 1637
1569 1638
1570 void Assembler::addq(Register dst, Register src) { 1639 void Assembler::addq(Register dst, Register src) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 EmitUint8(0x69); 1770 EmitUint8(0x69);
1702 EmitOperand(reg & 7, Operand(reg)); 1771 EmitOperand(reg & 7, Operand(reg));
1703 EmitImmediate(imm); 1772 EmitImmediate(imm);
1704 } else { 1773 } else {
1705 movq(TMP, imm); 1774 movq(TMP, imm);
1706 imulq(reg, TMP); 1775 imulq(reg, TMP);
1707 } 1776 }
1708 } 1777 }
1709 1778
1710 1779
1780 void Assembler::MulImmediate(Register reg, const Immediate& imm, Register pp) {
1781 if (imm.is_int32()) {
1782 imulq(reg, imm);
1783 } else {
1784 ASSERT(reg != TMP);
1785 LoadImmediate(TMP, imm, pp);
1786 imulq(reg, TMP);
1787 }
1788 }
1789
1790
1711 void Assembler::imulq(Register dst, const Address& address) { 1791 void Assembler::imulq(Register dst, const Address& address) {
1712 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1792 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1713 EmitOperandREX(dst, address, REX_W); 1793 EmitOperandREX(dst, address, REX_W);
1714 EmitUint8(0x0F); 1794 EmitUint8(0x0F);
1715 EmitUint8(0xAF); 1795 EmitUint8(0xAF);
1716 EmitOperand(dst & 7, address); 1796 EmitOperand(dst & 7, address);
1717 } 1797 }
1718 1798
1719 1799
1720 void Assembler::subq(Register dst, Register src) { 1800 void Assembler::subq(Register dst, Register src) {
(...skipping 18 matching lines...) Expand all
1739 1819
1740 1820
1741 void Assembler::subq(Register reg, const Address& address) { 1821 void Assembler::subq(Register reg, const Address& address) {
1742 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1822 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1743 EmitOperandREX(reg, address, REX_W); 1823 EmitOperandREX(reg, address, REX_W);
1744 EmitUint8(0x2B); 1824 EmitUint8(0x2B);
1745 EmitOperand(reg & 7, address); 1825 EmitOperand(reg & 7, address);
1746 } 1826 }
1747 1827
1748 1828
1829 void Assembler::subq(const Address& address, Register reg) {
1830 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1831 EmitOperandREX(reg, address, REX_W);
1832 EmitUint8(0x29);
1833 EmitOperand(reg & 7, address);
1834 }
1835
1836
1837 void Assembler::subq(const Address& address, const Immediate& imm) {
1838 // TODO(srdjan): Implement shorter version for imm32.
1839 movq(TMP, imm);
1840 subq(address, TMP);
1841 }
1842
1843
1749 void Assembler::shll(Register reg, const Immediate& imm) { 1844 void Assembler::shll(Register reg, const Immediate& imm) {
1750 EmitGenericShift(false, 4, reg, imm); 1845 EmitGenericShift(false, 4, reg, imm);
1751 } 1846 }
1752 1847
1753 1848
1754 void Assembler::shll(Register operand, Register shifter) { 1849 void Assembler::shll(Register operand, Register shifter) {
1755 EmitGenericShift(false, 4, operand, shifter); 1850 EmitGenericShift(false, 4, operand, shifter);
1756 } 1851 }
1757 1852
1758 1853
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 movq(to, from); 2226 movq(to, from);
2132 } 2227 }
2133 } 2228 }
2134 2229
2135 2230
2136 void Assembler::PopRegister(Register r) { 2231 void Assembler::PopRegister(Register r) {
2137 popq(r); 2232 popq(r);
2138 } 2233 }
2139 2234
2140 2235
2141 void Assembler::AddImmediate(Register reg, const Immediate& imm) { 2236 void Assembler::AddImmediate(Register reg, const Immediate& imm, Register pp) {
2142 int64_t value = imm.value(); 2237 int64_t value = imm.value();
2143 if (value > 0) { 2238 if (value > 0) {
2144 if (value == 1) { 2239 if (value == 1) {
2145 incq(reg); 2240 incq(reg);
2146 } else if (value != 0) { 2241 } else if (value != 0) {
2147 addq(reg, imm); 2242 if (imm.is_int32()) {
2243 addq(reg, imm);
2244 } else {
2245 ASSERT(reg != TMP);
2246 LoadImmediate(TMP, imm, pp);
2247 addq(reg, TMP);
2248 }
2148 } 2249 }
2149 } else if (value < 0) { 2250 } else if (value < 0) {
2150 value = -value; 2251 value = -value;
2151 if (value == 1) { 2252 if (value == 1) {
2152 decq(reg); 2253 decq(reg);
2153 } else if (value != 0) { 2254 } else if (value != 0) {
2154 subq(reg, Immediate(value)); 2255 const Immediate& s = Immediate(value);
2256 if (s.is_int32()) {
2257 subq(reg, Immediate(value));
2258 } else {
2259 ASSERT(reg != TMP);
2260 LoadImmediate(TMP, s, pp);
2261 subq(reg, TMP);
2262 }
2263 }
2264 }
2265 }
2266
2267
2268 void Assembler::AddImmediate(const Address& address, const Immediate& imm,
2269 Register pp) {
2270 int64_t value = imm.value();
2271 if (value > 0) {
2272 if (value == 1) {
2273 incq(address);
2274 } else if (value != 0) {
2275 if (imm.is_int32()) {
2276 addq(address, imm);
2277 } else {
2278 LoadImmediate(TMP, imm, pp);
2279 addq(address, TMP);
2280 }
2281 }
2282 } else if (value < 0) {
2283 value = -value;
2284 if (value == 1) {
2285 decq(address);
2286 } else if (value != 0) {
2287 const Immediate& s = Immediate(value);
2288 if (s.is_int32()) {
2289 subq(address, s);
2290 } else {
2291 LoadImmediate(TMP, s, pp);
2292 subq(address, TMP);
2293 }
2155 } 2294 }
2156 } 2295 }
2157 } 2296 }
2158 2297
2159 2298
2160 void Assembler::Drop(intptr_t stack_elements) { 2299 void Assembler::Drop(intptr_t stack_elements) {
2161 ASSERT(stack_elements >= 0); 2300 ASSERT(stack_elements >= 0);
2162 if (stack_elements <= 4) { 2301 if (stack_elements <= 4) {
2163 for (intptr_t i = 0; i < stack_elements; i++) { 2302 for (intptr_t i = 0; i < stack_elements; i++) {
2164 popq(TMP); 2303 popq(TMP);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2254 2393
2255 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { 2394 void Assembler::LoadObject(Register dst, const Object& object, Register pp) {
2256 if (CanLoadFromObjectPool(object)) { 2395 if (CanLoadFromObjectPool(object)) {
2257 const int32_t offset = 2396 const int32_t offset =
2258 Array::element_offset(FindObject(object, kNotPatchable)); 2397 Array::element_offset(FindObject(object, kNotPatchable));
2259 LoadWordFromPoolOffset(dst, pp, offset - kHeapObjectTag); 2398 LoadWordFromPoolOffset(dst, pp, offset - kHeapObjectTag);
2260 } else { 2399 } else {
2261 ASSERT((Isolate::Current() == Dart::vm_isolate()) || 2400 ASSERT((Isolate::Current() == Dart::vm_isolate()) ||
2262 object.IsSmi() || 2401 object.IsSmi() ||
2263 object.InVMHeap()); 2402 object.InVMHeap());
2264 movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); 2403 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
2265 } 2404 }
2266 } 2405 }
2267 2406
2268 2407
2269 void Assembler::StoreObject(const Address& dst, const Object& object) { 2408 void Assembler::StoreObject(const Address& dst, const Object& object,
2409 Register pp) {
2270 if (CanLoadFromObjectPool(object)) { 2410 if (CanLoadFromObjectPool(object)) {
2271 LoadObject(TMP, object, PP); 2411 LoadObject(TMP, object, pp);
2272 movq(dst, TMP); 2412 movq(dst, TMP);
2273 } else { 2413 } else {
2274 movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); 2414 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
2275 } 2415 }
2276 } 2416 }
2277 2417
2278 2418
2279 void Assembler::PushObject(const Object& object) { 2419 void Assembler::PushObject(const Object& object, Register pp) {
2280 if (CanLoadFromObjectPool(object)) { 2420 if (CanLoadFromObjectPool(object)) {
2281 LoadObject(TMP, object, PP); 2421 LoadObject(TMP, object, pp);
2282 pushq(TMP); 2422 pushq(TMP);
2283 } else { 2423 } else {
2284 pushq(Immediate(reinterpret_cast<int64_t>(object.raw()))); 2424 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
2285 } 2425 }
2286 } 2426 }
2287 2427
2288 2428
2289 void Assembler::CompareObject(Register reg, const Object& object) { 2429 void Assembler::CompareObject(Register reg, const Object& object, Register pp) {
2290 if (CanLoadFromObjectPool(object)) { 2430 if (CanLoadFromObjectPool(object)) {
2291 ASSERT(reg != TMP); 2431 ASSERT(reg != TMP);
2292 LoadObject(TMP, object, PP); 2432 LoadObject(TMP, object, pp);
2293 cmpq(reg, TMP); 2433 cmpq(reg, TMP);
2294 } else { 2434 } else {
2295 cmpq(reg, Immediate(reinterpret_cast<int64_t>(object.raw()))); 2435 CompareImmediate(
2436 reg, Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
2437 }
2438 }
2439
2440
2441 intptr_t Assembler::FindImmediate(int64_t imm) {
2442 ASSERT(Isolate::Current() != Dart::vm_isolate());
2443 ASSERT(!object_pool_.IsNull());
2444 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm));
2445 return FindObject(smi, kNotPatchable);
2446 }
2447
2448
2449 void Assembler::LoadImmediate(Register reg, const Immediate& imm, Register pp) {
2450 if (imm.is_int32() ||
2451 (pp == kNoRegister) ||
2452 (Isolate::Current() == Dart::vm_isolate())) {
2453 movq(reg, imm);
2454 } else {
2455 // It's a 64-bit constant and we're not in the VM isolate, so load from
2456 // object pool.
2457 int64_t val = imm.value();
2458 // Save the bits that must be masked-off for the SmiTag
2459 int64_t val_smi_tag = val & kSmiTagMask;
2460 val &= ~kSmiTagMask; // Mask off the tag bits.
2461 const int32_t offset = Array::element_offset(FindImmediate(val));
2462 LoadWordFromPoolOffset(reg, pp, offset - kHeapObjectTag);
2463 if (val_smi_tag != 0) {
2464 // Add back the tag bits.
2465 orq(reg, Immediate(val_smi_tag));
2466 }
2467 }
2468 }
2469
2470
2471 void Assembler::LoadImmediate(const Address& dst, const Immediate& imm,
2472 Register pp) {
2473 if (imm.is_int32() ||
2474 (pp == kNoRegister) ||
2475 (Isolate::Current() == Dart::vm_isolate())) {
Florian Schneider 2013/09/30 18:43:35 These 3 conditions seem to be repeated a couple of
zra 2013/09/30 19:59:31 Done.
2476 movq(dst, imm);
2477 } else {
2478 LoadImmediate(TMP, imm, pp);
2479 movq(dst, TMP);
2296 } 2480 }
2297 } 2481 }
2298 2482
2299 2483
2300 // Destroys the value register. 2484 // Destroys the value register.
2301 void Assembler::StoreIntoObjectFilterNoSmi(Register object, 2485 void Assembler::StoreIntoObjectFilterNoSmi(Register object,
2302 Register value, 2486 Register value,
2303 Label* no_update) { 2487 Label* no_update) {
2304 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && 2488 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
2305 (kOldObjectAlignmentOffset == 0), young_alignment); 2489 (kOldObjectAlignmentOffset == 0), young_alignment);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2376 // No store buffer update. 2560 // No store buffer update.
2377 } 2561 }
2378 2562
2379 2563
2380 void Assembler::DoubleNegate(XmmRegister d) { 2564 void Assembler::DoubleNegate(XmmRegister d) {
2381 static const struct ALIGN16 { 2565 static const struct ALIGN16 {
2382 uint64_t a; 2566 uint64_t a;
2383 uint64_t b; 2567 uint64_t b;
2384 } double_negate_constant = 2568 } double_negate_constant =
2385 {0x8000000000000000LL, 0x8000000000000000LL}; 2569 {0x8000000000000000LL, 0x8000000000000000LL};
2386 movq(TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant))); 2570 LoadImmediate(
2571 TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)), PP);
2387 xorpd(d, Address(TMP, 0)); 2572 xorpd(d, Address(TMP, 0));
2388 } 2573 }
2389 2574
2390 2575
2391 void Assembler::DoubleAbs(XmmRegister reg) { 2576 void Assembler::DoubleAbs(XmmRegister reg) {
2392 static const struct ALIGN16 { 2577 static const struct ALIGN16 {
2393 uint64_t a; 2578 uint64_t a;
2394 uint64_t b; 2579 uint64_t b;
2395 } double_abs_constant = 2580 } double_abs_constant =
2396 {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}; 2581 {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
2397 movq(TMP, Immediate(reinterpret_cast<intptr_t>(&double_abs_constant))); 2582 LoadImmediate(TMP,
2583 Immediate(reinterpret_cast<intptr_t>(&double_abs_constant)), PP);
2398 andpd(reg, Address(TMP, 0)); 2584 andpd(reg, Address(TMP, 0));
2399 } 2585 }
2400 2586
2401 2587
2402 void Assembler::Stop(const char* message) { 2588 void Assembler::Stop(const char* message) {
2403 int64_t message_address = reinterpret_cast<int64_t>(message); 2589 int64_t message_address = reinterpret_cast<int64_t>(message);
2404 if (FLAG_print_stop_message) { 2590 if (FLAG_print_stop_message) {
2405 pushq(TMP); // Preserve TMP register. 2591 pushq(TMP); // Preserve TMP register.
2406 pushq(RDI); // Preserve RDI register. 2592 pushq(RDI); // Preserve RDI register.
2407 movq(RDI, Immediate(message_address)); 2593 LoadImmediate(RDI, Immediate(message_address), PP);
2408 call(&StubCode::PrintStopMessageLabel()); 2594 call(&StubCode::PrintStopMessageLabel());
2409 popq(RDI); // Restore RDI register. 2595 popq(RDI); // Restore RDI register.
2410 popq(TMP); // Restore TMP register. 2596 popq(TMP); // Restore TMP register.
2411 } else { 2597 } else {
2412 // Emit the lower half and the higher half of the message address as 2598 // Emit the lower half and the higher half of the message address as
2413 // immediate operands in the test rax instructions. 2599 // immediate operands in the test rax instructions.
2414 testl(RAX, Immediate(Utils::Low32Bits(message_address))); 2600 testl(RAX, Immediate(Utils::Low32Bits(message_address)));
2415 testl(RAX, Immediate(Utils::High32Bits(message_address))); 2601 testl(RAX, Immediate(Utils::High32Bits(message_address)));
2416 } 2602 }
2417 // Emit the int3 instruction. 2603 // Emit the int3 instruction.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2470 LeaveFrameWithPP(); 2656 LeaveFrameWithPP();
2471 ret(); 2657 ret();
2472 nop(4); 2658 nop(4);
2473 ASSERT((buffer_.GetPosition() - start) == 13); 2659 ASSERT((buffer_.GetPosition() - start) == 13);
2474 } 2660 }
2475 2661
2476 2662
2477 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { 2663 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
2478 // Reserve space for arguments and align frame before entering 2664 // Reserve space for arguments and align frame before entering
2479 // the C++ world. 2665 // the C++ world.
2480 AddImmediate(RSP, Immediate(-frame_space)); 2666 if (frame_space != 0) {
2667 subq(RSP, Immediate(frame_space));
2668 }
2481 if (OS::ActivationFrameAlignment() > 1) { 2669 if (OS::ActivationFrameAlignment() > 1) {
2482 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); 2670 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
2483 } 2671 }
2484 } 2672 }
2485 2673
2486 2674
2487 // TODO(srdjan): Add XMM registers once they are used by the compiler. 2675 // TODO(srdjan): Add XMM registers once they are used by the compiler.
2488 // Based on http://x86-64.org/documentation/abi.pdf Fig. 3.4 2676 // Based on http://x86-64.org/documentation/abi.pdf Fig. 3.4
2489 static const intptr_t kNumberOfVolatileCpuRegisters = 9; 2677 static const intptr_t kNumberOfVolatileCpuRegisters = 9;
2490 static const Register volatile_cpu_registers[kNumberOfVolatileCpuRegisters] = { 2678 static const Register volatile_cpu_registers[kNumberOfVolatileCpuRegisters] = {
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2660 EnterFrame(0); 2848 EnterFrame(0);
2661 pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames. 2849 pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames.
2662 pushq(PP); // Save caller's pool pointer 2850 pushq(PP); // Save caller's pool pointer
2663 LoadPoolPointer(PP); 2851 LoadPoolPointer(PP);
2664 } 2852 }
2665 2853
2666 2854
2667 void Assembler::TryAllocate(const Class& cls, 2855 void Assembler::TryAllocate(const Class& cls,
2668 Label* failure, 2856 Label* failure,
2669 bool near_jump, 2857 bool near_jump,
2670 Register instance_reg) { 2858 Register instance_reg,
2859 Register pp) {
2671 ASSERT(failure != NULL); 2860 ASSERT(failure != NULL);
2672 if (FLAG_inline_alloc) { 2861 if (FLAG_inline_alloc) {
2673 Heap* heap = Isolate::Current()->heap(); 2862 Heap* heap = Isolate::Current()->heap();
2674 const intptr_t instance_size = cls.instance_size(); 2863 const intptr_t instance_size = cls.instance_size();
2675 movq(TMP, Immediate(heap->TopAddress())); 2864 LoadImmediate(TMP, Immediate(heap->TopAddress()), pp);
2676 movq(instance_reg, Address(TMP, 0)); 2865 movq(instance_reg, Address(TMP, 0));
2677 addq(instance_reg, Immediate(instance_size)); 2866 AddImmediate(instance_reg, Immediate(instance_size), pp);
2678 // instance_reg: potential next object start. 2867 // instance_reg: potential next object start.
2679 movq(TMP, Immediate(heap->EndAddress())); 2868 LoadImmediate(TMP, Immediate(heap->EndAddress()), pp);
2680 cmpq(instance_reg, Address(TMP, 0)); 2869 cmpq(instance_reg, Address(TMP, 0));
2681 j(ABOVE_EQUAL, failure, near_jump); 2870 j(ABOVE_EQUAL, failure, near_jump);
2682 // Successfully allocated the object, now update top to point to 2871 // Successfully allocated the object, now update top to point to
2683 // next object start and store the class in the class field of object. 2872 // next object start and store the class in the class field of object.
2684 movq(TMP, Immediate(heap->TopAddress())); 2873 LoadImmediate(TMP, Immediate(heap->TopAddress()), pp);
2685 movq(Address(TMP, 0), instance_reg); 2874 movq(Address(TMP, 0), instance_reg);
2686 ASSERT(instance_size >= kHeapObjectTag); 2875 ASSERT(instance_size >= kHeapObjectTag);
2687 subq(instance_reg, Immediate(instance_size - kHeapObjectTag)); 2876 AddImmediate(instance_reg, Immediate(kHeapObjectTag - instance_size), pp);
2688 uword tags = 0; 2877 uword tags = 0;
2689 tags = RawObject::SizeTag::update(instance_size, tags); 2878 tags = RawObject::SizeTag::update(instance_size, tags);
2690 ASSERT(cls.id() != kIllegalCid); 2879 ASSERT(cls.id() != kIllegalCid);
2691 tags = RawObject::ClassIdTag::update(cls.id(), tags); 2880 tags = RawObject::ClassIdTag::update(cls.id(), tags);
2692 movq(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags)); 2881 LoadImmediate(FieldAddress(instance_reg, Object::tags_offset()),
2882 Immediate(tags), pp);
2693 } else { 2883 } else {
2694 jmp(failure); 2884 jmp(failure);
2695 } 2885 }
2696 } 2886 }
2697 2887
2698 2888
2699 void Assembler::Align(int alignment, int offset) { 2889 void Assembler::Align(int alignment, int offset) {
2700 ASSERT(Utils::IsPowerOfTwo(alignment)); 2890 ASSERT(Utils::IsPowerOfTwo(alignment));
2701 int pos = offset + buffer_.GetPosition(); 2891 int pos = offset + buffer_.GetPosition();
2702 int mod = pos & (alignment - 1); 2892 int mod = pos & (alignment - 1);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
2882 3072
2883 3073
2884 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3074 const char* Assembler::FpuRegisterName(FpuRegister reg) {
2885 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 3075 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
2886 return xmm_reg_names[reg]; 3076 return xmm_reg_names[reg];
2887 } 3077 }
2888 3078
2889 } // namespace dart 3079 } // namespace dart
2890 3080
2891 #endif // defined TARGET_ARCH_X64 3081 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698