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