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

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 form
Florian Schneider 2013/09/30 11:48:35 /s/form/from/
zra 2013/09/30 18:01:08 Done.
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 movq(dst, imm);
2475 } else {
2476 LoadImmediate(TMP, imm, pp);
Florian Schneider 2013/09/30 11:48:35 This does not emit the most compact code in the ca
zra 2013/09/30 18:01:08 Done.
2477 movq(dst, TMP);
2296 } 2478 }
2297 } 2479 }
2298 2480
2299 2481
2300 // Destroys the value register. 2482 // Destroys the value register.
2301 void Assembler::StoreIntoObjectFilterNoSmi(Register object, 2483 void Assembler::StoreIntoObjectFilterNoSmi(Register object,
2302 Register value, 2484 Register value,
2303 Label* no_update) { 2485 Label* no_update) {
2304 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && 2486 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
2305 (kOldObjectAlignmentOffset == 0), young_alignment); 2487 (kOldObjectAlignmentOffset == 0), young_alignment);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2376 // No store buffer update. 2558 // No store buffer update.
2377 } 2559 }
2378 2560
2379 2561
2380 void Assembler::DoubleNegate(XmmRegister d) { 2562 void Assembler::DoubleNegate(XmmRegister d) {
2381 static const struct ALIGN16 { 2563 static const struct ALIGN16 {
2382 uint64_t a; 2564 uint64_t a;
2383 uint64_t b; 2565 uint64_t b;
2384 } double_negate_constant = 2566 } double_negate_constant =
2385 {0x8000000000000000LL, 0x8000000000000000LL}; 2567 {0x8000000000000000LL, 0x8000000000000000LL};
2386 movq(TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant))); 2568 LoadImmediate(
2569 TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)), PP);
2387 xorpd(d, Address(TMP, 0)); 2570 xorpd(d, Address(TMP, 0));
2388 } 2571 }
2389 2572
2390 2573
2391 void Assembler::DoubleAbs(XmmRegister reg) { 2574 void Assembler::DoubleAbs(XmmRegister reg) {
2392 static const struct ALIGN16 { 2575 static const struct ALIGN16 {
2393 uint64_t a; 2576 uint64_t a;
2394 uint64_t b; 2577 uint64_t b;
2395 } double_abs_constant = 2578 } double_abs_constant =
2396 {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}; 2579 {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
2397 movq(TMP, Immediate(reinterpret_cast<intptr_t>(&double_abs_constant))); 2580 LoadImmediate(TMP,
2581 Immediate(reinterpret_cast<intptr_t>(&double_abs_constant)), PP);
2398 andpd(reg, Address(TMP, 0)); 2582 andpd(reg, Address(TMP, 0));
2399 } 2583 }
2400 2584
2401 2585
2402 void Assembler::Stop(const char* message) { 2586 void Assembler::Stop(const char* message) {
2403 int64_t message_address = reinterpret_cast<int64_t>(message); 2587 int64_t message_address = reinterpret_cast<int64_t>(message);
2404 if (FLAG_print_stop_message) { 2588 if (FLAG_print_stop_message) {
2405 pushq(TMP); // Preserve TMP register. 2589 pushq(TMP); // Preserve TMP register.
2406 pushq(RDI); // Preserve RDI register. 2590 pushq(RDI); // Preserve RDI register.
2407 movq(RDI, Immediate(message_address)); 2591 LoadImmediate(RDI, Immediate(message_address), PP);
2408 call(&StubCode::PrintStopMessageLabel()); 2592 call(&StubCode::PrintStopMessageLabel());
2409 popq(RDI); // Restore RDI register. 2593 popq(RDI); // Restore RDI register.
2410 popq(TMP); // Restore TMP register. 2594 popq(TMP); // Restore TMP register.
2411 } else { 2595 } else {
2412 // Emit the lower half and the higher half of the message address as 2596 // Emit the lower half and the higher half of the message address as
2413 // immediate operands in the test rax instructions. 2597 // immediate operands in the test rax instructions.
2414 testl(RAX, Immediate(Utils::Low32Bits(message_address))); 2598 testl(RAX, Immediate(Utils::Low32Bits(message_address)));
2415 testl(RAX, Immediate(Utils::High32Bits(message_address))); 2599 testl(RAX, Immediate(Utils::High32Bits(message_address)));
2416 } 2600 }
2417 // Emit the int3 instruction. 2601 // Emit the int3 instruction.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2470 LeaveFrameWithPP(); 2654 LeaveFrameWithPP();
2471 ret(); 2655 ret();
2472 nop(4); 2656 nop(4);
2473 ASSERT((buffer_.GetPosition() - start) == 13); 2657 ASSERT((buffer_.GetPosition() - start) == 13);
2474 } 2658 }
2475 2659
2476 2660
2477 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { 2661 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
2478 // Reserve space for arguments and align frame before entering 2662 // Reserve space for arguments and align frame before entering
2479 // the C++ world. 2663 // the C++ world.
2480 AddImmediate(RSP, Immediate(-frame_space)); 2664 if (frame_space != 0) {
2665 subq(RSP, Immediate(frame_space));
2666 }
2481 if (OS::ActivationFrameAlignment() > 1) { 2667 if (OS::ActivationFrameAlignment() > 1) {
2482 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); 2668 andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
2483 } 2669 }
2484 } 2670 }
2485 2671
2486 2672
2487 // TODO(srdjan): Add XMM registers once they are used by the compiler. 2673 // 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 2674 // Based on http://x86-64.org/documentation/abi.pdf Fig. 3.4
2489 static const intptr_t kNumberOfVolatileCpuRegisters = 9; 2675 static const intptr_t kNumberOfVolatileCpuRegisters = 9;
2490 static const Register volatile_cpu_registers[kNumberOfVolatileCpuRegisters] = { 2676 static const Register volatile_cpu_registers[kNumberOfVolatileCpuRegisters] = {
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2660 EnterFrame(0); 2846 EnterFrame(0);
2661 pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames. 2847 pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames.
2662 pushq(PP); // Save caller's pool pointer 2848 pushq(PP); // Save caller's pool pointer
2663 LoadPoolPointer(PP); 2849 LoadPoolPointer(PP);
2664 } 2850 }
2665 2851
2666 2852
2667 void Assembler::TryAllocate(const Class& cls, 2853 void Assembler::TryAllocate(const Class& cls,
2668 Label* failure, 2854 Label* failure,
2669 bool near_jump, 2855 bool near_jump,
2670 Register instance_reg) { 2856 Register instance_reg,
2857 Register pp) {
2671 ASSERT(failure != NULL); 2858 ASSERT(failure != NULL);
2672 if (FLAG_inline_alloc) { 2859 if (FLAG_inline_alloc) {
2673 Heap* heap = Isolate::Current()->heap(); 2860 Heap* heap = Isolate::Current()->heap();
2674 const intptr_t instance_size = cls.instance_size(); 2861 const intptr_t instance_size = cls.instance_size();
2675 movq(TMP, Immediate(heap->TopAddress())); 2862 LoadImmediate(TMP, Immediate(heap->TopAddress()), pp);
2676 movq(instance_reg, Address(TMP, 0)); 2863 movq(instance_reg, Address(TMP, 0));
2677 addq(instance_reg, Immediate(instance_size)); 2864 AddImmediate(instance_reg, Immediate(instance_size), pp);
2678 // instance_reg: potential next object start. 2865 // instance_reg: potential next object start.
2679 movq(TMP, Immediate(heap->EndAddress())); 2866 LoadImmediate(TMP, Immediate(heap->EndAddress()), pp);
2680 cmpq(instance_reg, Address(TMP, 0)); 2867 cmpq(instance_reg, Address(TMP, 0));
2681 j(ABOVE_EQUAL, failure, near_jump); 2868 j(ABOVE_EQUAL, failure, near_jump);
2682 // Successfully allocated the object, now update top to point to 2869 // Successfully allocated the object, now update top to point to
2683 // next object start and store the class in the class field of object. 2870 // next object start and store the class in the class field of object.
2684 movq(TMP, Immediate(heap->TopAddress())); 2871 LoadImmediate(TMP, Immediate(heap->TopAddress()), pp);
2685 movq(Address(TMP, 0), instance_reg); 2872 movq(Address(TMP, 0), instance_reg);
2686 ASSERT(instance_size >= kHeapObjectTag); 2873 ASSERT(instance_size >= kHeapObjectTag);
2687 subq(instance_reg, Immediate(instance_size - kHeapObjectTag)); 2874 AddImmediate(instance_reg, Immediate(kHeapObjectTag - instance_size), pp);
2688 uword tags = 0; 2875 uword tags = 0;
2689 tags = RawObject::SizeTag::update(instance_size, tags); 2876 tags = RawObject::SizeTag::update(instance_size, tags);
2690 ASSERT(cls.id() != kIllegalCid); 2877 ASSERT(cls.id() != kIllegalCid);
2691 tags = RawObject::ClassIdTag::update(cls.id(), tags); 2878 tags = RawObject::ClassIdTag::update(cls.id(), tags);
2692 movq(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags)); 2879 LoadImmediate(FieldAddress(instance_reg, Object::tags_offset()),
2880 Immediate(tags), pp);
2693 } else { 2881 } else {
2694 jmp(failure); 2882 jmp(failure);
2695 } 2883 }
2696 } 2884 }
2697 2885
2698 2886
2699 void Assembler::Align(int alignment, int offset) { 2887 void Assembler::Align(int alignment, int offset) {
2700 ASSERT(Utils::IsPowerOfTwo(alignment)); 2888 ASSERT(Utils::IsPowerOfTwo(alignment));
2701 int pos = offset + buffer_.GetPosition(); 2889 int pos = offset + buffer_.GetPosition();
2702 int mod = pos & (alignment - 1); 2890 int mod = pos & (alignment - 1);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
2882 3070
2883 3071
2884 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3072 const char* Assembler::FpuRegisterName(FpuRegister reg) {
2885 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 3073 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
2886 return xmm_reg_names[reg]; 3074 return xmm_reg_names[reg];
2887 } 3075 }
2888 3076
2889 } // namespace dart 3077 } // namespace dart
2890 3078
2891 #endif // defined TARGET_ARCH_X64 3079 #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