| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 last_pc_ = pc_; | 453 last_pc_ = pc_; |
| 454 emit_rex_64(reg, op); | 454 emit_rex_64(reg, op); |
| 455 emit(opcode); | 455 emit(opcode); |
| 456 emit_operand(reg, op); | 456 emit_operand(reg, op); |
| 457 } | 457 } |
| 458 | 458 |
| 459 | 459 |
| 460 void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) { | 460 void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) { |
| 461 EnsureSpace ensure_space(this); | 461 EnsureSpace ensure_space(this); |
| 462 last_pc_ = pc_; | 462 last_pc_ = pc_; |
| 463 emit_rex_64(reg, rm_reg); | 463 ASSERT((opcode & 0xC6) == 2); |
| 464 emit(opcode); | 464 if (rm_reg.low_bits() == 4) { // Forces SIB byte. |
| 465 emit_modrm(reg, rm_reg); | 465 emit_rex_64(rm_reg, reg); |
| 466 emit(opcode ^ 0x02); |
| 467 emit_modrm(rm_reg, reg); |
| 468 } else { |
| 469 emit_rex_64(reg, rm_reg); |
| 470 emit(opcode); |
| 471 emit_modrm(reg, rm_reg); |
| 472 } |
| 466 } | 473 } |
| 467 | 474 |
| 468 | 475 |
| 469 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) { | 476 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) { |
| 470 EnsureSpace ensure_space(this); | 477 EnsureSpace ensure_space(this); |
| 471 last_pc_ = pc_; | 478 last_pc_ = pc_; |
| 472 emit(0x66); | 479 ASSERT((opcode & 0xC6) == 2); |
| 473 emit_optional_rex_32(reg, rm_reg); | 480 if (rm_reg.low_bits() == 4) { // Forces SIB byte. |
| 474 emit(opcode); | 481 emit(0x66); |
| 475 emit_modrm(reg, rm_reg); | 482 emit_optional_rex_32(rm_reg, reg); |
| 483 emit(opcode ^ 0x02); |
| 484 emit_modrm(rm_reg, reg); |
| 485 } else { |
| 486 emit(0x66); |
| 487 emit_optional_rex_32(reg, rm_reg); |
| 488 emit(opcode); |
| 489 emit_modrm(reg, rm_reg); |
| 490 } |
| 476 } | 491 } |
| 477 | 492 |
| 478 | 493 |
| 479 void Assembler::arithmetic_op_16(byte opcode, | 494 void Assembler::arithmetic_op_16(byte opcode, |
| 480 Register reg, | 495 Register reg, |
| 481 const Operand& rm_reg) { | 496 const Operand& rm_reg) { |
| 482 EnsureSpace ensure_space(this); | 497 EnsureSpace ensure_space(this); |
| 483 last_pc_ = pc_; | 498 last_pc_ = pc_; |
| 484 emit(0x66); | 499 emit(0x66); |
| 485 emit_optional_rex_32(reg, rm_reg); | 500 emit_optional_rex_32(reg, rm_reg); |
| 486 emit(opcode); | 501 emit(opcode); |
| 487 emit_operand(reg, rm_reg); | 502 emit_operand(reg, rm_reg); |
| 488 } | 503 } |
| 489 | 504 |
| 490 | 505 |
| 491 void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) { | 506 void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) { |
| 492 EnsureSpace ensure_space(this); | 507 EnsureSpace ensure_space(this); |
| 493 last_pc_ = pc_; | 508 last_pc_ = pc_; |
| 494 emit_optional_rex_32(reg, rm_reg); | 509 ASSERT((opcode & 0xC6) == 2); |
| 495 emit(opcode); | 510 if (rm_reg.low_bits() == 4) { // Forces SIB byte. |
| 496 emit_modrm(reg, rm_reg); | 511 emit_optional_rex_32(rm_reg, reg); |
| 512 emit(opcode ^ 0x02); // E.g. 0x03 -> 0x01 for ADD. |
| 513 emit_modrm(rm_reg, reg); |
| 514 } else { |
| 515 emit_optional_rex_32(reg, rm_reg); |
| 516 emit(opcode); |
| 517 emit_modrm(reg, rm_reg); |
| 518 } |
| 497 } | 519 } |
| 498 | 520 |
| 499 | 521 |
| 500 void Assembler::arithmetic_op_32(byte opcode, | 522 void Assembler::arithmetic_op_32(byte opcode, |
| 501 Register reg, | 523 Register reg, |
| 502 const Operand& rm_reg) { | 524 const Operand& rm_reg) { |
| 503 EnsureSpace ensure_space(this); | 525 EnsureSpace ensure_space(this); |
| 504 last_pc_ = pc_; | 526 last_pc_ = pc_; |
| 505 emit_optional_rex_32(reg, rm_reg); | 527 emit_optional_rex_32(reg, rm_reg); |
| 506 emit(opcode); | 528 emit(opcode); |
| (...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1285 last_pc_ = pc_; | 1307 last_pc_ = pc_; |
| 1286 emit_optional_rex_32(dst, src); | 1308 emit_optional_rex_32(dst, src); |
| 1287 emit(0x8B); | 1309 emit(0x8B); |
| 1288 emit_operand(dst, src); | 1310 emit_operand(dst, src); |
| 1289 } | 1311 } |
| 1290 | 1312 |
| 1291 | 1313 |
| 1292 void Assembler::movl(Register dst, Register src) { | 1314 void Assembler::movl(Register dst, Register src) { |
| 1293 EnsureSpace ensure_space(this); | 1315 EnsureSpace ensure_space(this); |
| 1294 last_pc_ = pc_; | 1316 last_pc_ = pc_; |
| 1295 emit_optional_rex_32(dst, src); | 1317 if (src.low_bits() == 4) { |
| 1296 emit(0x8B); | 1318 emit_optional_rex_32(src, dst); |
| 1297 emit_modrm(dst, src); | 1319 emit(0x89); |
| 1320 emit_modrm(src, dst); |
| 1321 } else { |
| 1322 emit_optional_rex_32(dst, src); |
| 1323 emit(0x8B); |
| 1324 emit_modrm(dst, src); |
| 1325 } |
| 1298 } | 1326 } |
| 1299 | 1327 |
| 1300 | 1328 |
| 1301 void Assembler::movl(const Operand& dst, Register src) { | 1329 void Assembler::movl(const Operand& dst, Register src) { |
| 1302 EnsureSpace ensure_space(this); | 1330 EnsureSpace ensure_space(this); |
| 1303 last_pc_ = pc_; | 1331 last_pc_ = pc_; |
| 1304 emit_optional_rex_32(src, dst); | 1332 emit_optional_rex_32(src, dst); |
| 1305 emit(0x89); | 1333 emit(0x89); |
| 1306 emit_operand(src, dst); | 1334 emit_operand(src, dst); |
| 1307 } | 1335 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1332 last_pc_ = pc_; | 1360 last_pc_ = pc_; |
| 1333 emit_rex_64(dst, src); | 1361 emit_rex_64(dst, src); |
| 1334 emit(0x8B); | 1362 emit(0x8B); |
| 1335 emit_operand(dst, src); | 1363 emit_operand(dst, src); |
| 1336 } | 1364 } |
| 1337 | 1365 |
| 1338 | 1366 |
| 1339 void Assembler::movq(Register dst, Register src) { | 1367 void Assembler::movq(Register dst, Register src) { |
| 1340 EnsureSpace ensure_space(this); | 1368 EnsureSpace ensure_space(this); |
| 1341 last_pc_ = pc_; | 1369 last_pc_ = pc_; |
| 1342 emit_rex_64(dst, src); | 1370 if (src.low_bits() == 4) { |
| 1343 emit(0x8B); | 1371 emit_rex_64(src, dst); |
| 1344 emit_modrm(dst, src); | 1372 emit(0x89); |
| 1373 emit_modrm(src, dst); |
| 1374 } else { |
| 1375 emit_rex_64(dst, src); |
| 1376 emit(0x8B); |
| 1377 emit_modrm(dst, src); |
| 1378 } |
| 1345 } | 1379 } |
| 1346 | 1380 |
| 1347 | 1381 |
| 1348 void Assembler::movq(Register dst, Immediate value) { | 1382 void Assembler::movq(Register dst, Immediate value) { |
| 1349 EnsureSpace ensure_space(this); | 1383 EnsureSpace ensure_space(this); |
| 1350 last_pc_ = pc_; | 1384 last_pc_ = pc_; |
| 1351 emit_rex_64(dst); | 1385 emit_rex_64(dst); |
| 1352 emit(0xC7); | 1386 emit(0xC7); |
| 1353 emit_modrm(0x0, dst); | 1387 emit_modrm(0x0, dst); |
| 1354 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. | 1388 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1855 } | 1889 } |
| 1856 | 1890 |
| 1857 | 1891 |
| 1858 void Assembler::xchg(Register dst, Register src) { | 1892 void Assembler::xchg(Register dst, Register src) { |
| 1859 EnsureSpace ensure_space(this); | 1893 EnsureSpace ensure_space(this); |
| 1860 last_pc_ = pc_; | 1894 last_pc_ = pc_; |
| 1861 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding | 1895 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding |
| 1862 Register other = src.is(rax) ? dst : src; | 1896 Register other = src.is(rax) ? dst : src; |
| 1863 emit_rex_64(other); | 1897 emit_rex_64(other); |
| 1864 emit(0x90 | other.low_bits()); | 1898 emit(0x90 | other.low_bits()); |
| 1899 } else if (dst.low_bits() == 4) { |
| 1900 emit_rex_64(dst, src); |
| 1901 emit(0x87); |
| 1902 emit_modrm(dst, src); |
| 1865 } else { | 1903 } else { |
| 1866 emit_rex_64(src, dst); | 1904 emit_rex_64(src, dst); |
| 1867 emit(0x87); | 1905 emit(0x87); |
| 1868 emit_modrm(src, dst); | 1906 emit_modrm(src, dst); |
| 1869 } | 1907 } |
| 1870 } | 1908 } |
| 1871 | 1909 |
| 1872 | 1910 |
| 1873 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) { | 1911 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) { |
| 1874 EnsureSpace ensure_space(this); | 1912 EnsureSpace ensure_space(this); |
| 1875 last_pc_ = pc_; | 1913 last_pc_ = pc_; |
| 1876 emit(0x48); // REX.W | 1914 emit(0x48); // REX.W |
| 1877 emit(0xA3); | 1915 emit(0xA3); |
| 1878 emitq(reinterpret_cast<uintptr_t>(dst), mode); | 1916 emitq(reinterpret_cast<uintptr_t>(dst), mode); |
| 1879 } | 1917 } |
| 1880 | 1918 |
| 1881 | 1919 |
| 1882 void Assembler::store_rax(ExternalReference ref) { | 1920 void Assembler::store_rax(ExternalReference ref) { |
| 1883 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE); | 1921 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE); |
| 1884 } | 1922 } |
| 1885 | 1923 |
| 1886 | 1924 |
| 1887 void Assembler::testb(Register dst, Register src) { | 1925 void Assembler::testb(Register dst, Register src) { |
| 1888 EnsureSpace ensure_space(this); | 1926 EnsureSpace ensure_space(this); |
| 1889 last_pc_ = pc_; | 1927 last_pc_ = pc_; |
| 1890 if (dst.code() > 3 || src.code() > 3) { | 1928 if (src.low_bits() == 4) { |
| 1891 // Register is not one of al, bl, cl, dl. Its encoding needs REX. | 1929 emit_rex_32(src, dst); |
| 1892 emit_rex_32(dst, src); | 1930 emit(0x84); |
| 1931 emit_modrm(src, dst); |
| 1932 } else { |
| 1933 if (dst.code() > 3 || src.code() > 3) { |
| 1934 // Register is not one of al, bl, cl, dl. Its encoding needs REX. |
| 1935 emit_rex_32(dst, src); |
| 1936 } |
| 1937 emit(0x84); |
| 1938 emit_modrm(dst, src); |
| 1893 } | 1939 } |
| 1894 emit(0x84); | |
| 1895 emit_modrm(dst, src); | |
| 1896 } | 1940 } |
| 1897 | 1941 |
| 1898 | 1942 |
| 1899 void Assembler::testb(Register reg, Immediate mask) { | 1943 void Assembler::testb(Register reg, Immediate mask) { |
| 1900 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_)); | 1944 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_)); |
| 1901 EnsureSpace ensure_space(this); | 1945 EnsureSpace ensure_space(this); |
| 1902 last_pc_ = pc_; | 1946 last_pc_ = pc_; |
| 1903 if (reg.is(rax)) { | 1947 if (reg.is(rax)) { |
| 1904 emit(0xA8); | 1948 emit(0xA8); |
| 1905 emit(mask.value_); // Low byte emitted. | 1949 emit(mask.value_); // Low byte emitted. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1936 emit_optional_rex_32(reg, op); | 1980 emit_optional_rex_32(reg, op); |
| 1937 } | 1981 } |
| 1938 emit(0x84); | 1982 emit(0x84); |
| 1939 emit_operand(reg, op); | 1983 emit_operand(reg, op); |
| 1940 } | 1984 } |
| 1941 | 1985 |
| 1942 | 1986 |
| 1943 void Assembler::testl(Register dst, Register src) { | 1987 void Assembler::testl(Register dst, Register src) { |
| 1944 EnsureSpace ensure_space(this); | 1988 EnsureSpace ensure_space(this); |
| 1945 last_pc_ = pc_; | 1989 last_pc_ = pc_; |
| 1946 emit_optional_rex_32(dst, src); | 1990 if (src.low_bits() == 4) { |
| 1947 emit(0x85); | 1991 emit_optional_rex_32(src, dst); |
| 1948 emit_modrm(dst, src); | 1992 emit(0x85); |
| 1993 emit_modrm(src, dst); |
| 1994 } else { |
| 1995 emit_optional_rex_32(dst, src); |
| 1996 emit(0x85); |
| 1997 emit_modrm(dst, src); |
| 1998 } |
| 1949 } | 1999 } |
| 1950 | 2000 |
| 1951 | 2001 |
| 1952 void Assembler::testl(Register reg, Immediate mask) { | 2002 void Assembler::testl(Register reg, Immediate mask) { |
| 1953 // testl with a mask that fits in the low byte is exactly testb. | 2003 // testl with a mask that fits in the low byte is exactly testb. |
| 1954 if (is_uint8(mask.value_)) { | 2004 if (is_uint8(mask.value_)) { |
| 1955 testb(reg, mask); | 2005 testb(reg, mask); |
| 1956 return; | 2006 return; |
| 1957 } | 2007 } |
| 1958 EnsureSpace ensure_space(this); | 2008 EnsureSpace ensure_space(this); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1989 last_pc_ = pc_; | 2039 last_pc_ = pc_; |
| 1990 emit_rex_64(reg, op); | 2040 emit_rex_64(reg, op); |
| 1991 emit(0x85); | 2041 emit(0x85); |
| 1992 emit_operand(reg, op); | 2042 emit_operand(reg, op); |
| 1993 } | 2043 } |
| 1994 | 2044 |
| 1995 | 2045 |
| 1996 void Assembler::testq(Register dst, Register src) { | 2046 void Assembler::testq(Register dst, Register src) { |
| 1997 EnsureSpace ensure_space(this); | 2047 EnsureSpace ensure_space(this); |
| 1998 last_pc_ = pc_; | 2048 last_pc_ = pc_; |
| 1999 emit_rex_64(dst, src); | 2049 if (src.low_bits() == 4) { |
| 2000 emit(0x85); | 2050 emit_rex_64(src, dst); |
| 2001 emit_modrm(dst, src); | 2051 emit(0x85); |
| 2052 emit_modrm(src, dst); |
| 2053 } else { |
| 2054 emit_rex_64(dst, src); |
| 2055 emit(0x85); |
| 2056 emit_modrm(dst, src); |
| 2057 } |
| 2002 } | 2058 } |
| 2003 | 2059 |
| 2004 | 2060 |
| 2005 void Assembler::testq(Register dst, Immediate mask) { | 2061 void Assembler::testq(Register dst, Immediate mask) { |
| 2006 EnsureSpace ensure_space(this); | 2062 EnsureSpace ensure_space(this); |
| 2007 last_pc_ = pc_; | 2063 last_pc_ = pc_; |
| 2008 if (dst.is(rax)) { | 2064 if (dst.is(rax)) { |
| 2009 emit_rex_64(); | 2065 emit_rex_64(); |
| 2010 emit(0xA9); | 2066 emit(0xA9); |
| 2011 emit(mask); | 2067 emit(mask); |
| (...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2737 } | 2793 } |
| 2738 | 2794 |
| 2739 | 2795 |
| 2740 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | | 2796 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | |
| 2741 1 << RelocInfo::INTERNAL_REFERENCE | | 2797 1 << RelocInfo::INTERNAL_REFERENCE | |
| 2742 1 << RelocInfo::JS_RETURN; | 2798 1 << RelocInfo::JS_RETURN; |
| 2743 | 2799 |
| 2744 } } // namespace v8::internal | 2800 } } // namespace v8::internal |
| 2745 | 2801 |
| 2746 #endif // V8_TARGET_ARCH_X64 | 2802 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |