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