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