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