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

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

Issue 196139: X64: Convert smis to holding 32 bits of payload. (Closed)
Patch Set: Addressed review comments. Forwarded to head. Created 11 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
« no previous file with comments | « src/x64/assembler-x64.h ('k') | src/x64/assembler-x64-inl.h » ('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 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 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 last_pc_ = pc_; 701 last_pc_ = pc_;
702 emit_optional_rex_32(dst); 702 emit_optional_rex_32(dst);
703 emit(0xD3); 703 emit(0xD3);
704 emit_modrm(subcode, dst); 704 emit_modrm(subcode, dst);
705 } 705 }
706 706
707 707
708 void Assembler::shift_32(Register dst, Immediate shift_amount, int subcode) { 708 void Assembler::shift_32(Register dst, Immediate shift_amount, int subcode) {
709 EnsureSpace ensure_space(this); 709 EnsureSpace ensure_space(this);
710 last_pc_ = pc_; 710 last_pc_ = pc_;
711 ASSERT(is_uint6(shift_amount.value_)); // illegal shift count 711 ASSERT(is_uint5(shift_amount.value_)); // illegal shift count
712 if (shift_amount.value_ == 1) { 712 if (shift_amount.value_ == 1) {
713 emit_optional_rex_32(dst); 713 emit_optional_rex_32(dst);
714 emit(0xD1); 714 emit(0xD1);
715 emit_modrm(subcode, dst); 715 emit_modrm(subcode, dst);
716 } else { 716 } else {
717 emit_optional_rex_32(dst); 717 emit_optional_rex_32(dst);
718 emit(0xC1); 718 emit(0xC1);
719 emit_modrm(subcode, dst); 719 emit_modrm(subcode, dst);
720 emit(shift_amount.value_); 720 emit(shift_amount.value_);
721 } 721 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 void Assembler::call(const Operand& op) { 787 void Assembler::call(const Operand& op) {
788 EnsureSpace ensure_space(this); 788 EnsureSpace ensure_space(this);
789 last_pc_ = pc_; 789 last_pc_ = pc_;
790 // Opcode: FF /2 m64 790 // Opcode: FF /2 m64
791 emit_rex_64(op); 791 emit_rex_64(op);
792 emit(0xFF); 792 emit(0xFF);
793 emit_operand(2, op); 793 emit_operand(2, op);
794 } 794 }
795 795
796 796
797 void Assembler::clc() {
798 EnsureSpace ensure_space(this);
799 last_pc_ = pc_;
800 emit(0xF8);
801 }
802
797 void Assembler::cdq() { 803 void Assembler::cdq() {
798 EnsureSpace ensure_space(this); 804 EnsureSpace ensure_space(this);
799 last_pc_ = pc_; 805 last_pc_ = pc_;
800 emit(0x99); 806 emit(0x99);
801 } 807 }
802 808
803 809
804 void Assembler::cmovq(Condition cc, Register dst, Register src) { 810 void Assembler::cmovq(Condition cc, Register dst, Register src) {
811 if (cc == always) {
812 movq(dst, src);
813 } else if (cc == never) {
814 return;
815 }
805 // No need to check CpuInfo for CMOV support, it's a required part of the 816 // No need to check CpuInfo for CMOV support, it's a required part of the
806 // 64-bit architecture. 817 // 64-bit architecture.
807 ASSERT(cc >= 0); // Use mov for unconditional moves. 818 ASSERT(cc >= 0); // Use mov for unconditional moves.
808 EnsureSpace ensure_space(this); 819 EnsureSpace ensure_space(this);
809 last_pc_ = pc_; 820 last_pc_ = pc_;
810 // Opcode: REX.W 0f 40 + cc /r 821 // Opcode: REX.W 0f 40 + cc /r
811 emit_rex_64(dst, src); 822 emit_rex_64(dst, src);
812 emit(0x0f); 823 emit(0x0f);
813 emit(0x40 + cc); 824 emit(0x40 + cc);
814 emit_modrm(dst, src); 825 emit_modrm(dst, src);
815 } 826 }
816 827
817 828
818 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) { 829 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) {
830 if (cc == always) {
831 movq(dst, src);
832 } else if (cc == never) {
833 return;
834 }
819 ASSERT(cc >= 0); 835 ASSERT(cc >= 0);
820 EnsureSpace ensure_space(this); 836 EnsureSpace ensure_space(this);
821 last_pc_ = pc_; 837 last_pc_ = pc_;
822 // Opcode: REX.W 0f 40 + cc /r 838 // Opcode: REX.W 0f 40 + cc /r
823 emit_rex_64(dst, src); 839 emit_rex_64(dst, src);
824 emit(0x0f); 840 emit(0x0f);
825 emit(0x40 + cc); 841 emit(0x40 + cc);
826 emit_operand(dst, src); 842 emit_operand(dst, src);
827 } 843 }
828 844
829 845
830 void Assembler::cmovl(Condition cc, Register dst, Register src) { 846 void Assembler::cmovl(Condition cc, Register dst, Register src) {
847 if (cc == always) {
848 movl(dst, src);
849 } else if (cc == never) {
850 return;
851 }
831 ASSERT(cc >= 0); 852 ASSERT(cc >= 0);
832 EnsureSpace ensure_space(this); 853 EnsureSpace ensure_space(this);
833 last_pc_ = pc_; 854 last_pc_ = pc_;
834 // Opcode: 0f 40 + cc /r 855 // Opcode: 0f 40 + cc /r
835 emit_optional_rex_32(dst, src); 856 emit_optional_rex_32(dst, src);
836 emit(0x0f); 857 emit(0x0f);
837 emit(0x40 + cc); 858 emit(0x40 + cc);
838 emit_modrm(dst, src); 859 emit_modrm(dst, src);
839 } 860 }
840 861
841 862
842 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) { 863 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) {
864 if (cc == always) {
865 movl(dst, src);
866 } else if (cc == never) {
867 return;
868 }
843 ASSERT(cc >= 0); 869 ASSERT(cc >= 0);
844 EnsureSpace ensure_space(this); 870 EnsureSpace ensure_space(this);
845 last_pc_ = pc_; 871 last_pc_ = pc_;
846 // Opcode: 0f 40 + cc /r 872 // Opcode: 0f 40 + cc /r
847 emit_optional_rex_32(dst, src); 873 emit_optional_rex_32(dst, src);
848 emit(0x0f); 874 emit(0x0f);
849 emit(0x40 + cc); 875 emit(0x40 + cc);
850 emit_operand(dst, src); 876 emit_operand(dst, src);
851 } 877 }
852 878
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 1077
1052 1078
1053 void Assembler::int3() { 1079 void Assembler::int3() {
1054 EnsureSpace ensure_space(this); 1080 EnsureSpace ensure_space(this);
1055 last_pc_ = pc_; 1081 last_pc_ = pc_;
1056 emit(0xCC); 1082 emit(0xCC);
1057 } 1083 }
1058 1084
1059 1085
1060 void Assembler::j(Condition cc, Label* L) { 1086 void Assembler::j(Condition cc, Label* L) {
1087 if (cc == always) {
1088 jmp(L);
1089 return;
1090 } else if (cc == never) {
1091 return;
1092 }
1061 EnsureSpace ensure_space(this); 1093 EnsureSpace ensure_space(this);
1062 last_pc_ = pc_; 1094 last_pc_ = pc_;
1063 ASSERT(is_uint4(cc)); 1095 ASSERT(is_uint4(cc));
1064 if (L->is_bound()) { 1096 if (L->is_bound()) {
1065 const int short_size = 2; 1097 const int short_size = 2;
1066 const int long_size = 6; 1098 const int long_size = 6;
1067 int offs = L->pos() - pc_offset(); 1099 int offs = L->pos() - pc_offset();
1068 ASSERT(offs <= 0); 1100 ASSERT(offs <= 0);
1069 if (is_int8(offs - short_size)) { 1101 if (is_int8(offs - short_size)) {
1070 // 0111 tttn #8-bit disp 1102 // 0111 tttn #8-bit disp
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 } 1419 }
1388 1420
1389 1421
1390 void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) { 1422 void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) {
1391 // If there is no relocation info, emit the value of the handle efficiently 1423 // If there is no relocation info, emit the value of the handle efficiently
1392 // (possibly using less that 8 bytes for the value). 1424 // (possibly using less that 8 bytes for the value).
1393 if (mode == RelocInfo::NONE) { 1425 if (mode == RelocInfo::NONE) {
1394 // There is no possible reason to store a heap pointer without relocation 1426 // There is no possible reason to store a heap pointer without relocation
1395 // info, so it must be a smi. 1427 // info, so it must be a smi.
1396 ASSERT(value->IsSmi()); 1428 ASSERT(value->IsSmi());
1397 // Smis never have more than 32 significant bits, but they might 1429 movq(dst, reinterpret_cast<int64_t>(*value), RelocInfo::NONE);
1398 // have garbage in the high bits.
1399 movq(dst,
1400 Immediate(static_cast<int32_t>(reinterpret_cast<intptr_t>(*value))));
1401 } else { 1430 } else {
1402 EnsureSpace ensure_space(this); 1431 EnsureSpace ensure_space(this);
1403 last_pc_ = pc_; 1432 last_pc_ = pc_;
1404 ASSERT(value->IsHeapObject()); 1433 ASSERT(value->IsHeapObject());
1405 ASSERT(!Heap::InNewSpace(*value)); 1434 ASSERT(!Heap::InNewSpace(*value));
1406 emit_rex_64(dst); 1435 emit_rex_64(dst);
1407 emit(0xB8 | dst.low_bits()); 1436 emit(0xB8 | dst.low_bits());
1408 emitq(reinterpret_cast<uintptr_t>(value.location()), mode); 1437 emitq(reinterpret_cast<uintptr_t>(value.location()), mode);
1409 } 1438 }
1410 } 1439 }
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1664 } 1693 }
1665 1694
1666 1695
1667 void Assembler::pushfq() { 1696 void Assembler::pushfq() {
1668 EnsureSpace ensure_space(this); 1697 EnsureSpace ensure_space(this);
1669 last_pc_ = pc_; 1698 last_pc_ = pc_;
1670 emit(0x9C); 1699 emit(0x9C);
1671 } 1700 }
1672 1701
1673 1702
1674 void Assembler::rcl(Register dst, uint8_t imm8) {
1675 EnsureSpace ensure_space(this);
1676 last_pc_ = pc_;
1677 ASSERT(is_uint6(imm8)); // illegal shift count
1678 if (imm8 == 1) {
1679 emit_rex_64(dst);
1680 emit(0xD1);
1681 emit_modrm(0x2, dst);
1682 } else {
1683 emit_rex_64(dst);
1684 emit(0xC1);
1685 emit_modrm(0x2, dst);
1686 emit(imm8);
1687 }
1688 }
1689
1690 void Assembler::rdtsc() { 1703 void Assembler::rdtsc() {
1691 EnsureSpace ensure_space(this); 1704 EnsureSpace ensure_space(this);
1692 last_pc_ = pc_; 1705 last_pc_ = pc_;
1693 emit(0x0F); 1706 emit(0x0F);
1694 emit(0x31); 1707 emit(0x31);
1695 } 1708 }
1696 1709
1697 1710
1698 void Assembler::ret(int imm16) { 1711 void Assembler::ret(int imm16) {
1699 EnsureSpace ensure_space(this); 1712 EnsureSpace ensure_space(this);
1700 last_pc_ = pc_; 1713 last_pc_ = pc_;
1701 ASSERT(is_uint16(imm16)); 1714 ASSERT(is_uint16(imm16));
1702 if (imm16 == 0) { 1715 if (imm16 == 0) {
1703 emit(0xC3); 1716 emit(0xC3);
1704 } else { 1717 } else {
1705 emit(0xC2); 1718 emit(0xC2);
1706 emit(imm16 & 0xFF); 1719 emit(imm16 & 0xFF);
1707 emit((imm16 >> 8) & 0xFF); 1720 emit((imm16 >> 8) & 0xFF);
1708 } 1721 }
1709 } 1722 }
1710 1723
1711 1724
1712 void Assembler::setcc(Condition cc, Register reg) { 1725 void Assembler::setcc(Condition cc, Register reg) {
1726 if (cc > last_condition) {
1727 movb(reg, Immediate(cc == always ? 1 : 0));
1728 return;
1729 }
1713 EnsureSpace ensure_space(this); 1730 EnsureSpace ensure_space(this);
1714 last_pc_ = pc_; 1731 last_pc_ = pc_;
1715 ASSERT(is_uint4(cc)); 1732 ASSERT(is_uint4(cc));
1716 if (reg.code() > 3) { // Use x64 byte registers, where different. 1733 if (reg.code() > 3) { // Use x64 byte registers, where different.
1717 emit_rex_32(reg); 1734 emit_rex_32(reg);
1718 } 1735 }
1719 emit(0x0F); 1736 emit(0x0F);
1720 emit(0x90 | cc); 1737 emit(0x90 | cc);
1721 emit_modrm(0x0, reg); 1738 emit_modrm(0x0, reg);
1722 } 1739 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1764 emit(0xA3); 1781 emit(0xA3);
1765 emitq(reinterpret_cast<uintptr_t>(dst), mode); 1782 emitq(reinterpret_cast<uintptr_t>(dst), mode);
1766 } 1783 }
1767 1784
1768 1785
1769 void Assembler::store_rax(ExternalReference ref) { 1786 void Assembler::store_rax(ExternalReference ref) {
1770 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE); 1787 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1771 } 1788 }
1772 1789
1773 1790
1791 void Assembler::testb(Register dst, Register src) {
1792 EnsureSpace ensure_space(this);
1793 last_pc_ = pc_;
1794 if (dst.code() > 3 || src.code() > 3) {
1795 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1796 emit_rex_32(dst, src);
1797 }
1798 emit(0x84);
1799 emit_modrm(dst, src);
1800 }
1801
1802
1774 void Assembler::testb(Register reg, Immediate mask) { 1803 void Assembler::testb(Register reg, Immediate mask) {
1775 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_)); 1804 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
1776 EnsureSpace ensure_space(this); 1805 EnsureSpace ensure_space(this);
1777 last_pc_ = pc_; 1806 last_pc_ = pc_;
1778 if (reg.is(rax)) { 1807 if (reg.is(rax)) {
1779 emit(0xA8); 1808 emit(0xA8);
1780 emit(mask.value_); // Low byte emitted. 1809 emit(mask.value_); // Low byte emitted.
1781 } else { 1810 } else {
1782 if (reg.code() > 3) { 1811 if (reg.code() > 3) {
1783 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 1812 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
2438 written_position_ = current_position_; 2467 written_position_ = current_position_;
2439 } 2468 }
2440 } 2469 }
2441 2470
2442 2471
2443 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | 2472 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
2444 1 << RelocInfo::INTERNAL_REFERENCE | 2473 1 << RelocInfo::INTERNAL_REFERENCE |
2445 1 << RelocInfo::JS_RETURN; 2474 1 << RelocInfo::JS_RETURN;
2446 2475
2447 } } // namespace v8::internal 2476 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.h ('k') | src/x64/assembler-x64-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698