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