Home | History | Annotate | Download | only in x87
      1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
      2 // All Rights Reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions
      6 // are met:
      7 //
      8 // - Redistributions of source code must retain the above copyright notice,
      9 // this list of conditions and the following disclaimer.
     10 //
     11 // - Redistribution in binary form must reproduce the above copyright
     12 // notice, this list of conditions and the following disclaimer in the
     13 // documentation and/or other materials provided with the
     14 // distribution.
     15 //
     16 // - Neither the name of Sun Microsystems or the names of contributors may
     17 // be used to endorse or promote products derived from this software without
     18 // specific prior written permission.
     19 //
     20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     31 // OF THE POSSIBILITY OF SUCH DAMAGE.
     32 
     33 // The original source code covered by the above license above has been modified
     34 // significantly by Google Inc.
     35 // Copyright 2012 the V8 project authors. All rights reserved.
     36 
     37 #include "src/x87/assembler-x87.h"
     38 
     39 #if V8_TARGET_ARCH_X87
     40 
     41 #include "src/base/bits.h"
     42 #include "src/base/cpu.h"
     43 #include "src/disassembler.h"
     44 #include "src/macro-assembler.h"
     45 #include "src/v8.h"
     46 
     47 namespace v8 {
     48 namespace internal {
     49 
     50 // -----------------------------------------------------------------------------
     51 // Implementation of CpuFeatures
     52 
     53 void CpuFeatures::ProbeImpl(bool cross_compile) {
     54   base::CPU cpu;
     55 
     56   // Only use statically determined features for cross compile (snapshot).
     57   if (cross_compile) return;
     58 }
     59 
     60 
     61 void CpuFeatures::PrintTarget() { }
     62 void CpuFeatures::PrintFeatures() { }
     63 
     64 
     65 // -----------------------------------------------------------------------------
     66 // Implementation of Displacement
     67 
     68 void Displacement::init(Label* L, Type type) {
     69   DCHECK(!L->is_bound());
     70   int next = 0;
     71   if (L->is_linked()) {
     72     next = L->pos();
     73     DCHECK(next > 0);  // Displacements must be at positions > 0
     74   }
     75   // Ensure that we _never_ overflow the next field.
     76   DCHECK(NextField::is_valid(Assembler::kMaximalBufferSize));
     77   data_ = NextField::encode(next) | TypeField::encode(type);
     78 }
     79 
     80 
     81 // -----------------------------------------------------------------------------
     82 // Implementation of RelocInfo
     83 
     84 
     85 const int RelocInfo::kApplyMask =
     86     RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
     87     1 << RelocInfo::INTERNAL_REFERENCE | 1 << RelocInfo::CODE_AGE_SEQUENCE |
     88     RelocInfo::kDebugBreakSlotMask;
     89 
     90 
     91 bool RelocInfo::IsCodedSpecially() {
     92   // The deserializer needs to know whether a pointer is specially coded.  Being
     93   // specially coded on IA32 means that it is a relative address, as used by
     94   // branch instructions.  These are also the ones that need changing when a
     95   // code object moves.
     96   return (1 << rmode_) & kApplyMask;
     97 }
     98 
     99 
    100 bool RelocInfo::IsInConstantPool() {
    101   return false;
    102 }
    103 
    104 
    105 // -----------------------------------------------------------------------------
    106 // Implementation of Operand
    107 
    108 Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
    109   // [base + disp/r]
    110   if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
    111     // [base]
    112     set_modrm(0, base);
    113     if (base.is(esp)) set_sib(times_1, esp, base);
    114   } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
    115     // [base + disp8]
    116     set_modrm(1, base);
    117     if (base.is(esp)) set_sib(times_1, esp, base);
    118     set_disp8(disp);
    119   } else {
    120     // [base + disp/r]
    121     set_modrm(2, base);
    122     if (base.is(esp)) set_sib(times_1, esp, base);
    123     set_dispr(disp, rmode);
    124   }
    125 }
    126 
    127 
    128 Operand::Operand(Register base,
    129                  Register index,
    130                  ScaleFactor scale,
    131                  int32_t disp,
    132                  RelocInfo::Mode rmode) {
    133   DCHECK(!index.is(esp));  // illegal addressing mode
    134   // [base + index*scale + disp/r]
    135   if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
    136     // [base + index*scale]
    137     set_modrm(0, esp);
    138     set_sib(scale, index, base);
    139   } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
    140     // [base + index*scale + disp8]
    141     set_modrm(1, esp);
    142     set_sib(scale, index, base);
    143     set_disp8(disp);
    144   } else {
    145     // [base + index*scale + disp/r]
    146     set_modrm(2, esp);
    147     set_sib(scale, index, base);
    148     set_dispr(disp, rmode);
    149   }
    150 }
    151 
    152 
    153 Operand::Operand(Register index,
    154                  ScaleFactor scale,
    155                  int32_t disp,
    156                  RelocInfo::Mode rmode) {
    157   DCHECK(!index.is(esp));  // illegal addressing mode
    158   // [index*scale + disp/r]
    159   set_modrm(0, esp);
    160   set_sib(scale, index, ebp);
    161   set_dispr(disp, rmode);
    162 }
    163 
    164 
    165 bool Operand::is_reg(Register reg) const {
    166   return ((buf_[0] & 0xF8) == 0xC0)  // addressing mode is register only.
    167       && ((buf_[0] & 0x07) == reg.code());  // register codes match.
    168 }
    169 
    170 
    171 bool Operand::is_reg_only() const {
    172   return (buf_[0] & 0xF8) == 0xC0;  // Addressing mode is register only.
    173 }
    174 
    175 
    176 Register Operand::reg() const {
    177   DCHECK(is_reg_only());
    178   return Register::from_code(buf_[0] & 0x07);
    179 }
    180 
    181 
    182 // -----------------------------------------------------------------------------
    183 // Implementation of Assembler.
    184 
    185 // Emit a single byte. Must always be inlined.
    186 #define EMIT(x)                                 \
    187   *pc_++ = (x)
    188 
    189 
    190 #ifdef GENERATED_CODE_COVERAGE
    191 static void InitCoverageLog();
    192 #endif
    193 
    194 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
    195     : AssemblerBase(isolate, buffer, buffer_size),
    196       positions_recorder_(this) {
    197   // Clear the buffer in debug mode unless it was provided by the
    198   // caller in which case we can't be sure it's okay to overwrite
    199   // existing code in it; see CodePatcher::CodePatcher(...).
    200 #ifdef DEBUG
    201   if (own_buffer_) {
    202     memset(buffer_, 0xCC, buffer_size_);  // int3
    203   }
    204 #endif
    205 
    206   reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
    207 
    208 #ifdef GENERATED_CODE_COVERAGE
    209   InitCoverageLog();
    210 #endif
    211 }
    212 
    213 
    214 void Assembler::GetCode(CodeDesc* desc) {
    215   // Finalize code (at this point overflow() may be true, but the gap ensures
    216   // that we are still not overlapping instructions and relocation info).
    217   reloc_info_writer.Finish();
    218   DCHECK(pc_ <= reloc_info_writer.pos());  // No overlap.
    219   // Set up code descriptor.
    220   desc->buffer = buffer_;
    221   desc->buffer_size = buffer_size_;
    222   desc->instr_size = pc_offset();
    223   desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
    224   desc->origin = this;
    225   desc->constant_pool_size = 0;
    226 }
    227 
    228 
    229 void Assembler::Align(int m) {
    230   DCHECK(base::bits::IsPowerOfTwo32(m));
    231   int mask = m - 1;
    232   int addr = pc_offset();
    233   Nop((m - (addr & mask)) & mask);
    234 }
    235 
    236 
    237 bool Assembler::IsNop(Address addr) {
    238   Address a = addr;
    239   while (*a == 0x66) a++;
    240   if (*a == 0x90) return true;
    241   if (a[0] == 0xf && a[1] == 0x1f) return true;
    242   return false;
    243 }
    244 
    245 
    246 void Assembler::Nop(int bytes) {
    247   EnsureSpace ensure_space(this);
    248 
    249   // Older CPUs that do not support SSE2 may not support multibyte NOP
    250   // instructions.
    251   for (; bytes > 0; bytes--) {
    252     EMIT(0x90);
    253   }
    254   return;
    255 }
    256 
    257 
    258 void Assembler::CodeTargetAlign() {
    259   Align(16);  // Preferred alignment of jump targets on ia32.
    260 }
    261 
    262 
    263 void Assembler::cpuid() {
    264   EnsureSpace ensure_space(this);
    265   EMIT(0x0F);
    266   EMIT(0xA2);
    267 }
    268 
    269 
    270 void Assembler::pushad() {
    271   EnsureSpace ensure_space(this);
    272   EMIT(0x60);
    273 }
    274 
    275 
    276 void Assembler::popad() {
    277   EnsureSpace ensure_space(this);
    278   EMIT(0x61);
    279 }
    280 
    281 
    282 void Assembler::pushfd() {
    283   EnsureSpace ensure_space(this);
    284   EMIT(0x9C);
    285 }
    286 
    287 
    288 void Assembler::popfd() {
    289   EnsureSpace ensure_space(this);
    290   EMIT(0x9D);
    291 }
    292 
    293 
    294 void Assembler::push(const Immediate& x) {
    295   EnsureSpace ensure_space(this);
    296   if (x.is_int8()) {
    297     EMIT(0x6a);
    298     EMIT(x.x_);
    299   } else {
    300     EMIT(0x68);
    301     emit(x);
    302   }
    303 }
    304 
    305 
    306 void Assembler::push_imm32(int32_t imm32) {
    307   EnsureSpace ensure_space(this);
    308   EMIT(0x68);
    309   emit(imm32);
    310 }
    311 
    312 
    313 void Assembler::push(Register src) {
    314   EnsureSpace ensure_space(this);
    315   EMIT(0x50 | src.code());
    316 }
    317 
    318 
    319 void Assembler::push(const Operand& src) {
    320   EnsureSpace ensure_space(this);
    321   EMIT(0xFF);
    322   emit_operand(esi, src);
    323 }
    324 
    325 
    326 void Assembler::pop(Register dst) {
    327   DCHECK(reloc_info_writer.last_pc() != NULL);
    328   EnsureSpace ensure_space(this);
    329   EMIT(0x58 | dst.code());
    330 }
    331 
    332 
    333 void Assembler::pop(const Operand& dst) {
    334   EnsureSpace ensure_space(this);
    335   EMIT(0x8F);
    336   emit_operand(eax, dst);
    337 }
    338 
    339 
    340 void Assembler::enter(const Immediate& size) {
    341   EnsureSpace ensure_space(this);
    342   EMIT(0xC8);
    343   emit_w(size);
    344   EMIT(0);
    345 }
    346 
    347 
    348 void Assembler::leave() {
    349   EnsureSpace ensure_space(this);
    350   EMIT(0xC9);
    351 }
    352 
    353 
    354 void Assembler::mov_b(Register dst, const Operand& src) {
    355   CHECK(dst.is_byte_register());
    356   EnsureSpace ensure_space(this);
    357   EMIT(0x8A);
    358   emit_operand(dst, src);
    359 }
    360 
    361 
    362 void Assembler::mov_b(const Operand& dst, const Immediate& src) {
    363   EnsureSpace ensure_space(this);
    364   EMIT(0xC6);
    365   emit_operand(eax, dst);
    366   EMIT(static_cast<int8_t>(src.x_));
    367 }
    368 
    369 
    370 void Assembler::mov_b(const Operand& dst, int8_t imm8) {
    371   EnsureSpace ensure_space(this);
    372   EMIT(0xC6);
    373   emit_operand(eax, dst);
    374   EMIT(imm8);
    375 }
    376 
    377 
    378 void Assembler::mov_b(const Operand& dst, Register src) {
    379   CHECK(src.is_byte_register());
    380   EnsureSpace ensure_space(this);
    381   EMIT(0x88);
    382   emit_operand(src, dst);
    383 }
    384 
    385 
    386 void Assembler::mov_w(Register dst, const Operand& src) {
    387   EnsureSpace ensure_space(this);
    388   EMIT(0x66);
    389   EMIT(0x8B);
    390   emit_operand(dst, src);
    391 }
    392 
    393 
    394 void Assembler::mov_w(const Operand& dst, Register src) {
    395   EnsureSpace ensure_space(this);
    396   EMIT(0x66);
    397   EMIT(0x89);
    398   emit_operand(src, dst);
    399 }
    400 
    401 
    402 void Assembler::mov_w(const Operand& dst, int16_t imm16) {
    403   EnsureSpace ensure_space(this);
    404   EMIT(0x66);
    405   EMIT(0xC7);
    406   emit_operand(eax, dst);
    407   EMIT(static_cast<int8_t>(imm16 & 0xff));
    408   EMIT(static_cast<int8_t>(imm16 >> 8));
    409 }
    410 
    411 
    412 void Assembler::mov_w(const Operand& dst, const Immediate& src) {
    413   EnsureSpace ensure_space(this);
    414   EMIT(0x66);
    415   EMIT(0xC7);
    416   emit_operand(eax, dst);
    417   EMIT(static_cast<int8_t>(src.x_ & 0xff));
    418   EMIT(static_cast<int8_t>(src.x_ >> 8));
    419 }
    420 
    421 
    422 void Assembler::mov(Register dst, int32_t imm32) {
    423   EnsureSpace ensure_space(this);
    424   EMIT(0xB8 | dst.code());
    425   emit(imm32);
    426 }
    427 
    428 
    429 void Assembler::mov(Register dst, const Immediate& x) {
    430   EnsureSpace ensure_space(this);
    431   EMIT(0xB8 | dst.code());
    432   emit(x);
    433 }
    434 
    435 
    436 void Assembler::mov(Register dst, Handle<Object> handle) {
    437   EnsureSpace ensure_space(this);
    438   EMIT(0xB8 | dst.code());
    439   emit(handle);
    440 }
    441 
    442 
    443 void Assembler::mov(Register dst, const Operand& src) {
    444   EnsureSpace ensure_space(this);
    445   EMIT(0x8B);
    446   emit_operand(dst, src);
    447 }
    448 
    449 
    450 void Assembler::mov(Register dst, Register src) {
    451   EnsureSpace ensure_space(this);
    452   EMIT(0x89);
    453   EMIT(0xC0 | src.code() << 3 | dst.code());
    454 }
    455 
    456 
    457 void Assembler::mov(const Operand& dst, const Immediate& x) {
    458   EnsureSpace ensure_space(this);
    459   EMIT(0xC7);
    460   emit_operand(eax, dst);
    461   emit(x);
    462 }
    463 
    464 
    465 void Assembler::mov(const Operand& dst, Handle<Object> handle) {
    466   EnsureSpace ensure_space(this);
    467   EMIT(0xC7);
    468   emit_operand(eax, dst);
    469   emit(handle);
    470 }
    471 
    472 
    473 void Assembler::mov(const Operand& dst, Register src) {
    474   EnsureSpace ensure_space(this);
    475   EMIT(0x89);
    476   emit_operand(src, dst);
    477 }
    478 
    479 
    480 void Assembler::movsx_b(Register dst, const Operand& src) {
    481   EnsureSpace ensure_space(this);
    482   EMIT(0x0F);
    483   EMIT(0xBE);
    484   emit_operand(dst, src);
    485 }
    486 
    487 
    488 void Assembler::movsx_w(Register dst, const Operand& src) {
    489   EnsureSpace ensure_space(this);
    490   EMIT(0x0F);
    491   EMIT(0xBF);
    492   emit_operand(dst, src);
    493 }
    494 
    495 
    496 void Assembler::movzx_b(Register dst, const Operand& src) {
    497   EnsureSpace ensure_space(this);
    498   EMIT(0x0F);
    499   EMIT(0xB6);
    500   emit_operand(dst, src);
    501 }
    502 
    503 
    504 void Assembler::movzx_w(Register dst, const Operand& src) {
    505   EnsureSpace ensure_space(this);
    506   EMIT(0x0F);
    507   EMIT(0xB7);
    508   emit_operand(dst, src);
    509 }
    510 
    511 
    512 void Assembler::cld() {
    513   EnsureSpace ensure_space(this);
    514   EMIT(0xFC);
    515 }
    516 
    517 
    518 void Assembler::rep_movs() {
    519   EnsureSpace ensure_space(this);
    520   EMIT(0xF3);
    521   EMIT(0xA5);
    522 }
    523 
    524 
    525 void Assembler::rep_stos() {
    526   EnsureSpace ensure_space(this);
    527   EMIT(0xF3);
    528   EMIT(0xAB);
    529 }
    530 
    531 
    532 void Assembler::stos() {
    533   EnsureSpace ensure_space(this);
    534   EMIT(0xAB);
    535 }
    536 
    537 
    538 void Assembler::xchg(Register dst, Register src) {
    539   EnsureSpace ensure_space(this);
    540   if (src.is(eax) || dst.is(eax)) {  // Single-byte encoding.
    541     EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
    542   } else {
    543     EMIT(0x87);
    544     EMIT(0xC0 | src.code() << 3 | dst.code());
    545   }
    546 }
    547 
    548 
    549 void Assembler::xchg(Register dst, const Operand& src) {
    550   EnsureSpace ensure_space(this);
    551   EMIT(0x87);
    552   emit_operand(dst, src);
    553 }
    554 
    555 
    556 void Assembler::adc(Register dst, int32_t imm32) {
    557   EnsureSpace ensure_space(this);
    558   emit_arith(2, Operand(dst), Immediate(imm32));
    559 }
    560 
    561 
    562 void Assembler::adc(Register dst, const Operand& src) {
    563   EnsureSpace ensure_space(this);
    564   EMIT(0x13);
    565   emit_operand(dst, src);
    566 }
    567 
    568 
    569 void Assembler::add(Register dst, const Operand& src) {
    570   EnsureSpace ensure_space(this);
    571   EMIT(0x03);
    572   emit_operand(dst, src);
    573 }
    574 
    575 
    576 void Assembler::add(const Operand& dst, Register src) {
    577   EnsureSpace ensure_space(this);
    578   EMIT(0x01);
    579   emit_operand(src, dst);
    580 }
    581 
    582 
    583 void Assembler::add(const Operand& dst, const Immediate& x) {
    584   DCHECK(reloc_info_writer.last_pc() != NULL);
    585   EnsureSpace ensure_space(this);
    586   emit_arith(0, dst, x);
    587 }
    588 
    589 
    590 void Assembler::and_(Register dst, int32_t imm32) {
    591   and_(dst, Immediate(imm32));
    592 }
    593 
    594 
    595 void Assembler::and_(Register dst, const Immediate& x) {
    596   EnsureSpace ensure_space(this);
    597   emit_arith(4, Operand(dst), x);
    598 }
    599 
    600 
    601 void Assembler::and_(Register dst, const Operand& src) {
    602   EnsureSpace ensure_space(this);
    603   EMIT(0x23);
    604   emit_operand(dst, src);
    605 }
    606 
    607 
    608 void Assembler::and_(const Operand& dst, const Immediate& x) {
    609   EnsureSpace ensure_space(this);
    610   emit_arith(4, dst, x);
    611 }
    612 
    613 
    614 void Assembler::and_(const Operand& dst, Register src) {
    615   EnsureSpace ensure_space(this);
    616   EMIT(0x21);
    617   emit_operand(src, dst);
    618 }
    619 
    620 
    621 void Assembler::cmpb(const Operand& op, int8_t imm8) {
    622   EnsureSpace ensure_space(this);
    623   if (op.is_reg(eax)) {
    624     EMIT(0x3C);
    625   } else {
    626     EMIT(0x80);
    627     emit_operand(edi, op);  // edi == 7
    628   }
    629   EMIT(imm8);
    630 }
    631 
    632 
    633 void Assembler::cmpb(const Operand& op, Register reg) {
    634   CHECK(reg.is_byte_register());
    635   EnsureSpace ensure_space(this);
    636   EMIT(0x38);
    637   emit_operand(reg, op);
    638 }
    639 
    640 
    641 void Assembler::cmpb(Register reg, const Operand& op) {
    642   CHECK(reg.is_byte_register());
    643   EnsureSpace ensure_space(this);
    644   EMIT(0x3A);
    645   emit_operand(reg, op);
    646 }
    647 
    648 
    649 void Assembler::cmpw(const Operand& op, Immediate imm16) {
    650   DCHECK(imm16.is_int16());
    651   EnsureSpace ensure_space(this);
    652   EMIT(0x66);
    653   EMIT(0x81);
    654   emit_operand(edi, op);
    655   emit_w(imm16);
    656 }
    657 
    658 
    659 void Assembler::cmp(Register reg, int32_t imm32) {
    660   EnsureSpace ensure_space(this);
    661   emit_arith(7, Operand(reg), Immediate(imm32));
    662 }
    663 
    664 
    665 void Assembler::cmp(Register reg, Handle<Object> handle) {
    666   EnsureSpace ensure_space(this);
    667   emit_arith(7, Operand(reg), Immediate(handle));
    668 }
    669 
    670 
    671 void Assembler::cmp(Register reg, const Operand& op) {
    672   EnsureSpace ensure_space(this);
    673   EMIT(0x3B);
    674   emit_operand(reg, op);
    675 }
    676 
    677 
    678 void Assembler::cmp(const Operand& op, const Immediate& imm) {
    679   EnsureSpace ensure_space(this);
    680   emit_arith(7, op, imm);
    681 }
    682 
    683 
    684 void Assembler::cmp(const Operand& op, Handle<Object> handle) {
    685   EnsureSpace ensure_space(this);
    686   emit_arith(7, op, Immediate(handle));
    687 }
    688 
    689 
    690 void Assembler::cmpb_al(const Operand& op) {
    691   EnsureSpace ensure_space(this);
    692   EMIT(0x38);  // CMP r/m8, r8
    693   emit_operand(eax, op);  // eax has same code as register al.
    694 }
    695 
    696 
    697 void Assembler::cmpw_ax(const Operand& op) {
    698   EnsureSpace ensure_space(this);
    699   EMIT(0x66);
    700   EMIT(0x39);  // CMP r/m16, r16
    701   emit_operand(eax, op);  // eax has same code as register ax.
    702 }
    703 
    704 
    705 void Assembler::dec_b(Register dst) {
    706   CHECK(dst.is_byte_register());
    707   EnsureSpace ensure_space(this);
    708   EMIT(0xFE);
    709   EMIT(0xC8 | dst.code());
    710 }
    711 
    712 
    713 void Assembler::dec_b(const Operand& dst) {
    714   EnsureSpace ensure_space(this);
    715   EMIT(0xFE);
    716   emit_operand(ecx, dst);
    717 }
    718 
    719 
    720 void Assembler::dec(Register dst) {
    721   EnsureSpace ensure_space(this);
    722   EMIT(0x48 | dst.code());
    723 }
    724 
    725 
    726 void Assembler::dec(const Operand& dst) {
    727   EnsureSpace ensure_space(this);
    728   EMIT(0xFF);
    729   emit_operand(ecx, dst);
    730 }
    731 
    732 
    733 void Assembler::cdq() {
    734   EnsureSpace ensure_space(this);
    735   EMIT(0x99);
    736 }
    737 
    738 
    739 void Assembler::idiv(const Operand& src) {
    740   EnsureSpace ensure_space(this);
    741   EMIT(0xF7);
    742   emit_operand(edi, src);
    743 }
    744 
    745 
    746 void Assembler::div(const Operand& src) {
    747   EnsureSpace ensure_space(this);
    748   EMIT(0xF7);
    749   emit_operand(esi, src);
    750 }
    751 
    752 
    753 void Assembler::imul(Register reg) {
    754   EnsureSpace ensure_space(this);
    755   EMIT(0xF7);
    756   EMIT(0xE8 | reg.code());
    757 }
    758 
    759 
    760 void Assembler::imul(Register dst, const Operand& src) {
    761   EnsureSpace ensure_space(this);
    762   EMIT(0x0F);
    763   EMIT(0xAF);
    764   emit_operand(dst, src);
    765 }
    766 
    767 
    768 void Assembler::imul(Register dst, Register src, int32_t imm32) {
    769   imul(dst, Operand(src), imm32);
    770 }
    771 
    772 
    773 void Assembler::imul(Register dst, const Operand& src, int32_t imm32) {
    774   EnsureSpace ensure_space(this);
    775   if (is_int8(imm32)) {
    776     EMIT(0x6B);
    777     emit_operand(dst, src);
    778     EMIT(imm32);
    779   } else {
    780     EMIT(0x69);
    781     emit_operand(dst, src);
    782     emit(imm32);
    783   }
    784 }
    785 
    786 
    787 void Assembler::inc(Register dst) {
    788   EnsureSpace ensure_space(this);
    789   EMIT(0x40 | dst.code());
    790 }
    791 
    792 
    793 void Assembler::inc(const Operand& dst) {
    794   EnsureSpace ensure_space(this);
    795   EMIT(0xFF);
    796   emit_operand(eax, dst);
    797 }
    798 
    799 
    800 void Assembler::lea(Register dst, const Operand& src) {
    801   EnsureSpace ensure_space(this);
    802   EMIT(0x8D);
    803   emit_operand(dst, src);
    804 }
    805 
    806 
    807 void Assembler::mul(Register src) {
    808   EnsureSpace ensure_space(this);
    809   EMIT(0xF7);
    810   EMIT(0xE0 | src.code());
    811 }
    812 
    813 
    814 void Assembler::neg(Register dst) {
    815   EnsureSpace ensure_space(this);
    816   EMIT(0xF7);
    817   EMIT(0xD8 | dst.code());
    818 }
    819 
    820 
    821 void Assembler::neg(const Operand& dst) {
    822   EnsureSpace ensure_space(this);
    823   EMIT(0xF7);
    824   emit_operand(ebx, dst);
    825 }
    826 
    827 
    828 void Assembler::not_(Register dst) {
    829   EnsureSpace ensure_space(this);
    830   EMIT(0xF7);
    831   EMIT(0xD0 | dst.code());
    832 }
    833 
    834 
    835 void Assembler::not_(const Operand& dst) {
    836   EnsureSpace ensure_space(this);
    837   EMIT(0xF7);
    838   emit_operand(edx, dst);
    839 }
    840 
    841 
    842 void Assembler::or_(Register dst, int32_t imm32) {
    843   EnsureSpace ensure_space(this);
    844   emit_arith(1, Operand(dst), Immediate(imm32));
    845 }
    846 
    847 
    848 void Assembler::or_(Register dst, const Operand& src) {
    849   EnsureSpace ensure_space(this);
    850   EMIT(0x0B);
    851   emit_operand(dst, src);
    852 }
    853 
    854 
    855 void Assembler::or_(const Operand& dst, const Immediate& x) {
    856   EnsureSpace ensure_space(this);
    857   emit_arith(1, dst, x);
    858 }
    859 
    860 
    861 void Assembler::or_(const Operand& dst, Register src) {
    862   EnsureSpace ensure_space(this);
    863   EMIT(0x09);
    864   emit_operand(src, dst);
    865 }
    866 
    867 
    868 void Assembler::rcl(Register dst, uint8_t imm8) {
    869   EnsureSpace ensure_space(this);
    870   DCHECK(is_uint5(imm8));  // illegal shift count
    871   if (imm8 == 1) {
    872     EMIT(0xD1);
    873     EMIT(0xD0 | dst.code());
    874   } else {
    875     EMIT(0xC1);
    876     EMIT(0xD0 | dst.code());
    877     EMIT(imm8);
    878   }
    879 }
    880 
    881 
    882 void Assembler::rcr(Register dst, uint8_t imm8) {
    883   EnsureSpace ensure_space(this);
    884   DCHECK(is_uint5(imm8));  // illegal shift count
    885   if (imm8 == 1) {
    886     EMIT(0xD1);
    887     EMIT(0xD8 | dst.code());
    888   } else {
    889     EMIT(0xC1);
    890     EMIT(0xD8 | dst.code());
    891     EMIT(imm8);
    892   }
    893 }
    894 
    895 
    896 void Assembler::ror(const Operand& dst, uint8_t imm8) {
    897   EnsureSpace ensure_space(this);
    898   DCHECK(is_uint5(imm8));  // illegal shift count
    899   if (imm8 == 1) {
    900     EMIT(0xD1);
    901     emit_operand(ecx, dst);
    902   } else {
    903     EMIT(0xC1);
    904     emit_operand(ecx, dst);
    905     EMIT(imm8);
    906   }
    907 }
    908 
    909 
    910 void Assembler::ror_cl(const Operand& dst) {
    911   EnsureSpace ensure_space(this);
    912   EMIT(0xD3);
    913   emit_operand(ecx, dst);
    914 }
    915 
    916 
    917 void Assembler::sar(const Operand& dst, uint8_t imm8) {
    918   EnsureSpace ensure_space(this);
    919   DCHECK(is_uint5(imm8));  // illegal shift count
    920   if (imm8 == 1) {
    921     EMIT(0xD1);
    922     emit_operand(edi, dst);
    923   } else {
    924     EMIT(0xC1);
    925     emit_operand(edi, dst);
    926     EMIT(imm8);
    927   }
    928 }
    929 
    930 
    931 void Assembler::sar_cl(const Operand& dst) {
    932   EnsureSpace ensure_space(this);
    933   EMIT(0xD3);
    934   emit_operand(edi, dst);
    935 }
    936 
    937 
    938 void Assembler::sbb(Register dst, const Operand& src) {
    939   EnsureSpace ensure_space(this);
    940   EMIT(0x1B);
    941   emit_operand(dst, src);
    942 }
    943 
    944 
    945 void Assembler::shld(Register dst, const Operand& src) {
    946   EnsureSpace ensure_space(this);
    947   EMIT(0x0F);
    948   EMIT(0xA5);
    949   emit_operand(dst, src);
    950 }
    951 
    952 
    953 void Assembler::shl(const Operand& dst, uint8_t imm8) {
    954   EnsureSpace ensure_space(this);
    955   DCHECK(is_uint5(imm8));  // illegal shift count
    956   if (imm8 == 1) {
    957     EMIT(0xD1);
    958     emit_operand(esp, dst);
    959   } else {
    960     EMIT(0xC1);
    961     emit_operand(esp, dst);
    962     EMIT(imm8);
    963   }
    964 }
    965 
    966 
    967 void Assembler::shl_cl(const Operand& dst) {
    968   EnsureSpace ensure_space(this);
    969   EMIT(0xD3);
    970   emit_operand(esp, dst);
    971 }
    972 
    973 
    974 void Assembler::shrd(Register dst, const Operand& src) {
    975   EnsureSpace ensure_space(this);
    976   EMIT(0x0F);
    977   EMIT(0xAD);
    978   emit_operand(dst, src);
    979 }
    980 
    981 
    982 void Assembler::shr(const Operand& dst, uint8_t imm8) {
    983   EnsureSpace ensure_space(this);
    984   DCHECK(is_uint5(imm8));  // illegal shift count
    985   if (imm8 == 1) {
    986     EMIT(0xD1);
    987     emit_operand(ebp, dst);
    988   } else {
    989     EMIT(0xC1);
    990     emit_operand(ebp, dst);
    991     EMIT(imm8);
    992   }
    993 }
    994 
    995 
    996 void Assembler::shr_cl(const Operand& dst) {
    997   EnsureSpace ensure_space(this);
    998   EMIT(0xD3);
    999   emit_operand(ebp, dst);
   1000 }
   1001 
   1002 
   1003 void Assembler::sub(const Operand& dst, const Immediate& x) {
   1004   EnsureSpace ensure_space(this);
   1005   emit_arith(5, dst, x);
   1006 }
   1007 
   1008 
   1009 void Assembler::sub(Register dst, const Operand& src) {
   1010   EnsureSpace ensure_space(this);
   1011   EMIT(0x2B);
   1012   emit_operand(dst, src);
   1013 }
   1014 
   1015 
   1016 void Assembler::sub(const Operand& dst, Register src) {
   1017   EnsureSpace ensure_space(this);
   1018   EMIT(0x29);
   1019   emit_operand(src, dst);
   1020 }
   1021 
   1022 
   1023 void Assembler::test(Register reg, const Immediate& imm) {
   1024   if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
   1025     test_b(reg, imm.x_);
   1026     return;
   1027   }
   1028 
   1029   EnsureSpace ensure_space(this);
   1030   // This is not using emit_arith because test doesn't support
   1031   // sign-extension of 8-bit operands.
   1032   if (reg.is(eax)) {
   1033     EMIT(0xA9);
   1034   } else {
   1035     EMIT(0xF7);
   1036     EMIT(0xC0 | reg.code());
   1037   }
   1038   emit(imm);
   1039 }
   1040 
   1041 
   1042 void Assembler::test(Register reg, const Operand& op) {
   1043   EnsureSpace ensure_space(this);
   1044   EMIT(0x85);
   1045   emit_operand(reg, op);
   1046 }
   1047 
   1048 
   1049 void Assembler::test_b(Register reg, const Operand& op) {
   1050   CHECK(reg.is_byte_register());
   1051   EnsureSpace ensure_space(this);
   1052   EMIT(0x84);
   1053   emit_operand(reg, op);
   1054 }
   1055 
   1056 
   1057 void Assembler::test(const Operand& op, const Immediate& imm) {
   1058   if (op.is_reg_only()) {
   1059     test(op.reg(), imm);
   1060     return;
   1061   }
   1062   if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
   1063     return test_b(op, imm.x_);
   1064   }
   1065   EnsureSpace ensure_space(this);
   1066   EMIT(0xF7);
   1067   emit_operand(eax, op);
   1068   emit(imm);
   1069 }
   1070 
   1071 
   1072 void Assembler::test_b(Register reg, uint8_t imm8) {
   1073   EnsureSpace ensure_space(this);
   1074   // Only use test against byte for registers that have a byte
   1075   // variant: eax, ebx, ecx, and edx.
   1076   if (reg.is(eax)) {
   1077     EMIT(0xA8);
   1078     EMIT(imm8);
   1079   } else if (reg.is_byte_register()) {
   1080     emit_arith_b(0xF6, 0xC0, reg, imm8);
   1081   } else {
   1082     EMIT(0xF7);
   1083     EMIT(0xC0 | reg.code());
   1084     emit(imm8);
   1085   }
   1086 }
   1087 
   1088 
   1089 void Assembler::test_b(const Operand& op, uint8_t imm8) {
   1090   if (op.is_reg_only()) {
   1091     test_b(op.reg(), imm8);
   1092     return;
   1093   }
   1094   EnsureSpace ensure_space(this);
   1095   EMIT(0xF6);
   1096   emit_operand(eax, op);
   1097   EMIT(imm8);
   1098 }
   1099 
   1100 
   1101 void Assembler::xor_(Register dst, int32_t imm32) {
   1102   EnsureSpace ensure_space(this);
   1103   emit_arith(6, Operand(dst), Immediate(imm32));
   1104 }
   1105 
   1106 
   1107 void Assembler::xor_(Register dst, const Operand& src) {
   1108   EnsureSpace ensure_space(this);
   1109   EMIT(0x33);
   1110   emit_operand(dst, src);
   1111 }
   1112 
   1113 
   1114 void Assembler::xor_(const Operand& dst, Register src) {
   1115   EnsureSpace ensure_space(this);
   1116   EMIT(0x31);
   1117   emit_operand(src, dst);
   1118 }
   1119 
   1120 
   1121 void Assembler::xor_(const Operand& dst, const Immediate& x) {
   1122   EnsureSpace ensure_space(this);
   1123   emit_arith(6, dst, x);
   1124 }
   1125 
   1126 
   1127 void Assembler::bt(const Operand& dst, Register src) {
   1128   EnsureSpace ensure_space(this);
   1129   EMIT(0x0F);
   1130   EMIT(0xA3);
   1131   emit_operand(src, dst);
   1132 }
   1133 
   1134 
   1135 void Assembler::bts(const Operand& dst, Register src) {
   1136   EnsureSpace ensure_space(this);
   1137   EMIT(0x0F);
   1138   EMIT(0xAB);
   1139   emit_operand(src, dst);
   1140 }
   1141 
   1142 
   1143 void Assembler::bsr(Register dst, const Operand& src) {
   1144   EnsureSpace ensure_space(this);
   1145   EMIT(0x0F);
   1146   EMIT(0xBD);
   1147   emit_operand(dst, src);
   1148 }
   1149 
   1150 
   1151 void Assembler::bsf(Register dst, const Operand& src) {
   1152   EnsureSpace ensure_space(this);
   1153   EMIT(0x0F);
   1154   EMIT(0xBC);
   1155   emit_operand(dst, src);
   1156 }
   1157 
   1158 
   1159 void Assembler::hlt() {
   1160   EnsureSpace ensure_space(this);
   1161   EMIT(0xF4);
   1162 }
   1163 
   1164 
   1165 void Assembler::int3() {
   1166   EnsureSpace ensure_space(this);
   1167   EMIT(0xCC);
   1168 }
   1169 
   1170 
   1171 void Assembler::nop() {
   1172   EnsureSpace ensure_space(this);
   1173   EMIT(0x90);
   1174 }
   1175 
   1176 
   1177 void Assembler::ret(int imm16) {
   1178   EnsureSpace ensure_space(this);
   1179   DCHECK(is_uint16(imm16));
   1180   if (imm16 == 0) {
   1181     EMIT(0xC3);
   1182   } else {
   1183     EMIT(0xC2);
   1184     EMIT(imm16 & 0xFF);
   1185     EMIT((imm16 >> 8) & 0xFF);
   1186   }
   1187 }
   1188 
   1189 
   1190 void Assembler::ud2() {
   1191   EnsureSpace ensure_space(this);
   1192   EMIT(0x0F);
   1193   EMIT(0x0B);
   1194 }
   1195 
   1196 
   1197 // Labels refer to positions in the (to be) generated code.
   1198 // There are bound, linked, and unused labels.
   1199 //
   1200 // Bound labels refer to known positions in the already
   1201 // generated code. pos() is the position the label refers to.
   1202 //
   1203 // Linked labels refer to unknown positions in the code
   1204 // to be generated; pos() is the position of the 32bit
   1205 // Displacement of the last instruction using the label.
   1206 
   1207 
   1208 void Assembler::print(Label* L) {
   1209   if (L->is_unused()) {
   1210     PrintF("unused label\n");
   1211   } else if (L->is_bound()) {
   1212     PrintF("bound label to %d\n", L->pos());
   1213   } else if (L->is_linked()) {
   1214     Label l = *L;
   1215     PrintF("unbound label");
   1216     while (l.is_linked()) {
   1217       Displacement disp = disp_at(&l);
   1218       PrintF("@ %d ", l.pos());
   1219       disp.print();
   1220       PrintF("\n");
   1221       disp.next(&l);
   1222     }
   1223   } else {
   1224     PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
   1225   }
   1226 }
   1227 
   1228 
   1229 void Assembler::bind_to(Label* L, int pos) {
   1230   EnsureSpace ensure_space(this);
   1231   DCHECK(0 <= pos && pos <= pc_offset());  // must have a valid binding position
   1232   while (L->is_linked()) {
   1233     Displacement disp = disp_at(L);
   1234     int fixup_pos = L->pos();
   1235     if (disp.type() == Displacement::CODE_ABSOLUTE) {
   1236       long_at_put(fixup_pos, reinterpret_cast<int>(buffer_ + pos));
   1237       internal_reference_positions_.push_back(fixup_pos);
   1238     } else if (disp.type() == Displacement::CODE_RELATIVE) {
   1239       // Relative to Code* heap object pointer.
   1240       long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
   1241     } else {
   1242       if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
   1243         DCHECK(byte_at(fixup_pos - 1) == 0xE9);  // jmp expected
   1244       }
   1245       // Relative address, relative to point after address.
   1246       int imm32 = pos - (fixup_pos + sizeof(int32_t));
   1247       long_at_put(fixup_pos, imm32);
   1248     }
   1249     disp.next(L);
   1250   }
   1251   while (L->is_near_linked()) {
   1252     int fixup_pos = L->near_link_pos();
   1253     int offset_to_next =
   1254         static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
   1255     DCHECK(offset_to_next <= 0);
   1256     // Relative address, relative to point after address.
   1257     int disp = pos - fixup_pos - sizeof(int8_t);
   1258     CHECK(0 <= disp && disp <= 127);
   1259     set_byte_at(fixup_pos, disp);
   1260     if (offset_to_next < 0) {
   1261       L->link_to(fixup_pos + offset_to_next, Label::kNear);
   1262     } else {
   1263       L->UnuseNear();
   1264     }
   1265   }
   1266   L->bind_to(pos);
   1267 }
   1268 
   1269 
   1270 void Assembler::bind(Label* L) {
   1271   EnsureSpace ensure_space(this);
   1272   DCHECK(!L->is_bound());  // label can only be bound once
   1273   bind_to(L, pc_offset());
   1274 }
   1275 
   1276 
   1277 void Assembler::call(Label* L) {
   1278   positions_recorder()->WriteRecordedPositions();
   1279   EnsureSpace ensure_space(this);
   1280   if (L->is_bound()) {
   1281     const int long_size = 5;
   1282     int offs = L->pos() - pc_offset();
   1283     DCHECK(offs <= 0);
   1284     // 1110 1000 #32-bit disp.
   1285     EMIT(0xE8);
   1286     emit(offs - long_size);
   1287   } else {
   1288     // 1110 1000 #32-bit disp.
   1289     EMIT(0xE8);
   1290     emit_disp(L, Displacement::OTHER);
   1291   }
   1292 }
   1293 
   1294 
   1295 void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
   1296   positions_recorder()->WriteRecordedPositions();
   1297   EnsureSpace ensure_space(this);
   1298   DCHECK(!RelocInfo::IsCodeTarget(rmode));
   1299   EMIT(0xE8);
   1300   if (RelocInfo::IsRuntimeEntry(rmode)) {
   1301     emit(reinterpret_cast<uint32_t>(entry), rmode);
   1302   } else {
   1303     emit(entry - (pc_ + sizeof(int32_t)), rmode);
   1304   }
   1305 }
   1306 
   1307 
   1308 int Assembler::CallSize(const Operand& adr) {
   1309   // Call size is 1 (opcode) + adr.len_ (operand).
   1310   return 1 + adr.len_;
   1311 }
   1312 
   1313 
   1314 void Assembler::call(const Operand& adr) {
   1315   positions_recorder()->WriteRecordedPositions();
   1316   EnsureSpace ensure_space(this);
   1317   EMIT(0xFF);
   1318   emit_operand(edx, adr);
   1319 }
   1320 
   1321 
   1322 int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
   1323   return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
   1324 }
   1325 
   1326 
   1327 void Assembler::call(Handle<Code> code,
   1328                      RelocInfo::Mode rmode,
   1329                      TypeFeedbackId ast_id) {
   1330   positions_recorder()->WriteRecordedPositions();
   1331   EnsureSpace ensure_space(this);
   1332   DCHECK(RelocInfo::IsCodeTarget(rmode)
   1333       || rmode == RelocInfo::CODE_AGE_SEQUENCE);
   1334   EMIT(0xE8);
   1335   emit(code, rmode, ast_id);
   1336 }
   1337 
   1338 
   1339 void Assembler::jmp(Label* L, Label::Distance distance) {
   1340   EnsureSpace ensure_space(this);
   1341   if (L->is_bound()) {
   1342     const int short_size = 2;
   1343     const int long_size  = 5;
   1344     int offs = L->pos() - pc_offset();
   1345     DCHECK(offs <= 0);
   1346     if (is_int8(offs - short_size)) {
   1347       // 1110 1011 #8-bit disp.
   1348       EMIT(0xEB);
   1349       EMIT((offs - short_size) & 0xFF);
   1350     } else {
   1351       // 1110 1001 #32-bit disp.
   1352       EMIT(0xE9);
   1353       emit(offs - long_size);
   1354     }
   1355   } else if (distance == Label::kNear) {
   1356     EMIT(0xEB);
   1357     emit_near_disp(L);
   1358   } else {
   1359     // 1110 1001 #32-bit disp.
   1360     EMIT(0xE9);
   1361     emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
   1362   }
   1363 }
   1364 
   1365 
   1366 void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
   1367   EnsureSpace ensure_space(this);
   1368   DCHECK(!RelocInfo::IsCodeTarget(rmode));
   1369   EMIT(0xE9);
   1370   if (RelocInfo::IsRuntimeEntry(rmode)) {
   1371     emit(reinterpret_cast<uint32_t>(entry), rmode);
   1372   } else {
   1373     emit(entry - (pc_ + sizeof(int32_t)), rmode);
   1374   }
   1375 }
   1376 
   1377 
   1378 void Assembler::jmp(const Operand& adr) {
   1379   EnsureSpace ensure_space(this);
   1380   EMIT(0xFF);
   1381   emit_operand(esp, adr);
   1382 }
   1383 
   1384 
   1385 void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
   1386   EnsureSpace ensure_space(this);
   1387   DCHECK(RelocInfo::IsCodeTarget(rmode));
   1388   EMIT(0xE9);
   1389   emit(code, rmode);
   1390 }
   1391 
   1392 
   1393 void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
   1394   EnsureSpace ensure_space(this);
   1395   DCHECK(0 <= cc && static_cast<int>(cc) < 16);
   1396   if (L->is_bound()) {
   1397     const int short_size = 2;
   1398     const int long_size  = 6;
   1399     int offs = L->pos() - pc_offset();
   1400     DCHECK(offs <= 0);
   1401     if (is_int8(offs - short_size)) {
   1402       // 0111 tttn #8-bit disp
   1403       EMIT(0x70 | cc);
   1404       EMIT((offs - short_size) & 0xFF);
   1405     } else {
   1406       // 0000 1111 1000 tttn #32-bit disp
   1407       EMIT(0x0F);
   1408       EMIT(0x80 | cc);
   1409       emit(offs - long_size);
   1410     }
   1411   } else if (distance == Label::kNear) {
   1412     EMIT(0x70 | cc);
   1413     emit_near_disp(L);
   1414   } else {
   1415     // 0000 1111 1000 tttn #32-bit disp
   1416     // Note: could eliminate cond. jumps to this jump if condition
   1417     //       is the same however, seems to be rather unlikely case.
   1418     EMIT(0x0F);
   1419     EMIT(0x80 | cc);
   1420     emit_disp(L, Displacement::OTHER);
   1421   }
   1422 }
   1423 
   1424 
   1425 void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
   1426   EnsureSpace ensure_space(this);
   1427   DCHECK((0 <= cc) && (static_cast<int>(cc) < 16));
   1428   // 0000 1111 1000 tttn #32-bit disp.
   1429   EMIT(0x0F);
   1430   EMIT(0x80 | cc);
   1431   if (RelocInfo::IsRuntimeEntry(rmode)) {
   1432     emit(reinterpret_cast<uint32_t>(entry), rmode);
   1433   } else {
   1434     emit(entry - (pc_ + sizeof(int32_t)), rmode);
   1435   }
   1436 }
   1437 
   1438 
   1439 void Assembler::j(Condition cc, Handle<Code> code, RelocInfo::Mode rmode) {
   1440   EnsureSpace ensure_space(this);
   1441   // 0000 1111 1000 tttn #32-bit disp
   1442   EMIT(0x0F);
   1443   EMIT(0x80 | cc);
   1444   emit(code, rmode);
   1445 }
   1446 
   1447 
   1448 // FPU instructions.
   1449 
   1450 void Assembler::fld(int i) {
   1451   EnsureSpace ensure_space(this);
   1452   emit_farith(0xD9, 0xC0, i);
   1453 }
   1454 
   1455 
   1456 void Assembler::fstp(int i) {
   1457   EnsureSpace ensure_space(this);
   1458   emit_farith(0xDD, 0xD8, i);
   1459 }
   1460 
   1461 
   1462 void Assembler::fld1() {
   1463   EnsureSpace ensure_space(this);
   1464   EMIT(0xD9);
   1465   EMIT(0xE8);
   1466 }
   1467 
   1468 
   1469 void Assembler::fldpi() {
   1470   EnsureSpace ensure_space(this);
   1471   EMIT(0xD9);
   1472   EMIT(0xEB);
   1473 }
   1474 
   1475 
   1476 void Assembler::fldz() {
   1477   EnsureSpace ensure_space(this);
   1478   EMIT(0xD9);
   1479   EMIT(0xEE);
   1480 }
   1481 
   1482 
   1483 void Assembler::fldln2() {
   1484   EnsureSpace ensure_space(this);
   1485   EMIT(0xD9);
   1486   EMIT(0xED);
   1487 }
   1488 
   1489 
   1490 void Assembler::fld_s(const Operand& adr) {
   1491   EnsureSpace ensure_space(this);
   1492   EMIT(0xD9);
   1493   emit_operand(eax, adr);
   1494 }
   1495 
   1496 
   1497 void Assembler::fld_d(const Operand& adr) {
   1498   EnsureSpace ensure_space(this);
   1499   EMIT(0xDD);
   1500   emit_operand(eax, adr);
   1501 }
   1502 
   1503 
   1504 void Assembler::fstp_s(const Operand& adr) {
   1505   EnsureSpace ensure_space(this);
   1506   EMIT(0xD9);
   1507   emit_operand(ebx, adr);
   1508 }
   1509 
   1510 
   1511 void Assembler::fst_s(const Operand& adr) {
   1512   EnsureSpace ensure_space(this);
   1513   EMIT(0xD9);
   1514   emit_operand(edx, adr);
   1515 }
   1516 
   1517 
   1518 void Assembler::fldcw(const Operand& adr) {
   1519   EnsureSpace ensure_space(this);
   1520   EMIT(0xD9);
   1521   emit_operand(ebp, adr);
   1522 }
   1523 
   1524 
   1525 void Assembler::fnstcw(const Operand& adr) {
   1526   EnsureSpace ensure_space(this);
   1527   EMIT(0xD9);
   1528   emit_operand(edi, adr);
   1529 }
   1530 
   1531 
   1532 void Assembler::fstp_d(const Operand& adr) {
   1533   EnsureSpace ensure_space(this);
   1534   EMIT(0xDD);
   1535   emit_operand(ebx, adr);
   1536 }
   1537 
   1538 
   1539 void Assembler::fst_d(const Operand& adr) {
   1540   EnsureSpace ensure_space(this);
   1541   EMIT(0xDD);
   1542   emit_operand(edx, adr);
   1543 }
   1544 
   1545 
   1546 void Assembler::fild_s(const Operand& adr) {
   1547   EnsureSpace ensure_space(this);
   1548   EMIT(0xDB);
   1549   emit_operand(eax, adr);
   1550 }
   1551 
   1552 
   1553 void Assembler::fild_d(const Operand& adr) {
   1554   EnsureSpace ensure_space(this);
   1555   EMIT(0xDF);
   1556   emit_operand(ebp, adr);
   1557 }
   1558 
   1559 
   1560 void Assembler::fistp_s(const Operand& adr) {
   1561   EnsureSpace ensure_space(this);
   1562   EMIT(0xDB);
   1563   emit_operand(ebx, adr);
   1564 }
   1565 
   1566 
   1567 void Assembler::fisttp_s(const Operand& adr) {
   1568   DCHECK(IsEnabled(SSE3));
   1569   EnsureSpace ensure_space(this);
   1570   EMIT(0xDB);
   1571   emit_operand(ecx, adr);
   1572 }
   1573 
   1574 
   1575 void Assembler::fisttp_d(const Operand& adr) {
   1576   DCHECK(IsEnabled(SSE3));
   1577   EnsureSpace ensure_space(this);
   1578   EMIT(0xDD);
   1579   emit_operand(ecx, adr);
   1580 }
   1581 
   1582 
   1583 void Assembler::fist_s(const Operand& adr) {
   1584   EnsureSpace ensure_space(this);
   1585   EMIT(0xDB);
   1586   emit_operand(edx, adr);
   1587 }
   1588 
   1589 
   1590 void Assembler::fistp_d(const Operand& adr) {
   1591   EnsureSpace ensure_space(this);
   1592   EMIT(0xDF);
   1593   emit_operand(edi, adr);
   1594 }
   1595 
   1596 
   1597 void Assembler::fabs() {
   1598   EnsureSpace ensure_space(this);
   1599   EMIT(0xD9);
   1600   EMIT(0xE1);
   1601 }
   1602 
   1603 
   1604 void Assembler::fchs() {
   1605   EnsureSpace ensure_space(this);
   1606   EMIT(0xD9);
   1607   EMIT(0xE0);
   1608 }
   1609 
   1610 
   1611 void Assembler::fsqrt() {
   1612   EnsureSpace ensure_space(this);
   1613   EMIT(0xD9);
   1614   EMIT(0xFA);
   1615 }
   1616 
   1617 
   1618 void Assembler::fcos() {
   1619   EnsureSpace ensure_space(this);
   1620   EMIT(0xD9);
   1621   EMIT(0xFF);
   1622 }
   1623 
   1624 
   1625 void Assembler::fsin() {
   1626   EnsureSpace ensure_space(this);
   1627   EMIT(0xD9);
   1628   EMIT(0xFE);
   1629 }
   1630 
   1631 
   1632 void Assembler::fptan() {
   1633   EnsureSpace ensure_space(this);
   1634   EMIT(0xD9);
   1635   EMIT(0xF2);
   1636 }
   1637 
   1638 
   1639 void Assembler::fyl2x() {
   1640   EnsureSpace ensure_space(this);
   1641   EMIT(0xD9);
   1642   EMIT(0xF1);
   1643 }
   1644 
   1645 
   1646 void Assembler::f2xm1() {
   1647   EnsureSpace ensure_space(this);
   1648   EMIT(0xD9);
   1649   EMIT(0xF0);
   1650 }
   1651 
   1652 
   1653 void Assembler::fscale() {
   1654   EnsureSpace ensure_space(this);
   1655   EMIT(0xD9);
   1656   EMIT(0xFD);
   1657 }
   1658 
   1659 
   1660 void Assembler::fninit() {
   1661   EnsureSpace ensure_space(this);
   1662   EMIT(0xDB);
   1663   EMIT(0xE3);
   1664 }
   1665 
   1666 
   1667 void Assembler::fadd(int i) {
   1668   EnsureSpace ensure_space(this);
   1669   emit_farith(0xDC, 0xC0, i);
   1670 }
   1671 
   1672 
   1673 void Assembler::fadd_i(int i) {
   1674   EnsureSpace ensure_space(this);
   1675   emit_farith(0xD8, 0xC0, i);
   1676 }
   1677 
   1678 
   1679 void Assembler::fadd_d(const Operand& adr) {
   1680   EnsureSpace ensure_space(this);
   1681   EMIT(0xDC);
   1682   emit_operand(eax, adr);
   1683 }
   1684 
   1685 
   1686 void Assembler::fsub(int i) {
   1687   EnsureSpace ensure_space(this);
   1688   emit_farith(0xDC, 0xE8, i);
   1689 }
   1690 
   1691 
   1692 void Assembler::fsub_i(int i) {
   1693   EnsureSpace ensure_space(this);
   1694   emit_farith(0xD8, 0xE0, i);
   1695 }
   1696 
   1697 
   1698 void Assembler::fsubr_d(const Operand& adr) {
   1699   EnsureSpace ensure_space(this);
   1700   EMIT(0xDC);
   1701   emit_operand(ebp, adr);
   1702 }
   1703 
   1704 
   1705 void Assembler::fsub_d(const Operand& adr) {
   1706   EnsureSpace ensure_space(this);
   1707   EMIT(0xDC);
   1708   emit_operand(esp, adr);
   1709 }
   1710 
   1711 
   1712 void Assembler::fisub_s(const Operand& adr) {
   1713   EnsureSpace ensure_space(this);
   1714   EMIT(0xDA);
   1715   emit_operand(esp, adr);
   1716 }
   1717 
   1718 
   1719 void Assembler::fmul_i(int i) {
   1720   EnsureSpace ensure_space(this);
   1721   emit_farith(0xD8, 0xC8, i);
   1722 }
   1723 
   1724 
   1725 void Assembler::fmul(int i) {
   1726   EnsureSpace ensure_space(this);
   1727   emit_farith(0xDC, 0xC8, i);
   1728 }
   1729 
   1730 
   1731 void Assembler::fmul_d(const Operand& adr) {
   1732   EnsureSpace ensure_space(this);
   1733   EMIT(0xDC);
   1734   emit_operand(ecx, adr);
   1735 }
   1736 
   1737 
   1738 void Assembler::fdiv(int i) {
   1739   EnsureSpace ensure_space(this);
   1740   emit_farith(0xDC, 0xF8, i);
   1741 }
   1742 
   1743 
   1744 void Assembler::fdiv_d(const Operand& adr) {
   1745   EnsureSpace ensure_space(this);
   1746   EMIT(0xDC);
   1747   emit_operand(esi, adr);
   1748 }
   1749 
   1750 
   1751 void Assembler::fdivr_d(const Operand& adr) {
   1752   EnsureSpace ensure_space(this);
   1753   EMIT(0xDC);
   1754   emit_operand(edi, adr);
   1755 }
   1756 
   1757 
   1758 void Assembler::fdiv_i(int i) {
   1759   EnsureSpace ensure_space(this);
   1760   emit_farith(0xD8, 0xF0, i);
   1761 }
   1762 
   1763 
   1764 void Assembler::faddp(int i) {
   1765   EnsureSpace ensure_space(this);
   1766   emit_farith(0xDE, 0xC0, i);
   1767 }
   1768 
   1769 
   1770 void Assembler::fsubp(int i) {
   1771   EnsureSpace ensure_space(this);
   1772   emit_farith(0xDE, 0xE8, i);
   1773 }
   1774 
   1775 
   1776 void Assembler::fsubrp(int i) {
   1777   EnsureSpace ensure_space(this);
   1778   emit_farith(0xDE, 0xE0, i);
   1779 }
   1780 
   1781 
   1782 void Assembler::fmulp(int i) {
   1783   EnsureSpace ensure_space(this);
   1784   emit_farith(0xDE, 0xC8, i);
   1785 }
   1786 
   1787 
   1788 void Assembler::fdivp(int i) {
   1789   EnsureSpace ensure_space(this);
   1790   emit_farith(0xDE, 0xF8, i);
   1791 }
   1792 
   1793 
   1794 void Assembler::fprem() {
   1795   EnsureSpace ensure_space(this);
   1796   EMIT(0xD9);
   1797   EMIT(0xF8);
   1798 }
   1799 
   1800 
   1801 void Assembler::fprem1() {
   1802   EnsureSpace ensure_space(this);
   1803   EMIT(0xD9);
   1804   EMIT(0xF5);
   1805 }
   1806 
   1807 
   1808 void Assembler::fxch(int i) {
   1809   EnsureSpace ensure_space(this);
   1810   emit_farith(0xD9, 0xC8, i);
   1811 }
   1812 
   1813 
   1814 void Assembler::fincstp() {
   1815   EnsureSpace ensure_space(this);
   1816   EMIT(0xD9);
   1817   EMIT(0xF7);
   1818 }
   1819 
   1820 
   1821 void Assembler::ffree(int i) {
   1822   EnsureSpace ensure_space(this);
   1823   emit_farith(0xDD, 0xC0, i);
   1824 }
   1825 
   1826 
   1827 void Assembler::ftst() {
   1828   EnsureSpace ensure_space(this);
   1829   EMIT(0xD9);
   1830   EMIT(0xE4);
   1831 }
   1832 
   1833 
   1834 void Assembler::fxam() {
   1835   EnsureSpace ensure_space(this);
   1836   EMIT(0xD9);
   1837   EMIT(0xE5);
   1838 }
   1839 
   1840 
   1841 void Assembler::fucomp(int i) {
   1842   EnsureSpace ensure_space(this);
   1843   emit_farith(0xDD, 0xE8, i);
   1844 }
   1845 
   1846 
   1847 void Assembler::fucompp() {
   1848   EnsureSpace ensure_space(this);
   1849   EMIT(0xDA);
   1850   EMIT(0xE9);
   1851 }
   1852 
   1853 
   1854 void Assembler::fucomi(int i) {
   1855   EnsureSpace ensure_space(this);
   1856   EMIT(0xDB);
   1857   EMIT(0xE8 + i);
   1858 }
   1859 
   1860 
   1861 void Assembler::fucomip() {
   1862   EnsureSpace ensure_space(this);
   1863   EMIT(0xDF);
   1864   EMIT(0xE9);
   1865 }
   1866 
   1867 
   1868 void Assembler::fcompp() {
   1869   EnsureSpace ensure_space(this);
   1870   EMIT(0xDE);
   1871   EMIT(0xD9);
   1872 }
   1873 
   1874 
   1875 void Assembler::fnstsw_ax() {
   1876   EnsureSpace ensure_space(this);
   1877   EMIT(0xDF);
   1878   EMIT(0xE0);
   1879 }
   1880 
   1881 
   1882 void Assembler::fwait() {
   1883   EnsureSpace ensure_space(this);
   1884   EMIT(0x9B);
   1885 }
   1886 
   1887 
   1888 void Assembler::frndint() {
   1889   EnsureSpace ensure_space(this);
   1890   EMIT(0xD9);
   1891   EMIT(0xFC);
   1892 }
   1893 
   1894 
   1895 void Assembler::fnclex() {
   1896   EnsureSpace ensure_space(this);
   1897   EMIT(0xDB);
   1898   EMIT(0xE2);
   1899 }
   1900 
   1901 
   1902 void Assembler::fnsave(const Operand& adr) {
   1903   EnsureSpace ensure_space(this);
   1904   EMIT(0xDD);
   1905   emit_operand(esi, adr);
   1906 }
   1907 
   1908 
   1909 void Assembler::frstor(const Operand& adr) {
   1910   EnsureSpace ensure_space(this);
   1911   EMIT(0xDD);
   1912   emit_operand(esp, adr);
   1913 }
   1914 
   1915 
   1916 void Assembler::sahf() {
   1917   EnsureSpace ensure_space(this);
   1918   EMIT(0x9E);
   1919 }
   1920 
   1921 
   1922 void Assembler::setcc(Condition cc, Register reg) {
   1923   DCHECK(reg.is_byte_register());
   1924   EnsureSpace ensure_space(this);
   1925   EMIT(0x0F);
   1926   EMIT(0x90 | cc);
   1927   EMIT(0xC0 | reg.code());
   1928 }
   1929 
   1930 
   1931 void Assembler::GrowBuffer() {
   1932   DCHECK(buffer_overflow());
   1933   if (!own_buffer_) FATAL("external code buffer is too small");
   1934 
   1935   // Compute new buffer size.
   1936   CodeDesc desc;  // the new buffer
   1937   desc.buffer_size = 2 * buffer_size_;
   1938 
   1939   // Some internal data structures overflow for very large buffers,
   1940   // they must ensure that kMaximalBufferSize is not too large.
   1941   if ((desc.buffer_size > kMaximalBufferSize) ||
   1942       (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
   1943     V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
   1944   }
   1945 
   1946   // Set up new buffer.
   1947   desc.buffer = NewArray<byte>(desc.buffer_size);
   1948   desc.origin = this;
   1949   desc.instr_size = pc_offset();
   1950   desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
   1951 
   1952   // Clear the buffer in debug mode. Use 'int3' instructions to make
   1953   // sure to get into problems if we ever run uninitialized code.
   1954 #ifdef DEBUG
   1955   memset(desc.buffer, 0xCC, desc.buffer_size);
   1956 #endif
   1957 
   1958   // Copy the data.
   1959   int pc_delta = desc.buffer - buffer_;
   1960   int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
   1961   MemMove(desc.buffer, buffer_, desc.instr_size);
   1962   MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
   1963           desc.reloc_size);
   1964 
   1965   DeleteArray(buffer_);
   1966   buffer_ = desc.buffer;
   1967   buffer_size_ = desc.buffer_size;
   1968   pc_ += pc_delta;
   1969   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
   1970                                reloc_info_writer.last_pc() + pc_delta);
   1971 
   1972   // Relocate internal references.
   1973   for (auto pos : internal_reference_positions_) {
   1974     int32_t* p = reinterpret_cast<int32_t*>(buffer_ + pos);
   1975     *p += pc_delta;
   1976   }
   1977 
   1978   DCHECK(!buffer_overflow());
   1979 }
   1980 
   1981 
   1982 void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
   1983   DCHECK(is_uint8(op1) && is_uint8(op2));  // wrong opcode
   1984   DCHECK(is_uint8(imm8));
   1985   DCHECK((op1 & 0x01) == 0);  // should be 8bit operation
   1986   EMIT(op1);
   1987   EMIT(op2 | dst.code());
   1988   EMIT(imm8);
   1989 }
   1990 
   1991 
   1992 void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
   1993   DCHECK((0 <= sel) && (sel <= 7));
   1994   Register ireg = { sel };
   1995   if (x.is_int8()) {
   1996     EMIT(0x83);  // using a sign-extended 8-bit immediate.
   1997     emit_operand(ireg, dst);
   1998     EMIT(x.x_ & 0xFF);
   1999   } else if (dst.is_reg(eax)) {
   2000     EMIT((sel << 3) | 0x05);  // short form if the destination is eax.
   2001     emit(x);
   2002   } else {
   2003     EMIT(0x81);  // using a literal 32-bit immediate.
   2004     emit_operand(ireg, dst);
   2005     emit(x);
   2006   }
   2007 }
   2008 
   2009 
   2010 void Assembler::emit_operand(Register reg, const Operand& adr) {
   2011   const unsigned length = adr.len_;
   2012   DCHECK(length > 0);
   2013 
   2014   // Emit updated ModRM byte containing the given register.
   2015   pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
   2016 
   2017   // Emit the rest of the encoded operand.
   2018   for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
   2019   pc_ += length;
   2020 
   2021   // Emit relocation information if necessary.
   2022   if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
   2023     pc_ -= sizeof(int32_t);  // pc_ must be *at* disp32
   2024     RecordRelocInfo(adr.rmode_);
   2025     if (adr.rmode_ == RelocInfo::INTERNAL_REFERENCE) {  // Fixup for labels
   2026       emit_label(*reinterpret_cast<Label**>(pc_));
   2027     } else {
   2028       pc_ += sizeof(int32_t);
   2029     }
   2030   }
   2031 }
   2032 
   2033 
   2034 void Assembler::emit_label(Label* label) {
   2035   if (label->is_bound()) {
   2036     internal_reference_positions_.push_back(pc_offset());
   2037     emit(reinterpret_cast<uint32_t>(buffer_ + label->pos()));
   2038   } else {
   2039     emit_disp(label, Displacement::CODE_ABSOLUTE);
   2040   }
   2041 }
   2042 
   2043 
   2044 void Assembler::emit_farith(int b1, int b2, int i) {
   2045   DCHECK(is_uint8(b1) && is_uint8(b2));  // wrong opcode
   2046   DCHECK(0 <= i &&  i < 8);  // illegal stack offset
   2047   EMIT(b1);
   2048   EMIT(b2 + i);
   2049 }
   2050 
   2051 
   2052 void Assembler::db(uint8_t data) {
   2053   EnsureSpace ensure_space(this);
   2054   EMIT(data);
   2055 }
   2056 
   2057 
   2058 void Assembler::dd(uint32_t data) {
   2059   EnsureSpace ensure_space(this);
   2060   emit(data);
   2061 }
   2062 
   2063 
   2064 void Assembler::dq(uint64_t data) {
   2065   EnsureSpace ensure_space(this);
   2066   emit_q(data);
   2067 }
   2068 
   2069 
   2070 void Assembler::dd(Label* label) {
   2071   EnsureSpace ensure_space(this);
   2072   RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
   2073   emit_label(label);
   2074 }
   2075 
   2076 
   2077 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
   2078   DCHECK(!RelocInfo::IsNone(rmode));
   2079   // Don't record external references unless the heap will be serialized.
   2080   if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
   2081       !serializer_enabled() && !emit_debug_code()) {
   2082       return;
   2083   }
   2084   RelocInfo rinfo(isolate(), pc_, rmode, data, NULL);
   2085   reloc_info_writer.Write(&rinfo);
   2086 }
   2087 
   2088 
   2089 #ifdef GENERATED_CODE_COVERAGE
   2090 static FILE* coverage_log = NULL;
   2091 
   2092 
   2093 static void InitCoverageLog() {
   2094   char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
   2095   if (file_name != NULL) {
   2096     coverage_log = fopen(file_name, "aw+");
   2097   }
   2098 }
   2099 
   2100 
   2101 void LogGeneratedCodeCoverage(const char* file_line) {
   2102   const char* return_address = (&file_line)[-1];
   2103   char* push_insn = const_cast<char*>(return_address - 12);
   2104   push_insn[0] = 0xeb;  // Relative branch insn.
   2105   push_insn[1] = 13;    // Skip over coverage insns.
   2106   if (coverage_log != NULL) {
   2107     fprintf(coverage_log, "%s\n", file_line);
   2108     fflush(coverage_log);
   2109   }
   2110 }
   2111 
   2112 #endif
   2113 
   2114 }  // namespace internal
   2115 }  // namespace v8
   2116 
   2117 #endif  // V8_TARGET_ARCH_X87
   2118