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 are
      6 // 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 distribution.
     14 //
     15 // - Neither the name of Sun Microsystems or the names of contributors may
     16 // be used to endorse or promote products derived from this software without
     17 // specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     20 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     21 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 // The original source code covered by the above license above has been
     32 // modified significantly by Google Inc.
     33 // Copyright 2011 the V8 project authors. All rights reserved.
     34 
     35 // A light-weight IA32 Assembler.
     36 
     37 #ifndef V8_X87_ASSEMBLER_X87_H_
     38 #define V8_X87_ASSEMBLER_X87_H_
     39 
     40 #include <deque>
     41 
     42 #include "src/assembler.h"
     43 #include "src/isolate.h"
     44 #include "src/utils.h"
     45 
     46 namespace v8 {
     47 namespace internal {
     48 
     49 #define GENERAL_REGISTERS(V) \
     50   V(eax)                     \
     51   V(ecx)                     \
     52   V(edx)                     \
     53   V(ebx)                     \
     54   V(esp)                     \
     55   V(ebp)                     \
     56   V(esi)                     \
     57   V(edi)
     58 
     59 #define ALLOCATABLE_GENERAL_REGISTERS(V) \
     60   V(eax)                                 \
     61   V(ecx)                                 \
     62   V(edx)                                 \
     63   V(ebx)                                 \
     64   V(esi)                                 \
     65   V(edi)
     66 
     67 #define DOUBLE_REGISTERS(V) \
     68   V(stX_0)                  \
     69   V(stX_1)                  \
     70   V(stX_2)                  \
     71   V(stX_3)                  \
     72   V(stX_4)                  \
     73   V(stX_5)                  \
     74   V(stX_6)                  \
     75   V(stX_7)
     76 
     77 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
     78   V(stX_0)                              \
     79   V(stX_1)                              \
     80   V(stX_2)                              \
     81   V(stX_3)                              \
     82   V(stX_4)                              \
     83   V(stX_5)
     84 
     85 // CPU Registers.
     86 //
     87 // 1) We would prefer to use an enum, but enum values are assignment-
     88 // compatible with int, which has caused code-generation bugs.
     89 //
     90 // 2) We would prefer to use a class instead of a struct but we don't like
     91 // the register initialization to depend on the particular initialization
     92 // order (which appears to be different on OS X, Linux, and Windows for the
     93 // installed versions of C++ we tried). Using a struct permits C-style
     94 // "initialization". Also, the Register objects cannot be const as this
     95 // forces initialization stubs in MSVC, making us dependent on initialization
     96 // order.
     97 //
     98 // 3) By not using an enum, we are possibly preventing the compiler from
     99 // doing certain constant folds, which may significantly reduce the
    100 // code generated for some assembly instructions (because they boil down
    101 // to a few constants). If this is a problem, we could change the code
    102 // such that we use an enum in optimized mode, and the struct in debug
    103 // mode. This way we get the compile-time error checking in debug mode
    104 // and best performance in optimized code.
    105 //
    106 struct Register {
    107   enum Code {
    108 #define REGISTER_CODE(R) kCode_##R,
    109     GENERAL_REGISTERS(REGISTER_CODE)
    110 #undef REGISTER_CODE
    111         kAfterLast,
    112     kCode_no_reg = -1
    113   };
    114 
    115   static const int kNumRegisters = Code::kAfterLast;
    116 
    117   static Register from_code(int code) {
    118     DCHECK(code >= 0);
    119     DCHECK(code < kNumRegisters);
    120     Register r = {code};
    121     return r;
    122   }
    123   const char* ToString();
    124   bool IsAllocatable() const;
    125   bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
    126   bool is(Register reg) const { return reg_code == reg.reg_code; }
    127   int code() const {
    128     DCHECK(is_valid());
    129     return reg_code;
    130   }
    131   int bit() const {
    132     DCHECK(is_valid());
    133     return 1 << reg_code;
    134   }
    135 
    136   bool is_byte_register() const { return reg_code <= 3; }
    137 
    138   // Unfortunately we can't make this private in a struct.
    139   int reg_code;
    140 };
    141 
    142 
    143 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
    144 GENERAL_REGISTERS(DECLARE_REGISTER)
    145 #undef DECLARE_REGISTER
    146 const Register no_reg = {Register::kCode_no_reg};
    147 
    148 
    149 struct DoubleRegister {
    150   enum Code {
    151 #define REGISTER_CODE(R) kCode_##R,
    152     DOUBLE_REGISTERS(REGISTER_CODE)
    153 #undef REGISTER_CODE
    154         kAfterLast,
    155     kCode_no_reg = -1
    156   };
    157 
    158   static const int kMaxNumRegisters = Code::kAfterLast;
    159   static const int kMaxNumAllocatableRegisters = 6;
    160 
    161   static DoubleRegister from_code(int code) {
    162     DoubleRegister result = {code};
    163     return result;
    164   }
    165 
    166   bool IsAllocatable() const;
    167   bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
    168 
    169   int code() const {
    170     DCHECK(is_valid());
    171     return reg_code;
    172   }
    173 
    174   bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
    175 
    176   const char* ToString();
    177 
    178   int reg_code;
    179 };
    180 
    181 #define DECLARE_REGISTER(R) \
    182   const DoubleRegister R = {DoubleRegister::kCode_##R};
    183 DOUBLE_REGISTERS(DECLARE_REGISTER)
    184 #undef DECLARE_REGISTER
    185 const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
    186 
    187 typedef DoubleRegister X87Register;
    188 
    189 enum Condition {
    190   // any value < 0 is considered no_condition
    191   no_condition  = -1,
    192 
    193   overflow      =  0,
    194   no_overflow   =  1,
    195   below         =  2,
    196   above_equal   =  3,
    197   equal         =  4,
    198   not_equal     =  5,
    199   below_equal   =  6,
    200   above         =  7,
    201   negative      =  8,
    202   positive      =  9,
    203   parity_even   = 10,
    204   parity_odd    = 11,
    205   less          = 12,
    206   greater_equal = 13,
    207   less_equal    = 14,
    208   greater       = 15,
    209 
    210   // aliases
    211   carry         = below,
    212   not_carry     = above_equal,
    213   zero          = equal,
    214   not_zero      = not_equal,
    215   sign          = negative,
    216   not_sign      = positive
    217 };
    218 
    219 
    220 // Returns the equivalent of !cc.
    221 // Negation of the default no_condition (-1) results in a non-default
    222 // no_condition value (-2). As long as tests for no_condition check
    223 // for condition < 0, this will work as expected.
    224 inline Condition NegateCondition(Condition cc) {
    225   return static_cast<Condition>(cc ^ 1);
    226 }
    227 
    228 
    229 // Commute a condition such that {a cond b == b cond' a}.
    230 inline Condition CommuteCondition(Condition cc) {
    231   switch (cc) {
    232     case below:
    233       return above;
    234     case above:
    235       return below;
    236     case above_equal:
    237       return below_equal;
    238     case below_equal:
    239       return above_equal;
    240     case less:
    241       return greater;
    242     case greater:
    243       return less;
    244     case greater_equal:
    245       return less_equal;
    246     case less_equal:
    247       return greater_equal;
    248     default:
    249       return cc;
    250   }
    251 }
    252 
    253 
    254 enum RoundingMode {
    255   kRoundToNearest = 0x0,
    256   kRoundDown = 0x1,
    257   kRoundUp = 0x2,
    258   kRoundToZero = 0x3
    259 };
    260 
    261 
    262 // -----------------------------------------------------------------------------
    263 // Machine instruction Immediates
    264 
    265 class Immediate BASE_EMBEDDED {
    266  public:
    267   inline explicit Immediate(int x);
    268   inline explicit Immediate(const ExternalReference& ext);
    269   inline explicit Immediate(Handle<Object> handle);
    270   inline explicit Immediate(Smi* value);
    271   inline explicit Immediate(Address addr);
    272 
    273   static Immediate CodeRelativeOffset(Label* label) {
    274     return Immediate(label);
    275   }
    276 
    277   bool is_zero() const { return x_ == 0 && RelocInfo::IsNone(rmode_); }
    278   bool is_int8() const {
    279     return -128 <= x_ && x_ < 128 && RelocInfo::IsNone(rmode_);
    280   }
    281   bool is_int16() const {
    282     return -32768 <= x_ && x_ < 32768 && RelocInfo::IsNone(rmode_);
    283   }
    284 
    285  private:
    286   inline explicit Immediate(Label* value);
    287 
    288   int x_;
    289   RelocInfo::Mode rmode_;
    290 
    291   friend class Operand;
    292   friend class Assembler;
    293   friend class MacroAssembler;
    294 };
    295 
    296 
    297 // -----------------------------------------------------------------------------
    298 // Machine instruction Operands
    299 
    300 enum ScaleFactor {
    301   times_1 = 0,
    302   times_2 = 1,
    303   times_4 = 2,
    304   times_8 = 3,
    305   times_int_size = times_4,
    306   times_half_pointer_size = times_2,
    307   times_pointer_size = times_4,
    308   times_twice_pointer_size = times_8
    309 };
    310 
    311 
    312 class Operand BASE_EMBEDDED {
    313  public:
    314   // reg
    315   INLINE(explicit Operand(Register reg));
    316 
    317   // [disp/r]
    318   INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode));
    319 
    320   // [disp/r]
    321   INLINE(explicit Operand(Immediate imm));
    322 
    323   // [base + disp/r]
    324   explicit Operand(Register base, int32_t disp,
    325                    RelocInfo::Mode rmode = RelocInfo::NONE32);
    326 
    327   // [base + index*scale + disp/r]
    328   explicit Operand(Register base,
    329                    Register index,
    330                    ScaleFactor scale,
    331                    int32_t disp,
    332                    RelocInfo::Mode rmode = RelocInfo::NONE32);
    333 
    334   // [index*scale + disp/r]
    335   explicit Operand(Register index,
    336                    ScaleFactor scale,
    337                    int32_t disp,
    338                    RelocInfo::Mode rmode = RelocInfo::NONE32);
    339 
    340   static Operand JumpTable(Register index, ScaleFactor scale, Label* table) {
    341     return Operand(index, scale, reinterpret_cast<int32_t>(table),
    342                    RelocInfo::INTERNAL_REFERENCE);
    343   }
    344 
    345   static Operand StaticVariable(const ExternalReference& ext) {
    346     return Operand(reinterpret_cast<int32_t>(ext.address()),
    347                    RelocInfo::EXTERNAL_REFERENCE);
    348   }
    349 
    350   static Operand StaticArray(Register index,
    351                              ScaleFactor scale,
    352                              const ExternalReference& arr) {
    353     return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()),
    354                    RelocInfo::EXTERNAL_REFERENCE);
    355   }
    356 
    357   static Operand ForCell(Handle<Cell> cell) {
    358     AllowDeferredHandleDereference embedding_raw_address;
    359     return Operand(reinterpret_cast<int32_t>(cell.location()),
    360                    RelocInfo::CELL);
    361   }
    362 
    363   static Operand ForRegisterPlusImmediate(Register base, Immediate imm) {
    364     return Operand(base, imm.x_, imm.rmode_);
    365   }
    366 
    367   // Returns true if this Operand is a wrapper for the specified register.
    368   bool is_reg(Register reg) const;
    369 
    370   // Returns true if this Operand is a wrapper for one register.
    371   bool is_reg_only() const;
    372 
    373   // Asserts that this Operand is a wrapper for one register and returns the
    374   // register.
    375   Register reg() const;
    376 
    377  private:
    378   // Set the ModRM byte without an encoded 'reg' register. The
    379   // register is encoded later as part of the emit_operand operation.
    380   inline void set_modrm(int mod, Register rm);
    381 
    382   inline void set_sib(ScaleFactor scale, Register index, Register base);
    383   inline void set_disp8(int8_t disp);
    384   inline void set_dispr(int32_t disp, RelocInfo::Mode rmode);
    385 
    386   byte buf_[6];
    387   // The number of bytes in buf_.
    388   unsigned int len_;
    389   // Only valid if len_ > 4.
    390   RelocInfo::Mode rmode_;
    391 
    392   friend class Assembler;
    393   friend class MacroAssembler;
    394 };
    395 
    396 
    397 // -----------------------------------------------------------------------------
    398 // A Displacement describes the 32bit immediate field of an instruction which
    399 // may be used together with a Label in order to refer to a yet unknown code
    400 // position. Displacements stored in the instruction stream are used to describe
    401 // the instruction and to chain a list of instructions using the same Label.
    402 // A Displacement contains 2 different fields:
    403 //
    404 // next field: position of next displacement in the chain (0 = end of list)
    405 // type field: instruction type
    406 //
    407 // A next value of null (0) indicates the end of a chain (note that there can
    408 // be no displacement at position zero, because there is always at least one
    409 // instruction byte before the displacement).
    410 //
    411 // Displacement _data field layout
    412 //
    413 // |31.....2|1......0|
    414 // [  next  |  type  |
    415 
    416 class Displacement BASE_EMBEDDED {
    417  public:
    418   enum Type { UNCONDITIONAL_JUMP, CODE_RELATIVE, OTHER, CODE_ABSOLUTE };
    419 
    420   int data() const { return data_; }
    421   Type type() const { return TypeField::decode(data_); }
    422   void next(Label* L) const {
    423     int n = NextField::decode(data_);
    424     n > 0 ? L->link_to(n) : L->Unuse();
    425   }
    426   void link_to(Label* L) { init(L, type()); }
    427 
    428   explicit Displacement(int data) { data_ = data; }
    429 
    430   Displacement(Label* L, Type type) { init(L, type); }
    431 
    432   void print() {
    433     PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"),
    434                        NextField::decode(data_));
    435   }
    436 
    437  private:
    438   int data_;
    439 
    440   class TypeField: public BitField<Type, 0, 2> {};
    441   class NextField: public BitField<int,  2, 32-2> {};
    442 
    443   void init(Label* L, Type type);
    444 };
    445 
    446 
    447 class Assembler : public AssemblerBase {
    448  private:
    449   // We check before assembling an instruction that there is sufficient
    450   // space to write an instruction and its relocation information.
    451   // The relocation writer's position must be kGap bytes above the end of
    452   // the generated instructions. This leaves enough space for the
    453   // longest possible ia32 instruction, 15 bytes, and the longest possible
    454   // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
    455   // (There is a 15 byte limit on ia32 instruction length that rules out some
    456   // otherwise valid instructions.)
    457   // This allows for a single, fast space check per instruction.
    458   static const int kGap = 32;
    459 
    460  public:
    461   // Create an assembler. Instructions and relocation information are emitted
    462   // into a buffer, with the instructions starting from the beginning and the
    463   // relocation information starting from the end of the buffer. See CodeDesc
    464   // for a detailed comment on the layout (globals.h).
    465   //
    466   // If the provided buffer is NULL, the assembler allocates and grows its own
    467   // buffer, and buffer_size determines the initial buffer size. The buffer is
    468   // owned by the assembler and deallocated upon destruction of the assembler.
    469   //
    470   // If the provided buffer is not NULL, the assembler uses the provided buffer
    471   // for code generation and assumes its size to be buffer_size. If the buffer
    472   // is too small, a fatal error occurs. No deallocation of the buffer is done
    473   // upon destruction of the assembler.
    474   // TODO(vitalyr): the assembler does not need an isolate.
    475   Assembler(Isolate* isolate, void* buffer, int buffer_size);
    476   virtual ~Assembler() { }
    477 
    478   // GetCode emits any pending (non-emitted) code and fills the descriptor
    479   // desc. GetCode() is idempotent; it returns the same result if no other
    480   // Assembler functions are invoked in between GetCode() calls.
    481   void GetCode(CodeDesc* desc);
    482 
    483   // Read/Modify the code target in the branch/call instruction at pc.
    484   inline static Address target_address_at(Address pc, Address constant_pool);
    485   inline static void set_target_address_at(
    486       Isolate* isolate, Address pc, Address constant_pool, Address target,
    487       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
    488   static inline Address target_address_at(Address pc, Code* code) {
    489     Address constant_pool = code ? code->constant_pool() : NULL;
    490     return target_address_at(pc, constant_pool);
    491   }
    492   static inline void set_target_address_at(
    493       Isolate* isolate, Address pc, Code* code, Address target,
    494       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED) {
    495     Address constant_pool = code ? code->constant_pool() : NULL;
    496     set_target_address_at(isolate, pc, constant_pool, target);
    497   }
    498 
    499   // Return the code target address at a call site from the return address
    500   // of that call in the instruction stream.
    501   inline static Address target_address_from_return_address(Address pc);
    502 
    503   // This sets the branch destination (which is in the instruction on x86).
    504   // This is for calls and branches within generated code.
    505   inline static void deserialization_set_special_target_at(
    506       Isolate* isolate, Address instruction_payload, Code* code,
    507       Address target) {
    508     set_target_address_at(isolate, instruction_payload, code, target);
    509   }
    510 
    511   // This sets the internal reference at the pc.
    512   inline static void deserialization_set_target_internal_reference_at(
    513       Isolate* isolate, Address pc, Address target,
    514       RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
    515 
    516   static const int kSpecialTargetSize = kPointerSize;
    517 
    518   // Distance between the address of the code target in the call instruction
    519   // and the return address
    520   static const int kCallTargetAddressOffset = kPointerSize;
    521 
    522   static const int kCallInstructionLength = 5;
    523 
    524   // The debug break slot must be able to contain a call instruction.
    525   static const int kDebugBreakSlotLength = kCallInstructionLength;
    526 
    527   // Distance between start of patched debug break slot and the emitted address
    528   // to jump to.
    529   static const int kPatchDebugBreakSlotAddressOffset = 1;  // JMP imm32.
    530 
    531   // One byte opcode for test al, 0xXX.
    532   static const byte kTestAlByte = 0xA8;
    533   // One byte opcode for nop.
    534   static const byte kNopByte = 0x90;
    535 
    536   // One byte opcode for a short unconditional jump.
    537   static const byte kJmpShortOpcode = 0xEB;
    538   // One byte prefix for a short conditional jump.
    539   static const byte kJccShortPrefix = 0x70;
    540   static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
    541   static const byte kJcShortOpcode = kJccShortPrefix | carry;
    542   static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
    543   static const byte kJzShortOpcode = kJccShortPrefix | zero;
    544 
    545 
    546   // ---------------------------------------------------------------------------
    547   // Code generation
    548   //
    549   // - function names correspond one-to-one to ia32 instruction mnemonics
    550   // - unless specified otherwise, instructions operate on 32bit operands
    551   // - instructions on 8bit (byte) operands/registers have a trailing '_b'
    552   // - instructions on 16bit (word) operands/registers have a trailing '_w'
    553   // - naming conflicts with C++ keywords are resolved via a trailing '_'
    554 
    555   // NOTE ON INTERFACE: Currently, the interface is not very consistent
    556   // in the sense that some operations (e.g. mov()) can be called in more
    557   // the one way to generate the same instruction: The Register argument
    558   // can in some cases be replaced with an Operand(Register) argument.
    559   // This should be cleaned up and made more orthogonal. The questions
    560   // is: should we always use Operands instead of Registers where an
    561   // Operand is possible, or should we have a Register (overloaded) form
    562   // instead? We must be careful to make sure that the selected instruction
    563   // is obvious from the parameters to avoid hard-to-find code generation
    564   // bugs.
    565 
    566   // Insert the smallest number of nop instructions
    567   // possible to align the pc offset to a multiple
    568   // of m. m must be a power of 2.
    569   void Align(int m);
    570   // Insert the smallest number of zero bytes possible to align the pc offset
    571   // to a mulitple of m. m must be a power of 2 (>= 2).
    572   void DataAlign(int m);
    573   void Nop(int bytes = 1);
    574   // Aligns code to something that's optimal for a jump target for the platform.
    575   void CodeTargetAlign();
    576 
    577   // Stack
    578   void pushad();
    579   void popad();
    580 
    581   void pushfd();
    582   void popfd();
    583 
    584   void push(const Immediate& x);
    585   void push_imm32(int32_t imm32);
    586   void push(Register src);
    587   void push(const Operand& src);
    588 
    589   void pop(Register dst);
    590   void pop(const Operand& dst);
    591 
    592   void enter(const Immediate& size);
    593   void leave();
    594 
    595   // Moves
    596   void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); }
    597   void mov_b(Register dst, const Operand& src);
    598   void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); }
    599   void mov_b(const Operand& dst, int8_t imm8);
    600   void mov_b(const Operand& dst, const Immediate& src);
    601   void mov_b(const Operand& dst, Register src);
    602 
    603   void mov_w(Register dst, const Operand& src);
    604   void mov_w(const Operand& dst, Register src);
    605   void mov_w(const Operand& dst, int16_t imm16);
    606   void mov_w(const Operand& dst, const Immediate& src);
    607 
    608 
    609   void mov(Register dst, int32_t imm32);
    610   void mov(Register dst, const Immediate& x);
    611   void mov(Register dst, Handle<Object> handle);
    612   void mov(Register dst, const Operand& src);
    613   void mov(Register dst, Register src);
    614   void mov(const Operand& dst, const Immediate& x);
    615   void mov(const Operand& dst, Handle<Object> handle);
    616   void mov(const Operand& dst, Register src);
    617 
    618   void movsx_b(Register dst, Register src) { movsx_b(dst, Operand(src)); }
    619   void movsx_b(Register dst, const Operand& src);
    620 
    621   void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); }
    622   void movsx_w(Register dst, const Operand& src);
    623 
    624   void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); }
    625   void movzx_b(Register dst, const Operand& src);
    626 
    627   void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); }
    628   void movzx_w(Register dst, const Operand& src);
    629 
    630   // Flag management.
    631   void cld();
    632 
    633   // Repetitive string instructions.
    634   void rep_movs();
    635   void rep_stos();
    636   void stos();
    637 
    638   // Exchange
    639   void xchg(Register dst, Register src);
    640   void xchg(Register dst, const Operand& src);
    641 
    642   // Arithmetics
    643   void adc(Register dst, int32_t imm32);
    644   void adc(Register dst, const Operand& src);
    645 
    646   void add(Register dst, Register src) { add(dst, Operand(src)); }
    647   void add(Register dst, const Operand& src);
    648   void add(const Operand& dst, Register src);
    649   void add(Register dst, const Immediate& imm) { add(Operand(dst), imm); }
    650   void add(const Operand& dst, const Immediate& x);
    651 
    652   void and_(Register dst, int32_t imm32);
    653   void and_(Register dst, const Immediate& x);
    654   void and_(Register dst, Register src) { and_(dst, Operand(src)); }
    655   void and_(Register dst, const Operand& src);
    656   void and_(const Operand& dst, Register src);
    657   void and_(const Operand& dst, const Immediate& x);
    658 
    659   void cmpb(Register reg, int8_t imm8) { cmpb(Operand(reg), imm8); }
    660   void cmpb(const Operand& op, int8_t imm8);
    661   void cmpb(Register reg, const Operand& op);
    662   void cmpb(const Operand& op, Register reg);
    663   void cmpb_al(const Operand& op);
    664   void cmpw_ax(const Operand& op);
    665   void cmpw(const Operand& op, Immediate imm16);
    666   void cmp(Register reg, int32_t imm32);
    667   void cmp(Register reg, Handle<Object> handle);
    668   void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); }
    669   void cmp(Register reg, const Operand& op);
    670   void cmp(Register reg, const Immediate& imm) { cmp(Operand(reg), imm); }
    671   void cmp(const Operand& op, const Immediate& imm);
    672   void cmp(const Operand& op, Handle<Object> handle);
    673 
    674   void dec_b(Register dst);
    675   void dec_b(const Operand& dst);
    676 
    677   void dec(Register dst);
    678   void dec(const Operand& dst);
    679 
    680   void cdq();
    681 
    682   void idiv(Register src) { idiv(Operand(src)); }
    683   void idiv(const Operand& src);
    684   void div(Register src) { div(Operand(src)); }
    685   void div(const Operand& src);
    686 
    687   // Signed multiply instructions.
    688   void imul(Register src);                               // edx:eax = eax * src.
    689   void imul(Register dst, Register src) { imul(dst, Operand(src)); }
    690   void imul(Register dst, const Operand& src);           // dst = dst * src.
    691   void imul(Register dst, Register src, int32_t imm32);  // dst = src * imm32.
    692   void imul(Register dst, const Operand& src, int32_t imm32);
    693 
    694   void inc(Register dst);
    695   void inc(const Operand& dst);
    696 
    697   void lea(Register dst, const Operand& src);
    698 
    699   // Unsigned multiply instruction.
    700   void mul(Register src);                                // edx:eax = eax * reg.
    701 
    702   void neg(Register dst);
    703   void neg(const Operand& dst);
    704 
    705   void not_(Register dst);
    706   void not_(const Operand& dst);
    707 
    708   void or_(Register dst, int32_t imm32);
    709   void or_(Register dst, Register src) { or_(dst, Operand(src)); }
    710   void or_(Register dst, const Operand& src);
    711   void or_(const Operand& dst, Register src);
    712   void or_(Register dst, const Immediate& imm) { or_(Operand(dst), imm); }
    713   void or_(const Operand& dst, const Immediate& x);
    714 
    715   void rcl(Register dst, uint8_t imm8);
    716   void rcr(Register dst, uint8_t imm8);
    717 
    718   void ror(Register dst, uint8_t imm8) { ror(Operand(dst), imm8); }
    719   void ror(const Operand& dst, uint8_t imm8);
    720   void ror_cl(Register dst) { ror_cl(Operand(dst)); }
    721   void ror_cl(const Operand& dst);
    722 
    723   void sar(Register dst, uint8_t imm8) { sar(Operand(dst), imm8); }
    724   void sar(const Operand& dst, uint8_t imm8);
    725   void sar_cl(Register dst) { sar_cl(Operand(dst)); }
    726   void sar_cl(const Operand& dst);
    727 
    728   void sbb(Register dst, const Operand& src);
    729 
    730   void shld(Register dst, Register src) { shld(dst, Operand(src)); }
    731   void shld(Register dst, const Operand& src);
    732 
    733   void shl(Register dst, uint8_t imm8) { shl(Operand(dst), imm8); }
    734   void shl(const Operand& dst, uint8_t imm8);
    735   void shl_cl(Register dst) { shl_cl(Operand(dst)); }
    736   void shl_cl(const Operand& dst);
    737 
    738   void shrd(Register dst, Register src) { shrd(dst, Operand(src)); }
    739   void shrd(Register dst, const Operand& src);
    740 
    741   void shr(Register dst, uint8_t imm8) { shr(Operand(dst), imm8); }
    742   void shr(const Operand& dst, uint8_t imm8);
    743   void shr_cl(Register dst) { shr_cl(Operand(dst)); }
    744   void shr_cl(const Operand& dst);
    745 
    746   void sub(Register dst, const Immediate& imm) { sub(Operand(dst), imm); }
    747   void sub(const Operand& dst, const Immediate& x);
    748   void sub(Register dst, Register src) { sub(dst, Operand(src)); }
    749   void sub(Register dst, const Operand& src);
    750   void sub(const Operand& dst, Register src);
    751 
    752   void test(Register reg, const Immediate& imm);
    753   void test(Register reg0, Register reg1) { test(reg0, Operand(reg1)); }
    754   void test(Register reg, const Operand& op);
    755   void test_b(Register reg, const Operand& op);
    756   void test(const Operand& op, const Immediate& imm);
    757   void test_b(Register reg, uint8_t imm8);
    758   void test_b(const Operand& op, uint8_t imm8);
    759 
    760   void xor_(Register dst, int32_t imm32);
    761   void xor_(Register dst, Register src) { xor_(dst, Operand(src)); }
    762   void xor_(Register dst, const Operand& src);
    763   void xor_(const Operand& dst, Register src);
    764   void xor_(Register dst, const Immediate& imm) { xor_(Operand(dst), imm); }
    765   void xor_(const Operand& dst, const Immediate& x);
    766 
    767   // Bit operations.
    768   void bt(const Operand& dst, Register src);
    769   void bts(Register dst, Register src) { bts(Operand(dst), src); }
    770   void bts(const Operand& dst, Register src);
    771   void bsr(Register dst, Register src) { bsr(dst, Operand(src)); }
    772   void bsr(Register dst, const Operand& src);
    773   void bsf(Register dst, Register src) { bsf(dst, Operand(src)); }
    774   void bsf(Register dst, const Operand& src);
    775 
    776   // Miscellaneous
    777   void hlt();
    778   void int3();
    779   void nop();
    780   void ret(int imm16);
    781   void ud2();
    782 
    783   // Label operations & relative jumps (PPUM Appendix D)
    784   //
    785   // Takes a branch opcode (cc) and a label (L) and generates
    786   // either a backward branch or a forward branch and links it
    787   // to the label fixup chain. Usage:
    788   //
    789   // Label L;    // unbound label
    790   // j(cc, &L);  // forward branch to unbound label
    791   // bind(&L);   // bind label to the current pc
    792   // j(cc, &L);  // backward branch to bound label
    793   // bind(&L);   // illegal: a label may be bound only once
    794   //
    795   // Note: The same Label can be used for forward and backward branches
    796   // but it may be bound only once.
    797 
    798   void bind(Label* L);  // binds an unbound label L to the current code position
    799 
    800   // Calls
    801   void call(Label* L);
    802   void call(byte* entry, RelocInfo::Mode rmode);
    803   int CallSize(const Operand& adr);
    804   void call(Register reg) { call(Operand(reg)); }
    805   void call(const Operand& adr);
    806   int CallSize(Handle<Code> code, RelocInfo::Mode mode);
    807   void call(Handle<Code> code,
    808             RelocInfo::Mode rmode,
    809             TypeFeedbackId id = TypeFeedbackId::None());
    810 
    811   // Jumps
    812   // unconditional jump to L
    813   void jmp(Label* L, Label::Distance distance = Label::kFar);
    814   void jmp(byte* entry, RelocInfo::Mode rmode);
    815   void jmp(Register reg) { jmp(Operand(reg)); }
    816   void jmp(const Operand& adr);
    817   void jmp(Handle<Code> code, RelocInfo::Mode rmode);
    818 
    819   // Conditional jumps
    820   void j(Condition cc,
    821          Label* L,
    822          Label::Distance distance = Label::kFar);
    823   void j(Condition cc, byte* entry, RelocInfo::Mode rmode);
    824   void j(Condition cc, Handle<Code> code,
    825          RelocInfo::Mode rmode = RelocInfo::CODE_TARGET);
    826 
    827   // Floating-point operations
    828   void fld(int i);
    829   void fstp(int i);
    830 
    831   void fld1();
    832   void fldz();
    833   void fldpi();
    834   void fldln2();
    835 
    836   void fld_s(const Operand& adr);
    837   void fld_d(const Operand& adr);
    838 
    839   void fstp_s(const Operand& adr);
    840   void fst_s(const Operand& adr);
    841   void fstp_d(const Operand& adr);
    842   void fst_d(const Operand& adr);
    843 
    844   void fild_s(const Operand& adr);
    845   void fild_d(const Operand& adr);
    846 
    847   void fist_s(const Operand& adr);
    848 
    849   void fistp_s(const Operand& adr);
    850   void fistp_d(const Operand& adr);
    851 
    852   // The fisttp instructions require SSE3.
    853   void fisttp_s(const Operand& adr);
    854   void fisttp_d(const Operand& adr);
    855 
    856   void fabs();
    857   void fchs();
    858   void fsqrt();
    859   void fcos();
    860   void fsin();
    861   void fptan();
    862   void fyl2x();
    863   void f2xm1();
    864   void fscale();
    865   void fninit();
    866 
    867   void fadd(int i);
    868   void fadd_i(int i);
    869   void fadd_d(const Operand& adr);
    870   void fsub(int i);
    871   void fsub_i(int i);
    872   void fsub_d(const Operand& adr);
    873   void fsubr_d(const Operand& adr);
    874   void fmul(int i);
    875   void fmul_d(const Operand& adr);
    876   void fmul_i(int i);
    877   void fdiv(int i);
    878   void fdiv_d(const Operand& adr);
    879   void fdivr_d(const Operand& adr);
    880   void fdiv_i(int i);
    881 
    882   void fisub_s(const Operand& adr);
    883 
    884   void faddp(int i = 1);
    885   void fsubp(int i = 1);
    886   void fsubr(int i = 1);
    887   void fsubrp(int i = 1);
    888   void fmulp(int i = 1);
    889   void fdivp(int i = 1);
    890   void fprem();
    891   void fprem1();
    892 
    893   void fxch(int i = 1);
    894   void fincstp();
    895   void ffree(int i = 0);
    896 
    897   void ftst();
    898   void fxam();
    899   void fucomp(int i);
    900   void fucompp();
    901   void fucomi(int i);
    902   void fucomip();
    903   void fcompp();
    904   void fnstsw_ax();
    905   void fldcw(const Operand& adr);
    906   void fnstcw(const Operand& adr);
    907   void fwait();
    908   void fnclex();
    909   void fnsave(const Operand& adr);
    910   void frstor(const Operand& adr);
    911 
    912   void frndint();
    913 
    914   void sahf();
    915   void setcc(Condition cc, Register reg);
    916 
    917   void cpuid();
    918 
    919   // TODO(lrn): Need SFENCE for movnt?
    920 
    921   // Check the code size generated from label to here.
    922   int SizeOfCodeGeneratedSince(Label* label) {
    923     return pc_offset() - label->pos();
    924   }
    925 
    926   // Mark generator continuation.
    927   void RecordGeneratorContinuation();
    928 
    929   // Mark address of a debug break slot.
    930   void RecordDebugBreakSlot(RelocInfo::Mode mode);
    931 
    932   // Record a comment relocation entry that can be used by a disassembler.
    933   // Use --code-comments to enable.
    934   void RecordComment(const char* msg);
    935 
    936   // Record a deoptimization reason that can be used by a log or cpu profiler.
    937   // Use --trace-deopt to enable.
    938   void RecordDeoptReason(const int reason, const SourcePosition position);
    939 
    940   // Writes a single byte or word of data in the code stream.  Used for
    941   // inline tables, e.g., jump-tables.
    942   void db(uint8_t data);
    943   void dd(uint32_t data);
    944   void dq(uint64_t data);
    945   void dp(uintptr_t data) { dd(data); }
    946   void dd(Label* label);
    947 
    948   // Check if there is less than kGap bytes available in the buffer.
    949   // If this is the case, we need to grow the buffer before emitting
    950   // an instruction or relocation information.
    951   inline bool buffer_overflow() const {
    952     return pc_ >= reloc_info_writer.pos() - kGap;
    953   }
    954 
    955   // Get the number of bytes available in the buffer.
    956   inline int available_space() const { return reloc_info_writer.pos() - pc_; }
    957 
    958   static bool IsNop(Address addr);
    959 
    960   PositionsRecorder* positions_recorder() { return &positions_recorder_; }
    961 
    962   int relocation_writer_size() {
    963     return (buffer_ + buffer_size_) - reloc_info_writer.pos();
    964   }
    965 
    966   // Avoid overflows for displacements etc.
    967   static const int kMaximalBufferSize = 512*MB;
    968 
    969   byte byte_at(int pos) { return buffer_[pos]; }
    970   void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
    971 
    972   void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
    973                                           ConstantPoolEntry::Access access,
    974                                           ConstantPoolEntry::Type type) {
    975     // No embedded constant pool support.
    976     UNREACHABLE();
    977   }
    978 
    979  protected:
    980   byte* addr_at(int pos) { return buffer_ + pos; }
    981 
    982 
    983  private:
    984   uint32_t long_at(int pos)  {
    985     return *reinterpret_cast<uint32_t*>(addr_at(pos));
    986   }
    987   void long_at_put(int pos, uint32_t x)  {
    988     *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
    989   }
    990 
    991   // code emission
    992   void GrowBuffer();
    993   inline void emit(uint32_t x);
    994   inline void emit(Handle<Object> handle);
    995   inline void emit(uint32_t x,
    996                    RelocInfo::Mode rmode,
    997                    TypeFeedbackId id = TypeFeedbackId::None());
    998   inline void emit(Handle<Code> code,
    999                    RelocInfo::Mode rmode,
   1000                    TypeFeedbackId id = TypeFeedbackId::None());
   1001   inline void emit(const Immediate& x);
   1002   inline void emit_w(const Immediate& x);
   1003   inline void emit_q(uint64_t x);
   1004 
   1005   // Emit the code-object-relative offset of the label's position
   1006   inline void emit_code_relative_offset(Label* label);
   1007 
   1008   // instruction generation
   1009   void emit_arith_b(int op1, int op2, Register dst, int imm8);
   1010 
   1011   // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81)
   1012   // with a given destination expression and an immediate operand.  It attempts
   1013   // to use the shortest encoding possible.
   1014   // sel specifies the /n in the modrm byte (see the Intel PRM).
   1015   void emit_arith(int sel, Operand dst, const Immediate& x);
   1016 
   1017   void emit_operand(Register reg, const Operand& adr);
   1018 
   1019   void emit_label(Label* label);
   1020 
   1021   void emit_farith(int b1, int b2, int i);
   1022 
   1023   // labels
   1024   void print(Label* L);
   1025   void bind_to(Label* L, int pos);
   1026 
   1027   // displacements
   1028   inline Displacement disp_at(Label* L);
   1029   inline void disp_at_put(Label* L, Displacement disp);
   1030   inline void emit_disp(Label* L, Displacement::Type type);
   1031   inline void emit_near_disp(Label* L);
   1032 
   1033   // record reloc info for current pc_
   1034   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
   1035 
   1036   friend class CodePatcher;
   1037   friend class EnsureSpace;
   1038 
   1039   // Internal reference positions, required for (potential) patching in
   1040   // GrowBuffer(); contains only those internal references whose labels
   1041   // are already bound.
   1042   std::deque<int> internal_reference_positions_;
   1043 
   1044   // code generation
   1045   RelocInfoWriter reloc_info_writer;
   1046 
   1047   PositionsRecorder positions_recorder_;
   1048   friend class PositionsRecorder;
   1049 };
   1050 
   1051 
   1052 // Helper class that ensures that there is enough space for generating
   1053 // instructions and relocation information.  The constructor makes
   1054 // sure that there is enough space and (in debug mode) the destructor
   1055 // checks that we did not generate too much.
   1056 class EnsureSpace BASE_EMBEDDED {
   1057  public:
   1058   explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
   1059     if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
   1060 #ifdef DEBUG
   1061     space_before_ = assembler_->available_space();
   1062 #endif
   1063   }
   1064 
   1065 #ifdef DEBUG
   1066   ~EnsureSpace() {
   1067     int bytes_generated = space_before_ - assembler_->available_space();
   1068     DCHECK(bytes_generated < assembler_->kGap);
   1069   }
   1070 #endif
   1071 
   1072  private:
   1073   Assembler* assembler_;
   1074 #ifdef DEBUG
   1075   int space_before_;
   1076 #endif
   1077 };
   1078 
   1079 }  // namespace internal
   1080 }  // namespace v8
   1081 
   1082 #endif  // V8_X87_ASSEMBLER_X87_H_
   1083