1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 2 // All Rights Reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions 6 // are met: 7 // 8 // - Redistributions of source code must retain the above copyright notice, 9 // this list of conditions and the following disclaimer. 10 // 11 // - Redistribution in binary form must reproduce the above copyright 12 // notice, this list of conditions and the following disclaimer in the 13 // documentation and/or other materials provided with the 14 // distribution. 15 // 16 // - Neither the name of Sun Microsystems or the names of contributors may 17 // be used to endorse or promote products derived from this software without 18 // specific prior written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31 // OF THE POSSIBILITY OF SUCH DAMAGE. 32 33 // The original source code covered by the above license above has been modified 34 // significantly by Google Inc. 35 // Copyright 2012 the V8 project authors. All rights reserved. 36 37 #include "src/v8.h" 38 39 #if V8_TARGET_ARCH_X87 40 41 #include "src/disassembler.h" 42 #include "src/macro-assembler.h" 43 #include "src/serialize.h" 44 45 namespace v8 { 46 namespace internal { 47 48 // ----------------------------------------------------------------------------- 49 // Implementation of CpuFeatures 50 51 void CpuFeatures::ProbeImpl(bool cross_compile) { 52 CPU cpu; 53 54 // Only use statically determined features for cross compile (snapshot). 55 if (cross_compile) return; 56 } 57 58 59 void CpuFeatures::PrintTarget() { } 60 void CpuFeatures::PrintFeatures() { } 61 62 63 // ----------------------------------------------------------------------------- 64 // Implementation of Displacement 65 66 void Displacement::init(Label* L, Type type) { 67 ASSERT(!L->is_bound()); 68 int next = 0; 69 if (L->is_linked()) { 70 next = L->pos(); 71 ASSERT(next > 0); // Displacements must be at positions > 0 72 } 73 // Ensure that we _never_ overflow the next field. 74 ASSERT(NextField::is_valid(Assembler::kMaximalBufferSize)); 75 data_ = NextField::encode(next) | TypeField::encode(type); 76 } 77 78 79 // ----------------------------------------------------------------------------- 80 // Implementation of RelocInfo 81 82 83 const int RelocInfo::kApplyMask = 84 RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY | 85 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE | 86 1 << RelocInfo::DEBUG_BREAK_SLOT | 1 << RelocInfo::CODE_AGE_SEQUENCE; 87 88 89 bool RelocInfo::IsCodedSpecially() { 90 // The deserializer needs to know whether a pointer is specially coded. Being 91 // specially coded on IA32 means that it is a relative address, as used by 92 // branch instructions. These are also the ones that need changing when a 93 // code object moves. 94 return (1 << rmode_) & kApplyMask; 95 } 96 97 98 bool RelocInfo::IsInConstantPool() { 99 return false; 100 } 101 102 103 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { 104 // Patch the code at the current address with the supplied instructions. 105 for (int i = 0; i < instruction_count; i++) { 106 *(pc_ + i) = *(instructions + i); 107 } 108 109 // Indicate that code has changed. 110 CPU::FlushICache(pc_, instruction_count); 111 } 112 113 114 // Patch the code at the current PC with a call to the target address. 115 // Additional guard int3 instructions can be added if required. 116 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { 117 // Call instruction takes up 5 bytes and int3 takes up one byte. 118 static const int kCallCodeSize = 5; 119 int code_size = kCallCodeSize + guard_bytes; 120 121 // Create a code patcher. 122 CodePatcher patcher(pc_, code_size); 123 124 // Add a label for checking the size of the code used for returning. 125 #ifdef DEBUG 126 Label check_codesize; 127 patcher.masm()->bind(&check_codesize); 128 #endif 129 130 // Patch the code. 131 patcher.masm()->call(target, RelocInfo::NONE32); 132 133 // Check that the size of the code generated is as expected. 134 ASSERT_EQ(kCallCodeSize, 135 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize)); 136 137 // Add the requested number of int3 instructions after the call. 138 ASSERT_GE(guard_bytes, 0); 139 for (int i = 0; i < guard_bytes; i++) { 140 patcher.masm()->int3(); 141 } 142 } 143 144 145 // ----------------------------------------------------------------------------- 146 // Implementation of Operand 147 148 Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) { 149 // [base + disp/r] 150 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) { 151 // [base] 152 set_modrm(0, base); 153 if (base.is(esp)) set_sib(times_1, esp, base); 154 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) { 155 // [base + disp8] 156 set_modrm(1, base); 157 if (base.is(esp)) set_sib(times_1, esp, base); 158 set_disp8(disp); 159 } else { 160 // [base + disp/r] 161 set_modrm(2, base); 162 if (base.is(esp)) set_sib(times_1, esp, base); 163 set_dispr(disp, rmode); 164 } 165 } 166 167 168 Operand::Operand(Register base, 169 Register index, 170 ScaleFactor scale, 171 int32_t disp, 172 RelocInfo::Mode rmode) { 173 ASSERT(!index.is(esp)); // illegal addressing mode 174 // [base + index*scale + disp/r] 175 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) { 176 // [base + index*scale] 177 set_modrm(0, esp); 178 set_sib(scale, index, base); 179 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) { 180 // [base + index*scale + disp8] 181 set_modrm(1, esp); 182 set_sib(scale, index, base); 183 set_disp8(disp); 184 } else { 185 // [base + index*scale + disp/r] 186 set_modrm(2, esp); 187 set_sib(scale, index, base); 188 set_dispr(disp, rmode); 189 } 190 } 191 192 193 Operand::Operand(Register index, 194 ScaleFactor scale, 195 int32_t disp, 196 RelocInfo::Mode rmode) { 197 ASSERT(!index.is(esp)); // illegal addressing mode 198 // [index*scale + disp/r] 199 set_modrm(0, esp); 200 set_sib(scale, index, ebp); 201 set_dispr(disp, rmode); 202 } 203 204 205 bool Operand::is_reg(Register reg) const { 206 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. 207 && ((buf_[0] & 0x07) == reg.code()); // register codes match. 208 } 209 210 211 bool Operand::is_reg_only() const { 212 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. 213 } 214 215 216 Register Operand::reg() const { 217 ASSERT(is_reg_only()); 218 return Register::from_code(buf_[0] & 0x07); 219 } 220 221 222 // ----------------------------------------------------------------------------- 223 // Implementation of Assembler. 224 225 // Emit a single byte. Must always be inlined. 226 #define EMIT(x) \ 227 *pc_++ = (x) 228 229 230 #ifdef GENERATED_CODE_COVERAGE 231 static void InitCoverageLog(); 232 #endif 233 234 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 235 : AssemblerBase(isolate, buffer, buffer_size), 236 positions_recorder_(this) { 237 // Clear the buffer in debug mode unless it was provided by the 238 // caller in which case we can't be sure it's okay to overwrite 239 // existing code in it; see CodePatcher::CodePatcher(...). 240 #ifdef DEBUG 241 if (own_buffer_) { 242 memset(buffer_, 0xCC, buffer_size_); // int3 243 } 244 #endif 245 246 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); 247 248 #ifdef GENERATED_CODE_COVERAGE 249 InitCoverageLog(); 250 #endif 251 } 252 253 254 void Assembler::GetCode(CodeDesc* desc) { 255 // Finalize code (at this point overflow() may be true, but the gap ensures 256 // that we are still not overlapping instructions and relocation info). 257 ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap. 258 // Set up code descriptor. 259 desc->buffer = buffer_; 260 desc->buffer_size = buffer_size_; 261 desc->instr_size = pc_offset(); 262 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 263 desc->origin = this; 264 } 265 266 267 void Assembler::Align(int m) { 268 ASSERT(IsPowerOf2(m)); 269 int mask = m - 1; 270 int addr = pc_offset(); 271 Nop((m - (addr & mask)) & mask); 272 } 273 274 275 bool Assembler::IsNop(Address addr) { 276 Address a = addr; 277 while (*a == 0x66) a++; 278 if (*a == 0x90) return true; 279 if (a[0] == 0xf && a[1] == 0x1f) return true; 280 return false; 281 } 282 283 284 void Assembler::Nop(int bytes) { 285 EnsureSpace ensure_space(this); 286 287 // Older CPUs that do not support SSE2 may not support multibyte NOP 288 // instructions. 289 for (; bytes > 0; bytes--) { 290 EMIT(0x90); 291 } 292 return; 293 } 294 295 296 void Assembler::CodeTargetAlign() { 297 Align(16); // Preferred alignment of jump targets on ia32. 298 } 299 300 301 void Assembler::cpuid() { 302 EnsureSpace ensure_space(this); 303 EMIT(0x0F); 304 EMIT(0xA2); 305 } 306 307 308 void Assembler::pushad() { 309 EnsureSpace ensure_space(this); 310 EMIT(0x60); 311 } 312 313 314 void Assembler::popad() { 315 EnsureSpace ensure_space(this); 316 EMIT(0x61); 317 } 318 319 320 void Assembler::pushfd() { 321 EnsureSpace ensure_space(this); 322 EMIT(0x9C); 323 } 324 325 326 void Assembler::popfd() { 327 EnsureSpace ensure_space(this); 328 EMIT(0x9D); 329 } 330 331 332 void Assembler::push(const Immediate& x) { 333 EnsureSpace ensure_space(this); 334 if (x.is_int8()) { 335 EMIT(0x6a); 336 EMIT(x.x_); 337 } else { 338 EMIT(0x68); 339 emit(x); 340 } 341 } 342 343 344 void Assembler::push_imm32(int32_t imm32) { 345 EnsureSpace ensure_space(this); 346 EMIT(0x68); 347 emit(imm32); 348 } 349 350 351 void Assembler::push(Register src) { 352 EnsureSpace ensure_space(this); 353 EMIT(0x50 | src.code()); 354 } 355 356 357 void Assembler::push(const Operand& src) { 358 EnsureSpace ensure_space(this); 359 EMIT(0xFF); 360 emit_operand(esi, src); 361 } 362 363 364 void Assembler::pop(Register dst) { 365 ASSERT(reloc_info_writer.last_pc() != NULL); 366 EnsureSpace ensure_space(this); 367 EMIT(0x58 | dst.code()); 368 } 369 370 371 void Assembler::pop(const Operand& dst) { 372 EnsureSpace ensure_space(this); 373 EMIT(0x8F); 374 emit_operand(eax, dst); 375 } 376 377 378 void Assembler::enter(const Immediate& size) { 379 EnsureSpace ensure_space(this); 380 EMIT(0xC8); 381 emit_w(size); 382 EMIT(0); 383 } 384 385 386 void Assembler::leave() { 387 EnsureSpace ensure_space(this); 388 EMIT(0xC9); 389 } 390 391 392 void Assembler::mov_b(Register dst, const Operand& src) { 393 CHECK(dst.is_byte_register()); 394 EnsureSpace ensure_space(this); 395 EMIT(0x8A); 396 emit_operand(dst, src); 397 } 398 399 400 void Assembler::mov_b(const Operand& dst, int8_t imm8) { 401 EnsureSpace ensure_space(this); 402 EMIT(0xC6); 403 emit_operand(eax, dst); 404 EMIT(imm8); 405 } 406 407 408 void Assembler::mov_b(const Operand& dst, Register src) { 409 CHECK(src.is_byte_register()); 410 EnsureSpace ensure_space(this); 411 EMIT(0x88); 412 emit_operand(src, dst); 413 } 414 415 416 void Assembler::mov_w(Register dst, const Operand& src) { 417 EnsureSpace ensure_space(this); 418 EMIT(0x66); 419 EMIT(0x8B); 420 emit_operand(dst, src); 421 } 422 423 424 void Assembler::mov_w(const Operand& dst, Register src) { 425 EnsureSpace ensure_space(this); 426 EMIT(0x66); 427 EMIT(0x89); 428 emit_operand(src, dst); 429 } 430 431 432 void Assembler::mov_w(const Operand& dst, int16_t imm16) { 433 EnsureSpace ensure_space(this); 434 EMIT(0x66); 435 EMIT(0xC7); 436 emit_operand(eax, dst); 437 EMIT(static_cast<int8_t>(imm16 & 0xff)); 438 EMIT(static_cast<int8_t>(imm16 >> 8)); 439 } 440 441 442 void Assembler::mov(Register dst, int32_t imm32) { 443 EnsureSpace ensure_space(this); 444 EMIT(0xB8 | dst.code()); 445 emit(imm32); 446 } 447 448 449 void Assembler::mov(Register dst, const Immediate& x) { 450 EnsureSpace ensure_space(this); 451 EMIT(0xB8 | dst.code()); 452 emit(x); 453 } 454 455 456 void Assembler::mov(Register dst, Handle<Object> handle) { 457 EnsureSpace ensure_space(this); 458 EMIT(0xB8 | dst.code()); 459 emit(handle); 460 } 461 462 463 void Assembler::mov(Register dst, const Operand& src) { 464 EnsureSpace ensure_space(this); 465 EMIT(0x8B); 466 emit_operand(dst, src); 467 } 468 469 470 void Assembler::mov(Register dst, Register src) { 471 EnsureSpace ensure_space(this); 472 EMIT(0x89); 473 EMIT(0xC0 | src.code() << 3 | dst.code()); 474 } 475 476 477 void Assembler::mov(const Operand& dst, const Immediate& x) { 478 EnsureSpace ensure_space(this); 479 EMIT(0xC7); 480 emit_operand(eax, dst); 481 emit(x); 482 } 483 484 485 void Assembler::mov(const Operand& dst, Handle<Object> handle) { 486 EnsureSpace ensure_space(this); 487 EMIT(0xC7); 488 emit_operand(eax, dst); 489 emit(handle); 490 } 491 492 493 void Assembler::mov(const Operand& dst, Register src) { 494 EnsureSpace ensure_space(this); 495 EMIT(0x89); 496 emit_operand(src, dst); 497 } 498 499 500 void Assembler::movsx_b(Register dst, const Operand& src) { 501 EnsureSpace ensure_space(this); 502 EMIT(0x0F); 503 EMIT(0xBE); 504 emit_operand(dst, src); 505 } 506 507 508 void Assembler::movsx_w(Register dst, const Operand& src) { 509 EnsureSpace ensure_space(this); 510 EMIT(0x0F); 511 EMIT(0xBF); 512 emit_operand(dst, src); 513 } 514 515 516 void Assembler::movzx_b(Register dst, const Operand& src) { 517 EnsureSpace ensure_space(this); 518 EMIT(0x0F); 519 EMIT(0xB6); 520 emit_operand(dst, src); 521 } 522 523 524 void Assembler::movzx_w(Register dst, const Operand& src) { 525 EnsureSpace ensure_space(this); 526 EMIT(0x0F); 527 EMIT(0xB7); 528 emit_operand(dst, src); 529 } 530 531 532 void Assembler::cld() { 533 EnsureSpace ensure_space(this); 534 EMIT(0xFC); 535 } 536 537 538 void Assembler::rep_movs() { 539 EnsureSpace ensure_space(this); 540 EMIT(0xF3); 541 EMIT(0xA5); 542 } 543 544 545 void Assembler::rep_stos() { 546 EnsureSpace ensure_space(this); 547 EMIT(0xF3); 548 EMIT(0xAB); 549 } 550 551 552 void Assembler::stos() { 553 EnsureSpace ensure_space(this); 554 EMIT(0xAB); 555 } 556 557 558 void Assembler::xchg(Register dst, Register src) { 559 EnsureSpace ensure_space(this); 560 if (src.is(eax) || dst.is(eax)) { // Single-byte encoding. 561 EMIT(0x90 | (src.is(eax) ? dst.code() : src.code())); 562 } else { 563 EMIT(0x87); 564 EMIT(0xC0 | src.code() << 3 | dst.code()); 565 } 566 } 567 568 569 void Assembler::adc(Register dst, int32_t imm32) { 570 EnsureSpace ensure_space(this); 571 emit_arith(2, Operand(dst), Immediate(imm32)); 572 } 573 574 575 void Assembler::adc(Register dst, const Operand& src) { 576 EnsureSpace ensure_space(this); 577 EMIT(0x13); 578 emit_operand(dst, src); 579 } 580 581 582 void Assembler::add(Register dst, const Operand& src) { 583 EnsureSpace ensure_space(this); 584 EMIT(0x03); 585 emit_operand(dst, src); 586 } 587 588 589 void Assembler::add(const Operand& dst, Register src) { 590 EnsureSpace ensure_space(this); 591 EMIT(0x01); 592 emit_operand(src, dst); 593 } 594 595 596 void Assembler::add(const Operand& dst, const Immediate& x) { 597 ASSERT(reloc_info_writer.last_pc() != NULL); 598 EnsureSpace ensure_space(this); 599 emit_arith(0, dst, x); 600 } 601 602 603 void Assembler::and_(Register dst, int32_t imm32) { 604 and_(dst, Immediate(imm32)); 605 } 606 607 608 void Assembler::and_(Register dst, const Immediate& x) { 609 EnsureSpace ensure_space(this); 610 emit_arith(4, Operand(dst), x); 611 } 612 613 614 void Assembler::and_(Register dst, const Operand& src) { 615 EnsureSpace ensure_space(this); 616 EMIT(0x23); 617 emit_operand(dst, src); 618 } 619 620 621 void Assembler::and_(const Operand& dst, const Immediate& x) { 622 EnsureSpace ensure_space(this); 623 emit_arith(4, dst, x); 624 } 625 626 627 void Assembler::and_(const Operand& dst, Register src) { 628 EnsureSpace ensure_space(this); 629 EMIT(0x21); 630 emit_operand(src, dst); 631 } 632 633 634 void Assembler::cmpb(const Operand& op, int8_t imm8) { 635 EnsureSpace ensure_space(this); 636 if (op.is_reg(eax)) { 637 EMIT(0x3C); 638 } else { 639 EMIT(0x80); 640 emit_operand(edi, op); // edi == 7 641 } 642 EMIT(imm8); 643 } 644 645 646 void Assembler::cmpb(const Operand& op, Register reg) { 647 CHECK(reg.is_byte_register()); 648 EnsureSpace ensure_space(this); 649 EMIT(0x38); 650 emit_operand(reg, op); 651 } 652 653 654 void Assembler::cmpb(Register reg, const Operand& op) { 655 CHECK(reg.is_byte_register()); 656 EnsureSpace ensure_space(this); 657 EMIT(0x3A); 658 emit_operand(reg, op); 659 } 660 661 662 void Assembler::cmpw(const Operand& op, Immediate imm16) { 663 ASSERT(imm16.is_int16()); 664 EnsureSpace ensure_space(this); 665 EMIT(0x66); 666 EMIT(0x81); 667 emit_operand(edi, op); 668 emit_w(imm16); 669 } 670 671 672 void Assembler::cmp(Register reg, int32_t imm32) { 673 EnsureSpace ensure_space(this); 674 emit_arith(7, Operand(reg), Immediate(imm32)); 675 } 676 677 678 void Assembler::cmp(Register reg, Handle<Object> handle) { 679 EnsureSpace ensure_space(this); 680 emit_arith(7, Operand(reg), Immediate(handle)); 681 } 682 683 684 void Assembler::cmp(Register reg, const Operand& op) { 685 EnsureSpace ensure_space(this); 686 EMIT(0x3B); 687 emit_operand(reg, op); 688 } 689 690 691 void Assembler::cmp(const Operand& op, const Immediate& imm) { 692 EnsureSpace ensure_space(this); 693 emit_arith(7, op, imm); 694 } 695 696 697 void Assembler::cmp(const Operand& op, Handle<Object> handle) { 698 EnsureSpace ensure_space(this); 699 emit_arith(7, op, Immediate(handle)); 700 } 701 702 703 void Assembler::cmpb_al(const Operand& op) { 704 EnsureSpace ensure_space(this); 705 EMIT(0x38); // CMP r/m8, r8 706 emit_operand(eax, op); // eax has same code as register al. 707 } 708 709 710 void Assembler::cmpw_ax(const Operand& op) { 711 EnsureSpace ensure_space(this); 712 EMIT(0x66); 713 EMIT(0x39); // CMP r/m16, r16 714 emit_operand(eax, op); // eax has same code as register ax. 715 } 716 717 718 void Assembler::dec_b(Register dst) { 719 CHECK(dst.is_byte_register()); 720 EnsureSpace ensure_space(this); 721 EMIT(0xFE); 722 EMIT(0xC8 | dst.code()); 723 } 724 725 726 void Assembler::dec_b(const Operand& dst) { 727 EnsureSpace ensure_space(this); 728 EMIT(0xFE); 729 emit_operand(ecx, dst); 730 } 731 732 733 void Assembler::dec(Register dst) { 734 EnsureSpace ensure_space(this); 735 EMIT(0x48 | dst.code()); 736 } 737 738 739 void Assembler::dec(const Operand& dst) { 740 EnsureSpace ensure_space(this); 741 EMIT(0xFF); 742 emit_operand(ecx, dst); 743 } 744 745 746 void Assembler::cdq() { 747 EnsureSpace ensure_space(this); 748 EMIT(0x99); 749 } 750 751 752 void Assembler::idiv(Register src) { 753 EnsureSpace ensure_space(this); 754 EMIT(0xF7); 755 EMIT(0xF8 | src.code()); 756 } 757 758 759 void Assembler::imul(Register reg) { 760 EnsureSpace ensure_space(this); 761 EMIT(0xF7); 762 EMIT(0xE8 | reg.code()); 763 } 764 765 766 void Assembler::imul(Register dst, const Operand& src) { 767 EnsureSpace ensure_space(this); 768 EMIT(0x0F); 769 EMIT(0xAF); 770 emit_operand(dst, src); 771 } 772 773 774 void Assembler::imul(Register dst, Register src, int32_t imm32) { 775 EnsureSpace ensure_space(this); 776 if (is_int8(imm32)) { 777 EMIT(0x6B); 778 EMIT(0xC0 | dst.code() << 3 | src.code()); 779 EMIT(imm32); 780 } else { 781 EMIT(0x69); 782 EMIT(0xC0 | dst.code() << 3 | src.code()); 783 emit(imm32); 784 } 785 } 786 787 788 void Assembler::inc(Register dst) { 789 EnsureSpace ensure_space(this); 790 EMIT(0x40 | dst.code()); 791 } 792 793 794 void Assembler::inc(const Operand& dst) { 795 EnsureSpace ensure_space(this); 796 EMIT(0xFF); 797 emit_operand(eax, dst); 798 } 799 800 801 void Assembler::lea(Register dst, const Operand& src) { 802 EnsureSpace ensure_space(this); 803 EMIT(0x8D); 804 emit_operand(dst, src); 805 } 806 807 808 void Assembler::mul(Register src) { 809 EnsureSpace ensure_space(this); 810 EMIT(0xF7); 811 EMIT(0xE0 | src.code()); 812 } 813 814 815 void Assembler::neg(Register dst) { 816 EnsureSpace ensure_space(this); 817 EMIT(0xF7); 818 EMIT(0xD8 | dst.code()); 819 } 820 821 822 void Assembler::not_(Register dst) { 823 EnsureSpace ensure_space(this); 824 EMIT(0xF7); 825 EMIT(0xD0 | dst.code()); 826 } 827 828 829 void Assembler::or_(Register dst, int32_t imm32) { 830 EnsureSpace ensure_space(this); 831 emit_arith(1, Operand(dst), Immediate(imm32)); 832 } 833 834 835 void Assembler::or_(Register dst, const Operand& src) { 836 EnsureSpace ensure_space(this); 837 EMIT(0x0B); 838 emit_operand(dst, src); 839 } 840 841 842 void Assembler::or_(const Operand& dst, const Immediate& x) { 843 EnsureSpace ensure_space(this); 844 emit_arith(1, dst, x); 845 } 846 847 848 void Assembler::or_(const Operand& dst, Register src) { 849 EnsureSpace ensure_space(this); 850 EMIT(0x09); 851 emit_operand(src, dst); 852 } 853 854 855 void Assembler::rcl(Register dst, uint8_t imm8) { 856 EnsureSpace ensure_space(this); 857 ASSERT(is_uint5(imm8)); // illegal shift count 858 if (imm8 == 1) { 859 EMIT(0xD1); 860 EMIT(0xD0 | dst.code()); 861 } else { 862 EMIT(0xC1); 863 EMIT(0xD0 | dst.code()); 864 EMIT(imm8); 865 } 866 } 867 868 869 void Assembler::rcr(Register dst, uint8_t imm8) { 870 EnsureSpace ensure_space(this); 871 ASSERT(is_uint5(imm8)); // illegal shift count 872 if (imm8 == 1) { 873 EMIT(0xD1); 874 EMIT(0xD8 | dst.code()); 875 } else { 876 EMIT(0xC1); 877 EMIT(0xD8 | dst.code()); 878 EMIT(imm8); 879 } 880 } 881 882 883 void Assembler::ror(Register dst, uint8_t imm8) { 884 EnsureSpace ensure_space(this); 885 ASSERT(is_uint5(imm8)); // illegal shift count 886 if (imm8 == 1) { 887 EMIT(0xD1); 888 EMIT(0xC8 | dst.code()); 889 } else { 890 EMIT(0xC1); 891 EMIT(0xC8 | dst.code()); 892 EMIT(imm8); 893 } 894 } 895 896 897 void Assembler::ror_cl(Register dst) { 898 EnsureSpace ensure_space(this); 899 EMIT(0xD3); 900 EMIT(0xC8 | dst.code()); 901 } 902 903 904 void Assembler::sar(Register dst, uint8_t imm8) { 905 EnsureSpace ensure_space(this); 906 ASSERT(is_uint5(imm8)); // illegal shift count 907 if (imm8 == 1) { 908 EMIT(0xD1); 909 EMIT(0xF8 | dst.code()); 910 } else { 911 EMIT(0xC1); 912 EMIT(0xF8 | dst.code()); 913 EMIT(imm8); 914 } 915 } 916 917 918 void Assembler::sar_cl(Register dst) { 919 EnsureSpace ensure_space(this); 920 EMIT(0xD3); 921 EMIT(0xF8 | dst.code()); 922 } 923 924 925 void Assembler::sbb(Register dst, const Operand& src) { 926 EnsureSpace ensure_space(this); 927 EMIT(0x1B); 928 emit_operand(dst, src); 929 } 930 931 932 void Assembler::shld(Register dst, const Operand& src) { 933 EnsureSpace ensure_space(this); 934 EMIT(0x0F); 935 EMIT(0xA5); 936 emit_operand(dst, src); 937 } 938 939 940 void Assembler::shl(Register dst, uint8_t imm8) { 941 EnsureSpace ensure_space(this); 942 ASSERT(is_uint5(imm8)); // illegal shift count 943 if (imm8 == 1) { 944 EMIT(0xD1); 945 EMIT(0xE0 | dst.code()); 946 } else { 947 EMIT(0xC1); 948 EMIT(0xE0 | dst.code()); 949 EMIT(imm8); 950 } 951 } 952 953 954 void Assembler::shl_cl(Register dst) { 955 EnsureSpace ensure_space(this); 956 EMIT(0xD3); 957 EMIT(0xE0 | dst.code()); 958 } 959 960 961 void Assembler::shrd(Register dst, const Operand& src) { 962 EnsureSpace ensure_space(this); 963 EMIT(0x0F); 964 EMIT(0xAD); 965 emit_operand(dst, src); 966 } 967 968 969 void Assembler::shr(Register dst, uint8_t imm8) { 970 EnsureSpace ensure_space(this); 971 ASSERT(is_uint5(imm8)); // illegal shift count 972 if (imm8 == 1) { 973 EMIT(0xD1); 974 EMIT(0xE8 | dst.code()); 975 } else { 976 EMIT(0xC1); 977 EMIT(0xE8 | dst.code()); 978 EMIT(imm8); 979 } 980 } 981 982 983 void Assembler::shr_cl(Register dst) { 984 EnsureSpace ensure_space(this); 985 EMIT(0xD3); 986 EMIT(0xE8 | dst.code()); 987 } 988 989 990 void Assembler::sub(const Operand& dst, const Immediate& x) { 991 EnsureSpace ensure_space(this); 992 emit_arith(5, dst, x); 993 } 994 995 996 void Assembler::sub(Register dst, const Operand& src) { 997 EnsureSpace ensure_space(this); 998 EMIT(0x2B); 999 emit_operand(dst, src); 1000 } 1001 1002 1003 void Assembler::sub(const Operand& dst, Register src) { 1004 EnsureSpace ensure_space(this); 1005 EMIT(0x29); 1006 emit_operand(src, dst); 1007 } 1008 1009 1010 void Assembler::test(Register reg, const Immediate& imm) { 1011 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) { 1012 test_b(reg, imm.x_); 1013 return; 1014 } 1015 1016 EnsureSpace ensure_space(this); 1017 // This is not using emit_arith because test doesn't support 1018 // sign-extension of 8-bit operands. 1019 if (reg.is(eax)) { 1020 EMIT(0xA9); 1021 } else { 1022 EMIT(0xF7); 1023 EMIT(0xC0 | reg.code()); 1024 } 1025 emit(imm); 1026 } 1027 1028 1029 void Assembler::test(Register reg, const Operand& op) { 1030 EnsureSpace ensure_space(this); 1031 EMIT(0x85); 1032 emit_operand(reg, op); 1033 } 1034 1035 1036 void Assembler::test_b(Register reg, const Operand& op) { 1037 CHECK(reg.is_byte_register()); 1038 EnsureSpace ensure_space(this); 1039 EMIT(0x84); 1040 emit_operand(reg, op); 1041 } 1042 1043 1044 void Assembler::test(const Operand& op, const Immediate& imm) { 1045 if (op.is_reg_only()) { 1046 test(op.reg(), imm); 1047 return; 1048 } 1049 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) { 1050 return test_b(op, imm.x_); 1051 } 1052 EnsureSpace ensure_space(this); 1053 EMIT(0xF7); 1054 emit_operand(eax, op); 1055 emit(imm); 1056 } 1057 1058 1059 void Assembler::test_b(Register reg, uint8_t imm8) { 1060 EnsureSpace ensure_space(this); 1061 // Only use test against byte for registers that have a byte 1062 // variant: eax, ebx, ecx, and edx. 1063 if (reg.is(eax)) { 1064 EMIT(0xA8); 1065 EMIT(imm8); 1066 } else if (reg.is_byte_register()) { 1067 emit_arith_b(0xF6, 0xC0, reg, imm8); 1068 } else { 1069 EMIT(0xF7); 1070 EMIT(0xC0 | reg.code()); 1071 emit(imm8); 1072 } 1073 } 1074 1075 1076 void Assembler::test_b(const Operand& op, uint8_t imm8) { 1077 if (op.is_reg_only()) { 1078 test_b(op.reg(), imm8); 1079 return; 1080 } 1081 EnsureSpace ensure_space(this); 1082 EMIT(0xF6); 1083 emit_operand(eax, op); 1084 EMIT(imm8); 1085 } 1086 1087 1088 void Assembler::xor_(Register dst, int32_t imm32) { 1089 EnsureSpace ensure_space(this); 1090 emit_arith(6, Operand(dst), Immediate(imm32)); 1091 } 1092 1093 1094 void Assembler::xor_(Register dst, const Operand& src) { 1095 EnsureSpace ensure_space(this); 1096 EMIT(0x33); 1097 emit_operand(dst, src); 1098 } 1099 1100 1101 void Assembler::xor_(const Operand& dst, Register src) { 1102 EnsureSpace ensure_space(this); 1103 EMIT(0x31); 1104 emit_operand(src, dst); 1105 } 1106 1107 1108 void Assembler::xor_(const Operand& dst, const Immediate& x) { 1109 EnsureSpace ensure_space(this); 1110 emit_arith(6, dst, x); 1111 } 1112 1113 1114 void Assembler::bt(const Operand& dst, Register src) { 1115 EnsureSpace ensure_space(this); 1116 EMIT(0x0F); 1117 EMIT(0xA3); 1118 emit_operand(src, dst); 1119 } 1120 1121 1122 void Assembler::bts(const Operand& dst, Register src) { 1123 EnsureSpace ensure_space(this); 1124 EMIT(0x0F); 1125 EMIT(0xAB); 1126 emit_operand(src, dst); 1127 } 1128 1129 1130 void Assembler::bsr(Register dst, const Operand& src) { 1131 EnsureSpace ensure_space(this); 1132 EMIT(0x0F); 1133 EMIT(0xBD); 1134 emit_operand(dst, src); 1135 } 1136 1137 1138 void Assembler::hlt() { 1139 EnsureSpace ensure_space(this); 1140 EMIT(0xF4); 1141 } 1142 1143 1144 void Assembler::int3() { 1145 EnsureSpace ensure_space(this); 1146 EMIT(0xCC); 1147 } 1148 1149 1150 void Assembler::nop() { 1151 EnsureSpace ensure_space(this); 1152 EMIT(0x90); 1153 } 1154 1155 1156 void Assembler::ret(int imm16) { 1157 EnsureSpace ensure_space(this); 1158 ASSERT(is_uint16(imm16)); 1159 if (imm16 == 0) { 1160 EMIT(0xC3); 1161 } else { 1162 EMIT(0xC2); 1163 EMIT(imm16 & 0xFF); 1164 EMIT((imm16 >> 8) & 0xFF); 1165 } 1166 } 1167 1168 1169 // Labels refer to positions in the (to be) generated code. 1170 // There are bound, linked, and unused labels. 1171 // 1172 // Bound labels refer to known positions in the already 1173 // generated code. pos() is the position the label refers to. 1174 // 1175 // Linked labels refer to unknown positions in the code 1176 // to be generated; pos() is the position of the 32bit 1177 // Displacement of the last instruction using the label. 1178 1179 1180 void Assembler::print(Label* L) { 1181 if (L->is_unused()) { 1182 PrintF("unused label\n"); 1183 } else if (L->is_bound()) { 1184 PrintF("bound label to %d\n", L->pos()); 1185 } else if (L->is_linked()) { 1186 Label l = *L; 1187 PrintF("unbound label"); 1188 while (l.is_linked()) { 1189 Displacement disp = disp_at(&l); 1190 PrintF("@ %d ", l.pos()); 1191 disp.print(); 1192 PrintF("\n"); 1193 disp.next(&l); 1194 } 1195 } else { 1196 PrintF("label in inconsistent state (pos = %d)\n", L->pos_); 1197 } 1198 } 1199 1200 1201 void Assembler::bind_to(Label* L, int pos) { 1202 EnsureSpace ensure_space(this); 1203 ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position 1204 while (L->is_linked()) { 1205 Displacement disp = disp_at(L); 1206 int fixup_pos = L->pos(); 1207 if (disp.type() == Displacement::CODE_RELATIVE) { 1208 // Relative to Code* heap object pointer. 1209 long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag); 1210 } else { 1211 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { 1212 ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected 1213 } 1214 // Relative address, relative to point after address. 1215 int imm32 = pos - (fixup_pos + sizeof(int32_t)); 1216 long_at_put(fixup_pos, imm32); 1217 } 1218 disp.next(L); 1219 } 1220 while (L->is_near_linked()) { 1221 int fixup_pos = L->near_link_pos(); 1222 int offset_to_next = 1223 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos))); 1224 ASSERT(offset_to_next <= 0); 1225 // Relative address, relative to point after address. 1226 int disp = pos - fixup_pos - sizeof(int8_t); 1227 CHECK(0 <= disp && disp <= 127); 1228 set_byte_at(fixup_pos, disp); 1229 if (offset_to_next < 0) { 1230 L->link_to(fixup_pos + offset_to_next, Label::kNear); 1231 } else { 1232 L->UnuseNear(); 1233 } 1234 } 1235 L->bind_to(pos); 1236 } 1237 1238 1239 void Assembler::bind(Label* L) { 1240 EnsureSpace ensure_space(this); 1241 ASSERT(!L->is_bound()); // label can only be bound once 1242 bind_to(L, pc_offset()); 1243 } 1244 1245 1246 void Assembler::call(Label* L) { 1247 positions_recorder()->WriteRecordedPositions(); 1248 EnsureSpace ensure_space(this); 1249 if (L->is_bound()) { 1250 const int long_size = 5; 1251 int offs = L->pos() - pc_offset(); 1252 ASSERT(offs <= 0); 1253 // 1110 1000 #32-bit disp. 1254 EMIT(0xE8); 1255 emit(offs - long_size); 1256 } else { 1257 // 1110 1000 #32-bit disp. 1258 EMIT(0xE8); 1259 emit_disp(L, Displacement::OTHER); 1260 } 1261 } 1262 1263 1264 void Assembler::call(byte* entry, RelocInfo::Mode rmode) { 1265 positions_recorder()->WriteRecordedPositions(); 1266 EnsureSpace ensure_space(this); 1267 ASSERT(!RelocInfo::IsCodeTarget(rmode)); 1268 EMIT(0xE8); 1269 if (RelocInfo::IsRuntimeEntry(rmode)) { 1270 emit(reinterpret_cast<uint32_t>(entry), rmode); 1271 } else { 1272 emit(entry - (pc_ + sizeof(int32_t)), rmode); 1273 } 1274 } 1275 1276 1277 int Assembler::CallSize(const Operand& adr) { 1278 // Call size is 1 (opcode) + adr.len_ (operand). 1279 return 1 + adr.len_; 1280 } 1281 1282 1283 void Assembler::call(const Operand& adr) { 1284 positions_recorder()->WriteRecordedPositions(); 1285 EnsureSpace ensure_space(this); 1286 EMIT(0xFF); 1287 emit_operand(edx, adr); 1288 } 1289 1290 1291 int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) { 1292 return 1 /* EMIT */ + sizeof(uint32_t) /* emit */; 1293 } 1294 1295 1296 void Assembler::call(Handle<Code> code, 1297 RelocInfo::Mode rmode, 1298 TypeFeedbackId ast_id) { 1299 positions_recorder()->WriteRecordedPositions(); 1300 EnsureSpace ensure_space(this); 1301 ASSERT(RelocInfo::IsCodeTarget(rmode) 1302 || rmode == RelocInfo::CODE_AGE_SEQUENCE); 1303 EMIT(0xE8); 1304 emit(code, rmode, ast_id); 1305 } 1306 1307 1308 void Assembler::jmp(Label* L, Label::Distance distance) { 1309 EnsureSpace ensure_space(this); 1310 if (L->is_bound()) { 1311 const int short_size = 2; 1312 const int long_size = 5; 1313 int offs = L->pos() - pc_offset(); 1314 ASSERT(offs <= 0); 1315 if (is_int8(offs - short_size)) { 1316 // 1110 1011 #8-bit disp. 1317 EMIT(0xEB); 1318 EMIT((offs - short_size) & 0xFF); 1319 } else { 1320 // 1110 1001 #32-bit disp. 1321 EMIT(0xE9); 1322 emit(offs - long_size); 1323 } 1324 } else if (distance == Label::kNear) { 1325 EMIT(0xEB); 1326 emit_near_disp(L); 1327 } else { 1328 // 1110 1001 #32-bit disp. 1329 EMIT(0xE9); 1330 emit_disp(L, Displacement::UNCONDITIONAL_JUMP); 1331 } 1332 } 1333 1334 1335 void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) { 1336 EnsureSpace ensure_space(this); 1337 ASSERT(!RelocInfo::IsCodeTarget(rmode)); 1338 EMIT(0xE9); 1339 if (RelocInfo::IsRuntimeEntry(rmode)) { 1340 emit(reinterpret_cast<uint32_t>(entry), rmode); 1341 } else { 1342 emit(entry - (pc_ + sizeof(int32_t)), rmode); 1343 } 1344 } 1345 1346 1347 void Assembler::jmp(const Operand& adr) { 1348 EnsureSpace ensure_space(this); 1349 EMIT(0xFF); 1350 emit_operand(esp, adr); 1351 } 1352 1353 1354 void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) { 1355 EnsureSpace ensure_space(this); 1356 ASSERT(RelocInfo::IsCodeTarget(rmode)); 1357 EMIT(0xE9); 1358 emit(code, rmode); 1359 } 1360 1361 1362 void Assembler::j(Condition cc, Label* L, Label::Distance distance) { 1363 EnsureSpace ensure_space(this); 1364 ASSERT(0 <= cc && static_cast<int>(cc) < 16); 1365 if (L->is_bound()) { 1366 const int short_size = 2; 1367 const int long_size = 6; 1368 int offs = L->pos() - pc_offset(); 1369 ASSERT(offs <= 0); 1370 if (is_int8(offs - short_size)) { 1371 // 0111 tttn #8-bit disp 1372 EMIT(0x70 | cc); 1373 EMIT((offs - short_size) & 0xFF); 1374 } else { 1375 // 0000 1111 1000 tttn #32-bit disp 1376 EMIT(0x0F); 1377 EMIT(0x80 | cc); 1378 emit(offs - long_size); 1379 } 1380 } else if (distance == Label::kNear) { 1381 EMIT(0x70 | cc); 1382 emit_near_disp(L); 1383 } else { 1384 // 0000 1111 1000 tttn #32-bit disp 1385 // Note: could eliminate cond. jumps to this jump if condition 1386 // is the same however, seems to be rather unlikely case. 1387 EMIT(0x0F); 1388 EMIT(0x80 | cc); 1389 emit_disp(L, Displacement::OTHER); 1390 } 1391 } 1392 1393 1394 void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) { 1395 EnsureSpace ensure_space(this); 1396 ASSERT((0 <= cc) && (static_cast<int>(cc) < 16)); 1397 // 0000 1111 1000 tttn #32-bit disp. 1398 EMIT(0x0F); 1399 EMIT(0x80 | cc); 1400 if (RelocInfo::IsRuntimeEntry(rmode)) { 1401 emit(reinterpret_cast<uint32_t>(entry), rmode); 1402 } else { 1403 emit(entry - (pc_ + sizeof(int32_t)), rmode); 1404 } 1405 } 1406 1407 1408 void Assembler::j(Condition cc, Handle<Code> code) { 1409 EnsureSpace ensure_space(this); 1410 // 0000 1111 1000 tttn #32-bit disp 1411 EMIT(0x0F); 1412 EMIT(0x80 | cc); 1413 emit(code, RelocInfo::CODE_TARGET); 1414 } 1415 1416 1417 // FPU instructions. 1418 1419 void Assembler::fld(int i) { 1420 EnsureSpace ensure_space(this); 1421 emit_farith(0xD9, 0xC0, i); 1422 } 1423 1424 1425 void Assembler::fstp(int i) { 1426 EnsureSpace ensure_space(this); 1427 emit_farith(0xDD, 0xD8, i); 1428 } 1429 1430 1431 void Assembler::fld1() { 1432 EnsureSpace ensure_space(this); 1433 EMIT(0xD9); 1434 EMIT(0xE8); 1435 } 1436 1437 1438 void Assembler::fldpi() { 1439 EnsureSpace ensure_space(this); 1440 EMIT(0xD9); 1441 EMIT(0xEB); 1442 } 1443 1444 1445 void Assembler::fldz() { 1446 EnsureSpace ensure_space(this); 1447 EMIT(0xD9); 1448 EMIT(0xEE); 1449 } 1450 1451 1452 void Assembler::fldln2() { 1453 EnsureSpace ensure_space(this); 1454 EMIT(0xD9); 1455 EMIT(0xED); 1456 } 1457 1458 1459 void Assembler::fld_s(const Operand& adr) { 1460 EnsureSpace ensure_space(this); 1461 EMIT(0xD9); 1462 emit_operand(eax, adr); 1463 } 1464 1465 1466 void Assembler::fld_d(const Operand& adr) { 1467 EnsureSpace ensure_space(this); 1468 EMIT(0xDD); 1469 emit_operand(eax, adr); 1470 } 1471 1472 1473 void Assembler::fstp_s(const Operand& adr) { 1474 EnsureSpace ensure_space(this); 1475 EMIT(0xD9); 1476 emit_operand(ebx, adr); 1477 } 1478 1479 1480 void Assembler::fst_s(const Operand& adr) { 1481 EnsureSpace ensure_space(this); 1482 EMIT(0xD9); 1483 emit_operand(edx, adr); 1484 } 1485 1486 1487 void Assembler::fstp_d(const Operand& adr) { 1488 EnsureSpace ensure_space(this); 1489 EMIT(0xDD); 1490 emit_operand(ebx, adr); 1491 } 1492 1493 1494 void Assembler::fst_d(const Operand& adr) { 1495 EnsureSpace ensure_space(this); 1496 EMIT(0xDD); 1497 emit_operand(edx, adr); 1498 } 1499 1500 1501 void Assembler::fild_s(const Operand& adr) { 1502 EnsureSpace ensure_space(this); 1503 EMIT(0xDB); 1504 emit_operand(eax, adr); 1505 } 1506 1507 1508 void Assembler::fild_d(const Operand& adr) { 1509 EnsureSpace ensure_space(this); 1510 EMIT(0xDF); 1511 emit_operand(ebp, adr); 1512 } 1513 1514 1515 void Assembler::fistp_s(const Operand& adr) { 1516 EnsureSpace ensure_space(this); 1517 EMIT(0xDB); 1518 emit_operand(ebx, adr); 1519 } 1520 1521 1522 void Assembler::fisttp_s(const Operand& adr) { 1523 ASSERT(IsEnabled(SSE3)); 1524 EnsureSpace ensure_space(this); 1525 EMIT(0xDB); 1526 emit_operand(ecx, adr); 1527 } 1528 1529 1530 void Assembler::fisttp_d(const Operand& adr) { 1531 ASSERT(IsEnabled(SSE3)); 1532 EnsureSpace ensure_space(this); 1533 EMIT(0xDD); 1534 emit_operand(ecx, adr); 1535 } 1536 1537 1538 void Assembler::fist_s(const Operand& adr) { 1539 EnsureSpace ensure_space(this); 1540 EMIT(0xDB); 1541 emit_operand(edx, adr); 1542 } 1543 1544 1545 void Assembler::fistp_d(const Operand& adr) { 1546 EnsureSpace ensure_space(this); 1547 EMIT(0xDF); 1548 emit_operand(edi, adr); 1549 } 1550 1551 1552 void Assembler::fabs() { 1553 EnsureSpace ensure_space(this); 1554 EMIT(0xD9); 1555 EMIT(0xE1); 1556 } 1557 1558 1559 void Assembler::fchs() { 1560 EnsureSpace ensure_space(this); 1561 EMIT(0xD9); 1562 EMIT(0xE0); 1563 } 1564 1565 1566 void Assembler::fcos() { 1567 EnsureSpace ensure_space(this); 1568 EMIT(0xD9); 1569 EMIT(0xFF); 1570 } 1571 1572 1573 void Assembler::fsin() { 1574 EnsureSpace ensure_space(this); 1575 EMIT(0xD9); 1576 EMIT(0xFE); 1577 } 1578 1579 1580 void Assembler::fptan() { 1581 EnsureSpace ensure_space(this); 1582 EMIT(0xD9); 1583 EMIT(0xF2); 1584 } 1585 1586 1587 void Assembler::fyl2x() { 1588 EnsureSpace ensure_space(this); 1589 EMIT(0xD9); 1590 EMIT(0xF1); 1591 } 1592 1593 1594 void Assembler::f2xm1() { 1595 EnsureSpace ensure_space(this); 1596 EMIT(0xD9); 1597 EMIT(0xF0); 1598 } 1599 1600 1601 void Assembler::fscale() { 1602 EnsureSpace ensure_space(this); 1603 EMIT(0xD9); 1604 EMIT(0xFD); 1605 } 1606 1607 1608 void Assembler::fninit() { 1609 EnsureSpace ensure_space(this); 1610 EMIT(0xDB); 1611 EMIT(0xE3); 1612 } 1613 1614 1615 void Assembler::fadd(int i) { 1616 EnsureSpace ensure_space(this); 1617 emit_farith(0xDC, 0xC0, i); 1618 } 1619 1620 1621 void Assembler::fadd_i(int i) { 1622 EnsureSpace ensure_space(this); 1623 emit_farith(0xD8, 0xC0, i); 1624 } 1625 1626 1627 void Assembler::fsub(int i) { 1628 EnsureSpace ensure_space(this); 1629 emit_farith(0xDC, 0xE8, i); 1630 } 1631 1632 1633 void Assembler::fsub_i(int i) { 1634 EnsureSpace ensure_space(this); 1635 emit_farith(0xD8, 0xE0, i); 1636 } 1637 1638 1639 void Assembler::fisub_s(const Operand& adr) { 1640 EnsureSpace ensure_space(this); 1641 EMIT(0xDA); 1642 emit_operand(esp, adr); 1643 } 1644 1645 1646 void Assembler::fmul_i(int i) { 1647 EnsureSpace ensure_space(this); 1648 emit_farith(0xD8, 0xC8, i); 1649 } 1650 1651 1652 void Assembler::fmul(int i) { 1653 EnsureSpace ensure_space(this); 1654 emit_farith(0xDC, 0xC8, i); 1655 } 1656 1657 1658 void Assembler::fdiv(int i) { 1659 EnsureSpace ensure_space(this); 1660 emit_farith(0xDC, 0xF8, i); 1661 } 1662 1663 1664 void Assembler::fdiv_i(int i) { 1665 EnsureSpace ensure_space(this); 1666 emit_farith(0xD8, 0xF0, i); 1667 } 1668 1669 1670 void Assembler::faddp(int i) { 1671 EnsureSpace ensure_space(this); 1672 emit_farith(0xDE, 0xC0, i); 1673 } 1674 1675 1676 void Assembler::fsubp(int i) { 1677 EnsureSpace ensure_space(this); 1678 emit_farith(0xDE, 0xE8, i); 1679 } 1680 1681 1682 void Assembler::fsubrp(int i) { 1683 EnsureSpace ensure_space(this); 1684 emit_farith(0xDE, 0xE0, i); 1685 } 1686 1687 1688 void Assembler::fmulp(int i) { 1689 EnsureSpace ensure_space(this); 1690 emit_farith(0xDE, 0xC8, i); 1691 } 1692 1693 1694 void Assembler::fdivp(int i) { 1695 EnsureSpace ensure_space(this); 1696 emit_farith(0xDE, 0xF8, i); 1697 } 1698 1699 1700 void Assembler::fprem() { 1701 EnsureSpace ensure_space(this); 1702 EMIT(0xD9); 1703 EMIT(0xF8); 1704 } 1705 1706 1707 void Assembler::fprem1() { 1708 EnsureSpace ensure_space(this); 1709 EMIT(0xD9); 1710 EMIT(0xF5); 1711 } 1712 1713 1714 void Assembler::fxch(int i) { 1715 EnsureSpace ensure_space(this); 1716 emit_farith(0xD9, 0xC8, i); 1717 } 1718 1719 1720 void Assembler::fincstp() { 1721 EnsureSpace ensure_space(this); 1722 EMIT(0xD9); 1723 EMIT(0xF7); 1724 } 1725 1726 1727 void Assembler::ffree(int i) { 1728 EnsureSpace ensure_space(this); 1729 emit_farith(0xDD, 0xC0, i); 1730 } 1731 1732 1733 void Assembler::ftst() { 1734 EnsureSpace ensure_space(this); 1735 EMIT(0xD9); 1736 EMIT(0xE4); 1737 } 1738 1739 1740 void Assembler::fucomp(int i) { 1741 EnsureSpace ensure_space(this); 1742 emit_farith(0xDD, 0xE8, i); 1743 } 1744 1745 1746 void Assembler::fucompp() { 1747 EnsureSpace ensure_space(this); 1748 EMIT(0xDA); 1749 EMIT(0xE9); 1750 } 1751 1752 1753 void Assembler::fucomi(int i) { 1754 EnsureSpace ensure_space(this); 1755 EMIT(0xDB); 1756 EMIT(0xE8 + i); 1757 } 1758 1759 1760 void Assembler::fucomip() { 1761 EnsureSpace ensure_space(this); 1762 EMIT(0xDF); 1763 EMIT(0xE9); 1764 } 1765 1766 1767 void Assembler::fcompp() { 1768 EnsureSpace ensure_space(this); 1769 EMIT(0xDE); 1770 EMIT(0xD9); 1771 } 1772 1773 1774 void Assembler::fnstsw_ax() { 1775 EnsureSpace ensure_space(this); 1776 EMIT(0xDF); 1777 EMIT(0xE0); 1778 } 1779 1780 1781 void Assembler::fwait() { 1782 EnsureSpace ensure_space(this); 1783 EMIT(0x9B); 1784 } 1785 1786 1787 void Assembler::frndint() { 1788 EnsureSpace ensure_space(this); 1789 EMIT(0xD9); 1790 EMIT(0xFC); 1791 } 1792 1793 1794 void Assembler::fnclex() { 1795 EnsureSpace ensure_space(this); 1796 EMIT(0xDB); 1797 EMIT(0xE2); 1798 } 1799 1800 1801 void Assembler::sahf() { 1802 EnsureSpace ensure_space(this); 1803 EMIT(0x9E); 1804 } 1805 1806 1807 void Assembler::setcc(Condition cc, Register reg) { 1808 ASSERT(reg.is_byte_register()); 1809 EnsureSpace ensure_space(this); 1810 EMIT(0x0F); 1811 EMIT(0x90 | cc); 1812 EMIT(0xC0 | reg.code()); 1813 } 1814 1815 1816 void Assembler::Print() { 1817 Disassembler::Decode(isolate(), stdout, buffer_, pc_); 1818 } 1819 1820 1821 void Assembler::RecordJSReturn() { 1822 positions_recorder()->WriteRecordedPositions(); 1823 EnsureSpace ensure_space(this); 1824 RecordRelocInfo(RelocInfo::JS_RETURN); 1825 } 1826 1827 1828 void Assembler::RecordDebugBreakSlot() { 1829 positions_recorder()->WriteRecordedPositions(); 1830 EnsureSpace ensure_space(this); 1831 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); 1832 } 1833 1834 1835 void Assembler::RecordComment(const char* msg, bool force) { 1836 if (FLAG_code_comments || force) { 1837 EnsureSpace ensure_space(this); 1838 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); 1839 } 1840 } 1841 1842 1843 void Assembler::GrowBuffer() { 1844 ASSERT(buffer_overflow()); 1845 if (!own_buffer_) FATAL("external code buffer is too small"); 1846 1847 // Compute new buffer size. 1848 CodeDesc desc; // the new buffer 1849 if (buffer_size_ < 4*KB) { 1850 desc.buffer_size = 4*KB; 1851 } else { 1852 desc.buffer_size = 2*buffer_size_; 1853 } 1854 // Some internal data structures overflow for very large buffers, 1855 // they must ensure that kMaximalBufferSize is not too large. 1856 if ((desc.buffer_size > kMaximalBufferSize) || 1857 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) { 1858 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); 1859 } 1860 1861 // Set up new buffer. 1862 desc.buffer = NewArray<byte>(desc.buffer_size); 1863 desc.instr_size = pc_offset(); 1864 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos()); 1865 1866 // Clear the buffer in debug mode. Use 'int3' instructions to make 1867 // sure to get into problems if we ever run uninitialized code. 1868 #ifdef DEBUG 1869 memset(desc.buffer, 0xCC, desc.buffer_size); 1870 #endif 1871 1872 // Copy the data. 1873 int pc_delta = desc.buffer - buffer_; 1874 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); 1875 MemMove(desc.buffer, buffer_, desc.instr_size); 1876 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(), 1877 desc.reloc_size); 1878 1879 // Switch buffers. 1880 if (isolate()->assembler_spare_buffer() == NULL && 1881 buffer_size_ == kMinimalBufferSize) { 1882 isolate()->set_assembler_spare_buffer(buffer_); 1883 } else { 1884 DeleteArray(buffer_); 1885 } 1886 buffer_ = desc.buffer; 1887 buffer_size_ = desc.buffer_size; 1888 pc_ += pc_delta; 1889 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 1890 reloc_info_writer.last_pc() + pc_delta); 1891 1892 // Relocate runtime entries. 1893 for (RelocIterator it(desc); !it.done(); it.next()) { 1894 RelocInfo::Mode rmode = it.rinfo()->rmode(); 1895 if (rmode == RelocInfo::INTERNAL_REFERENCE) { 1896 int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc()); 1897 if (*p != 0) { // 0 means uninitialized. 1898 *p += pc_delta; 1899 } 1900 } 1901 } 1902 1903 ASSERT(!buffer_overflow()); 1904 } 1905 1906 1907 void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { 1908 ASSERT(is_uint8(op1) && is_uint8(op2)); // wrong opcode 1909 ASSERT(is_uint8(imm8)); 1910 ASSERT((op1 & 0x01) == 0); // should be 8bit operation 1911 EMIT(op1); 1912 EMIT(op2 | dst.code()); 1913 EMIT(imm8); 1914 } 1915 1916 1917 void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) { 1918 ASSERT((0 <= sel) && (sel <= 7)); 1919 Register ireg = { sel }; 1920 if (x.is_int8()) { 1921 EMIT(0x83); // using a sign-extended 8-bit immediate. 1922 emit_operand(ireg, dst); 1923 EMIT(x.x_ & 0xFF); 1924 } else if (dst.is_reg(eax)) { 1925 EMIT((sel << 3) | 0x05); // short form if the destination is eax. 1926 emit(x); 1927 } else { 1928 EMIT(0x81); // using a literal 32-bit immediate. 1929 emit_operand(ireg, dst); 1930 emit(x); 1931 } 1932 } 1933 1934 1935 void Assembler::emit_operand(Register reg, const Operand& adr) { 1936 const unsigned length = adr.len_; 1937 ASSERT(length > 0); 1938 1939 // Emit updated ModRM byte containing the given register. 1940 pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3); 1941 1942 // Emit the rest of the encoded operand. 1943 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; 1944 pc_ += length; 1945 1946 // Emit relocation information if necessary. 1947 if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) { 1948 pc_ -= sizeof(int32_t); // pc_ must be *at* disp32 1949 RecordRelocInfo(adr.rmode_); 1950 pc_ += sizeof(int32_t); 1951 } 1952 } 1953 1954 1955 void Assembler::emit_farith(int b1, int b2, int i) { 1956 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode 1957 ASSERT(0 <= i && i < 8); // illegal stack offset 1958 EMIT(b1); 1959 EMIT(b2 + i); 1960 } 1961 1962 1963 void Assembler::db(uint8_t data) { 1964 EnsureSpace ensure_space(this); 1965 EMIT(data); 1966 } 1967 1968 1969 void Assembler::dd(uint32_t data) { 1970 EnsureSpace ensure_space(this); 1971 emit(data); 1972 } 1973 1974 1975 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 1976 ASSERT(!RelocInfo::IsNone(rmode)); 1977 // Don't record external references unless the heap will be serialized. 1978 if (rmode == RelocInfo::EXTERNAL_REFERENCE && 1979 !serializer_enabled() && !emit_debug_code()) { 1980 return; 1981 } 1982 RelocInfo rinfo(pc_, rmode, data, NULL); 1983 reloc_info_writer.Write(&rinfo); 1984 } 1985 1986 1987 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) { 1988 // No out-of-line constant pool support. 1989 ASSERT(!FLAG_enable_ool_constant_pool); 1990 return isolate->factory()->empty_constant_pool_array(); 1991 } 1992 1993 1994 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { 1995 // No out-of-line constant pool support. 1996 ASSERT(!FLAG_enable_ool_constant_pool); 1997 return; 1998 } 1999 2000 2001 #ifdef GENERATED_CODE_COVERAGE 2002 static FILE* coverage_log = NULL; 2003 2004 2005 static void InitCoverageLog() { 2006 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); 2007 if (file_name != NULL) { 2008 coverage_log = fopen(file_name, "aw+"); 2009 } 2010 } 2011 2012 2013 void LogGeneratedCodeCoverage(const char* file_line) { 2014 const char* return_address = (&file_line)[-1]; 2015 char* push_insn = const_cast<char*>(return_address - 12); 2016 push_insn[0] = 0xeb; // Relative branch insn. 2017 push_insn[1] = 13; // Skip over coverage insns. 2018 if (coverage_log != NULL) { 2019 fprintf(coverage_log, "%s\n", file_line); 2020 fflush(coverage_log); 2021 } 2022 } 2023 2024 #endif 2025 2026 } } // namespace v8::internal 2027 2028 #endif // V8_TARGET_ARCH_X87 2029