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 |