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