Home | History | Annotate | Download | only in x64
      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 2006-2009 the V8 project authors. All rights reserved.
     34 
     35 // A lightweight X64 Assembler.
     36 
     37 #ifndef V8_X64_ASSEMBLER_X64_H_
     38 #define V8_X64_ASSEMBLER_X64_H_
     39 
     40 #include "serialize.h"
     41 
     42 namespace v8 {
     43 namespace internal {
     44 
     45 // Utility functions
     46 
     47 // Test whether a 64-bit value is in a specific range.
     48 static inline bool is_uint32(int64_t x) {
     49   static const int64_t kUInt32Mask = V8_INT64_C(0xffffffff);
     50   return x == (x & kUInt32Mask);
     51 }
     52 
     53 static inline bool is_int32(int64_t x) {
     54   static const int64_t kMinIntValue = V8_INT64_C(-0x80000000);
     55   return is_uint32(x - kMinIntValue);
     56 }
     57 
     58 static inline bool uint_is_int32(uint64_t x) {
     59   static const uint64_t kMaxIntValue = V8_UINT64_C(0x80000000);
     60   return x < kMaxIntValue;
     61 }
     62 
     63 static inline bool is_uint32(uint64_t x) {
     64   static const uint64_t kMaxUIntValue = V8_UINT64_C(0x100000000);
     65   return x < kMaxUIntValue;
     66 }
     67 
     68 // CPU Registers.
     69 //
     70 // 1) We would prefer to use an enum, but enum values are assignment-
     71 // compatible with int, which has caused code-generation bugs.
     72 //
     73 // 2) We would prefer to use a class instead of a struct but we don't like
     74 // the register initialization to depend on the particular initialization
     75 // order (which appears to be different on OS X, Linux, and Windows for the
     76 // installed versions of C++ we tried). Using a struct permits C-style
     77 // "initialization". Also, the Register objects cannot be const as this
     78 // forces initialization stubs in MSVC, making us dependent on initialization
     79 // order.
     80 //
     81 // 3) By not using an enum, we are possibly preventing the compiler from
     82 // doing certain constant folds, which may significantly reduce the
     83 // code generated for some assembly instructions (because they boil down
     84 // to a few constants). If this is a problem, we could change the code
     85 // such that we use an enum in optimized mode, and the struct in debug
     86 // mode. This way we get the compile-time error checking in debug mode
     87 // and best performance in optimized code.
     88 //
     89 
     90 struct Register {
     91   static Register toRegister(int code) {
     92     Register r = { code };
     93     return r;
     94   }
     95   bool is_valid() const  { return 0 <= code_ && code_ < 16; }
     96   bool is(Register reg) const  { return code_ == reg.code_; }
     97   int code() const  {
     98     ASSERT(is_valid());
     99     return code_;
    100   }
    101   int bit() const  {
    102     return 1 << code_;
    103   }
    104 
    105   // Return the high bit of the register code as a 0 or 1.  Used often
    106   // when constructing the REX prefix byte.
    107   int high_bit() const {
    108     return code_ >> 3;
    109   }
    110   // Return the 3 low bits of the register code.  Used when encoding registers
    111   // in modR/M, SIB, and opcode bytes.
    112   int low_bits() const {
    113     return code_ & 0x7;
    114   }
    115 
    116   // Unfortunately we can't make this private in a struct when initializing
    117   // by assignment.
    118   int code_;
    119 };
    120 
    121 const Register rax = { 0 };
    122 const Register rcx = { 1 };
    123 const Register rdx = { 2 };
    124 const Register rbx = { 3 };
    125 const Register rsp = { 4 };
    126 const Register rbp = { 5 };
    127 const Register rsi = { 6 };
    128 const Register rdi = { 7 };
    129 const Register r8 = { 8 };
    130 const Register r9 = { 9 };
    131 const Register r10 = { 10 };
    132 const Register r11 = { 11 };
    133 const Register r12 = { 12 };
    134 const Register r13 = { 13 };
    135 const Register r14 = { 14 };
    136 const Register r15 = { 15 };
    137 const Register no_reg = { -1 };
    138 
    139 
    140 struct XMMRegister {
    141   bool is_valid() const  { return 0 <= code_ && code_ < 16; }
    142   int code() const  {
    143     ASSERT(is_valid());
    144     return code_;
    145   }
    146 
    147   // Return the high bit of the register code as a 0 or 1.  Used often
    148   // when constructing the REX prefix byte.
    149   int high_bit() const {
    150     return code_ >> 3;
    151   }
    152   // Return the 3 low bits of the register code.  Used when encoding registers
    153   // in modR/M, SIB, and opcode bytes.
    154   int low_bits() const {
    155     return code_ & 0x7;
    156   }
    157 
    158   int code_;
    159 };
    160 
    161 const XMMRegister xmm0 = { 0 };
    162 const XMMRegister xmm1 = { 1 };
    163 const XMMRegister xmm2 = { 2 };
    164 const XMMRegister xmm3 = { 3 };
    165 const XMMRegister xmm4 = { 4 };
    166 const XMMRegister xmm5 = { 5 };
    167 const XMMRegister xmm6 = { 6 };
    168 const XMMRegister xmm7 = { 7 };
    169 const XMMRegister xmm8 = { 8 };
    170 const XMMRegister xmm9 = { 9 };
    171 const XMMRegister xmm10 = { 10 };
    172 const XMMRegister xmm11 = { 11 };
    173 const XMMRegister xmm12 = { 12 };
    174 const XMMRegister xmm13 = { 13 };
    175 const XMMRegister xmm14 = { 14 };
    176 const XMMRegister xmm15 = { 15 };
    177 
    178 enum Condition {
    179   // any value < 0 is considered no_condition
    180   no_condition  = -1,
    181 
    182   overflow      =  0,
    183   no_overflow   =  1,
    184   below         =  2,
    185   above_equal   =  3,
    186   equal         =  4,
    187   not_equal     =  5,
    188   below_equal   =  6,
    189   above         =  7,
    190   negative      =  8,
    191   positive      =  9,
    192   parity_even   = 10,
    193   parity_odd    = 11,
    194   less          = 12,
    195   greater_equal = 13,
    196   less_equal    = 14,
    197   greater       = 15,
    198 
    199   // Fake conditions that are handled by the
    200   // opcodes using them.
    201   always        = 16,
    202   never         = 17,
    203   // aliases
    204   carry         = below,
    205   not_carry     = above_equal,
    206   zero          = equal,
    207   not_zero      = not_equal,
    208   sign          = negative,
    209   not_sign      = positive,
    210   last_condition = greater
    211 };
    212 
    213 
    214 // Returns the equivalent of !cc.
    215 // Negation of the default no_condition (-1) results in a non-default
    216 // no_condition value (-2). As long as tests for no_condition check
    217 // for condition < 0, this will work as expected.
    218 inline Condition NegateCondition(Condition cc);
    219 
    220 // Corresponds to transposing the operands of a comparison.
    221 inline Condition ReverseCondition(Condition cc) {
    222   switch (cc) {
    223     case below:
    224       return above;
    225     case above:
    226       return below;
    227     case above_equal:
    228       return below_equal;
    229     case below_equal:
    230       return above_equal;
    231     case less:
    232       return greater;
    233     case greater:
    234       return less;
    235     case greater_equal:
    236       return less_equal;
    237     case less_equal:
    238       return greater_equal;
    239     default:
    240       return cc;
    241   };
    242 }
    243 
    244 enum Hint {
    245   no_hint = 0,
    246   not_taken = 0x2e,
    247   taken = 0x3e
    248 };
    249 
    250 // The result of negating a hint is as if the corresponding condition
    251 // were negated by NegateCondition.  That is, no_hint is mapped to
    252 // itself and not_taken and taken are mapped to each other.
    253 inline Hint NegateHint(Hint hint) {
    254   return (hint == no_hint)
    255       ? no_hint
    256       : ((hint == not_taken) ? taken : not_taken);
    257 }
    258 
    259 
    260 // -----------------------------------------------------------------------------
    261 // Machine instruction Immediates
    262 
    263 class Immediate BASE_EMBEDDED {
    264  public:
    265   explicit Immediate(int32_t value) : value_(value) {}
    266 
    267  private:
    268   int32_t value_;
    269 
    270   friend class Assembler;
    271 };
    272 
    273 
    274 // -----------------------------------------------------------------------------
    275 // Machine instruction Operands
    276 
    277 enum ScaleFactor {
    278   times_1 = 0,
    279   times_2 = 1,
    280   times_4 = 2,
    281   times_8 = 3,
    282   times_int_size = times_4,
    283   times_pointer_size = times_8
    284 };
    285 
    286 
    287 class Operand BASE_EMBEDDED {
    288  public:
    289   // [base + disp/r]
    290   Operand(Register base, int32_t disp);
    291 
    292   // [base + index*scale + disp/r]
    293   Operand(Register base,
    294           Register index,
    295           ScaleFactor scale,
    296           int32_t disp);
    297 
    298   // [index*scale + disp/r]
    299   Operand(Register index,
    300           ScaleFactor scale,
    301           int32_t disp);
    302 
    303  private:
    304   byte rex_;
    305   byte buf_[10];
    306   // The number of bytes in buf_.
    307   unsigned int len_;
    308   RelocInfo::Mode rmode_;
    309 
    310   // Set the ModR/M byte without an encoded 'reg' register. The
    311   // register is encoded later as part of the emit_operand operation.
    312   // set_modrm can be called before or after set_sib and set_disp*.
    313   inline void set_modrm(int mod, Register rm);
    314 
    315   // Set the SIB byte if one is needed. Sets the length to 2 rather than 1.
    316   inline void set_sib(ScaleFactor scale, Register index, Register base);
    317 
    318   // Adds operand displacement fields (offsets added to the memory address).
    319   // Needs to be called after set_sib, not before it.
    320   inline void set_disp8(int disp);
    321   inline void set_disp32(int disp);
    322 
    323   friend class Assembler;
    324 };
    325 
    326 
    327 // CpuFeatures keeps track of which features are supported by the target CPU.
    328 // Supported features must be enabled by a Scope before use.
    329 // Example:
    330 //   if (CpuFeatures::IsSupported(SSE3)) {
    331 //     CpuFeatures::Scope fscope(SSE3);
    332 //     // Generate SSE3 floating point code.
    333 //   } else {
    334 //     // Generate standard x87 or SSE2 floating point code.
    335 //   }
    336 class CpuFeatures : public AllStatic {
    337  public:
    338   // Detect features of the target CPU. Set safe defaults if the serializer
    339   // is enabled (snapshots must be portable).
    340   static void Probe();
    341   // Check whether a feature is supported by the target CPU.
    342   static bool IsSupported(CpuFeature f) {
    343     if (f == SSE2 && !FLAG_enable_sse2) return false;
    344     if (f == SSE3 && !FLAG_enable_sse3) return false;
    345     if (f == CMOV && !FLAG_enable_cmov) return false;
    346     if (f == RDTSC && !FLAG_enable_rdtsc) return false;
    347     if (f == SAHF && !FLAG_enable_sahf) return false;
    348     return (supported_ & (V8_UINT64_C(1) << f)) != 0;
    349   }
    350   // Check whether a feature is currently enabled.
    351   static bool IsEnabled(CpuFeature f) {
    352     return (enabled_ & (V8_UINT64_C(1) << f)) != 0;
    353   }
    354   // Enable a specified feature within a scope.
    355   class Scope BASE_EMBEDDED {
    356 #ifdef DEBUG
    357    public:
    358     explicit Scope(CpuFeature f) {
    359       uint64_t mask = (V8_UINT64_C(1) << f);
    360       ASSERT(CpuFeatures::IsSupported(f));
    361       ASSERT(!Serializer::enabled() || (found_by_runtime_probing_ & mask) == 0);
    362       old_enabled_ = CpuFeatures::enabled_;
    363       CpuFeatures::enabled_ |= mask;
    364     }
    365     ~Scope() { CpuFeatures::enabled_ = old_enabled_; }
    366    private:
    367     uint64_t old_enabled_;
    368 #else
    369    public:
    370     explicit Scope(CpuFeature f) {}
    371 #endif
    372   };
    373  private:
    374   // Safe defaults include SSE2 and CMOV for X64. It is always available, if
    375   // anyone checks, but they shouldn't need to check.
    376   static const uint64_t kDefaultCpuFeatures = (1 << SSE2 | 1 << CMOV);
    377   static uint64_t supported_;
    378   static uint64_t enabled_;
    379   static uint64_t found_by_runtime_probing_;
    380 };
    381 
    382 
    383 class Assembler : public Malloced {
    384  private:
    385   // We check before assembling an instruction that there is sufficient
    386   // space to write an instruction and its relocation information.
    387   // The relocation writer's position must be kGap bytes above the end of
    388   // the generated instructions. This leaves enough space for the
    389   // longest possible x64 instruction, 15 bytes, and the longest possible
    390   // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
    391   // (There is a 15 byte limit on x64 instruction length that rules out some
    392   // otherwise valid instructions.)
    393   // This allows for a single, fast space check per instruction.
    394   static const int kGap = 32;
    395 
    396  public:
    397   // Create an assembler. Instructions and relocation information are emitted
    398   // into a buffer, with the instructions starting from the beginning and the
    399   // relocation information starting from the end of the buffer. See CodeDesc
    400   // for a detailed comment on the layout (globals.h).
    401   //
    402   // If the provided buffer is NULL, the assembler allocates and grows its own
    403   // buffer, and buffer_size determines the initial buffer size. The buffer is
    404   // owned by the assembler and deallocated upon destruction of the assembler.
    405   //
    406   // If the provided buffer is not NULL, the assembler uses the provided buffer
    407   // for code generation and assumes its size to be buffer_size. If the buffer
    408   // is too small, a fatal error occurs. No deallocation of the buffer is done
    409   // upon destruction of the assembler.
    410   Assembler(void* buffer, int buffer_size);
    411   ~Assembler();
    412 
    413   // GetCode emits any pending (non-emitted) code and fills the descriptor
    414   // desc. GetCode() is idempotent; it returns the same result if no other
    415   // Assembler functions are invoked in between GetCode() calls.
    416   void GetCode(CodeDesc* desc);
    417 
    418   // Read/Modify the code target in the relative branch/call instruction at pc.
    419   // On the x64 architecture, we use relative jumps with a 32-bit displacement
    420   // to jump to other Code objects in the Code space in the heap.
    421   // Jumps to C functions are done indirectly through a 64-bit register holding
    422   // the absolute address of the target.
    423   // These functions convert between absolute Addresses of Code objects and
    424   // the relative displacements stored in the code.
    425   static inline Address target_address_at(Address pc);
    426   static inline void set_target_address_at(Address pc, Address target);
    427 
    428   // This sets the branch destination (which is in the instruction on x64).
    429   // This is for calls and branches within generated code.
    430   inline static void set_target_at(Address instruction_payload,
    431                                    Address target) {
    432     set_target_address_at(instruction_payload, target);
    433   }
    434 
    435   // This sets the branch destination (which is a load instruction on x64).
    436   // This is for calls and branches to runtime code.
    437   inline static void set_external_target_at(Address instruction_payload,
    438                                             Address target) {
    439     *reinterpret_cast<Address*>(instruction_payload) = target;
    440   }
    441 
    442   inline Handle<Object> code_target_object_handle_at(Address pc);
    443   // Number of bytes taken up by the branch target in the code.
    444   static const int kCallTargetSize = 4;      // Use 32-bit displacement.
    445   static const int kExternalTargetSize = 8;  // Use 64-bit absolute.
    446   // Distance between the address of the code target in the call instruction
    447   // and the return address pushed on the stack.
    448   static const int kCallTargetAddressOffset = 4;  // Use 32-bit displacement.
    449   // Distance between the start of the JS return sequence and where the
    450   // 32-bit displacement of a near call would be, relative to the pushed
    451   // return address.  TODO: Use return sequence length instead.
    452   // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset;
    453   static const int kPatchReturnSequenceAddressOffset = 13 - 4;
    454   // TODO(X64): Rename this, removing the "Real", after changing the above.
    455   static const int kRealPatchReturnSequenceAddressOffset = 2;
    456 
    457   // The x64 JS return sequence is padded with int3 to make it large
    458   // enough to hold a call instruction when the debugger patches it.
    459   static const int kCallInstructionLength = 13;
    460   static const int kJSReturnSequenceLength = 13;
    461 
    462   // ---------------------------------------------------------------------------
    463   // Code generation
    464   //
    465   // Function names correspond one-to-one to x64 instruction mnemonics.
    466   // Unless specified otherwise, instructions operate on 64-bit operands.
    467   //
    468   // If we need versions of an assembly instruction that operate on different
    469   // width arguments, we add a single-letter suffix specifying the width.
    470   // This is done for the following instructions: mov, cmp, inc, dec,
    471   // add, sub, and test.
    472   // There are no versions of these instructions without the suffix.
    473   // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
    474   // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
    475   // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
    476   // - Instructions on 64-bit (quadword) operands/registers use 'q'.
    477   //
    478   // Some mnemonics, such as "and", are the same as C++ keywords.
    479   // Naming conflicts with C++ keywords are resolved by adding a trailing '_'.
    480 
    481   // Insert the smallest number of nop instructions
    482   // possible to align the pc offset to a multiple
    483   // of m. m must be a power of 2.
    484   void Align(int m);
    485 
    486   // Stack
    487   void pushfq();
    488   void popfq();
    489 
    490   void push(Immediate value);
    491   void push(Register src);
    492   void push(const Operand& src);
    493   void push(Label* label, RelocInfo::Mode relocation_mode);
    494 
    495   void pop(Register dst);
    496   void pop(const Operand& dst);
    497 
    498   void enter(Immediate size);
    499   void leave();
    500 
    501   // Moves
    502   void movb(Register dst, const Operand& src);
    503   void movb(Register dst, Immediate imm);
    504   void movb(const Operand& dst, Register src);
    505 
    506   // Move the low 16 bits of a 64-bit register value to a 16-bit
    507   // memory location.
    508   void movw(const Operand& dst, Register src);
    509 
    510   void movl(Register dst, Register src);
    511   void movl(Register dst, const Operand& src);
    512   void movl(const Operand& dst, Register src);
    513   void movl(const Operand& dst, Immediate imm);
    514   // Load a 32-bit immediate value, zero-extended to 64 bits.
    515   void movl(Register dst, Immediate imm32);
    516 
    517   // Move 64 bit register value to 64-bit memory location.
    518   void movq(const Operand& dst, Register src);
    519   // Move 64 bit memory location to 64-bit register value.
    520   void movq(Register dst, const Operand& src);
    521   void movq(Register dst, Register src);
    522   // Sign extends immediate 32-bit value to 64 bits.
    523   void movq(Register dst, Immediate x);
    524   // Move the offset of the label location relative to the current
    525   // position (after the move) to the destination.
    526   void movl(const Operand& dst, Label* src);
    527 
    528   // Move sign extended immediate to memory location.
    529   void movq(const Operand& dst, Immediate value);
    530   // New x64 instructions to load a 64-bit immediate into a register.
    531   // All 64-bit immediates must have a relocation mode.
    532   void movq(Register dst, void* ptr, RelocInfo::Mode rmode);
    533   void movq(Register dst, int64_t value, RelocInfo::Mode rmode);
    534   void movq(Register dst, const char* s, RelocInfo::Mode rmode);
    535   // Moves the address of the external reference into the register.
    536   void movq(Register dst, ExternalReference ext);
    537   void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode);
    538 
    539   void movsxbq(Register dst, const Operand& src);
    540   void movsxwq(Register dst, const Operand& src);
    541   void movsxlq(Register dst, Register src);
    542   void movsxlq(Register dst, const Operand& src);
    543   void movzxbq(Register dst, const Operand& src);
    544   void movzxbl(Register dst, const Operand& src);
    545   void movzxwq(Register dst, const Operand& src);
    546   void movzxwl(Register dst, const Operand& src);
    547 
    548   // Repeated moves.
    549 
    550   void repmovsb();
    551   void repmovsw();
    552   void repmovsl();
    553   void repmovsq();
    554 
    555   // New x64 instruction to load from an immediate 64-bit pointer into RAX.
    556   void load_rax(void* ptr, RelocInfo::Mode rmode);
    557   void load_rax(ExternalReference ext);
    558 
    559   // Conditional moves.
    560   void cmovq(Condition cc, Register dst, Register src);
    561   void cmovq(Condition cc, Register dst, const Operand& src);
    562   void cmovl(Condition cc, Register dst, Register src);
    563   void cmovl(Condition cc, Register dst, const Operand& src);
    564 
    565   // Exchange two registers
    566   void xchg(Register dst, Register src);
    567 
    568   // Arithmetics
    569   void addl(Register dst, Register src) {
    570     if (dst.low_bits() == 4) {  // Forces SIB byte.
    571       arithmetic_op_32(0x01, src, dst);
    572     } else {
    573       arithmetic_op_32(0x03, dst, src);
    574     }
    575   }
    576 
    577   void addl(Register dst, Immediate src) {
    578     immediate_arithmetic_op_32(0x0, dst, src);
    579   }
    580 
    581   void addl(Register dst, const Operand& src) {
    582     arithmetic_op_32(0x03, dst, src);
    583   }
    584 
    585   void addl(const Operand& dst, Immediate src) {
    586     immediate_arithmetic_op_32(0x0, dst, src);
    587   }
    588 
    589   void addq(Register dst, Register src) {
    590     arithmetic_op(0x03, dst, src);
    591   }
    592 
    593   void addq(Register dst, const Operand& src) {
    594     arithmetic_op(0x03, dst, src);
    595   }
    596 
    597   void addq(const Operand& dst, Register src) {
    598     arithmetic_op(0x01, src, dst);
    599   }
    600 
    601   void addq(Register dst, Immediate src) {
    602     immediate_arithmetic_op(0x0, dst, src);
    603   }
    604 
    605   void addq(const Operand& dst, Immediate src) {
    606     immediate_arithmetic_op(0x0, dst, src);
    607   }
    608 
    609   void cmpb(Register dst, Immediate src) {
    610     immediate_arithmetic_op_8(0x7, dst, src);
    611   }
    612 
    613   void cmpb_al(Immediate src);
    614 
    615   void cmpb(Register dst, Register src) {
    616     arithmetic_op(0x3A, dst, src);
    617   }
    618 
    619   void cmpb(Register dst, const Operand& src) {
    620     arithmetic_op(0x3A, dst, src);
    621   }
    622 
    623   void cmpb(const Operand& dst, Register src) {
    624     arithmetic_op(0x38, src, dst);
    625   }
    626 
    627   void cmpb(const Operand& dst, Immediate src) {
    628     immediate_arithmetic_op_8(0x7, dst, src);
    629   }
    630 
    631   void cmpw(const Operand& dst, Immediate src) {
    632     immediate_arithmetic_op_16(0x7, dst, src);
    633   }
    634 
    635   void cmpw(Register dst, Immediate src) {
    636     immediate_arithmetic_op_16(0x7, dst, src);
    637   }
    638 
    639   void cmpw(Register dst, const Operand& src) {
    640     arithmetic_op_16(0x3B, dst, src);
    641   }
    642 
    643   void cmpw(Register dst, Register src) {
    644     arithmetic_op_16(0x3B, dst, src);
    645   }
    646 
    647   void cmpw(const Operand& dst, Register src) {
    648     arithmetic_op_16(0x39, src, dst);
    649   }
    650 
    651   void cmpl(Register dst, Register src) {
    652     arithmetic_op_32(0x3B, dst, src);
    653   }
    654 
    655   void cmpl(Register dst, const Operand& src) {
    656     arithmetic_op_32(0x3B, dst, src);
    657   }
    658 
    659   void cmpl(const Operand& dst, Register src) {
    660     arithmetic_op_32(0x39, src, dst);
    661   }
    662 
    663   void cmpl(Register dst, Immediate src) {
    664     immediate_arithmetic_op_32(0x7, dst, src);
    665   }
    666 
    667   void cmpl(const Operand& dst, Immediate src) {
    668     immediate_arithmetic_op_32(0x7, dst, src);
    669   }
    670 
    671   void cmpq(Register dst, Register src) {
    672     arithmetic_op(0x3B, dst, src);
    673   }
    674 
    675   void cmpq(Register dst, const Operand& src) {
    676     arithmetic_op(0x3B, dst, src);
    677   }
    678 
    679   void cmpq(const Operand& dst, Register src) {
    680     arithmetic_op(0x39, src, dst);
    681   }
    682 
    683   void cmpq(Register dst, Immediate src) {
    684     immediate_arithmetic_op(0x7, dst, src);
    685   }
    686 
    687   void cmpq(const Operand& dst, Immediate src) {
    688     immediate_arithmetic_op(0x7, dst, src);
    689   }
    690 
    691   void and_(Register dst, Register src) {
    692     arithmetic_op(0x23, dst, src);
    693   }
    694 
    695   void and_(Register dst, const Operand& src) {
    696     arithmetic_op(0x23, dst, src);
    697   }
    698 
    699   void and_(const Operand& dst, Register src) {
    700     arithmetic_op(0x21, src, dst);
    701   }
    702 
    703   void and_(Register dst, Immediate src) {
    704     immediate_arithmetic_op(0x4, dst, src);
    705   }
    706 
    707   void and_(const Operand& dst, Immediate src) {
    708     immediate_arithmetic_op(0x4, dst, src);
    709   }
    710 
    711   void andl(Register dst, Immediate src) {
    712     immediate_arithmetic_op_32(0x4, dst, src);
    713   }
    714 
    715   void andl(Register dst, Register src) {
    716     arithmetic_op_32(0x23, dst, src);
    717   }
    718 
    719   void andb(Register dst, Immediate src) {
    720     immediate_arithmetic_op_8(0x4, dst, src);
    721   }
    722 
    723   void decq(Register dst);
    724   void decq(const Operand& dst);
    725   void decl(Register dst);
    726   void decl(const Operand& dst);
    727   void decb(Register dst);
    728   void decb(const Operand& dst);
    729 
    730   // Sign-extends rax into rdx:rax.
    731   void cqo();
    732   // Sign-extends eax into edx:eax.
    733   void cdq();
    734 
    735   // Divide rdx:rax by src.  Quotient in rax, remainder in rdx.
    736   void idivq(Register src);
    737   // Divide edx:eax by lower 32 bits of src.  Quotient in eax, rem. in edx.
    738   void idivl(Register src);
    739 
    740   // Signed multiply instructions.
    741   void imul(Register src);                               // rdx:rax = rax * src.
    742   void imul(Register dst, Register src);                 // dst = dst * src.
    743   void imul(Register dst, const Operand& src);           // dst = dst * src.
    744   void imul(Register dst, Register src, Immediate imm);  // dst = src * imm.
    745   // Multiply 32 bit registers
    746   void imull(Register dst, Register src);                // dst = dst * src.
    747 
    748   void incq(Register dst);
    749   void incq(const Operand& dst);
    750   void incl(const Operand& dst);
    751 
    752   void lea(Register dst, const Operand& src);
    753 
    754   // Multiply rax by src, put the result in rdx:rax.
    755   void mul(Register src);
    756 
    757   void neg(Register dst);
    758   void neg(const Operand& dst);
    759   void negl(Register dst);
    760 
    761   void not_(Register dst);
    762   void not_(const Operand& dst);
    763 
    764   void or_(Register dst, Register src) {
    765     arithmetic_op(0x0B, dst, src);
    766   }
    767 
    768   void orl(Register dst, Register src) {
    769     arithmetic_op_32(0x0B, dst, src);
    770   }
    771 
    772   void or_(Register dst, const Operand& src) {
    773     arithmetic_op(0x0B, dst, src);
    774   }
    775 
    776   void or_(const Operand& dst, Register src) {
    777     arithmetic_op(0x09, src, dst);
    778   }
    779 
    780   void or_(Register dst, Immediate src) {
    781     immediate_arithmetic_op(0x1, dst, src);
    782   }
    783 
    784   void orl(Register dst, Immediate src) {
    785     immediate_arithmetic_op_32(0x1, dst, src);
    786   }
    787 
    788   void or_(const Operand& dst, Immediate src) {
    789     immediate_arithmetic_op(0x1, dst, src);
    790   }
    791 
    792   void orl(const Operand& dst, Immediate src) {
    793     immediate_arithmetic_op_32(0x1, dst, src);
    794   }
    795 
    796 
    797   void rcl(Register dst, Immediate imm8) {
    798     shift(dst, imm8, 0x2);
    799   }
    800 
    801   void rol(Register dst, Immediate imm8) {
    802     shift(dst, imm8, 0x0);
    803   }
    804 
    805   void rcr(Register dst, Immediate imm8) {
    806     shift(dst, imm8, 0x3);
    807   }
    808 
    809   void ror(Register dst, Immediate imm8) {
    810     shift(dst, imm8, 0x1);
    811   }
    812 
    813   // Shifts dst:src left by cl bits, affecting only dst.
    814   void shld(Register dst, Register src);
    815 
    816   // Shifts src:dst right by cl bits, affecting only dst.
    817   void shrd(Register dst, Register src);
    818 
    819   // Shifts dst right, duplicating sign bit, by shift_amount bits.
    820   // Shifting by 1 is handled efficiently.
    821   void sar(Register dst, Immediate shift_amount) {
    822     shift(dst, shift_amount, 0x7);
    823   }
    824 
    825   // Shifts dst right, duplicating sign bit, by shift_amount bits.
    826   // Shifting by 1 is handled efficiently.
    827   void sarl(Register dst, Immediate shift_amount) {
    828     shift_32(dst, shift_amount, 0x7);
    829   }
    830 
    831   // Shifts dst right, duplicating sign bit, by cl % 64 bits.
    832   void sar_cl(Register dst) {
    833     shift(dst, 0x7);
    834   }
    835 
    836   // Shifts dst right, duplicating sign bit, by cl % 64 bits.
    837   void sarl_cl(Register dst) {
    838     shift_32(dst, 0x7);
    839   }
    840 
    841   void shl(Register dst, Immediate shift_amount) {
    842     shift(dst, shift_amount, 0x4);
    843   }
    844 
    845   void shl_cl(Register dst) {
    846     shift(dst, 0x4);
    847   }
    848 
    849   void shll_cl(Register dst) {
    850     shift_32(dst, 0x4);
    851   }
    852 
    853   void shll(Register dst, Immediate shift_amount) {
    854     shift_32(dst, shift_amount, 0x4);
    855   }
    856 
    857   void shr(Register dst, Immediate shift_amount) {
    858     shift(dst, shift_amount, 0x5);
    859   }
    860 
    861   void shr_cl(Register dst) {
    862     shift(dst, 0x5);
    863   }
    864 
    865   void shrl_cl(Register dst) {
    866     shift_32(dst, 0x5);
    867   }
    868 
    869   void shrl(Register dst, Immediate shift_amount) {
    870     shift_32(dst, shift_amount, 0x5);
    871   }
    872 
    873   void store_rax(void* dst, RelocInfo::Mode mode);
    874   void store_rax(ExternalReference ref);
    875 
    876   void subq(Register dst, Register src) {
    877     arithmetic_op(0x2B, dst, src);
    878   }
    879 
    880   void subq(Register dst, const Operand& src) {
    881     arithmetic_op(0x2B, dst, src);
    882   }
    883 
    884   void subq(const Operand& dst, Register src) {
    885     arithmetic_op(0x29, src, dst);
    886   }
    887 
    888   void subq(Register dst, Immediate src) {
    889     immediate_arithmetic_op(0x5, dst, src);
    890   }
    891 
    892   void subq(const Operand& dst, Immediate src) {
    893     immediate_arithmetic_op(0x5, dst, src);
    894   }
    895 
    896   void subl(Register dst, Register src) {
    897     arithmetic_op_32(0x2B, dst, src);
    898   }
    899 
    900   void subl(Register dst, const Operand& src) {
    901     arithmetic_op_32(0x2B, dst, src);
    902   }
    903 
    904   void subl(const Operand& dst, Immediate src) {
    905     immediate_arithmetic_op_32(0x5, dst, src);
    906   }
    907 
    908   void subl(Register dst, Immediate src) {
    909     immediate_arithmetic_op_32(0x5, dst, src);
    910   }
    911 
    912   void subb(Register dst, Immediate src) {
    913     immediate_arithmetic_op_8(0x5, dst, src);
    914   }
    915 
    916   void testb(Register dst, Register src);
    917   void testb(Register reg, Immediate mask);
    918   void testb(const Operand& op, Immediate mask);
    919   void testb(const Operand& op, Register reg);
    920   void testl(Register dst, Register src);
    921   void testl(Register reg, Immediate mask);
    922   void testl(const Operand& op, Immediate mask);
    923   void testq(const Operand& op, Register reg);
    924   void testq(Register dst, Register src);
    925   void testq(Register dst, Immediate mask);
    926 
    927   void xor_(Register dst, Register src) {
    928     if (dst.code() == src.code()) {
    929       arithmetic_op_32(0x33, dst, src);
    930     } else {
    931       arithmetic_op(0x33, dst, src);
    932     }
    933   }
    934 
    935   void xorl(Register dst, Register src) {
    936     arithmetic_op_32(0x33, dst, src);
    937   }
    938 
    939   void xor_(Register dst, const Operand& src) {
    940     arithmetic_op(0x33, dst, src);
    941   }
    942 
    943   void xor_(const Operand& dst, Register src) {
    944     arithmetic_op(0x31, src, dst);
    945   }
    946 
    947   void xor_(Register dst, Immediate src) {
    948     immediate_arithmetic_op(0x6, dst, src);
    949   }
    950 
    951   void xor_(const Operand& dst, Immediate src) {
    952     immediate_arithmetic_op(0x6, dst, src);
    953   }
    954 
    955   // Bit operations.
    956   void bt(const Operand& dst, Register src);
    957   void bts(const Operand& dst, Register src);
    958 
    959   // Miscellaneous
    960   void clc();
    961   void cpuid();
    962   void hlt();
    963   void int3();
    964   void nop();
    965   void nop(int n);
    966   void rdtsc();
    967   void ret(int imm16);
    968   void setcc(Condition cc, Register reg);
    969 
    970   // Label operations & relative jumps (PPUM Appendix D)
    971   //
    972   // Takes a branch opcode (cc) and a label (L) and generates
    973   // either a backward branch or a forward branch and links it
    974   // to the label fixup chain. Usage:
    975   //
    976   // Label L;    // unbound label
    977   // j(cc, &L);  // forward branch to unbound label
    978   // bind(&L);   // bind label to the current pc
    979   // j(cc, &L);  // backward branch to bound label
    980   // bind(&L);   // illegal: a label may be bound only once
    981   //
    982   // Note: The same Label can be used for forward and backward branches
    983   // but it may be bound only once.
    984 
    985   void bind(Label* L);  // binds an unbound label L to the current code position
    986 
    987   // Calls
    988   // Call near relative 32-bit displacement, relative to next instruction.
    989   void call(Label* L);
    990   void call(Handle<Code> target, RelocInfo::Mode rmode);
    991 
    992   // Call near absolute indirect, address in register
    993   void call(Register adr);
    994 
    995   // Call near indirect
    996   void call(const Operand& operand);
    997 
    998   // Jumps
    999   // Jump short or near relative.
   1000   // Use a 32-bit signed displacement.
   1001   void jmp(Label* L);  // unconditional jump to L
   1002   void jmp(Handle<Code> target, RelocInfo::Mode rmode);
   1003 
   1004   // Jump near absolute indirect (r64)
   1005   void jmp(Register adr);
   1006 
   1007   // Jump near absolute indirect (m64)
   1008   void jmp(const Operand& src);
   1009 
   1010   // Conditional jumps
   1011   void j(Condition cc, Label* L);
   1012   void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
   1013 
   1014   // Floating-point operations
   1015   void fld(int i);
   1016 
   1017   void fld1();
   1018   void fldz();
   1019 
   1020   void fld_s(const Operand& adr);
   1021   void fld_d(const Operand& adr);
   1022 
   1023   void fstp_s(const Operand& adr);
   1024   void fstp_d(const Operand& adr);
   1025   void fstp(int index);
   1026 
   1027   void fild_s(const Operand& adr);
   1028   void fild_d(const Operand& adr);
   1029 
   1030   void fist_s(const Operand& adr);
   1031 
   1032   void fistp_s(const Operand& adr);
   1033   void fistp_d(const Operand& adr);
   1034 
   1035   void fisttp_s(const Operand& adr);
   1036   void fisttp_d(const Operand& adr);
   1037 
   1038   void fabs();
   1039   void fchs();
   1040 
   1041   void fadd(int i);
   1042   void fsub(int i);
   1043   void fmul(int i);
   1044   void fdiv(int i);
   1045 
   1046   void fisub_s(const Operand& adr);
   1047 
   1048   void faddp(int i = 1);
   1049   void fsubp(int i = 1);
   1050   void fsubrp(int i = 1);
   1051   void fmulp(int i = 1);
   1052   void fdivp(int i = 1);
   1053   void fprem();
   1054   void fprem1();
   1055 
   1056   void fxch(int i = 1);
   1057   void fincstp();
   1058   void ffree(int i = 0);
   1059 
   1060   void ftst();
   1061   void fucomp(int i);
   1062   void fucompp();
   1063   void fucomi(int i);
   1064   void fucomip();
   1065 
   1066   void fcompp();
   1067   void fnstsw_ax();
   1068   void fwait();
   1069   void fnclex();
   1070 
   1071   void fsin();
   1072   void fcos();
   1073 
   1074   void frndint();
   1075 
   1076   void sahf();
   1077 
   1078   // SSE2 instructions
   1079   void movsd(const Operand& dst, XMMRegister src);
   1080   void movsd(XMMRegister src, XMMRegister dst);
   1081   void movsd(XMMRegister src, const Operand& dst);
   1082 
   1083   void cvttss2si(Register dst, const Operand& src);
   1084   void cvttsd2si(Register dst, const Operand& src);
   1085 
   1086   void cvtlsi2sd(XMMRegister dst, const Operand& src);
   1087   void cvtlsi2sd(XMMRegister dst, Register src);
   1088   void cvtqsi2sd(XMMRegister dst, const Operand& src);
   1089   void cvtqsi2sd(XMMRegister dst, Register src);
   1090 
   1091   void addsd(XMMRegister dst, XMMRegister src);
   1092   void subsd(XMMRegister dst, XMMRegister src);
   1093   void mulsd(XMMRegister dst, XMMRegister src);
   1094   void divsd(XMMRegister dst, XMMRegister src);
   1095 
   1096   void xorpd(XMMRegister dst, XMMRegister src);
   1097 
   1098   void comisd(XMMRegister dst, XMMRegister src);
   1099   void ucomisd(XMMRegister dst, XMMRegister src);
   1100 
   1101   void emit_sse_operand(XMMRegister dst, XMMRegister src);
   1102   void emit_sse_operand(XMMRegister reg, const Operand& adr);
   1103   void emit_sse_operand(XMMRegister dst, Register src);
   1104 
   1105   // Use either movsd or movlpd.
   1106   // void movdbl(XMMRegister dst, const Operand& src);
   1107   // void movdbl(const Operand& dst, XMMRegister src);
   1108 
   1109   // Debugging
   1110   void Print();
   1111 
   1112   // Check the code size generated from label to here.
   1113   int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); }
   1114 
   1115   // Mark address of the ExitJSFrame code.
   1116   void RecordJSReturn();
   1117 
   1118   // Record a comment relocation entry that can be used by a disassembler.
   1119   // Use --debug_code to enable.
   1120   void RecordComment(const char* msg);
   1121 
   1122   void RecordPosition(int pos);
   1123   void RecordStatementPosition(int pos);
   1124   void WriteRecordedPositions();
   1125 
   1126   int pc_offset() const  { return static_cast<int>(pc_ - buffer_); }
   1127   int current_statement_position() const { return current_statement_position_; }
   1128   int current_position() const  { return current_position_; }
   1129 
   1130   // Check if there is less than kGap bytes available in the buffer.
   1131   // If this is the case, we need to grow the buffer before emitting
   1132   // an instruction or relocation information.
   1133   inline bool buffer_overflow() const {
   1134     return pc_ >= reloc_info_writer.pos() - kGap;
   1135   }
   1136 
   1137   // Get the number of bytes available in the buffer.
   1138   inline int available_space() const {
   1139     return static_cast<int>(reloc_info_writer.pos() - pc_);
   1140   }
   1141 
   1142   // Avoid overflows for displacements etc.
   1143   static const int kMaximalBufferSize = 512*MB;
   1144   static const int kMinimalBufferSize = 4*KB;
   1145 
   1146  private:
   1147   byte* addr_at(int pos)  { return buffer_ + pos; }
   1148   byte byte_at(int pos)  { return buffer_[pos]; }
   1149   uint32_t long_at(int pos)  {
   1150     return *reinterpret_cast<uint32_t*>(addr_at(pos));
   1151   }
   1152   void long_at_put(int pos, uint32_t x)  {
   1153     *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
   1154   }
   1155 
   1156   // code emission
   1157   void GrowBuffer();
   1158 
   1159   void emit(byte x) { *pc_++ = x; }
   1160   inline void emitl(uint32_t x);
   1161   inline void emitq(uint64_t x, RelocInfo::Mode rmode);
   1162   inline void emitw(uint16_t x);
   1163   inline void emit_code_target(Handle<Code> target, RelocInfo::Mode rmode);
   1164   void emit(Immediate x) { emitl(x.value_); }
   1165 
   1166   // Emits a REX prefix that encodes a 64-bit operand size and
   1167   // the top bit of both register codes.
   1168   // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
   1169   // REX.W is set.
   1170   inline void emit_rex_64(Register reg, Register rm_reg);
   1171   inline void emit_rex_64(XMMRegister reg, Register rm_reg);
   1172 
   1173   // Emits a REX prefix that encodes a 64-bit operand size and
   1174   // the top bit of the destination, index, and base register codes.
   1175   // The high bit of reg is used for REX.R, the high bit of op's base
   1176   // register is used for REX.B, and the high bit of op's index register
   1177   // is used for REX.X.  REX.W is set.
   1178   inline void emit_rex_64(Register reg, const Operand& op);
   1179   inline void emit_rex_64(XMMRegister reg, const Operand& op);
   1180 
   1181   // Emits a REX prefix that encodes a 64-bit operand size and
   1182   // the top bit of the register code.
   1183   // The high bit of register is used for REX.B.
   1184   // REX.W is set and REX.R and REX.X are clear.
   1185   inline void emit_rex_64(Register rm_reg);
   1186 
   1187   // Emits a REX prefix that encodes a 64-bit operand size and
   1188   // the top bit of the index and base register codes.
   1189   // The high bit of op's base register is used for REX.B, and the high
   1190   // bit of op's index register is used for REX.X.
   1191   // REX.W is set and REX.R clear.
   1192   inline void emit_rex_64(const Operand& op);
   1193 
   1194   // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
   1195   void emit_rex_64() { emit(0x48); }
   1196 
   1197   // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
   1198   // REX.W is clear.
   1199   inline void emit_rex_32(Register reg, Register rm_reg);
   1200 
   1201   // The high bit of reg is used for REX.R, the high bit of op's base
   1202   // register is used for REX.B, and the high bit of op's index register
   1203   // is used for REX.X.  REX.W is cleared.
   1204   inline void emit_rex_32(Register reg, const Operand& op);
   1205 
   1206   // High bit of rm_reg goes to REX.B.
   1207   // REX.W, REX.R and REX.X are clear.
   1208   inline void emit_rex_32(Register rm_reg);
   1209 
   1210   // High bit of base goes to REX.B and high bit of index to REX.X.
   1211   // REX.W and REX.R are clear.
   1212   inline void emit_rex_32(const Operand& op);
   1213 
   1214   // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
   1215   // REX.W is cleared.  If no REX bits are set, no byte is emitted.
   1216   inline void emit_optional_rex_32(Register reg, Register rm_reg);
   1217 
   1218   // The high bit of reg is used for REX.R, the high bit of op's base
   1219   // register is used for REX.B, and the high bit of op's index register
   1220   // is used for REX.X.  REX.W is cleared.  If no REX bits are set, nothing
   1221   // is emitted.
   1222   inline void emit_optional_rex_32(Register reg, const Operand& op);
   1223 
   1224   // As for emit_optional_rex_32(Register, Register), except that
   1225   // the registers are XMM registers.
   1226   inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
   1227 
   1228   // As for emit_optional_rex_32(Register, Register), except that
   1229   // the registers are XMM registers.
   1230   inline void emit_optional_rex_32(XMMRegister reg, Register base);
   1231 
   1232   // As for emit_optional_rex_32(Register, const Operand&), except that
   1233   // the register is an XMM register.
   1234   inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);
   1235 
   1236   // Optionally do as emit_rex_32(Register) if the register number has
   1237   // the high bit set.
   1238   inline void emit_optional_rex_32(Register rm_reg);
   1239 
   1240   // Optionally do as emit_rex_32(const Operand&) if the operand register
   1241   // numbers have a high bit set.
   1242   inline void emit_optional_rex_32(const Operand& op);
   1243 
   1244 
   1245   // Emit the ModR/M byte, and optionally the SIB byte and
   1246   // 1- or 4-byte offset for a memory operand.  Also encodes
   1247   // the second operand of the operation, a register or operation
   1248   // subcode, into the reg field of the ModR/M byte.
   1249   void emit_operand(Register reg, const Operand& adr) {
   1250     emit_operand(reg.low_bits(), adr);
   1251   }
   1252 
   1253   // Emit the ModR/M byte, and optionally the SIB byte and
   1254   // 1- or 4-byte offset for a memory operand.  Also used to encode
   1255   // a three-bit opcode extension into the ModR/M byte.
   1256   void emit_operand(int rm, const Operand& adr);
   1257 
   1258   // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
   1259   void emit_modrm(Register reg, Register rm_reg) {
   1260     emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
   1261   }
   1262 
   1263   // Emit a ModR/M byte with an operation subcode in the reg field and
   1264   // a register in the rm_reg field.
   1265   void emit_modrm(int code, Register rm_reg) {
   1266     ASSERT(is_uint3(code));
   1267     emit(0xC0 | code << 3 | rm_reg.low_bits());
   1268   }
   1269 
   1270   // Emit the code-object-relative offset of the label's position
   1271   inline void emit_code_relative_offset(Label* label);
   1272 
   1273   // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
   1274   // AND, OR, XOR, or CMP.  The encodings of these operations are all
   1275   // similar, differing just in the opcode or in the reg field of the
   1276   // ModR/M byte.
   1277   void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
   1278   void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
   1279   void arithmetic_op_32(byte opcode, Register reg, Register rm_reg);
   1280   void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg);
   1281   void arithmetic_op(byte opcode, Register reg, Register rm_reg);
   1282   void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg);
   1283   void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
   1284   void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
   1285   // Operate on a byte in memory or register.
   1286   void immediate_arithmetic_op_8(byte subcode,
   1287                                  Register dst,
   1288                                  Immediate src);
   1289   void immediate_arithmetic_op_8(byte subcode,
   1290                                  const Operand& dst,
   1291                                  Immediate src);
   1292   // Operate on a word in memory or register.
   1293   void immediate_arithmetic_op_16(byte subcode,
   1294                                   Register dst,
   1295                                   Immediate src);
   1296   void immediate_arithmetic_op_16(byte subcode,
   1297                                   const Operand& dst,
   1298                                   Immediate src);
   1299   // Operate on a 32-bit word in memory or register.
   1300   void immediate_arithmetic_op_32(byte subcode,
   1301                                   Register dst,
   1302                                   Immediate src);
   1303   void immediate_arithmetic_op_32(byte subcode,
   1304                                   const Operand& dst,
   1305                                   Immediate src);
   1306 
   1307   // Emit machine code for a shift operation.
   1308   void shift(Register dst, Immediate shift_amount, int subcode);
   1309   void shift_32(Register dst, Immediate shift_amount, int subcode);
   1310   // Shift dst by cl % 64 bits.
   1311   void shift(Register dst, int subcode);
   1312   void shift_32(Register dst, int subcode);
   1313 
   1314   void emit_farith(int b1, int b2, int i);
   1315 
   1316   // labels
   1317   // void print(Label* L);
   1318   void bind_to(Label* L, int pos);
   1319   void link_to(Label* L, Label* appendix);
   1320 
   1321   // record reloc info for current pc_
   1322   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
   1323 
   1324   friend class CodePatcher;
   1325   friend class EnsureSpace;
   1326   friend class RegExpMacroAssemblerX64;
   1327 
   1328   // Code buffer:
   1329   // The buffer into which code and relocation info are generated.
   1330   byte* buffer_;
   1331   int buffer_size_;
   1332   // True if the assembler owns the buffer, false if buffer is external.
   1333   bool own_buffer_;
   1334   // A previously allocated buffer of kMinimalBufferSize bytes, or NULL.
   1335   static byte* spare_buffer_;
   1336 
   1337   // code generation
   1338   byte* pc_;  // the program counter; moves forward
   1339   RelocInfoWriter reloc_info_writer;
   1340 
   1341   List< Handle<Code> > code_targets_;
   1342   // push-pop elimination
   1343   byte* last_pc_;
   1344 
   1345   // source position information
   1346   int current_statement_position_;
   1347   int current_position_;
   1348   int written_statement_position_;
   1349   int written_position_;
   1350 };
   1351 
   1352 
   1353 // Helper class that ensures that there is enough space for generating
   1354 // instructions and relocation information.  The constructor makes
   1355 // sure that there is enough space and (in debug mode) the destructor
   1356 // checks that we did not generate too much.
   1357 class EnsureSpace BASE_EMBEDDED {
   1358  public:
   1359   explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
   1360     if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
   1361 #ifdef DEBUG
   1362     space_before_ = assembler_->available_space();
   1363 #endif
   1364   }
   1365 
   1366 #ifdef DEBUG
   1367   ~EnsureSpace() {
   1368     int bytes_generated = space_before_ - assembler_->available_space();
   1369     ASSERT(bytes_generated < assembler_->kGap);
   1370   }
   1371 #endif
   1372 
   1373  private:
   1374   Assembler* assembler_;
   1375 #ifdef DEBUG
   1376   int space_before_;
   1377 #endif
   1378 };
   1379 
   1380 } }  // namespace v8::internal
   1381 
   1382 #endif  // V8_X64_ASSEMBLER_X64_H_
   1383