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

Side by Side Diff: src/x64/assembler-x64.cc

Issue 2075010: X64: Make all arithmetic ops, and a few other, try to avoid rsp and r12 as base register. (Closed)
Patch Set: Created 10 years, 7 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
« no previous file with comments | « src/x64/assembler-x64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698