| OLD | NEW |
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 | 49 |
| 50 #include "src/base/bits.h" | 50 #include "src/base/bits.h" |
| 51 #include "src/base/cpu.h" | 51 #include "src/base/cpu.h" |
| 52 #include "src/disassembler.h" | 52 #include "src/disassembler.h" |
| 53 #include "src/macro-assembler.h" | 53 #include "src/macro-assembler.h" |
| 54 #include "src/v8.h" | 54 #include "src/v8.h" |
| 55 | 55 |
| 56 namespace v8 { | 56 namespace v8 { |
| 57 namespace internal { | 57 namespace internal { |
| 58 | 58 |
| 59 Immediate Immediate::EmbeddedNumber(double value) { |
| 60 int32_t smi; |
| 61 if (DoubleToSmiInteger(value, &smi)) return Immediate(Smi::FromInt(smi)); |
| 62 Immediate result(0, RelocInfo::EMBEDDED_OBJECT); |
| 63 result.is_heap_number_ = true; |
| 64 result.value_.heap_number = value; |
| 65 return result; |
| 66 } |
| 67 |
| 59 // ----------------------------------------------------------------------------- | 68 // ----------------------------------------------------------------------------- |
| 60 // Implementation of CpuFeatures | 69 // Implementation of CpuFeatures |
| 61 | 70 |
| 62 namespace { | 71 namespace { |
| 63 | 72 |
| 64 #if !V8_LIBC_MSVCRT | 73 #if !V8_LIBC_MSVCRT |
| 65 | 74 |
| 66 V8_INLINE uint64_t _xgetbv(unsigned int xcr) { | 75 V8_INLINE uint64_t _xgetbv(unsigned int xcr) { |
| 67 unsigned eax, edx; | 76 unsigned eax, edx; |
| 68 // Check xgetbv; this uses a .byte sequence instead of the instruction | 77 // Check xgetbv; this uses a .byte sequence instead of the instruction |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 // existing code in it; see CodePatcher::CodePatcher(...). | 322 // existing code in it; see CodePatcher::CodePatcher(...). |
| 314 #ifdef DEBUG | 323 #ifdef DEBUG |
| 315 if (own_buffer_) { | 324 if (own_buffer_) { |
| 316 memset(buffer_, 0xCC, buffer_size_); // int3 | 325 memset(buffer_, 0xCC, buffer_size_); // int3 |
| 317 } | 326 } |
| 318 #endif | 327 #endif |
| 319 | 328 |
| 320 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); | 329 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); |
| 321 } | 330 } |
| 322 | 331 |
| 323 | 332 void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) { |
| 324 void Assembler::GetCode(CodeDesc* desc) { | |
| 325 // Finalize code (at this point overflow() may be true, but the gap ensures | 333 // Finalize code (at this point overflow() may be true, but the gap ensures |
| 326 // that we are still not overlapping instructions and relocation info). | 334 // that we are still not overlapping instructions and relocation info). |
| 327 DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap. | 335 DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap. |
| 336 |
| 337 AllocateRequestedHeapNumbers(isolate); |
| 338 |
| 328 // Set up code descriptor. | 339 // Set up code descriptor. |
| 329 desc->buffer = buffer_; | 340 desc->buffer = buffer_; |
| 330 desc->buffer_size = buffer_size_; | 341 desc->buffer_size = buffer_size_; |
| 331 desc->instr_size = pc_offset(); | 342 desc->instr_size = pc_offset(); |
| 332 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); | 343 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); |
| 333 desc->origin = this; | 344 desc->origin = this; |
| 334 desc->constant_pool_size = 0; | 345 desc->constant_pool_size = 0; |
| 335 desc->unwinding_info_size = 0; | 346 desc->unwinding_info_size = 0; |
| 336 desc->unwinding_info = nullptr; | 347 desc->unwinding_info = nullptr; |
| 337 } | 348 } |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 void Assembler::popfd() { | 463 void Assembler::popfd() { |
| 453 EnsureSpace ensure_space(this); | 464 EnsureSpace ensure_space(this); |
| 454 EMIT(0x9D); | 465 EMIT(0x9D); |
| 455 } | 466 } |
| 456 | 467 |
| 457 | 468 |
| 458 void Assembler::push(const Immediate& x) { | 469 void Assembler::push(const Immediate& x) { |
| 459 EnsureSpace ensure_space(this); | 470 EnsureSpace ensure_space(this); |
| 460 if (x.is_int8()) { | 471 if (x.is_int8()) { |
| 461 EMIT(0x6a); | 472 EMIT(0x6a); |
| 462 EMIT(x.x_); | 473 EMIT(x.immediate()); |
| 463 } else { | 474 } else { |
| 464 EMIT(0x68); | 475 EMIT(0x68); |
| 465 emit(x); | 476 emit(x); |
| 466 } | 477 } |
| 467 } | 478 } |
| 468 | 479 |
| 469 | 480 |
| 470 void Assembler::push_imm32(int32_t imm32) { | 481 void Assembler::push_imm32(int32_t imm32) { |
| 471 EnsureSpace ensure_space(this); | 482 EnsureSpace ensure_space(this); |
| 472 EMIT(0x68); | 483 EMIT(0x68); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 EnsureSpace ensure_space(this); | 531 EnsureSpace ensure_space(this); |
| 521 EMIT(0x8A); | 532 EMIT(0x8A); |
| 522 emit_operand(dst, src); | 533 emit_operand(dst, src); |
| 523 } | 534 } |
| 524 | 535 |
| 525 | 536 |
| 526 void Assembler::mov_b(const Operand& dst, const Immediate& src) { | 537 void Assembler::mov_b(const Operand& dst, const Immediate& src) { |
| 527 EnsureSpace ensure_space(this); | 538 EnsureSpace ensure_space(this); |
| 528 EMIT(0xC6); | 539 EMIT(0xC6); |
| 529 emit_operand(eax, dst); | 540 emit_operand(eax, dst); |
| 530 EMIT(static_cast<int8_t>(src.x_)); | 541 EMIT(static_cast<int8_t>(src.immediate())); |
| 531 } | 542 } |
| 532 | 543 |
| 533 | 544 |
| 534 void Assembler::mov_b(const Operand& dst, Register src) { | 545 void Assembler::mov_b(const Operand& dst, Register src) { |
| 535 CHECK(src.is_byte_register()); | 546 CHECK(src.is_byte_register()); |
| 536 EnsureSpace ensure_space(this); | 547 EnsureSpace ensure_space(this); |
| 537 EMIT(0x88); | 548 EMIT(0x88); |
| 538 emit_operand(src, dst); | 549 emit_operand(src, dst); |
| 539 } | 550 } |
| 540 | 551 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 553 EMIT(0x89); | 564 EMIT(0x89); |
| 554 emit_operand(src, dst); | 565 emit_operand(src, dst); |
| 555 } | 566 } |
| 556 | 567 |
| 557 | 568 |
| 558 void Assembler::mov_w(const Operand& dst, const Immediate& src) { | 569 void Assembler::mov_w(const Operand& dst, const Immediate& src) { |
| 559 EnsureSpace ensure_space(this); | 570 EnsureSpace ensure_space(this); |
| 560 EMIT(0x66); | 571 EMIT(0x66); |
| 561 EMIT(0xC7); | 572 EMIT(0xC7); |
| 562 emit_operand(eax, dst); | 573 emit_operand(eax, dst); |
| 563 EMIT(static_cast<int8_t>(src.x_ & 0xff)); | 574 EMIT(static_cast<int8_t>(src.immediate() & 0xff)); |
| 564 EMIT(static_cast<int8_t>(src.x_ >> 8)); | 575 EMIT(static_cast<int8_t>(src.immediate() >> 8)); |
| 565 } | 576 } |
| 566 | 577 |
| 567 | 578 |
| 568 void Assembler::mov(Register dst, int32_t imm32) { | 579 void Assembler::mov(Register dst, int32_t imm32) { |
| 569 EnsureSpace ensure_space(this); | 580 EnsureSpace ensure_space(this); |
| 570 EMIT(0xB8 | dst.code()); | 581 EMIT(0xB8 | dst.code()); |
| 571 emit(imm32); | 582 emit(imm32); |
| 572 } | 583 } |
| 573 | 584 |
| 574 | 585 |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1297 | 1308 |
| 1298 void Assembler::test_b(Register reg, Immediate imm8) { | 1309 void Assembler::test_b(Register reg, Immediate imm8) { |
| 1299 DCHECK(imm8.is_uint8()); | 1310 DCHECK(imm8.is_uint8()); |
| 1300 EnsureSpace ensure_space(this); | 1311 EnsureSpace ensure_space(this); |
| 1301 // Only use test against byte for registers that have a byte | 1312 // Only use test against byte for registers that have a byte |
| 1302 // variant: eax, ebx, ecx, and edx. | 1313 // variant: eax, ebx, ecx, and edx. |
| 1303 if (reg.is(eax)) { | 1314 if (reg.is(eax)) { |
| 1304 EMIT(0xA8); | 1315 EMIT(0xA8); |
| 1305 emit_b(imm8); | 1316 emit_b(imm8); |
| 1306 } else if (reg.is_byte_register()) { | 1317 } else if (reg.is_byte_register()) { |
| 1307 emit_arith_b(0xF6, 0xC0, reg, static_cast<uint8_t>(imm8.x_)); | 1318 emit_arith_b(0xF6, 0xC0, reg, static_cast<uint8_t>(imm8.immediate())); |
| 1308 } else { | 1319 } else { |
| 1309 EMIT(0x66); | 1320 EMIT(0x66); |
| 1310 EMIT(0xF7); | 1321 EMIT(0xF7); |
| 1311 EMIT(0xC0 | reg.code()); | 1322 EMIT(0xC0 | reg.code()); |
| 1312 emit_w(imm8); | 1323 emit_w(imm8); |
| 1313 } | 1324 } |
| 1314 } | 1325 } |
| 1315 | 1326 |
| 1316 void Assembler::test_b(const Operand& op, Immediate imm8) { | 1327 void Assembler::test_b(const Operand& op, Immediate imm8) { |
| 1317 if (op.is_reg_only()) { | 1328 if (op.is_reg_only()) { |
| (...skipping 1749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3067 EMIT(imm8); | 3078 EMIT(imm8); |
| 3068 } | 3079 } |
| 3069 | 3080 |
| 3070 | 3081 |
| 3071 void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) { | 3082 void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) { |
| 3072 DCHECK((0 <= sel) && (sel <= 7)); | 3083 DCHECK((0 <= sel) && (sel <= 7)); |
| 3073 Register ireg = { sel }; | 3084 Register ireg = { sel }; |
| 3074 if (x.is_int8()) { | 3085 if (x.is_int8()) { |
| 3075 EMIT(0x83); // using a sign-extended 8-bit immediate. | 3086 EMIT(0x83); // using a sign-extended 8-bit immediate. |
| 3076 emit_operand(ireg, dst); | 3087 emit_operand(ireg, dst); |
| 3077 EMIT(x.x_ & 0xFF); | 3088 EMIT(x.immediate() & 0xFF); |
| 3078 } else if (dst.is_reg(eax)) { | 3089 } else if (dst.is_reg(eax)) { |
| 3079 EMIT((sel << 3) | 0x05); // short form if the destination is eax. | 3090 EMIT((sel << 3) | 0x05); // short form if the destination is eax. |
| 3080 emit(x); | 3091 emit(x); |
| 3081 } else { | 3092 } else { |
| 3082 EMIT(0x81); // using a literal 32-bit immediate. | 3093 EMIT(0x81); // using a literal 32-bit immediate. |
| 3083 emit_operand(ireg, dst); | 3094 emit_operand(ireg, dst); |
| 3084 emit(x); | 3095 emit(x); |
| 3085 } | 3096 } |
| 3086 } | 3097 } |
| 3087 | 3098 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3162 } | 3173 } |
| 3163 RelocInfo rinfo(pc_, rmode, data, NULL); | 3174 RelocInfo rinfo(pc_, rmode, data, NULL); |
| 3164 reloc_info_writer.Write(&rinfo); | 3175 reloc_info_writer.Write(&rinfo); |
| 3165 } | 3176 } |
| 3166 | 3177 |
| 3167 | 3178 |
| 3168 } // namespace internal | 3179 } // namespace internal |
| 3169 } // namespace v8 | 3180 } // namespace v8 |
| 3170 | 3181 |
| 3171 #endif // V8_TARGET_ARCH_IA32 | 3182 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |