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 "v8.h" 38 39 #if V8_TARGET_ARCH_IA32 40 41 #include "disassembler.h" 42 #include "macro-assembler.h" 43 #include "serialize.h" 44 45 namespace v8 { 46 namespace internal { 47 48 // ----------------------------------------------------------------------------- 49 // Implementation of CpuFeatures 50 51 #ifdef DEBUG 52 bool CpuFeatures::initialized_ = false; 53 #endif 54 uint64_t CpuFeatures::supported_ = 0; 55 uint64_t CpuFeatures::found_by_runtime_probing_only_ = 0; 56 uint64_t CpuFeatures::cross_compile_ = 0; 57 58 59 ExternalReference ExternalReference::cpu_features() { 60 ASSERT(CpuFeatures::initialized_); 61 return ExternalReference(&CpuFeatures::supported_); 62 } 63 64 65 int IntelDoubleRegister::NumAllocatableRegisters() { 66 if (CpuFeatures::IsSupported(SSE2)) { 67 return XMMRegister::kNumAllocatableRegisters; 68 } else { 69 return X87Register::kNumAllocatableRegisters; 70 } 71 } 72 73 74 int IntelDoubleRegister::NumRegisters() { 75 if (CpuFeatures::IsSupported(SSE2)) { 76 return XMMRegister::kNumRegisters; 77 } else { 78 return X87Register::kNumRegisters; 79 } 80 } 81 82 83 const char* IntelDoubleRegister::AllocationIndexToString(int index) { 84 if (CpuFeatures::IsSupported(SSE2)) { 85 return XMMRegister::AllocationIndexToString(index); 86 } else { 87 return X87Register::AllocationIndexToString(index); 88 } 89 } 90 91 92 void CpuFeatures::Probe() { 93 ASSERT(!initialized_); 94 ASSERT(supported_ == 0); 95 #ifdef DEBUG 96 initialized_ = true; 97 #endif 98 if (Serializer::enabled()) { 99 supported_ |= OS::CpuFeaturesImpliedByPlatform(); 100 return; // No features if we might serialize. 101 } 102 103 uint64_t probed_features = 0; 104 CPU cpu; 105 if (cpu.has_sse41()) { 106 probed_features |= static_cast<uint64_t>(1) << SSE4_1; 107 } 108 if (cpu.has_sse3()) { 109 probed_features |= static_cast<uint64_t>(1) << SSE3; 110 } 111 if (cpu.has_sse2()) { 112 probed_features |= static_cast<uint64_t>(1) << SSE2; 113 } 114 if (cpu.has_cmov()) { 115 probed_features |= static_cast<uint64_t>(1) << CMOV; 116 } 117 118 // SAHF must be available in compat/legacy mode. 119 ASSERT(cpu.has_sahf()); 120 probed_features |= static_cast<uint64_t>(1) << SAHF; 121 122 uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform(); 123 supported_ = probed_features | platform_features; 124 found_by_runtime_probing_only_ = probed_features & ~platform_features; 125 } 126 127 128 // ----------------------------------------------------------------------------- 129 // Implementation of Displacement 130 131 void Displacement::init(Label* L, Type type) { 132 ASSERT(!L->is_bound()); 133 int next = 0; 134 if (L->is_linked()) { 135 next = L->pos(); 136 ASSERT(next > 0); // Displacements must be at positions > 0 137 } 138 // Ensure that we _never_ overflow the next field. 139 ASSERT(NextField::is_valid(Assembler::kMaximalBufferSize)); 140 data_ = NextField::encode(next) | TypeField::encode(type); 141 } 142 143 144 // ----------------------------------------------------------------------------- 145 // Implementation of RelocInfo 146 147 148 const int RelocInfo::kApplyMask = 149 RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY | 150 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE | 151 1 << RelocInfo::DEBUG_BREAK_SLOT | 1 << RelocInfo::CODE_AGE_SEQUENCE; 152 153 154 bool RelocInfo::IsCodedSpecially() { 155 // The deserializer needs to know whether a pointer is specially coded. Being 156 // specially coded on IA32 means that it is a relative address, as used by 157 // branch instructions. These are also the ones that need changing when a 158 // code object moves. 159 return (1 << rmode_) & kApplyMask; 160 } 161 162 163 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { 164 // Patch the code at the current address with the supplied instructions. 165 for (int i = 0; i < instruction_count; i++) { 166 *(pc_ + i) = *(instructions + i); 167 } 168 169 // Indicate that code has changed. 170 CPU::FlushICache(pc_, instruction_count); 171 } 172 173 174 // Patch the code at the current PC with a call to the target address. 175 // Additional guard int3 instructions can be added if required. 176 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { 177 // Call instruction takes up 5 bytes and int3 takes up one byte. 178 static const int kCallCodeSize = 5; 179 int code_size = kCallCodeSize + guard_bytes; 180 181 // Create a code patcher. 182 CodePatcher patcher(pc_, code_size); 183 184 // Add a label for checking the size of the code used for returning. 185 #ifdef DEBUG 186 Label check_codesize; 187 patcher.masm()->bind(&check_codesize); 188 #endif 189 190 // Patch the code. 191 patcher.masm()->call(target, RelocInfo::NONE32); 192 193 // Check that the size of the code generated is as expected. 194 ASSERT_EQ(kCallCodeSize, 195 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize)); 196 197 // Add the requested number of int3 instructions after the call. 198 ASSERT_GE(guard_bytes, 0); 199 for (int i = 0; i < guard_bytes; i++) { 200 patcher.masm()->int3(); 201 } 202 } 203 204 205 // ----------------------------------------------------------------------------- 206 // Implementation of Operand 207 208 Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) { 209 // [base + disp/r] 210 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) { 211 // [base] 212 set_modrm(0, base); 213 if (base.is(esp)) set_sib(times_1, esp, base); 214 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) { 215 // [base + disp8] 216 set_modrm(1, base); 217 if (base.is(esp)) set_sib(times_1, esp, base); 218 set_disp8(disp); 219 } else { 220 // [base + disp/r] 221 set_modrm(2, base); 222 if (base.is(esp)) set_sib(times_1, esp, base); 223 set_dispr(disp, rmode); 224 } 225 } 226 227 228 Operand::Operand(Register base, 229 Register index, 230 ScaleFactor scale, 231 int32_t disp, 232 RelocInfo::Mode rmode) { 233 ASSERT(!index.is(esp)); // illegal addressing mode 234 // [base + index*scale + disp/r] 235 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) { 236 // [base + index*scale] 237 set_modrm(0, esp); 238 set_sib(scale, index, base); 239 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) { 240 // [base + index*scale + disp8] 241 set_modrm(1, esp); 242 set_sib(scale, index, base); 243 set_disp8(disp); 244 } else { 245 // [base + index*scale + disp/r] 246 set_modrm(2, esp); 247 set_sib(scale, index, base); 248 set_dispr(disp, rmode); 249 } 250 } 251 252 253 Operand::Operand(Register index, 254 ScaleFactor scale, 255 int32_t disp, 256 RelocInfo::Mode rmode) { 257 ASSERT(!index.is(esp)); // illegal addressing mode 258 // [index*scale + disp/r] 259 set_modrm(0, esp); 260 set_sib(scale, index, ebp); 261 set_dispr(disp, rmode); 262 } 263 264 265 bool Operand::is_reg(Register reg) const { 266 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. 267 && ((buf_[0] & 0x07) == reg.code()); // register codes match. 268 } 269 270 271 bool Operand::is_reg_only() const { 272 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. 273 } 274 275 276 Register Operand::reg() const { 277 ASSERT(is_reg_only()); 278 return Register::from_code(buf_[0] & 0x07); 279 } 280 281 282 // ----------------------------------------------------------------------------- 283 // Implementation of Assembler. 284 285 // Emit a single byte. Must always be inlined. 286 #define EMIT(x) \ 287 *pc_++ = (x) 288 289 290 #ifdef GENERATED_CODE_COVERAGE 291 static void InitCoverageLog(); 292 #endif 293 294 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 295 : AssemblerBase(isolate, buffer, buffer_size), 296 positions_recorder_(this) { 297 // Clear the buffer in debug mode unless it was provided by the 298 // caller in which case we can't be sure it's okay to overwrite 299 // existing code in it; see CodePatcher::CodePatcher(...). 300 #ifdef DEBUG 301 if (own_buffer_) { 302 memset(buffer_, 0xCC, buffer_size_); // int3 303 } 304 #endif 305 306 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); 307 308 #ifdef GENERATED_CODE_COVERAGE 309 InitCoverageLog(); 310 #endif 311 } 312 313 314 void Assembler::GetCode(CodeDesc* desc) { 315 // Finalize code (at this point overflow() may be true, but the gap ensures 316 // that we are still not overlapping instructions and relocation info). 317 ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap. 318 // Set up code descriptor. 319 desc->buffer = buffer_; 320 desc->buffer_size = buffer_size_; 321 desc->instr_size = pc_offset(); 322 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 323 desc->origin = this; 324 } 325 326 327 void Assembler::Align(int m) { 328 ASSERT(IsPowerOf2(m)); 329 int mask = m - 1; 330 int addr = pc_offset(); 331 Nop((m - (addr & mask)) & mask); 332 } 333 334 335 bool Assembler::IsNop(Address addr) { 336 Address a = addr; 337 while (*a == 0x66) a++; 338 if (*a == 0x90) return true; 339 if (a[0] == 0xf && a[1] == 0x1f) return true; 340 return false; 341 } 342 343 344 void Assembler::Nop(int bytes) { 345 EnsureSpace ensure_space(this); 346 347 if (!CpuFeatures::IsSupported(SSE2)) { 348 // Older CPUs that do not support SSE2 may not support multibyte NOP 349 // instructions. 350 for (; bytes > 0; bytes--) { 351 EMIT(0x90); 352 } 353 return; 354 } 355 356 // Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf 357 while (bytes > 0) { 358 switch (bytes) { 359 case 2: 360 EMIT(0x66); 361 case 1: 362 EMIT(0x90); 363 return; 364 case 3: 365 EMIT(0xf); 366 EMIT(0x1f); 367 EMIT(0); 368 return; 369 case 4: 370 EMIT(0xf); 371 EMIT(0x1f); 372 EMIT(0x40); 373 EMIT(0); 374 return; 375 case 6: 376 EMIT(0x66); 377 case 5: 378 EMIT(0xf); 379 EMIT(0x1f); 380 EMIT(0x44); 381 EMIT(0); 382 EMIT(0); 383 return; 384 case 7: 385 EMIT(0xf); 386 EMIT(0x1f); 387 EMIT(0x80); 388 EMIT(0); 389 EMIT(0); 390 EMIT(0); 391 EMIT(0); 392 return; 393 default: 394 case 11: 395 EMIT(0x66); 396 bytes--; 397 case 10: 398 EMIT(0x66); 399 bytes--; 400 case 9: 401 EMIT(0x66); 402 bytes--; 403 case 8: 404 EMIT(0xf); 405 EMIT(0x1f); 406 EMIT(0x84); 407 EMIT(0); 408 EMIT(0); 409 EMIT(0); 410 EMIT(0); 411 EMIT(0); 412 bytes -= 8; 413 } 414 } 415 } 416 417 418 void Assembler::CodeTargetAlign() { 419 Align(16); // Preferred alignment of jump targets on ia32. 420 } 421 422 423 void Assembler::cpuid() { 424 EnsureSpace ensure_space(this); 425 EMIT(0x0F); 426 EMIT(0xA2); 427 } 428 429 430 void Assembler::pushad() { 431 EnsureSpace ensure_space(this); 432 EMIT(0x60); 433 } 434 435 436 void Assembler::popad() { 437 EnsureSpace ensure_space(this); 438 EMIT(0x61); 439 } 440 441 442 void Assembler::pushfd() { 443 EnsureSpace ensure_space(this); 444 EMIT(0x9C); 445 } 446 447 448 void Assembler::popfd() { 449 EnsureSpace ensure_space(this); 450 EMIT(0x9D); 451 } 452 453 454 void Assembler::push(const Immediate& x) { 455 EnsureSpace ensure_space(this); 456 if (x.is_int8()) { 457 EMIT(0x6a); 458 EMIT(x.x_); 459 } else { 460 EMIT(0x68); 461 emit(x); 462 } 463 } 464 465 466 void Assembler::push_imm32(int32_t imm32) { 467 EnsureSpace ensure_space(this); 468 EMIT(0x68); 469 emit(imm32); 470 } 471 472 473 void Assembler::push(Register src) { 474 EnsureSpace ensure_space(this); 475 EMIT(0x50 | src.code()); 476 } 477 478 479 void Assembler::push(const Operand& src) { 480 EnsureSpace ensure_space(this); 481 EMIT(0xFF); 482 emit_operand(esi, src); 483 } 484 485 486 void Assembler::pop(Register dst) { 487 ASSERT(reloc_info_writer.last_pc() != NULL); 488 EnsureSpace ensure_space(this); 489 EMIT(0x58 | dst.code()); 490 } 491 492 493 void Assembler::pop(const Operand& dst) { 494 EnsureSpace ensure_space(this); 495 EMIT(0x8F); 496 emit_operand(eax, dst); 497 } 498 499 500 void Assembler::enter(const Immediate& size) { 501 EnsureSpace ensure_space(this); 502 EMIT(0xC8); 503 emit_w(size); 504 EMIT(0); 505 } 506 507 508 void Assembler::leave() { 509 EnsureSpace ensure_space(this); 510 EMIT(0xC9); 511 } 512 513 514 void Assembler::mov_b(Register dst, const Operand& src) { 515 CHECK(dst.is_byte_register()); 516 EnsureSpace ensure_space(this); 517 EMIT(0x8A); 518 emit_operand(dst, src); 519 } 520 521 522 void Assembler::mov_b(const Operand& dst, int8_t imm8) { 523 EnsureSpace ensure_space(this); 524 EMIT(0xC6); 525 emit_operand(eax, dst); 526 EMIT(imm8); 527 } 528 529 530 void Assembler::mov_b(const Operand& dst, Register src) { 531 CHECK(src.is_byte_register()); 532 EnsureSpace ensure_space(this); 533 EMIT(0x88); 534 emit_operand(src, dst); 535 } 536 537 538 void Assembler::mov_w(Register dst, const Operand& src) { 539 EnsureSpace ensure_space(this); 540 EMIT(0x66); 541 EMIT(0x8B); 542 emit_operand(dst, src); 543 } 544 545 546 void Assembler::mov_w(const Operand& dst, Register src) { 547 EnsureSpace ensure_space(this); 548 EMIT(0x66); 549 EMIT(0x89); 550 emit_operand(src, dst); 551 } 552 553 554 void Assembler::mov_w(const Operand& dst, int16_t imm16) { 555 EnsureSpace ensure_space(this); 556 EMIT(0x66); 557 EMIT(0xC7); 558 emit_operand(eax, dst); 559 EMIT(static_cast<int8_t>(imm16 & 0xff)); 560 EMIT(static_cast<int8_t>(imm16 >> 8)); 561 } 562 563 564 void Assembler::mov(Register dst, int32_t imm32) { 565 EnsureSpace ensure_space(this); 566 EMIT(0xB8 | dst.code()); 567 emit(imm32); 568 } 569 570 571 void Assembler::mov(Register dst, const Immediate& x) { 572 EnsureSpace ensure_space(this); 573 EMIT(0xB8 | dst.code()); 574 emit(x); 575 } 576 577 578 void Assembler::mov(Register dst, Handle<Object> handle) { 579 EnsureSpace ensure_space(this); 580 EMIT(0xB8 | dst.code()); 581 emit(handle); 582 } 583 584 585 void Assembler::mov(Register dst, const Operand& src) { 586 EnsureSpace ensure_space(this); 587 EMIT(0x8B); 588 emit_operand(dst, src); 589 } 590 591 592 void Assembler::mov(Register dst, Register src) { 593 EnsureSpace ensure_space(this); 594 EMIT(0x89); 595 EMIT(0xC0 | src.code() << 3 | dst.code()); 596 } 597 598 599 void Assembler::mov(const Operand& dst, const Immediate& x) { 600 EnsureSpace ensure_space(this); 601 EMIT(0xC7); 602 emit_operand(eax, dst); 603 emit(x); 604 } 605 606 607 void Assembler::mov(const Operand& dst, Handle<Object> handle) { 608 EnsureSpace ensure_space(this); 609 EMIT(0xC7); 610 emit_operand(eax, dst); 611 emit(handle); 612 } 613 614 615 void Assembler::mov(const Operand& dst, Register src) { 616 EnsureSpace ensure_space(this); 617 EMIT(0x89); 618 emit_operand(src, dst); 619 } 620 621 622 void Assembler::movsx_b(Register dst, const Operand& src) { 623 EnsureSpace ensure_space(this); 624 EMIT(0x0F); 625 EMIT(0xBE); 626 emit_operand(dst, src); 627 } 628 629 630 void Assembler::movsx_w(Register dst, const Operand& src) { 631 EnsureSpace ensure_space(this); 632 EMIT(0x0F); 633 EMIT(0xBF); 634 emit_operand(dst, src); 635 } 636 637 638 void Assembler::movzx_b(Register dst, const Operand& src) { 639 EnsureSpace ensure_space(this); 640 EMIT(0x0F); 641 EMIT(0xB6); 642 emit_operand(dst, src); 643 } 644 645 646 void Assembler::movzx_w(Register dst, const Operand& src) { 647 EnsureSpace ensure_space(this); 648 EMIT(0x0F); 649 EMIT(0xB7); 650 emit_operand(dst, src); 651 } 652 653 654 void Assembler::cmov(Condition cc, Register dst, const Operand& src) { 655 ASSERT(IsEnabled(CMOV)); 656 EnsureSpace ensure_space(this); 657 // Opcode: 0f 40 + cc /r. 658 EMIT(0x0F); 659 EMIT(0x40 + cc); 660 emit_operand(dst, src); 661 } 662 663 664 void Assembler::cld() { 665 EnsureSpace ensure_space(this); 666 EMIT(0xFC); 667 } 668 669 670 void Assembler::rep_movs() { 671 EnsureSpace ensure_space(this); 672 EMIT(0xF3); 673 EMIT(0xA5); 674 } 675 676 677 void Assembler::rep_stos() { 678 EnsureSpace ensure_space(this); 679 EMIT(0xF3); 680 EMIT(0xAB); 681 } 682 683 684 void Assembler::stos() { 685 EnsureSpace ensure_space(this); 686 EMIT(0xAB); 687 } 688 689 690 void Assembler::xchg(Register dst, Register src) { 691 EnsureSpace ensure_space(this); 692 if (src.is(eax) || dst.is(eax)) { // Single-byte encoding. 693 EMIT(0x90 | (src.is(eax) ? dst.code() : src.code())); 694 } else { 695 EMIT(0x87); 696 EMIT(0xC0 | src.code() << 3 | dst.code()); 697 } 698 } 699 700 701 void Assembler::adc(Register dst, int32_t imm32) { 702 EnsureSpace ensure_space(this); 703 emit_arith(2, Operand(dst), Immediate(imm32)); 704 } 705 706 707 void Assembler::adc(Register dst, const Operand& src) { 708 EnsureSpace ensure_space(this); 709 EMIT(0x13); 710 emit_operand(dst, src); 711 } 712 713 714 void Assembler::add(Register dst, const Operand& src) { 715 EnsureSpace ensure_space(this); 716 EMIT(0x03); 717 emit_operand(dst, src); 718 } 719 720 721 void Assembler::add(const Operand& dst, Register src) { 722 EnsureSpace ensure_space(this); 723 EMIT(0x01); 724 emit_operand(src, dst); 725 } 726 727 728 void Assembler::add(const Operand& dst, const Immediate& x) { 729 ASSERT(reloc_info_writer.last_pc() != NULL); 730 EnsureSpace ensure_space(this); 731 emit_arith(0, dst, x); 732 } 733 734 735 void Assembler::and_(Register dst, int32_t imm32) { 736 and_(dst, Immediate(imm32)); 737 } 738 739 740 void Assembler::and_(Register dst, const Immediate& x) { 741 EnsureSpace ensure_space(this); 742 emit_arith(4, Operand(dst), x); 743 } 744 745 746 void Assembler::and_(Register dst, const Operand& src) { 747 EnsureSpace ensure_space(this); 748 EMIT(0x23); 749 emit_operand(dst, src); 750 } 751 752 753 void Assembler::and_(const Operand& dst, const Immediate& x) { 754 EnsureSpace ensure_space(this); 755 emit_arith(4, dst, x); 756 } 757 758 759 void Assembler::and_(const Operand& dst, Register src) { 760 EnsureSpace ensure_space(this); 761 EMIT(0x21); 762 emit_operand(src, dst); 763 } 764 765 766 void Assembler::cmpb(const Operand& op, int8_t imm8) { 767 EnsureSpace ensure_space(this); 768 if (op.is_reg(eax)) { 769 EMIT(0x3C); 770 } else { 771 EMIT(0x80); 772 emit_operand(edi, op); // edi == 7 773 } 774 EMIT(imm8); 775 } 776 777 778 void Assembler::cmpb(const Operand& op, Register reg) { 779 CHECK(reg.is_byte_register()); 780 EnsureSpace ensure_space(this); 781 EMIT(0x38); 782 emit_operand(reg, op); 783 } 784 785 786 void Assembler::cmpb(Register reg, const Operand& op) { 787 CHECK(reg.is_byte_register()); 788 EnsureSpace ensure_space(this); 789 EMIT(0x3A); 790 emit_operand(reg, op); 791 } 792 793 794 void Assembler::cmpw(const Operand& op, Immediate imm16) { 795 ASSERT(imm16.is_int16()); 796 EnsureSpace ensure_space(this); 797 EMIT(0x66); 798 EMIT(0x81); 799 emit_operand(edi, op); 800 emit_w(imm16); 801 } 802 803 804 void Assembler::cmp(Register reg, int32_t imm32) { 805 EnsureSpace ensure_space(this); 806 emit_arith(7, Operand(reg), Immediate(imm32)); 807 } 808 809 810 void Assembler::cmp(Register reg, Handle<Object> handle) { 811 EnsureSpace ensure_space(this); 812 emit_arith(7, Operand(reg), Immediate(handle)); 813 } 814 815 816 void Assembler::cmp(Register reg, const Operand& op) { 817 EnsureSpace ensure_space(this); 818 EMIT(0x3B); 819 emit_operand(reg, op); 820 } 821 822 823 void Assembler::cmp(const Operand& op, const Immediate& imm) { 824 EnsureSpace ensure_space(this); 825 emit_arith(7, op, imm); 826 } 827 828 829 void Assembler::cmp(const Operand& op, Handle<Object> handle) { 830 EnsureSpace ensure_space(this); 831 emit_arith(7, op, Immediate(handle)); 832 } 833 834 835 void Assembler::cmpb_al(const Operand& op) { 836 EnsureSpace ensure_space(this); 837 EMIT(0x38); // CMP r/m8, r8 838 emit_operand(eax, op); // eax has same code as register al. 839 } 840 841 842 void Assembler::cmpw_ax(const Operand& op) { 843 EnsureSpace ensure_space(this); 844 EMIT(0x66); 845 EMIT(0x39); // CMP r/m16, r16 846 emit_operand(eax, op); // eax has same code as register ax. 847 } 848 849 850 void Assembler::dec_b(Register dst) { 851 CHECK(dst.is_byte_register()); 852 EnsureSpace ensure_space(this); 853 EMIT(0xFE); 854 EMIT(0xC8 | dst.code()); 855 } 856 857 858 void Assembler::dec_b(const Operand& dst) { 859 EnsureSpace ensure_space(this); 860 EMIT(0xFE); 861 emit_operand(ecx, dst); 862 } 863 864 865 void Assembler::dec(Register dst) { 866 EnsureSpace ensure_space(this); 867 EMIT(0x48 | dst.code()); 868 } 869 870 871 void Assembler::dec(const Operand& dst) { 872 EnsureSpace ensure_space(this); 873 EMIT(0xFF); 874 emit_operand(ecx, dst); 875 } 876 877 878 void Assembler::cdq() { 879 EnsureSpace ensure_space(this); 880 EMIT(0x99); 881 } 882 883 884 void Assembler::idiv(Register src) { 885 EnsureSpace ensure_space(this); 886 EMIT(0xF7); 887 EMIT(0xF8 | src.code()); 888 } 889 890 891 void Assembler::imul(Register reg) { 892 EnsureSpace ensure_space(this); 893 EMIT(0xF7); 894 EMIT(0xE8 | reg.code()); 895 } 896 897 898 void Assembler::imul(Register dst, const Operand& src) { 899 EnsureSpace ensure_space(this); 900 EMIT(0x0F); 901 EMIT(0xAF); 902 emit_operand(dst, src); 903 } 904 905 906 void Assembler::imul(Register dst, Register src, int32_t imm32) { 907 EnsureSpace ensure_space(this); 908 if (is_int8(imm32)) { 909 EMIT(0x6B); 910 EMIT(0xC0 | dst.code() << 3 | src.code()); 911 EMIT(imm32); 912 } else { 913 EMIT(0x69); 914 EMIT(0xC0 | dst.code() << 3 | src.code()); 915 emit(imm32); 916 } 917 } 918 919 920 void Assembler::inc(Register dst) { 921 EnsureSpace ensure_space(this); 922 EMIT(0x40 | dst.code()); 923 } 924 925 926 void Assembler::inc(const Operand& dst) { 927 EnsureSpace ensure_space(this); 928 EMIT(0xFF); 929 emit_operand(eax, dst); 930 } 931 932 933 void Assembler::lea(Register dst, const Operand& src) { 934 EnsureSpace ensure_space(this); 935 EMIT(0x8D); 936 emit_operand(dst, src); 937 } 938 939 940 void Assembler::mul(Register src) { 941 EnsureSpace ensure_space(this); 942 EMIT(0xF7); 943 EMIT(0xE0 | src.code()); 944 } 945 946 947 void Assembler::neg(Register dst) { 948 EnsureSpace ensure_space(this); 949 EMIT(0xF7); 950 EMIT(0xD8 | dst.code()); 951 } 952 953 954 void Assembler::not_(Register dst) { 955 EnsureSpace ensure_space(this); 956 EMIT(0xF7); 957 EMIT(0xD0 | dst.code()); 958 } 959 960 961 void Assembler::or_(Register dst, int32_t imm32) { 962 EnsureSpace ensure_space(this); 963 emit_arith(1, Operand(dst), Immediate(imm32)); 964 } 965 966 967 void Assembler::or_(Register dst, const Operand& src) { 968 EnsureSpace ensure_space(this); 969 EMIT(0x0B); 970 emit_operand(dst, src); 971 } 972 973 974 void Assembler::or_(const Operand& dst, const Immediate& x) { 975 EnsureSpace ensure_space(this); 976 emit_arith(1, dst, x); 977 } 978 979 980 void Assembler::or_(const Operand& dst, Register src) { 981 EnsureSpace ensure_space(this); 982 EMIT(0x09); 983 emit_operand(src, dst); 984 } 985 986 987 void Assembler::rcl(Register dst, uint8_t imm8) { 988 EnsureSpace ensure_space(this); 989 ASSERT(is_uint5(imm8)); // illegal shift count 990 if (imm8 == 1) { 991 EMIT(0xD1); 992 EMIT(0xD0 | dst.code()); 993 } else { 994 EMIT(0xC1); 995 EMIT(0xD0 | dst.code()); 996 EMIT(imm8); 997 } 998 } 999 1000 1001 void Assembler::rcr(Register dst, uint8_t imm8) { 1002 EnsureSpace ensure_space(this); 1003 ASSERT(is_uint5(imm8)); // illegal shift count 1004 if (imm8 == 1) { 1005 EMIT(0xD1); 1006 EMIT(0xD8 | dst.code()); 1007 } else { 1008 EMIT(0xC1); 1009 EMIT(0xD8 | dst.code()); 1010 EMIT(imm8); 1011 } 1012 } 1013 1014 1015 void Assembler::ror(Register dst, uint8_t imm8) { 1016 EnsureSpace ensure_space(this); 1017 ASSERT(is_uint5(imm8)); // illegal shift count 1018 if (imm8 == 1) { 1019 EMIT(0xD1); 1020 EMIT(0xC8 | dst.code()); 1021 } else { 1022 EMIT(0xC1); 1023 EMIT(0xC8 | dst.code()); 1024 EMIT(imm8); 1025 } 1026 } 1027 1028 1029 void Assembler::ror_cl(Register dst) { 1030 EnsureSpace ensure_space(this); 1031 EMIT(0xD3); 1032 EMIT(0xC8 | dst.code()); 1033 } 1034 1035 1036 void Assembler::sar(Register dst, uint8_t imm8) { 1037 EnsureSpace ensure_space(this); 1038 ASSERT(is_uint5(imm8)); // illegal shift count 1039 if (imm8 == 1) { 1040 EMIT(0xD1); 1041 EMIT(0xF8 | dst.code()); 1042 } else { 1043 EMIT(0xC1); 1044 EMIT(0xF8 | dst.code()); 1045 EMIT(imm8); 1046 } 1047 } 1048 1049 1050 void Assembler::sar_cl(Register dst) { 1051 EnsureSpace ensure_space(this); 1052 EMIT(0xD3); 1053 EMIT(0xF8 | dst.code()); 1054 } 1055 1056 1057 void Assembler::sbb(Register dst, const Operand& src) { 1058 EnsureSpace ensure_space(this); 1059 EMIT(0x1B); 1060 emit_operand(dst, src); 1061 } 1062 1063 1064 void Assembler::shld(Register dst, const Operand& src) { 1065 EnsureSpace ensure_space(this); 1066 EMIT(0x0F); 1067 EMIT(0xA5); 1068 emit_operand(dst, src); 1069 } 1070 1071 1072 void Assembler::shl(Register dst, uint8_t imm8) { 1073 EnsureSpace ensure_space(this); 1074 ASSERT(is_uint5(imm8)); // illegal shift count 1075 if (imm8 == 1) { 1076 EMIT(0xD1); 1077 EMIT(0xE0 | dst.code()); 1078 } else { 1079 EMIT(0xC1); 1080 EMIT(0xE0 | dst.code()); 1081 EMIT(imm8); 1082 } 1083 } 1084 1085 1086 void Assembler::shl_cl(Register dst) { 1087 EnsureSpace ensure_space(this); 1088 EMIT(0xD3); 1089 EMIT(0xE0 | dst.code()); 1090 } 1091 1092 1093 void Assembler::shrd(Register dst, const Operand& src) { 1094 EnsureSpace ensure_space(this); 1095 EMIT(0x0F); 1096 EMIT(0xAD); 1097 emit_operand(dst, src); 1098 } 1099 1100 1101 void Assembler::shr(Register dst, uint8_t imm8) { 1102 EnsureSpace ensure_space(this); 1103 ASSERT(is_uint5(imm8)); // illegal shift count 1104 if (imm8 == 1) { 1105 EMIT(0xD1); 1106 EMIT(0xE8 | dst.code()); 1107 } else { 1108 EMIT(0xC1); 1109 EMIT(0xE8 | dst.code()); 1110 EMIT(imm8); 1111 } 1112 } 1113 1114 1115 void Assembler::shr_cl(Register dst) { 1116 EnsureSpace ensure_space(this); 1117 EMIT(0xD3); 1118 EMIT(0xE8 | dst.code()); 1119 } 1120 1121 1122 void Assembler::sub(const Operand& dst, const Immediate& x) { 1123 EnsureSpace ensure_space(this); 1124 emit_arith(5, dst, x); 1125 } 1126 1127 1128 void Assembler::sub(Register dst, const Operand& src) { 1129 EnsureSpace ensure_space(this); 1130 EMIT(0x2B); 1131 emit_operand(dst, src); 1132 } 1133 1134 1135 void Assembler::sub(const Operand& dst, Register src) { 1136 EnsureSpace ensure_space(this); 1137 EMIT(0x29); 1138 emit_operand(src, dst); 1139 } 1140 1141 1142 void Assembler::test(Register reg, const Immediate& imm) { 1143 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) { 1144 test_b(reg, imm.x_); 1145 return; 1146 } 1147 1148 EnsureSpace ensure_space(this); 1149 // This is not using emit_arith because test doesn't support 1150 // sign-extension of 8-bit operands. 1151 if (reg.is(eax)) { 1152 EMIT(0xA9); 1153 } else { 1154 EMIT(0xF7); 1155 EMIT(0xC0 | reg.code()); 1156 } 1157 emit(imm); 1158 } 1159 1160 1161 void Assembler::test(Register reg, const Operand& op) { 1162 EnsureSpace ensure_space(this); 1163 EMIT(0x85); 1164 emit_operand(reg, op); 1165 } 1166 1167 1168 void Assembler::test_b(Register reg, const Operand& op) { 1169 CHECK(reg.is_byte_register()); 1170 EnsureSpace ensure_space(this); 1171 EMIT(0x84); 1172 emit_operand(reg, op); 1173 } 1174 1175 1176 void Assembler::test(const Operand& op, const Immediate& imm) { 1177 if (op.is_reg_only()) { 1178 test(op.reg(), imm); 1179 return; 1180 } 1181 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) { 1182 return test_b(op, imm.x_); 1183 } 1184 EnsureSpace ensure_space(this); 1185 EMIT(0xF7); 1186 emit_operand(eax, op); 1187 emit(imm); 1188 } 1189 1190 1191 void Assembler::test_b(Register reg, uint8_t imm8) { 1192 EnsureSpace ensure_space(this); 1193 // Only use test against byte for registers that have a byte 1194 // variant: eax, ebx, ecx, and edx. 1195 if (reg.is(eax)) { 1196 EMIT(0xA8); 1197 EMIT(imm8); 1198 } else if (reg.is_byte_register()) { 1199 emit_arith_b(0xF6, 0xC0, reg, imm8); 1200 } else { 1201 EMIT(0xF7); 1202 EMIT(0xC0 | reg.code()); 1203 emit(imm8); 1204 } 1205 } 1206 1207 1208 void Assembler::test_b(const Operand& op, uint8_t imm8) { 1209 if (op.is_reg_only()) { 1210 test_b(op.reg(), imm8); 1211 return; 1212 } 1213 EnsureSpace ensure_space(this); 1214 EMIT(0xF6); 1215 emit_operand(eax, op); 1216 EMIT(imm8); 1217 } 1218 1219 1220 void Assembler::xor_(Register dst, int32_t imm32) { 1221 EnsureSpace ensure_space(this); 1222 emit_arith(6, Operand(dst), Immediate(imm32)); 1223 } 1224 1225 1226 void Assembler::xor_(Register dst, const Operand& src) { 1227 EnsureSpace ensure_space(this); 1228 EMIT(0x33); 1229 emit_operand(dst, src); 1230 } 1231 1232 1233 void Assembler::xor_(const Operand& dst, Register src) { 1234 EnsureSpace ensure_space(this); 1235 EMIT(0x31); 1236 emit_operand(src, dst); 1237 } 1238 1239 1240 void Assembler::xor_(const Operand& dst, const Immediate& x) { 1241 EnsureSpace ensure_space(this); 1242 emit_arith(6, dst, x); 1243 } 1244 1245 1246 void Assembler::bt(const Operand& dst, Register src) { 1247 EnsureSpace ensure_space(this); 1248 EMIT(0x0F); 1249 EMIT(0xA3); 1250 emit_operand(src, dst); 1251 } 1252 1253 1254 void Assembler::bts(const Operand& dst, Register src) { 1255 EnsureSpace ensure_space(this); 1256 EMIT(0x0F); 1257 EMIT(0xAB); 1258 emit_operand(src, dst); 1259 } 1260 1261 1262 void Assembler::hlt() { 1263 EnsureSpace ensure_space(this); 1264 EMIT(0xF4); 1265 } 1266 1267 1268 void Assembler::int3() { 1269 EnsureSpace ensure_space(this); 1270 EMIT(0xCC); 1271 } 1272 1273 1274 void Assembler::nop() { 1275 EnsureSpace ensure_space(this); 1276 EMIT(0x90); 1277 } 1278 1279 1280 void Assembler::ret(int imm16) { 1281 EnsureSpace ensure_space(this); 1282 ASSERT(is_uint16(imm16)); 1283 if (imm16 == 0) { 1284 EMIT(0xC3); 1285 } else { 1286 EMIT(0xC2); 1287 EMIT(imm16 & 0xFF); 1288 EMIT((imm16 >> 8) & 0xFF); 1289 } 1290 } 1291 1292 1293 // Labels refer to positions in the (to be) generated code. 1294 // There are bound, linked, and unused labels. 1295 // 1296 // Bound labels refer to known positions in the already 1297 // generated code. pos() is the position the label refers to. 1298 // 1299 // Linked labels refer to unknown positions in the code 1300 // to be generated; pos() is the position of the 32bit 1301 // Displacement of the last instruction using the label. 1302 1303 1304 void Assembler::print(Label* L) { 1305 if (L->is_unused()) { 1306 PrintF("unused label\n"); 1307 } else if (L->is_bound()) { 1308 PrintF("bound label to %d\n", L->pos()); 1309 } else if (L->is_linked()) { 1310 Label l = *L; 1311 PrintF("unbound label"); 1312 while (l.is_linked()) { 1313 Displacement disp = disp_at(&l); 1314 PrintF("@ %d ", l.pos()); 1315 disp.print(); 1316 PrintF("\n"); 1317 disp.next(&l); 1318 } 1319 } else { 1320 PrintF("label in inconsistent state (pos = %d)\n", L->pos_); 1321 } 1322 } 1323 1324 1325 void Assembler::bind_to(Label* L, int pos) { 1326 EnsureSpace ensure_space(this); 1327 ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position 1328 while (L->is_linked()) { 1329 Displacement disp = disp_at(L); 1330 int fixup_pos = L->pos(); 1331 if (disp.type() == Displacement::CODE_RELATIVE) { 1332 // Relative to Code* heap object pointer. 1333 long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag); 1334 } else { 1335 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { 1336 ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected 1337 } 1338 // Relative address, relative to point after address. 1339 int imm32 = pos - (fixup_pos + sizeof(int32_t)); 1340 long_at_put(fixup_pos, imm32); 1341 } 1342 disp.next(L); 1343 } 1344 while (L->is_near_linked()) { 1345 int fixup_pos = L->near_link_pos(); 1346 int offset_to_next = 1347 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos))); 1348 ASSERT(offset_to_next <= 0); 1349 // Relative address, relative to point after address. 1350 int disp = pos - fixup_pos - sizeof(int8_t); 1351 CHECK(0 <= disp && disp <= 127); 1352 set_byte_at(fixup_pos, disp); 1353 if (offset_to_next < 0) { 1354 L->link_to(fixup_pos + offset_to_next, Label::kNear); 1355 } else { 1356 L->UnuseNear(); 1357 } 1358 } 1359 L->bind_to(pos); 1360 } 1361 1362 1363 void Assembler::bind(Label* L) { 1364 EnsureSpace ensure_space(this); 1365 ASSERT(!L->is_bound()); // label can only be bound once 1366 bind_to(L, pc_offset()); 1367 } 1368 1369 1370 void Assembler::call(Label* L) { 1371 positions_recorder()->WriteRecordedPositions(); 1372 EnsureSpace ensure_space(this); 1373 if (L->is_bound()) { 1374 const int long_size = 5; 1375 int offs = L->pos() - pc_offset(); 1376 ASSERT(offs <= 0); 1377 // 1110 1000 #32-bit disp. 1378 EMIT(0xE8); 1379 emit(offs - long_size); 1380 } else { 1381 // 1110 1000 #32-bit disp. 1382 EMIT(0xE8); 1383 emit_disp(L, Displacement::OTHER); 1384 } 1385 } 1386 1387 1388 void Assembler::call(byte* entry, RelocInfo::Mode rmode) { 1389 positions_recorder()->WriteRecordedPositions(); 1390 EnsureSpace ensure_space(this); 1391 ASSERT(!RelocInfo::IsCodeTarget(rmode)); 1392 EMIT(0xE8); 1393 if (RelocInfo::IsRuntimeEntry(rmode)) { 1394 emit(reinterpret_cast<uint32_t>(entry), rmode); 1395 } else { 1396 emit(entry - (pc_ + sizeof(int32_t)), rmode); 1397 } 1398 } 1399 1400 1401 int Assembler::CallSize(const Operand& adr) { 1402 // Call size is 1 (opcode) + adr.len_ (operand). 1403 return 1 + adr.len_; 1404 } 1405 1406 1407 void Assembler::call(const Operand& adr) { 1408 positions_recorder()->WriteRecordedPositions(); 1409 EnsureSpace ensure_space(this); 1410 EMIT(0xFF); 1411 emit_operand(edx, adr); 1412 } 1413 1414 1415 int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) { 1416 return 1 /* EMIT */ + sizeof(uint32_t) /* emit */; 1417 } 1418 1419 1420 void Assembler::call(Handle<Code> code, 1421 RelocInfo::Mode rmode, 1422 TypeFeedbackId ast_id) { 1423 positions_recorder()->WriteRecordedPositions(); 1424 EnsureSpace ensure_space(this); 1425 ASSERT(RelocInfo::IsCodeTarget(rmode) 1426 || rmode == RelocInfo::CODE_AGE_SEQUENCE); 1427 EMIT(0xE8); 1428 emit(code, rmode, ast_id); 1429 } 1430 1431 1432 void Assembler::jmp(Label* L, Label::Distance distance) { 1433 EnsureSpace ensure_space(this); 1434 if (L->is_bound()) { 1435 const int short_size = 2; 1436 const int long_size = 5; 1437 int offs = L->pos() - pc_offset(); 1438 ASSERT(offs <= 0); 1439 if (is_int8(offs - short_size)) { 1440 // 1110 1011 #8-bit disp. 1441 EMIT(0xEB); 1442 EMIT((offs - short_size) & 0xFF); 1443 } else { 1444 // 1110 1001 #32-bit disp. 1445 EMIT(0xE9); 1446 emit(offs - long_size); 1447 } 1448 } else if (distance == Label::kNear) { 1449 EMIT(0xEB); 1450 emit_near_disp(L); 1451 } else { 1452 // 1110 1001 #32-bit disp. 1453 EMIT(0xE9); 1454 emit_disp(L, Displacement::UNCONDITIONAL_JUMP); 1455 } 1456 } 1457 1458 1459 void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) { 1460 EnsureSpace ensure_space(this); 1461 ASSERT(!RelocInfo::IsCodeTarget(rmode)); 1462 EMIT(0xE9); 1463 if (RelocInfo::IsRuntimeEntry(rmode)) { 1464 emit(reinterpret_cast<uint32_t>(entry), rmode); 1465 } else { 1466 emit(entry - (pc_ + sizeof(int32_t)), rmode); 1467 } 1468 } 1469 1470 1471 void Assembler::jmp(const Operand& adr) { 1472 EnsureSpace ensure_space(this); 1473 EMIT(0xFF); 1474 emit_operand(esp, adr); 1475 } 1476 1477 1478 void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) { 1479 EnsureSpace ensure_space(this); 1480 ASSERT(RelocInfo::IsCodeTarget(rmode)); 1481 EMIT(0xE9); 1482 emit(code, rmode); 1483 } 1484 1485 1486 void Assembler::j(Condition cc, Label* L, Label::Distance distance) { 1487 EnsureSpace ensure_space(this); 1488 ASSERT(0 <= cc && static_cast<int>(cc) < 16); 1489 if (L->is_bound()) { 1490 const int short_size = 2; 1491 const int long_size = 6; 1492 int offs = L->pos() - pc_offset(); 1493 ASSERT(offs <= 0); 1494 if (is_int8(offs - short_size)) { 1495 // 0111 tttn #8-bit disp 1496 EMIT(0x70 | cc); 1497 EMIT((offs - short_size) & 0xFF); 1498 } else { 1499 // 0000 1111 1000 tttn #32-bit disp 1500 EMIT(0x0F); 1501 EMIT(0x80 | cc); 1502 emit(offs - long_size); 1503 } 1504 } else if (distance == Label::kNear) { 1505 EMIT(0x70 | cc); 1506 emit_near_disp(L); 1507 } else { 1508 // 0000 1111 1000 tttn #32-bit disp 1509 // Note: could eliminate cond. jumps to this jump if condition 1510 // is the same however, seems to be rather unlikely case. 1511 EMIT(0x0F); 1512 EMIT(0x80 | cc); 1513 emit_disp(L, Displacement::OTHER); 1514 } 1515 } 1516 1517 1518 void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) { 1519 EnsureSpace ensure_space(this); 1520 ASSERT((0 <= cc) && (static_cast<int>(cc) < 16)); 1521 // 0000 1111 1000 tttn #32-bit disp. 1522 EMIT(0x0F); 1523 EMIT(0x80 | cc); 1524 if (RelocInfo::IsRuntimeEntry(rmode)) { 1525 emit(reinterpret_cast<uint32_t>(entry), rmode); 1526 } else { 1527 emit(entry - (pc_ + sizeof(int32_t)), rmode); 1528 } 1529 } 1530 1531 1532 void Assembler::j(Condition cc, Handle<Code> code) { 1533 EnsureSpace ensure_space(this); 1534 // 0000 1111 1000 tttn #32-bit disp 1535 EMIT(0x0F); 1536 EMIT(0x80 | cc); 1537 emit(code, RelocInfo::CODE_TARGET); 1538 } 1539 1540 1541 // FPU instructions. 1542 1543 void Assembler::fld(int i) { 1544 EnsureSpace ensure_space(this); 1545 emit_farith(0xD9, 0xC0, i); 1546 } 1547 1548 1549 void Assembler::fstp(int i) { 1550 EnsureSpace ensure_space(this); 1551 emit_farith(0xDD, 0xD8, i); 1552 } 1553 1554 1555 void Assembler::fld1() { 1556 EnsureSpace ensure_space(this); 1557 EMIT(0xD9); 1558 EMIT(0xE8); 1559 } 1560 1561 1562 void Assembler::fldpi() { 1563 EnsureSpace ensure_space(this); 1564 EMIT(0xD9); 1565 EMIT(0xEB); 1566 } 1567 1568 1569 void Assembler::fldz() { 1570 EnsureSpace ensure_space(this); 1571 EMIT(0xD9); 1572 EMIT(0xEE); 1573 } 1574 1575 1576 void Assembler::fldln2() { 1577 EnsureSpace ensure_space(this); 1578 EMIT(0xD9); 1579 EMIT(0xED); 1580 } 1581 1582 1583 void Assembler::fld_s(const Operand& adr) { 1584 EnsureSpace ensure_space(this); 1585 EMIT(0xD9); 1586 emit_operand(eax, adr); 1587 } 1588 1589 1590 void Assembler::fld_d(const Operand& adr) { 1591 EnsureSpace ensure_space(this); 1592 EMIT(0xDD); 1593 emit_operand(eax, adr); 1594 } 1595 1596 1597 void Assembler::fstp_s(const Operand& adr) { 1598 EnsureSpace ensure_space(this); 1599 EMIT(0xD9); 1600 emit_operand(ebx, adr); 1601 } 1602 1603 1604 void Assembler::fst_s(const Operand& adr) { 1605 EnsureSpace ensure_space(this); 1606 EMIT(0xD9); 1607 emit_operand(edx, adr); 1608 } 1609 1610 1611 void Assembler::fstp_d(const Operand& adr) { 1612 EnsureSpace ensure_space(this); 1613 EMIT(0xDD); 1614 emit_operand(ebx, adr); 1615 } 1616 1617 1618 void Assembler::fst_d(const Operand& adr) { 1619 EnsureSpace ensure_space(this); 1620 EMIT(0xDD); 1621 emit_operand(edx, adr); 1622 } 1623 1624 1625 void Assembler::fild_s(const Operand& adr) { 1626 EnsureSpace ensure_space(this); 1627 EMIT(0xDB); 1628 emit_operand(eax, adr); 1629 } 1630 1631 1632 void Assembler::fild_d(const Operand& adr) { 1633 EnsureSpace ensure_space(this); 1634 EMIT(0xDF); 1635 emit_operand(ebp, adr); 1636 } 1637 1638 1639 void Assembler::fistp_s(const Operand& adr) { 1640 EnsureSpace ensure_space(this); 1641 EMIT(0xDB); 1642 emit_operand(ebx, adr); 1643 } 1644 1645 1646 void Assembler::fisttp_s(const Operand& adr) { 1647 ASSERT(IsEnabled(SSE3)); 1648 EnsureSpace ensure_space(this); 1649 EMIT(0xDB); 1650 emit_operand(ecx, adr); 1651 } 1652 1653 1654 void Assembler::fisttp_d(const Operand& adr) { 1655 ASSERT(IsEnabled(SSE3)); 1656 EnsureSpace ensure_space(this); 1657 EMIT(0xDD); 1658 emit_operand(ecx, adr); 1659 } 1660 1661 1662 void Assembler::fist_s(const Operand& adr) { 1663 EnsureSpace ensure_space(this); 1664 EMIT(0xDB); 1665 emit_operand(edx, adr); 1666 } 1667 1668 1669 void Assembler::fistp_d(const Operand& adr) { 1670 EnsureSpace ensure_space(this); 1671 EMIT(0xDF); 1672 emit_operand(edi, adr); 1673 } 1674 1675 1676 void Assembler::fabs() { 1677 EnsureSpace ensure_space(this); 1678 EMIT(0xD9); 1679 EMIT(0xE1); 1680 } 1681 1682 1683 void Assembler::fchs() { 1684 EnsureSpace ensure_space(this); 1685 EMIT(0xD9); 1686 EMIT(0xE0); 1687 } 1688 1689 1690 void Assembler::fcos() { 1691 EnsureSpace ensure_space(this); 1692 EMIT(0xD9); 1693 EMIT(0xFF); 1694 } 1695 1696 1697 void Assembler::fsin() { 1698 EnsureSpace ensure_space(this); 1699 EMIT(0xD9); 1700 EMIT(0xFE); 1701 } 1702 1703 1704 void Assembler::fptan() { 1705 EnsureSpace ensure_space(this); 1706 EMIT(0xD9); 1707 EMIT(0xF2); 1708 } 1709 1710 1711 void Assembler::fyl2x() { 1712 EnsureSpace ensure_space(this); 1713 EMIT(0xD9); 1714 EMIT(0xF1); 1715 } 1716 1717 1718 void Assembler::f2xm1() { 1719 EnsureSpace ensure_space(this); 1720 EMIT(0xD9); 1721 EMIT(0xF0); 1722 } 1723 1724 1725 void Assembler::fscale() { 1726 EnsureSpace ensure_space(this); 1727 EMIT(0xD9); 1728 EMIT(0xFD); 1729 } 1730 1731 1732 void Assembler::fninit() { 1733 EnsureSpace ensure_space(this); 1734 EMIT(0xDB); 1735 EMIT(0xE3); 1736 } 1737 1738 1739 void Assembler::fadd(int i) { 1740 EnsureSpace ensure_space(this); 1741 emit_farith(0xDC, 0xC0, i); 1742 } 1743 1744 1745 void Assembler::fadd_i(int i) { 1746 EnsureSpace ensure_space(this); 1747 emit_farith(0xD8, 0xC0, i); 1748 } 1749 1750 1751 void Assembler::fsub(int i) { 1752 EnsureSpace ensure_space(this); 1753 emit_farith(0xDC, 0xE8, i); 1754 } 1755 1756 1757 void Assembler::fsub_i(int i) { 1758 EnsureSpace ensure_space(this); 1759 emit_farith(0xD8, 0xE0, i); 1760 } 1761 1762 1763 void Assembler::fisub_s(const Operand& adr) { 1764 EnsureSpace ensure_space(this); 1765 EMIT(0xDA); 1766 emit_operand(esp, adr); 1767 } 1768 1769 1770 void Assembler::fmul_i(int i) { 1771 EnsureSpace ensure_space(this); 1772 emit_farith(0xD8, 0xC8, i); 1773 } 1774 1775 1776 void Assembler::fmul(int i) { 1777 EnsureSpace ensure_space(this); 1778 emit_farith(0xDC, 0xC8, i); 1779 } 1780 1781 1782 void Assembler::fdiv(int i) { 1783 EnsureSpace ensure_space(this); 1784 emit_farith(0xDC, 0xF8, i); 1785 } 1786 1787 1788 void Assembler::fdiv_i(int i) { 1789 EnsureSpace ensure_space(this); 1790 emit_farith(0xD8, 0xF0, i); 1791 } 1792 1793 1794 void Assembler::faddp(int i) { 1795 EnsureSpace ensure_space(this); 1796 emit_farith(0xDE, 0xC0, i); 1797 } 1798 1799 1800 void Assembler::fsubp(int i) { 1801 EnsureSpace ensure_space(this); 1802 emit_farith(0xDE, 0xE8, i); 1803 } 1804 1805 1806 void Assembler::fsubrp(int i) { 1807 EnsureSpace ensure_space(this); 1808 emit_farith(0xDE, 0xE0, i); 1809 } 1810 1811 1812 void Assembler::fmulp(int i) { 1813 EnsureSpace ensure_space(this); 1814 emit_farith(0xDE, 0xC8, i); 1815 } 1816 1817 1818 void Assembler::fdivp(int i) { 1819 EnsureSpace ensure_space(this); 1820 emit_farith(0xDE, 0xF8, i); 1821 } 1822 1823 1824 void Assembler::fprem() { 1825 EnsureSpace ensure_space(this); 1826 EMIT(0xD9); 1827 EMIT(0xF8); 1828 } 1829 1830 1831 void Assembler::fprem1() { 1832 EnsureSpace ensure_space(this); 1833 EMIT(0xD9); 1834 EMIT(0xF5); 1835 } 1836 1837 1838 void Assembler::fxch(int i) { 1839 EnsureSpace ensure_space(this); 1840 emit_farith(0xD9, 0xC8, i); 1841 } 1842 1843 1844 void Assembler::fincstp() { 1845 EnsureSpace ensure_space(this); 1846 EMIT(0xD9); 1847 EMIT(0xF7); 1848 } 1849 1850 1851 void Assembler::ffree(int i) { 1852 EnsureSpace ensure_space(this); 1853 emit_farith(0xDD, 0xC0, i); 1854 } 1855 1856 1857 void Assembler::ftst() { 1858 EnsureSpace ensure_space(this); 1859 EMIT(0xD9); 1860 EMIT(0xE4); 1861 } 1862 1863 1864 void Assembler::fucomp(int i) { 1865 EnsureSpace ensure_space(this); 1866 emit_farith(0xDD, 0xE8, i); 1867 } 1868 1869 1870 void Assembler::fucompp() { 1871 EnsureSpace ensure_space(this); 1872 EMIT(0xDA); 1873 EMIT(0xE9); 1874 } 1875 1876 1877 void Assembler::fucomi(int i) { 1878 EnsureSpace ensure_space(this); 1879 EMIT(0xDB); 1880 EMIT(0xE8 + i); 1881 } 1882 1883 1884 void Assembler::fucomip() { 1885 EnsureSpace ensure_space(this); 1886 EMIT(0xDF); 1887 EMIT(0xE9); 1888 } 1889 1890 1891 void Assembler::fcompp() { 1892 EnsureSpace ensure_space(this); 1893 EMIT(0xDE); 1894 EMIT(0xD9); 1895 } 1896 1897 1898 void Assembler::fnstsw_ax() { 1899 EnsureSpace ensure_space(this); 1900 EMIT(0xDF); 1901 EMIT(0xE0); 1902 } 1903 1904 1905 void Assembler::fwait() { 1906 EnsureSpace ensure_space(this); 1907 EMIT(0x9B); 1908 } 1909 1910 1911 void Assembler::frndint() { 1912 EnsureSpace ensure_space(this); 1913 EMIT(0xD9); 1914 EMIT(0xFC); 1915 } 1916 1917 1918 void Assembler::fnclex() { 1919 EnsureSpace ensure_space(this); 1920 EMIT(0xDB); 1921 EMIT(0xE2); 1922 } 1923 1924 1925 void Assembler::sahf() { 1926 EnsureSpace ensure_space(this); 1927 EMIT(0x9E); 1928 } 1929 1930 1931 void Assembler::setcc(Condition cc, Register reg) { 1932 ASSERT(reg.is_byte_register()); 1933 EnsureSpace ensure_space(this); 1934 EMIT(0x0F); 1935 EMIT(0x90 | cc); 1936 EMIT(0xC0 | reg.code()); 1937 } 1938 1939 1940 void Assembler::cvttss2si(Register dst, const Operand& src) { 1941 ASSERT(IsEnabled(SSE2)); 1942 EnsureSpace ensure_space(this); 1943 EMIT(0xF3); 1944 EMIT(0x0F); 1945 EMIT(0x2C); 1946 emit_operand(dst, src); 1947 } 1948 1949 1950 void Assembler::cvttsd2si(Register dst, const Operand& src) { 1951 ASSERT(IsEnabled(SSE2)); 1952 EnsureSpace ensure_space(this); 1953 EMIT(0xF2); 1954 EMIT(0x0F); 1955 EMIT(0x2C); 1956 emit_operand(dst, src); 1957 } 1958 1959 1960 void Assembler::cvtsd2si(Register dst, XMMRegister src) { 1961 ASSERT(IsEnabled(SSE2)); 1962 EnsureSpace ensure_space(this); 1963 EMIT(0xF2); 1964 EMIT(0x0F); 1965 EMIT(0x2D); 1966 emit_sse_operand(dst, src); 1967 } 1968 1969 1970 void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) { 1971 ASSERT(IsEnabled(SSE2)); 1972 EnsureSpace ensure_space(this); 1973 EMIT(0xF2); 1974 EMIT(0x0F); 1975 EMIT(0x2A); 1976 emit_sse_operand(dst, src); 1977 } 1978 1979 1980 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) { 1981 ASSERT(IsEnabled(SSE2)); 1982 EnsureSpace ensure_space(this); 1983 EMIT(0xF3); 1984 EMIT(0x0F); 1985 EMIT(0x5A); 1986 emit_sse_operand(dst, src); 1987 } 1988 1989 1990 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) { 1991 ASSERT(IsEnabled(SSE2)); 1992 EnsureSpace ensure_space(this); 1993 EMIT(0xF2); 1994 EMIT(0x0F); 1995 EMIT(0x5A); 1996 emit_sse_operand(dst, src); 1997 } 1998 1999 2000 void Assembler::addsd(XMMRegister dst, XMMRegister src) { 2001 ASSERT(IsEnabled(SSE2)); 2002 EnsureSpace ensure_space(this); 2003 EMIT(0xF2); 2004 EMIT(0x0F); 2005 EMIT(0x58); 2006 emit_sse_operand(dst, src); 2007 } 2008 2009 2010 void Assembler::addsd(XMMRegister dst, const Operand& src) { 2011 ASSERT(IsEnabled(SSE2)); 2012 EnsureSpace ensure_space(this); 2013 EMIT(0xF2); 2014 EMIT(0x0F); 2015 EMIT(0x58); 2016 emit_sse_operand(dst, src); 2017 } 2018 2019 2020 void Assembler::mulsd(XMMRegister dst, XMMRegister src) { 2021 ASSERT(IsEnabled(SSE2)); 2022 EnsureSpace ensure_space(this); 2023 EMIT(0xF2); 2024 EMIT(0x0F); 2025 EMIT(0x59); 2026 emit_sse_operand(dst, src); 2027 } 2028 2029 2030 void Assembler::mulsd(XMMRegister dst, const Operand& src) { 2031 ASSERT(IsEnabled(SSE2)); 2032 EnsureSpace ensure_space(this); 2033 EMIT(0xF2); 2034 EMIT(0x0F); 2035 EMIT(0x59); 2036 emit_sse_operand(dst, src); 2037 } 2038 2039 2040 void Assembler::subsd(XMMRegister dst, XMMRegister src) { 2041 ASSERT(IsEnabled(SSE2)); 2042 EnsureSpace ensure_space(this); 2043 EMIT(0xF2); 2044 EMIT(0x0F); 2045 EMIT(0x5C); 2046 emit_sse_operand(dst, src); 2047 } 2048 2049 2050 void Assembler::divsd(XMMRegister dst, XMMRegister src) { 2051 ASSERT(IsEnabled(SSE2)); 2052 EnsureSpace ensure_space(this); 2053 EMIT(0xF2); 2054 EMIT(0x0F); 2055 EMIT(0x5E); 2056 emit_sse_operand(dst, src); 2057 } 2058 2059 2060 void Assembler::xorpd(XMMRegister dst, XMMRegister src) { 2061 ASSERT(IsEnabled(SSE2)); 2062 EnsureSpace ensure_space(this); 2063 EMIT(0x66); 2064 EMIT(0x0F); 2065 EMIT(0x57); 2066 emit_sse_operand(dst, src); 2067 } 2068 2069 2070 void Assembler::andps(XMMRegister dst, const Operand& src) { 2071 ASSERT(IsEnabled(SSE2)); 2072 EnsureSpace ensure_space(this); 2073 EMIT(0x0F); 2074 EMIT(0x54); 2075 emit_sse_operand(dst, src); 2076 } 2077 2078 2079 void Assembler::orps(XMMRegister dst, const Operand& src) { 2080 ASSERT(IsEnabled(SSE2)); 2081 EnsureSpace ensure_space(this); 2082 EMIT(0x0F); 2083 EMIT(0x56); 2084 emit_sse_operand(dst, src); 2085 } 2086 2087 2088 void Assembler::xorps(XMMRegister dst, const Operand& src) { 2089 ASSERT(IsEnabled(SSE2)); 2090 EnsureSpace ensure_space(this); 2091 EMIT(0x0F); 2092 EMIT(0x57); 2093 emit_sse_operand(dst, src); 2094 } 2095 2096 2097 void Assembler::addps(XMMRegister dst, const Operand& src) { 2098 ASSERT(IsEnabled(SSE2)); 2099 EnsureSpace ensure_space(this); 2100 EMIT(0x0F); 2101 EMIT(0x58); 2102 emit_sse_operand(dst, src); 2103 } 2104 2105 2106 void Assembler::subps(XMMRegister dst, const Operand& src) { 2107 ASSERT(IsEnabled(SSE2)); 2108 EnsureSpace ensure_space(this); 2109 EMIT(0x0F); 2110 EMIT(0x5C); 2111 emit_sse_operand(dst, src); 2112 } 2113 2114 2115 void Assembler::mulps(XMMRegister dst, const Operand& src) { 2116 ASSERT(IsEnabled(SSE2)); 2117 EnsureSpace ensure_space(this); 2118 EMIT(0x0F); 2119 EMIT(0x59); 2120 emit_sse_operand(dst, src); 2121 } 2122 2123 2124 void Assembler::divps(XMMRegister dst, const Operand& src) { 2125 ASSERT(IsEnabled(SSE2)); 2126 EnsureSpace ensure_space(this); 2127 EMIT(0x0F); 2128 EMIT(0x5E); 2129 emit_sse_operand(dst, src); 2130 } 2131 2132 2133 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { 2134 ASSERT(IsEnabled(SSE2)); 2135 EnsureSpace ensure_space(this); 2136 EMIT(0xF2); 2137 EMIT(0x0F); 2138 EMIT(0x51); 2139 emit_sse_operand(dst, src); 2140 } 2141 2142 2143 void Assembler::andpd(XMMRegister dst, XMMRegister src) { 2144 ASSERT(IsEnabled(SSE2)); 2145 EnsureSpace ensure_space(this); 2146 EMIT(0x66); 2147 EMIT(0x0F); 2148 EMIT(0x54); 2149 emit_sse_operand(dst, src); 2150 } 2151 2152 2153 void Assembler::orpd(XMMRegister dst, XMMRegister src) { 2154 ASSERT(IsEnabled(SSE2)); 2155 EnsureSpace ensure_space(this); 2156 EMIT(0x66); 2157 EMIT(0x0F); 2158 EMIT(0x56); 2159 emit_sse_operand(dst, src); 2160 } 2161 2162 2163 void Assembler::ucomisd(XMMRegister dst, const Operand& src) { 2164 ASSERT(IsEnabled(SSE2)); 2165 EnsureSpace ensure_space(this); 2166 EMIT(0x66); 2167 EMIT(0x0F); 2168 EMIT(0x2E); 2169 emit_sse_operand(dst, src); 2170 } 2171 2172 2173 void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) { 2174 ASSERT(IsEnabled(SSE4_1)); 2175 EnsureSpace ensure_space(this); 2176 EMIT(0x66); 2177 EMIT(0x0F); 2178 EMIT(0x3A); 2179 EMIT(0x0B); 2180 emit_sse_operand(dst, src); 2181 // Mask precision exeption. 2182 EMIT(static_cast<byte>(mode) | 0x8); 2183 } 2184 2185 2186 void Assembler::movmskpd(Register dst, XMMRegister src) { 2187 ASSERT(IsEnabled(SSE2)); 2188 EnsureSpace ensure_space(this); 2189 EMIT(0x66); 2190 EMIT(0x0F); 2191 EMIT(0x50); 2192 emit_sse_operand(dst, src); 2193 } 2194 2195 2196 void Assembler::movmskps(Register dst, XMMRegister src) { 2197 ASSERT(IsEnabled(SSE2)); 2198 EnsureSpace ensure_space(this); 2199 EMIT(0x0F); 2200 EMIT(0x50); 2201 emit_sse_operand(dst, src); 2202 } 2203 2204 2205 void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) { 2206 ASSERT(IsEnabled(SSE2)); 2207 EnsureSpace ensure_space(this); 2208 EMIT(0x66); 2209 EMIT(0x0F); 2210 EMIT(0x76); 2211 emit_sse_operand(dst, src); 2212 } 2213 2214 2215 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) { 2216 ASSERT(IsEnabled(SSE2)); 2217 EnsureSpace ensure_space(this); 2218 EMIT(0xF2); 2219 EMIT(0x0F); 2220 EMIT(0xC2); 2221 emit_sse_operand(dst, src); 2222 EMIT(1); // LT == 1 2223 } 2224 2225 2226 void Assembler::movaps(XMMRegister dst, XMMRegister src) { 2227 ASSERT(IsEnabled(SSE2)); 2228 EnsureSpace ensure_space(this); 2229 EMIT(0x0F); 2230 EMIT(0x28); 2231 emit_sse_operand(dst, src); 2232 } 2233 2234 2235 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) { 2236 ASSERT(IsEnabled(SSE2)); 2237 ASSERT(is_uint8(imm8)); 2238 EnsureSpace ensure_space(this); 2239 EMIT(0x0F); 2240 EMIT(0xC6); 2241 emit_sse_operand(dst, src); 2242 EMIT(imm8); 2243 } 2244 2245 2246 void Assembler::movdqa(const Operand& dst, XMMRegister src) { 2247 ASSERT(IsEnabled(SSE2)); 2248 EnsureSpace ensure_space(this); 2249 EMIT(0x66); 2250 EMIT(0x0F); 2251 EMIT(0x7F); 2252 emit_sse_operand(src, dst); 2253 } 2254 2255 2256 void Assembler::movdqa(XMMRegister dst, const Operand& src) { 2257 ASSERT(IsEnabled(SSE2)); 2258 EnsureSpace ensure_space(this); 2259 EMIT(0x66); 2260 EMIT(0x0F); 2261 EMIT(0x6F); 2262 emit_sse_operand(dst, src); 2263 } 2264 2265 2266 void Assembler::movdqu(const Operand& dst, XMMRegister src ) { 2267 ASSERT(IsEnabled(SSE2)); 2268 EnsureSpace ensure_space(this); 2269 EMIT(0xF3); 2270 EMIT(0x0F); 2271 EMIT(0x7F); 2272 emit_sse_operand(src, dst); 2273 } 2274 2275 2276 void Assembler::movdqu(XMMRegister dst, const Operand& src) { 2277 ASSERT(IsEnabled(SSE2)); 2278 EnsureSpace ensure_space(this); 2279 EMIT(0xF3); 2280 EMIT(0x0F); 2281 EMIT(0x6F); 2282 emit_sse_operand(dst, src); 2283 } 2284 2285 2286 void Assembler::movntdqa(XMMRegister dst, const Operand& src) { 2287 ASSERT(IsEnabled(SSE4_1)); 2288 EnsureSpace ensure_space(this); 2289 EMIT(0x66); 2290 EMIT(0x0F); 2291 EMIT(0x38); 2292 EMIT(0x2A); 2293 emit_sse_operand(dst, src); 2294 } 2295 2296 2297 void Assembler::movntdq(const Operand& dst, XMMRegister src) { 2298 ASSERT(IsEnabled(SSE2)); 2299 EnsureSpace ensure_space(this); 2300 EMIT(0x66); 2301 EMIT(0x0F); 2302 EMIT(0xE7); 2303 emit_sse_operand(src, dst); 2304 } 2305 2306 2307 void Assembler::prefetch(const Operand& src, int level) { 2308 ASSERT(is_uint2(level)); 2309 EnsureSpace ensure_space(this); 2310 EMIT(0x0F); 2311 EMIT(0x18); 2312 // Emit hint number in Reg position of RegR/M. 2313 XMMRegister code = XMMRegister::from_code(level); 2314 emit_sse_operand(code, src); 2315 } 2316 2317 2318 void Assembler::movsd(const Operand& dst, XMMRegister src ) { 2319 ASSERT(IsEnabled(SSE2)); 2320 EnsureSpace ensure_space(this); 2321 EMIT(0xF2); // double 2322 EMIT(0x0F); 2323 EMIT(0x11); // store 2324 emit_sse_operand(src, dst); 2325 } 2326 2327 2328 void Assembler::movsd(XMMRegister dst, const Operand& src) { 2329 ASSERT(IsEnabled(SSE2)); 2330 EnsureSpace ensure_space(this); 2331 EMIT(0xF2); // double 2332 EMIT(0x0F); 2333 EMIT(0x10); // load 2334 emit_sse_operand(dst, src); 2335 } 2336 2337 2338 void Assembler::movss(const Operand& dst, XMMRegister src ) { 2339 ASSERT(IsEnabled(SSE2)); 2340 EnsureSpace ensure_space(this); 2341 EMIT(0xF3); // float 2342 EMIT(0x0F); 2343 EMIT(0x11); // store 2344 emit_sse_operand(src, dst); 2345 } 2346 2347 2348 void Assembler::movss(XMMRegister dst, const Operand& src) { 2349 ASSERT(IsEnabled(SSE2)); 2350 EnsureSpace ensure_space(this); 2351 EMIT(0xF3); // float 2352 EMIT(0x0F); 2353 EMIT(0x10); // load 2354 emit_sse_operand(dst, src); 2355 } 2356 2357 2358 void Assembler::movd(XMMRegister dst, const Operand& src) { 2359 ASSERT(IsEnabled(SSE2)); 2360 EnsureSpace ensure_space(this); 2361 EMIT(0x66); 2362 EMIT(0x0F); 2363 EMIT(0x6E); 2364 emit_sse_operand(dst, src); 2365 } 2366 2367 2368 void Assembler::movd(const Operand& dst, XMMRegister src) { 2369 ASSERT(IsEnabled(SSE2)); 2370 EnsureSpace ensure_space(this); 2371 EMIT(0x66); 2372 EMIT(0x0F); 2373 EMIT(0x7E); 2374 emit_sse_operand(src, dst); 2375 } 2376 2377 2378 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { 2379 ASSERT(IsEnabled(SSE4_1)); 2380 ASSERT(is_uint8(imm8)); 2381 EnsureSpace ensure_space(this); 2382 EMIT(0x66); 2383 EMIT(0x0F); 2384 EMIT(0x3A); 2385 EMIT(0x17); 2386 emit_sse_operand(src, dst); 2387 EMIT(imm8); 2388 } 2389 2390 2391 void Assembler::pand(XMMRegister dst, XMMRegister src) { 2392 ASSERT(IsEnabled(SSE2)); 2393 EnsureSpace ensure_space(this); 2394 EMIT(0x66); 2395 EMIT(0x0F); 2396 EMIT(0xDB); 2397 emit_sse_operand(dst, src); 2398 } 2399 2400 2401 void Assembler::pxor(XMMRegister dst, XMMRegister src) { 2402 ASSERT(IsEnabled(SSE2)); 2403 EnsureSpace ensure_space(this); 2404 EMIT(0x66); 2405 EMIT(0x0F); 2406 EMIT(0xEF); 2407 emit_sse_operand(dst, src); 2408 } 2409 2410 2411 void Assembler::por(XMMRegister dst, XMMRegister src) { 2412 ASSERT(IsEnabled(SSE2)); 2413 EnsureSpace ensure_space(this); 2414 EMIT(0x66); 2415 EMIT(0x0F); 2416 EMIT(0xEB); 2417 emit_sse_operand(dst, src); 2418 } 2419 2420 2421 void Assembler::ptest(XMMRegister dst, XMMRegister src) { 2422 ASSERT(IsEnabled(SSE4_1)); 2423 EnsureSpace ensure_space(this); 2424 EMIT(0x66); 2425 EMIT(0x0F); 2426 EMIT(0x38); 2427 EMIT(0x17); 2428 emit_sse_operand(dst, src); 2429 } 2430 2431 2432 void Assembler::psllq(XMMRegister reg, int8_t shift) { 2433 ASSERT(IsEnabled(SSE2)); 2434 EnsureSpace ensure_space(this); 2435 EMIT(0x66); 2436 EMIT(0x0F); 2437 EMIT(0x73); 2438 emit_sse_operand(esi, reg); // esi == 6 2439 EMIT(shift); 2440 } 2441 2442 2443 void Assembler::psllq(XMMRegister dst, XMMRegister src) { 2444 ASSERT(IsEnabled(SSE2)); 2445 EnsureSpace ensure_space(this); 2446 EMIT(0x66); 2447 EMIT(0x0F); 2448 EMIT(0xF3); 2449 emit_sse_operand(dst, src); 2450 } 2451 2452 2453 void Assembler::psrlq(XMMRegister reg, int8_t shift) { 2454 ASSERT(IsEnabled(SSE2)); 2455 EnsureSpace ensure_space(this); 2456 EMIT(0x66); 2457 EMIT(0x0F); 2458 EMIT(0x73); 2459 emit_sse_operand(edx, reg); // edx == 2 2460 EMIT(shift); 2461 } 2462 2463 2464 void Assembler::psrlq(XMMRegister dst, XMMRegister src) { 2465 ASSERT(IsEnabled(SSE2)); 2466 EnsureSpace ensure_space(this); 2467 EMIT(0x66); 2468 EMIT(0x0F); 2469 EMIT(0xD3); 2470 emit_sse_operand(dst, src); 2471 } 2472 2473 2474 void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) { 2475 ASSERT(IsEnabled(SSE2)); 2476 EnsureSpace ensure_space(this); 2477 EMIT(0x66); 2478 EMIT(0x0F); 2479 EMIT(0x70); 2480 emit_sse_operand(dst, src); 2481 EMIT(shuffle); 2482 } 2483 2484 2485 void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) { 2486 ASSERT(IsEnabled(SSE4_1)); 2487 EnsureSpace ensure_space(this); 2488 EMIT(0x66); 2489 EMIT(0x0F); 2490 EMIT(0x3A); 2491 EMIT(0x16); 2492 emit_sse_operand(src, dst); 2493 EMIT(offset); 2494 } 2495 2496 2497 void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) { 2498 ASSERT(IsEnabled(SSE4_1)); 2499 EnsureSpace ensure_space(this); 2500 EMIT(0x66); 2501 EMIT(0x0F); 2502 EMIT(0x3A); 2503 EMIT(0x22); 2504 emit_sse_operand(dst, src); 2505 EMIT(offset); 2506 } 2507 2508 2509 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { 2510 Register ireg = { reg.code() }; 2511 emit_operand(ireg, adr); 2512 } 2513 2514 2515 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { 2516 EMIT(0xC0 | dst.code() << 3 | src.code()); 2517 } 2518 2519 2520 void Assembler::emit_sse_operand(Register dst, XMMRegister src) { 2521 EMIT(0xC0 | dst.code() << 3 | src.code()); 2522 } 2523 2524 2525 void Assembler::emit_sse_operand(XMMRegister dst, Register src) { 2526 EMIT(0xC0 | (dst.code() << 3) | src.code()); 2527 } 2528 2529 2530 void Assembler::Print() { 2531 Disassembler::Decode(isolate(), stdout, buffer_, pc_); 2532 } 2533 2534 2535 void Assembler::RecordJSReturn() { 2536 positions_recorder()->WriteRecordedPositions(); 2537 EnsureSpace ensure_space(this); 2538 RecordRelocInfo(RelocInfo::JS_RETURN); 2539 } 2540 2541 2542 void Assembler::RecordDebugBreakSlot() { 2543 positions_recorder()->WriteRecordedPositions(); 2544 EnsureSpace ensure_space(this); 2545 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); 2546 } 2547 2548 2549 void Assembler::RecordComment(const char* msg, bool force) { 2550 if (FLAG_code_comments || force) { 2551 EnsureSpace ensure_space(this); 2552 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); 2553 } 2554 } 2555 2556 2557 void Assembler::GrowBuffer() { 2558 ASSERT(overflow()); 2559 if (!own_buffer_) FATAL("external code buffer is too small"); 2560 2561 // Compute new buffer size. 2562 CodeDesc desc; // the new buffer 2563 if (buffer_size_ < 4*KB) { 2564 desc.buffer_size = 4*KB; 2565 } else { 2566 desc.buffer_size = 2*buffer_size_; 2567 } 2568 // Some internal data structures overflow for very large buffers, 2569 // they must ensure that kMaximalBufferSize is not too large. 2570 if ((desc.buffer_size > kMaximalBufferSize) || 2571 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) { 2572 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); 2573 } 2574 2575 // Set up new buffer. 2576 desc.buffer = NewArray<byte>(desc.buffer_size); 2577 desc.instr_size = pc_offset(); 2578 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos()); 2579 2580 // Clear the buffer in debug mode. Use 'int3' instructions to make 2581 // sure to get into problems if we ever run uninitialized code. 2582 #ifdef DEBUG 2583 memset(desc.buffer, 0xCC, desc.buffer_size); 2584 #endif 2585 2586 // Copy the data. 2587 int pc_delta = desc.buffer - buffer_; 2588 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); 2589 OS::MemMove(desc.buffer, buffer_, desc.instr_size); 2590 OS::MemMove(rc_delta + reloc_info_writer.pos(), 2591 reloc_info_writer.pos(), desc.reloc_size); 2592 2593 // Switch buffers. 2594 if (isolate()->assembler_spare_buffer() == NULL && 2595 buffer_size_ == kMinimalBufferSize) { 2596 isolate()->set_assembler_spare_buffer(buffer_); 2597 } else { 2598 DeleteArray(buffer_); 2599 } 2600 buffer_ = desc.buffer; 2601 buffer_size_ = desc.buffer_size; 2602 pc_ += pc_delta; 2603 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 2604 reloc_info_writer.last_pc() + pc_delta); 2605 2606 // Relocate runtime entries. 2607 for (RelocIterator it(desc); !it.done(); it.next()) { 2608 RelocInfo::Mode rmode = it.rinfo()->rmode(); 2609 if (rmode == RelocInfo::INTERNAL_REFERENCE) { 2610 int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc()); 2611 if (*p != 0) { // 0 means uninitialized. 2612 *p += pc_delta; 2613 } 2614 } 2615 } 2616 2617 ASSERT(!overflow()); 2618 } 2619 2620 2621 void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { 2622 ASSERT(is_uint8(op1) && is_uint8(op2)); // wrong opcode 2623 ASSERT(is_uint8(imm8)); 2624 ASSERT((op1 & 0x01) == 0); // should be 8bit operation 2625 EMIT(op1); 2626 EMIT(op2 | dst.code()); 2627 EMIT(imm8); 2628 } 2629 2630 2631 void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) { 2632 ASSERT((0 <= sel) && (sel <= 7)); 2633 Register ireg = { sel }; 2634 if (x.is_int8()) { 2635 EMIT(0x83); // using a sign-extended 8-bit immediate. 2636 emit_operand(ireg, dst); 2637 EMIT(x.x_ & 0xFF); 2638 } else if (dst.is_reg(eax)) { 2639 EMIT((sel << 3) | 0x05); // short form if the destination is eax. 2640 emit(x); 2641 } else { 2642 EMIT(0x81); // using a literal 32-bit immediate. 2643 emit_operand(ireg, dst); 2644 emit(x); 2645 } 2646 } 2647 2648 2649 void Assembler::emit_operand(Register reg, const Operand& adr) { 2650 const unsigned length = adr.len_; 2651 ASSERT(length > 0); 2652 2653 // Emit updated ModRM byte containing the given register. 2654 pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3); 2655 2656 // Emit the rest of the encoded operand. 2657 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; 2658 pc_ += length; 2659 2660 // Emit relocation information if necessary. 2661 if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) { 2662 pc_ -= sizeof(int32_t); // pc_ must be *at* disp32 2663 RecordRelocInfo(adr.rmode_); 2664 pc_ += sizeof(int32_t); 2665 } 2666 } 2667 2668 2669 void Assembler::emit_farith(int b1, int b2, int i) { 2670 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode 2671 ASSERT(0 <= i && i < 8); // illegal stack offset 2672 EMIT(b1); 2673 EMIT(b2 + i); 2674 } 2675 2676 2677 void Assembler::db(uint8_t data) { 2678 EnsureSpace ensure_space(this); 2679 EMIT(data); 2680 } 2681 2682 2683 void Assembler::dd(uint32_t data) { 2684 EnsureSpace ensure_space(this); 2685 emit(data); 2686 } 2687 2688 2689 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2690 ASSERT(!RelocInfo::IsNone(rmode)); 2691 // Don't record external references unless the heap will be serialized. 2692 if (rmode == RelocInfo::EXTERNAL_REFERENCE) { 2693 #ifdef DEBUG 2694 if (!Serializer::enabled()) { 2695 Serializer::TooLateToEnableNow(); 2696 } 2697 #endif 2698 if (!Serializer::enabled() && !emit_debug_code()) { 2699 return; 2700 } 2701 } 2702 RelocInfo rinfo(pc_, rmode, data, NULL); 2703 reloc_info_writer.Write(&rinfo); 2704 } 2705 2706 2707 #ifdef GENERATED_CODE_COVERAGE 2708 static FILE* coverage_log = NULL; 2709 2710 2711 static void InitCoverageLog() { 2712 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); 2713 if (file_name != NULL) { 2714 coverage_log = fopen(file_name, "aw+"); 2715 } 2716 } 2717 2718 2719 void LogGeneratedCodeCoverage(const char* file_line) { 2720 const char* return_address = (&file_line)[-1]; 2721 char* push_insn = const_cast<char*>(return_address - 12); 2722 push_insn[0] = 0xeb; // Relative branch insn. 2723 push_insn[1] = 13; // Skip over coverage insns. 2724 if (coverage_log != NULL) { 2725 fprintf(coverage_log, "%s\n", file_line); 2726 fflush(coverage_log); 2727 } 2728 } 2729 2730 #endif 2731 2732 } } // namespace v8::internal 2733 2734 #endif // V8_TARGET_ARCH_IA32 2735