Home | History | Annotate | Download | only in ia32
      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