| 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 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 if (*p != 0) { // 0 means uninitialized. | 373 if (*p != 0) { // 0 means uninitialized. |
| 374 *p += pc_delta; | 374 *p += pc_delta; |
| 375 } | 375 } |
| 376 } | 376 } |
| 377 } | 377 } |
| 378 | 378 |
| 379 ASSERT(!overflow()); | 379 ASSERT(!overflow()); |
| 380 } | 380 } |
| 381 | 381 |
| 382 | 382 |
| 383 void Assembler::emit_operand(int rm, const Operand& adr) { | 383 void Assembler::emit_operand(int code, const Operand& adr) { |
| 384 ASSERT_EQ(rm & 0x07, rm); | 384 ASSERT(is_uint3(code)); |
| 385 const unsigned length = adr.len_; | 385 const unsigned length = adr.len_; |
| 386 ASSERT(length > 0); | 386 ASSERT(length > 0); |
| 387 | 387 |
| 388 // Emit updated ModR/M byte containing the given register. | 388 // Emit updated ModR/M byte containing the given register. |
| 389 pc_[0] = (adr.buf_[0] & ~0x38) | (rm << 3); | 389 ASSERT((adr.buf_[0] & 0x38) == 0); |
| 390 pc_[0] = adr.buf_[0] | code << 3; |
| 390 | 391 |
| 391 // Emit the rest of the encoded operand. | 392 // Emit the rest of the encoded operand. |
| 392 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; | 393 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; |
| 393 pc_ += length; | 394 pc_ += length; |
| 394 } | 395 } |
| 395 | 396 |
| 396 | 397 |
| 397 // Assembler Instruction implementations | 398 // Assembler Instruction implementations |
| 398 | 399 |
| 399 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) { | 400 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) { |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 emitl(current); | 587 emitl(current); |
| 587 L->link_to(current); | 588 L->link_to(current); |
| 588 } | 589 } |
| 589 } | 590 } |
| 590 | 591 |
| 591 | 592 |
| 592 void Assembler::call(Register adr) { | 593 void Assembler::call(Register adr) { |
| 593 EnsureSpace ensure_space(this); | 594 EnsureSpace ensure_space(this); |
| 594 last_pc_ = pc_; | 595 last_pc_ = pc_; |
| 595 // Opcode: FF /2 r64 | 596 // Opcode: FF /2 r64 |
| 596 if (adr.code() > 7) { | 597 if (adr.high_bit()) { |
| 597 emit_rex_64(adr); | 598 emit_rex_64(adr); |
| 598 } | 599 } |
| 599 emit(0xFF); | 600 emit(0xFF); |
| 600 emit_modrm(0x2, adr); | 601 emit_modrm(0x2, adr); |
| 601 } | 602 } |
| 602 | 603 |
| 603 | 604 |
| 604 void Assembler::call(const Operand& op) { | 605 void Assembler::call(const Operand& op) { |
| 605 EnsureSpace ensure_space(this); | 606 EnsureSpace ensure_space(this); |
| 606 last_pc_ = pc_; | 607 last_pc_ = pc_; |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 void Assembler::int3() { | 757 void Assembler::int3() { |
| 757 EnsureSpace ensure_space(this); | 758 EnsureSpace ensure_space(this); |
| 758 last_pc_ = pc_; | 759 last_pc_ = pc_; |
| 759 emit(0xCC); | 760 emit(0xCC); |
| 760 } | 761 } |
| 761 | 762 |
| 762 | 763 |
| 763 void Assembler::j(Condition cc, Label* L) { | 764 void Assembler::j(Condition cc, Label* L) { |
| 764 EnsureSpace ensure_space(this); | 765 EnsureSpace ensure_space(this); |
| 765 last_pc_ = pc_; | 766 last_pc_ = pc_; |
| 766 ASSERT(0 <= cc && cc < 16); | 767 ASSERT(is_uint4(cc)); |
| 767 if (L->is_bound()) { | 768 if (L->is_bound()) { |
| 768 const int short_size = 2; | 769 const int short_size = 2; |
| 769 const int long_size = 6; | 770 const int long_size = 6; |
| 770 int offs = L->pos() - pc_offset(); | 771 int offs = L->pos() - pc_offset(); |
| 771 ASSERT(offs <= 0); | 772 ASSERT(offs <= 0); |
| 772 if (is_int8(offs - short_size)) { | 773 if (is_int8(offs - short_size)) { |
| 773 // 0111 tttn #8-bit disp | 774 // 0111 tttn #8-bit disp |
| 774 emit(0x70 | cc); | 775 emit(0x70 | cc); |
| 775 emit((offs - short_size) & 0xFF); | 776 emit((offs - short_size) & 0xFF); |
| 776 } else { | 777 } else { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 emitl(current); | 825 emitl(current); |
| 825 L->link_to(current); | 826 L->link_to(current); |
| 826 } | 827 } |
| 827 } | 828 } |
| 828 | 829 |
| 829 | 830 |
| 830 void Assembler::jmp(Register target) { | 831 void Assembler::jmp(Register target) { |
| 831 EnsureSpace ensure_space(this); | 832 EnsureSpace ensure_space(this); |
| 832 last_pc_ = pc_; | 833 last_pc_ = pc_; |
| 833 // Opcode FF/4 r64 | 834 // Opcode FF/4 r64 |
| 834 if (target.code() > 7) { | 835 if (target.high_bit()) { |
| 835 emit_rex_64(target); | 836 emit_rex_64(target); |
| 836 } | 837 } |
| 837 emit(0xFF); | 838 emit(0xFF); |
| 838 emit_modrm(0x4, target); | 839 emit_modrm(0x4, target); |
| 839 } | 840 } |
| 840 | 841 |
| 841 | 842 |
| 842 void Assembler::lea(Register dst, const Operand& src) { | 843 void Assembler::lea(Register dst, const Operand& src) { |
| 843 EnsureSpace ensure_space(this); | 844 EnsureSpace ensure_space(this); |
| 844 last_pc_ = pc_; | 845 last_pc_ = pc_; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 emit_rex_64(src, dst); | 976 emit_rex_64(src, dst); |
| 976 emit(0x89); | 977 emit(0x89); |
| 977 emit_operand(src, dst); | 978 emit_operand(src, dst); |
| 978 } | 979 } |
| 979 | 980 |
| 980 | 981 |
| 981 void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) { | 982 void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) { |
| 982 EnsureSpace ensure_space(this); | 983 EnsureSpace ensure_space(this); |
| 983 last_pc_ = pc_; | 984 last_pc_ = pc_; |
| 984 emit_rex_64(dst); | 985 emit_rex_64(dst); |
| 985 emit(0xB8 | (dst.code() & 0x7)); | 986 emit(0xB8 | dst.low_bits()); |
| 986 emitq(reinterpret_cast<uintptr_t>(value), rmode); | 987 emitq(reinterpret_cast<uintptr_t>(value), rmode); |
| 987 } | 988 } |
| 988 | 989 |
| 989 | 990 |
| 990 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) { | 991 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) { |
| 991 EnsureSpace ensure_space(this); | 992 EnsureSpace ensure_space(this); |
| 992 last_pc_ = pc_; | 993 last_pc_ = pc_; |
| 993 emit_rex_64(dst); | 994 emit_rex_64(dst); |
| 994 emit(0xB8 | (dst.code() & 0x7)); // Not a ModR/M byte. | 995 emit(0xB8 | dst.low_bits()); |
| 995 emitq(value, rmode); | 996 emitq(value, rmode); |
| 996 } | 997 } |
| 997 | 998 |
| 998 | 999 |
| 999 void Assembler::movq(Register dst, ExternalReference ref) { | 1000 void Assembler::movq(Register dst, ExternalReference ref) { |
| 1000 EnsureSpace ensure_space(this); | 1001 EnsureSpace ensure_space(this); |
| 1001 last_pc_ = pc_; | 1002 last_pc_ = pc_; |
| 1002 emit_rex_64(dst); | 1003 emit_rex_64(dst); |
| 1003 emit(0xB8 | (dst.code() & 0x7)); | 1004 emit(0xB8 | dst.low_bits()); |
| 1004 emitq(reinterpret_cast<uintptr_t>(ref.address()), | 1005 emitq(reinterpret_cast<uintptr_t>(ref.address()), |
| 1005 RelocInfo::EXTERNAL_REFERENCE); | 1006 RelocInfo::EXTERNAL_REFERENCE); |
| 1006 } | 1007 } |
| 1007 | 1008 |
| 1008 | 1009 |
| 1009 void Assembler::movq(const Operand& dst, Immediate value) { | 1010 void Assembler::movq(const Operand& dst, Immediate value) { |
| 1010 EnsureSpace ensure_space(this); | 1011 EnsureSpace ensure_space(this); |
| 1011 last_pc_ = pc_; | 1012 last_pc_ = pc_; |
| 1012 emit_rex_64(dst); | 1013 emit_rex_64(dst); |
| 1013 emit(0xC7); | 1014 emit(0xC7); |
| 1014 emit_operand(0, dst); | 1015 emit_operand(0, dst); |
| 1015 emit(value); | 1016 emit(value); |
| 1016 } | 1017 } |
| 1017 | 1018 |
| 1018 | 1019 |
| 1019 void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) { | 1020 void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) { |
| 1020 EnsureSpace ensure_space(this); | 1021 EnsureSpace ensure_space(this); |
| 1021 last_pc_ = pc_; | 1022 last_pc_ = pc_; |
| 1022 ASSERT(!Heap::InNewSpace(*value)); | 1023 ASSERT(!Heap::InNewSpace(*value)); |
| 1023 emit_rex_64(dst); | 1024 emit_rex_64(dst); |
| 1024 emit(0xB8 | (dst.code() & 0x7)); | 1025 emit(0xB8 | dst.low_bits()); |
| 1025 if (value->IsHeapObject()) { | 1026 if (value->IsHeapObject()) { |
| 1026 emitq(reinterpret_cast<uintptr_t>(value.location()), mode); | 1027 emitq(reinterpret_cast<uintptr_t>(value.location()), mode); |
| 1027 } else { | 1028 } else { |
| 1028 ASSERT_EQ(RelocInfo::NONE, mode); | 1029 ASSERT_EQ(RelocInfo::NONE, mode); |
| 1029 emitq(reinterpret_cast<uintptr_t>(*value), RelocInfo::NONE); | 1030 emitq(reinterpret_cast<uintptr_t>(*value), RelocInfo::NONE); |
| 1030 } | 1031 } |
| 1031 } | 1032 } |
| 1032 | 1033 |
| 1033 | 1034 |
| 1034 void Assembler::movsxlq(Register dst, Register src) { | 1035 void Assembler::movsxlq(Register dst, Register src) { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1185 emit(0x00); | 1186 emit(0x00); |
| 1186 emit(0x00); | 1187 emit(0x00); |
| 1187 return; | 1188 return; |
| 1188 } | 1189 } |
| 1189 } | 1190 } |
| 1190 | 1191 |
| 1191 | 1192 |
| 1192 void Assembler::pop(Register dst) { | 1193 void Assembler::pop(Register dst) { |
| 1193 EnsureSpace ensure_space(this); | 1194 EnsureSpace ensure_space(this); |
| 1194 last_pc_ = pc_; | 1195 last_pc_ = pc_; |
| 1195 if (dst.code() > 7) { | 1196 if (dst.high_bit()) { |
| 1196 emit_rex_64(dst); | 1197 emit_rex_64(dst); |
| 1197 } | 1198 } |
| 1198 emit(0x58 | (dst.code() & 0x7)); | 1199 emit(0x58 | dst.low_bits()); |
| 1199 } | 1200 } |
| 1200 | 1201 |
| 1201 | 1202 |
| 1202 void Assembler::pop(const Operand& dst) { | 1203 void Assembler::pop(const Operand& dst) { |
| 1203 EnsureSpace ensure_space(this); | 1204 EnsureSpace ensure_space(this); |
| 1204 last_pc_ = pc_; | 1205 last_pc_ = pc_; |
| 1205 emit_rex_64(dst); // Could be omitted in some cases. | 1206 emit_rex_64(dst); // Could be omitted in some cases. |
| 1206 emit(0x8F); | 1207 emit(0x8F); |
| 1207 emit_operand(0, dst); | 1208 emit_operand(0, dst); |
| 1208 } | 1209 } |
| 1209 | 1210 |
| 1210 | 1211 |
| 1211 void Assembler::popfq() { | 1212 void Assembler::popfq() { |
| 1212 EnsureSpace ensure_space(this); | 1213 EnsureSpace ensure_space(this); |
| 1213 last_pc_ = pc_; | 1214 last_pc_ = pc_; |
| 1214 emit(0x9D); | 1215 emit(0x9D); |
| 1215 } | 1216 } |
| 1216 | 1217 |
| 1217 | 1218 |
| 1218 void Assembler::push(Register src) { | 1219 void Assembler::push(Register src) { |
| 1219 EnsureSpace ensure_space(this); | 1220 EnsureSpace ensure_space(this); |
| 1220 last_pc_ = pc_; | 1221 last_pc_ = pc_; |
| 1221 if (src.code() > 7) { | 1222 if (src.high_bit()) { |
| 1222 emit_rex_64(src); | 1223 emit_rex_64(src); |
| 1223 } | 1224 } |
| 1224 emit(0x50 | (src.code() & 0x7)); | 1225 emit(0x50 | src.low_bits()); |
| 1225 } | 1226 } |
| 1226 | 1227 |
| 1227 | 1228 |
| 1228 void Assembler::push(const Operand& src) { | 1229 void Assembler::push(const Operand& src) { |
| 1229 EnsureSpace ensure_space(this); | 1230 EnsureSpace ensure_space(this); |
| 1230 last_pc_ = pc_; | 1231 last_pc_ = pc_; |
| 1231 emit_rex_64(src); // Could be omitted in some cases. | 1232 emit_rex_64(src); // Could be omitted in some cases. |
| 1232 emit(0xFF); | 1233 emit(0xFF); |
| 1233 emit_operand(6, src); | 1234 emit_operand(6, src); |
| 1234 } | 1235 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1288 emit(0xC2); | 1289 emit(0xC2); |
| 1289 emit(imm16 & 0xFF); | 1290 emit(imm16 & 0xFF); |
| 1290 emit((imm16 >> 8) & 0xFF); | 1291 emit((imm16 >> 8) & 0xFF); |
| 1291 } | 1292 } |
| 1292 } | 1293 } |
| 1293 | 1294 |
| 1294 | 1295 |
| 1295 void Assembler::setcc(Condition cc, Register reg) { | 1296 void Assembler::setcc(Condition cc, Register reg) { |
| 1296 EnsureSpace ensure_space(this); | 1297 EnsureSpace ensure_space(this); |
| 1297 last_pc_ = pc_; | 1298 last_pc_ = pc_; |
| 1298 ASSERT(0 <= cc && cc < 16); | 1299 ASSERT(is_uint4(cc)); |
| 1299 if (reg.code() > 3) { // Use x64 byte registers, where different. | 1300 if (reg.code() > 3) { // Use x64 byte registers, where different. |
| 1300 emit_rex_32(reg); | 1301 emit_rex_32(reg); |
| 1301 } | 1302 } |
| 1302 emit(0x0F); | 1303 emit(0x0F); |
| 1303 emit(0x90 | cc); | 1304 emit(0x90 | cc); |
| 1304 emit_modrm(0x0, reg); | 1305 emit_modrm(0x0, reg); |
| 1305 } | 1306 } |
| 1306 | 1307 |
| 1307 | 1308 |
| 1308 void Assembler::shld(Register dst, Register src) { | 1309 void Assembler::shld(Register dst, Register src) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1324 emit_modrm(src, dst); | 1325 emit_modrm(src, dst); |
| 1325 } | 1326 } |
| 1326 | 1327 |
| 1327 | 1328 |
| 1328 void Assembler::xchg(Register dst, Register src) { | 1329 void Assembler::xchg(Register dst, Register src) { |
| 1329 EnsureSpace ensure_space(this); | 1330 EnsureSpace ensure_space(this); |
| 1330 last_pc_ = pc_; | 1331 last_pc_ = pc_; |
| 1331 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding | 1332 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding |
| 1332 Register other = src.is(rax) ? dst : src; | 1333 Register other = src.is(rax) ? dst : src; |
| 1333 emit_rex_64(other); | 1334 emit_rex_64(other); |
| 1334 emit(0x90 | (other.code() & 0x7)); | 1335 emit(0x90 | other.low_bits()); |
| 1335 } else { | 1336 } else { |
| 1336 emit_rex_64(src, dst); | 1337 emit_rex_64(src, dst); |
| 1337 emit(0x87); | 1338 emit(0x87); |
| 1338 emit_modrm(src, dst); | 1339 emit_modrm(src, dst); |
| 1339 } | 1340 } |
| 1340 } | 1341 } |
| 1341 | 1342 |
| 1342 | 1343 |
| 1343 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) { | 1344 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) { |
| 1344 EnsureSpace ensure_space(this); | 1345 EnsureSpace ensure_space(this); |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1748 void Assembler::fnclex() { | 1749 void Assembler::fnclex() { |
| 1749 EnsureSpace ensure_space(this); | 1750 EnsureSpace ensure_space(this); |
| 1750 last_pc_ = pc_; | 1751 last_pc_ = pc_; |
| 1751 emit(0xDB); | 1752 emit(0xDB); |
| 1752 emit(0xE2); | 1753 emit(0xE2); |
| 1753 } | 1754 } |
| 1754 | 1755 |
| 1755 | 1756 |
| 1756 void Assembler::emit_farith(int b1, int b2, int i) { | 1757 void Assembler::emit_farith(int b1, int b2, int i) { |
| 1757 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode | 1758 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode |
| 1758 ASSERT(0 <= i && i < 8); // illegal stack offset | 1759 ASSERT(is_uint3(i)); // illegal stack offset |
| 1759 emit(b1); | 1760 emit(b1); |
| 1760 emit(b2 + i); | 1761 emit(b2 + i); |
| 1761 } | 1762 } |
| 1762 | 1763 |
| 1763 | 1764 |
| 1764 // Relocation information implementations | 1765 // Relocation information implementations |
| 1765 | 1766 |
| 1766 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { | 1767 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
| 1767 ASSERT(rmode != RelocInfo::NONE); | 1768 ASSERT(rmode != RelocInfo::NONE); |
| 1768 // Don't record external references unless the heap will be serialized. | 1769 // Don't record external references unless the heap will be serialized. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1880 | 1881 |
| 1881 void CallIC::GenerateMegamorphic(MacroAssembler* a, int b) { | 1882 void CallIC::GenerateMegamorphic(MacroAssembler* a, int b) { |
| 1882 UNIMPLEMENTED(); | 1883 UNIMPLEMENTED(); |
| 1883 } | 1884 } |
| 1884 | 1885 |
| 1885 void CallIC::GenerateNormal(MacroAssembler* a, int b) { | 1886 void CallIC::GenerateNormal(MacroAssembler* a, int b) { |
| 1886 UNIMPLEMENTED(); | 1887 UNIMPLEMENTED(); |
| 1887 } | 1888 } |
| 1888 | 1889 |
| 1889 } } // namespace v8::internal | 1890 } } // namespace v8::internal |
| OLD | NEW |