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