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 |