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