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