Home | History | Annotate | Download | only in ia32
      1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
      2 // All Rights Reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions 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_IA32_ASSEMBLER_IA32_H_
     38 #define V8_IA32_ASSEMBLER_IA32_H_
     39 
     40 #include "isolate.h"
     41 #include "serialize.h"
     42 
     43 namespace v8 {
     44 namespace internal {
     45 
     46 // CPU Registers.
     47 //
     48 // 1) We would prefer to use an enum, but enum values are assignment-
     49 // compatible with int, which has caused code-generation bugs.
     50 //
     51 // 2) We would prefer to use a class instead of a struct but we don't like
     52 // the register initialization to depend on the particular initialization
     53 // order (which appears to be different on OS X, Linux, and Windows for the
     54 // installed versions of C++ we tried). Using a struct permits C-style
     55 // "initialization". Also, the Register objects cannot be const as this
     56 // forces initialization stubs in MSVC, making us dependent on initialization
     57 // order.
     58 //
     59 // 3) By not using an enum, we are possibly preventing the compiler from
     60 // doing certain constant folds, which may significantly reduce the
     61 // code generated for some assembly instructions (because they boil down
     62 // to a few constants). If this is a problem, we could change the code
     63 // such that we use an enum in optimized mode, and the struct in debug
     64 // mode. This way we get the compile-time error checking in debug mode
     65 // and best performance in optimized code.
     66 //
     67 struct Register {
     68   static const int kMaxNumAllocatableRegisters = 6;
     69   static int NumAllocatableRegisters() {
     70     return kMaxNumAllocatableRegisters;
     71   }
     72   static const int kNumRegisters = 8;
     73 
     74   static inline const char* AllocationIndexToString(int index);
     75 
     76   static inline int ToAllocationIndex(Register reg);
     77 
     78   static inline Register FromAllocationIndex(int index);
     79 
     80   static Register from_code(int code) {
     81     ASSERT(code >= 0);
     82     ASSERT(code < kNumRegisters);
     83     Register r = { code };
     84     return r;
     85   }
     86   bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
     87   bool is(Register reg) const { return code_ == reg.code_; }
     88   // eax, ebx, ecx and edx are byte registers, the rest are not.
     89   bool is_byte_register() const { return code_ <= 3; }
     90   int code() const {
     91     ASSERT(is_valid());
     92     return code_;
     93   }
     94   int bit() const {
     95     ASSERT(is_valid());
     96     return 1 << code_;
     97   }
     98 
     99   // Unfortunately we can't make this private in a struct.
    100   int code_;
    101 };
    102 
    103 const int kRegister_eax_Code = 0;
    104 const int kRegister_ecx_Code = 1;
    105 const int kRegister_edx_Code = 2;
    106 const int kRegister_ebx_Code = 3;
    107 const int kRegister_esp_Code = 4;
    108 const int kRegister_ebp_Code = 5;
    109 const int kRegister_esi_Code = 6;
    110 const int kRegister_edi_Code = 7;
    111 const int kRegister_no_reg_Code = -1;
    112 
    113 const Register eax = { kRegister_eax_Code };
    114 const Register ecx = { kRegister_ecx_Code };
    115 const Register edx = { kRegister_edx_Code };
    116 const Register ebx = { kRegister_ebx_Code };
    117 const Register esp = { kRegister_esp_Code };
    118 const Register ebp = { kRegister_ebp_Code };
    119 const Register esi = { kRegister_esi_Code };
    120 const Register edi = { kRegister_edi_Code };
    121 const Register no_reg = { kRegister_no_reg_Code };
    122 
    123 
    124 inline const char* Register::AllocationIndexToString(int index) {
    125   ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
    126   // This is the mapping of allocation indices to registers.
    127   const char* const kNames[] = { "eax", "ecx", "edx", "ebx", "esi", "edi" };
    128   return kNames[index];
    129 }
    130 
    131 
    132 inline int Register::ToAllocationIndex(Register reg) {
    133   ASSERT(reg.is_valid() && !reg.is(esp) && !reg.is(ebp));
    134   return (reg.code() >= 6) ? reg.code() - 2 : reg.code();
    135 }
    136 
    137 
    138 inline Register Register::FromAllocationIndex(int index)  {
    139   ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
    140   return (index >= 4) ? from_code(index + 2) : from_code(index);
    141 }
    142 
    143 
    144 struct IntelDoubleRegister {
    145   static const int kMaxNumRegisters = 8;
    146   static const int kMaxNumAllocatableRegisters = 7;
    147   static int NumAllocatableRegisters();
    148   static int NumRegisters();
    149   static const char* AllocationIndexToString(int index);
    150 
    151   static int ToAllocationIndex(IntelDoubleRegister reg) {
    152     ASSERT(reg.code() != 0);
    153     return reg.code() - 1;
    154   }
    155 
    156   static IntelDoubleRegister FromAllocationIndex(int index) {
    157     ASSERT(index >= 0 && index < NumAllocatableRegisters());
    158     return from_code(index + 1);
    159   }
    160 
    161   static IntelDoubleRegister from_code(int code) {
    162     IntelDoubleRegister result = { code };
    163     return result;
    164   }
    165 
    166   bool is_valid() const {
    167     return 0 <= code_ && code_ < NumRegisters();
    168   }
    169   int code() const {
    170     ASSERT(is_valid());
    171     return code_;
    172   }
    173 
    174   int code_;
    175 };
    176 
    177 
    178 const IntelDoubleRegister double_register_0 = { 0 };
    179 const IntelDoubleRegister double_register_1 = { 1 };
    180 const IntelDoubleRegister double_register_2 = { 2 };
    181 const IntelDoubleRegister double_register_3 = { 3 };
    182 const IntelDoubleRegister double_register_4 = { 4 };
    183 const IntelDoubleRegister double_register_5 = { 5 };
    184 const IntelDoubleRegister double_register_6 = { 6 };
    185 const IntelDoubleRegister double_register_7 = { 7 };
    186 const IntelDoubleRegister no_double_reg = { -1 };
    187 
    188 
    189 struct XMMRegister : IntelDoubleRegister {
    190   static const int kNumAllocatableRegisters = 7;
    191   static const int kNumRegisters = 8;
    192 
    193   static XMMRegister from_code(int code) {
    194     STATIC_ASSERT(sizeof(XMMRegister) == sizeof(IntelDoubleRegister));
    195     XMMRegister result;
    196     result.code_ = code;
    197     return result;
    198   }
    199 
    200   bool is(XMMRegister reg) const { return code_ == reg.code_; }
    201 
    202   static XMMRegister FromAllocationIndex(int index) {
    203     ASSERT(index >= 0 && index < NumAllocatableRegisters());
    204     return from_code(index + 1);
    205   }
    206 
    207   static const char* AllocationIndexToString(int index) {
    208     ASSERT(index >= 0 && index < kNumAllocatableRegisters);
    209     const char* const names[] = {
    210       "xmm1",
    211       "xmm2",
    212       "xmm3",
    213       "xmm4",
    214       "xmm5",
    215       "xmm6",
    216       "xmm7"
    217     };
    218     return names[index];
    219   }
    220 };
    221 
    222 
    223 #define xmm0 (static_cast<const XMMRegister&>(double_register_0))
    224 #define xmm1 (static_cast<const XMMRegister&>(double_register_1))
    225 #define xmm2 (static_cast<const XMMRegister&>(double_register_2))
    226 #define xmm3 (static_cast<const XMMRegister&>(double_register_3))
    227 #define xmm4 (static_cast<const XMMRegister&>(double_register_4))
    228 #define xmm5 (static_cast<const XMMRegister&>(double_register_5))
    229 #define xmm6 (static_cast<const XMMRegister&>(double_register_6))
    230 #define xmm7 (static_cast<const XMMRegister&>(double_register_7))
    231 #define no_xmm_reg (static_cast<const XMMRegister&>(no_double_reg))
    232 
    233 
    234 struct X87Register : IntelDoubleRegister {
    235   static const int kNumAllocatableRegisters = 5;
    236   static const int kNumRegisters = 5;
    237 
    238   bool is(X87Register reg) const {
    239     return code_ == reg.code_;
    240   }
    241 
    242   static const char* AllocationIndexToString(int index) {
    243     ASSERT(index >= 0 && index < kNumAllocatableRegisters);
    244     const char* const names[] = {
    245       "stX_0", "stX_1", "stX_2", "stX_3", "stX_4"
    246     };
    247     return names[index];
    248   }
    249 
    250   static X87Register FromAllocationIndex(int index) {
    251     STATIC_ASSERT(sizeof(X87Register) == sizeof(IntelDoubleRegister));
    252     ASSERT(index >= 0 && index < NumAllocatableRegisters());
    253     X87Register result;
    254     result.code_ = index;
    255     return result;
    256   }
    257 
    258   static int ToAllocationIndex(X87Register reg) {
    259     return reg.code_;
    260   }
    261 };
    262 
    263 #define stX_0 static_cast<const X87Register&>(double_register_0)
    264 #define stX_1 static_cast<const X87Register&>(double_register_1)
    265 #define stX_2 static_cast<const X87Register&>(double_register_2)
    266 #define stX_3 static_cast<const X87Register&>(double_register_3)
    267 #define stX_4 static_cast<const X87Register&>(double_register_4)
    268 
    269 
    270 typedef IntelDoubleRegister DoubleRegister;
    271 
    272 
    273 enum Condition {
    274   // any value < 0 is considered no_condition
    275   no_condition  = -1,
    276 
    277   overflow      =  0,
    278   no_overflow   =  1,
    279   below         =  2,
    280   above_equal   =  3,
    281   equal         =  4,
    282   not_equal     =  5,
    283   below_equal   =  6,
    284   above         =  7,
    285   negative      =  8,
    286   positive      =  9,
    287   parity_even   = 10,
    288   parity_odd    = 11,
    289   less          = 12,
    290   greater_equal = 13,
    291   less_equal    = 14,
    292   greater       = 15,
    293 
    294   // aliases
    295   carry         = below,
    296   not_carry     = above_equal,
    297   zero          = equal,
    298   not_zero      = not_equal,
    299   sign          = negative,
    300   not_sign      = positive
    301 };
    302 
    303 
    304 // Returns the equivalent of !cc.
    305 // Negation of the default no_condition (-1) results in a non-default
    306 // no_condition value (-2). As long as tests for no_condition check
    307 // for condition < 0, this will work as expected.
    308 inline Condition NegateCondition(Condition cc) {
    309   return static_cast<Condition>(cc ^ 1);
    310 }
    311 
    312 
    313 // Corresponds to transposing the operands of a comparison.
    314 inline Condition ReverseCondition(Condition cc) {
    315   switch (cc) {
    316     case below:
    317       return above;
    318     case above:
    319       return below;
    320     case above_equal:
    321       return below_equal;
    322     case below_equal:
    323       return above_equal;
    324     case less:
    325       return greater;
    326     case greater:
    327       return less;
    328     case greater_equal:
    329       return less_equal;
    330     case less_equal:
    331       return greater_equal;
    332     default:
    333       return cc;
    334   };
    335 }
    336 
    337 
    338 // -----------------------------------------------------------------------------
    339 // Machine instruction Immediates
    340 
    341 class Immediate BASE_EMBEDDED {
    342  public:
    343   inline explicit Immediate(int x);
    344   inline explicit Immediate(const ExternalReference& ext);
    345   inline explicit Immediate(Handle<Object> handle);
    346   inline explicit Immediate(Smi* value);
    347   inline explicit Immediate(Address addr);
    348 
    349   static Immediate CodeRelativeOffset(Label* label) {
    350     return Immediate(label);
    351   }
    352 
    353   bool is_zero() const { return x_ == 0 && RelocInfo::IsNone(rmode_); }
    354   bool is_int8() const {
    355     return -128 <= x_ && x_ < 128 && RelocInfo::IsNone(rmode_);
    356   }
    357   bool is_int16() const {
    358     return -32768 <= x_ && x_ < 32768 && RelocInfo::IsNone(rmode_);
    359   }
    360 
    361  private:
    362   inline explicit Immediate(Label* value);
    363 
    364   int x_;
    365   RelocInfo::Mode rmode_;
    366 
    367   friend class Assembler;
    368   friend class MacroAssembler;
    369 };
    370 
    371 
    372 // -----------------------------------------------------------------------------
    373 // Machine instruction Operands
    374 
    375 enum ScaleFactor {
    376   times_1 = 0,
    377   times_2 = 1,
    378   times_4 = 2,
    379   times_8 = 3,
    380   times_int_size = times_4,
    381   times_half_pointer_size = times_2,
    382   times_pointer_size = times_4,
    383   times_twice_pointer_size = times_8
    384 };
    385 
    386 
    387 class Operand BASE_EMBEDDED {
    388  public:
    389   // XMM reg
    390   INLINE(explicit Operand(XMMRegister xmm_reg));
    391 
    392   // [disp/r]
    393   INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode));
    394   // disp only must always be relocated
    395 
    396   // [base + disp/r]
    397   explicit Operand(Register base, int32_t disp,
    398                    RelocInfo::Mode rmode = RelocInfo::NONE32);
    399 
    400   // [base + index*scale + disp/r]
    401   explicit Operand(Register base,
    402                    Register index,
    403                    ScaleFactor scale,
    404                    int32_t disp,
    405                    RelocInfo::Mode rmode = RelocInfo::NONE32);
    406 
    407   // [index*scale + disp/r]
    408   explicit Operand(Register index,
    409                    ScaleFactor scale,
    410                    int32_t disp,
    411                    RelocInfo::Mode rmode = RelocInfo::NONE32);
    412 
    413   static Operand StaticVariable(const ExternalReference& ext) {
    414     return Operand(reinterpret_cast<int32_t>(ext.address()),
    415                    RelocInfo::EXTERNAL_REFERENCE);
    416   }
    417 
    418   static Operand StaticArray(Register index,
    419                              ScaleFactor scale,
    420                              const ExternalReference& arr) {
    421     return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()),
    422                    RelocInfo::EXTERNAL_REFERENCE);
    423   }
    424 
    425   static Operand ForCell(Handle<Cell> cell) {
    426     AllowDeferredHandleDereference embedding_raw_address;
    427     return Operand(reinterpret_cast<int32_t>(cell.location()),
    428                    RelocInfo::CELL);
    429   }
    430 
    431   // Returns true if this Operand is a wrapper for the specified register.
    432   bool is_reg(Register reg) const;
    433 
    434   // Returns true if this Operand is a wrapper for one register.
    435   bool is_reg_only() const;
    436 
    437   // Asserts that this Operand is a wrapper for one register and returns the
    438   // register.
    439   Register reg() const;
    440 
    441  private:
    442   // reg
    443   INLINE(explicit Operand(Register reg));
    444 
    445   // Set the ModRM byte without an encoded 'reg' register. The
    446   // register is encoded later as part of the emit_operand operation.
    447   inline void set_modrm(int mod, Register rm);
    448 
    449   inline void set_sib(ScaleFactor scale, Register index, Register base);
    450   inline void set_disp8(int8_t disp);
    451   inline void set_dispr(int32_t disp, RelocInfo::Mode rmode);
    452 
    453   byte buf_[6];
    454   // The number of bytes in buf_.
    455   unsigned int len_;
    456   // Only valid if len_ > 4.
    457   RelocInfo::Mode rmode_;
    458 
    459   friend class Assembler;
    460   friend class MacroAssembler;
    461   friend class LCodeGen;
    462 };
    463 
    464 
    465 // -----------------------------------------------------------------------------
    466 // A Displacement describes the 32bit immediate field of an instruction which
    467 // may be used together with a Label in order to refer to a yet unknown code
    468 // position. Displacements stored in the instruction stream are used to describe
    469 // the instruction and to chain a list of instructions using the same Label.
    470 // A Displacement contains 2 different fields:
    471 //
    472 // next field: position of next displacement in the chain (0 = end of list)
    473 // type field: instruction type
    474 //
    475 // A next value of null (0) indicates the end of a chain (note that there can
    476 // be no displacement at position zero, because there is always at least one
    477 // instruction byte before the displacement).
    478 //
    479 // Displacement _data field layout
    480 //
    481 // |31.....2|1......0|
    482 // [  next  |  type  |
    483 
    484 class Displacement BASE_EMBEDDED {
    485  public:
    486   enum Type {
    487     UNCONDITIONAL_JUMP,
    488     CODE_RELATIVE,
    489     OTHER
    490   };
    491 
    492   int data() const { return data_; }
    493   Type type() const { return TypeField::decode(data_); }
    494   void next(Label* L) const {
    495     int n = NextField::decode(data_);
    496     n > 0 ? L->link_to(n) : L->Unuse();
    497   }
    498   void link_to(Label* L) { init(L, type()); }
    499 
    500   explicit Displacement(int data) { data_ = data; }
    501 
    502   Displacement(Label* L, Type type) { init(L, type); }
    503 
    504   void print() {
    505     PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"),
    506                        NextField::decode(data_));
    507   }
    508 
    509  private:
    510   int data_;
    511 
    512   class TypeField: public BitField<Type, 0, 2> {};
    513   class NextField: public BitField<int,  2, 32-2> {};
    514 
    515   void init(Label* L, Type type);
    516 };
    517 
    518 
    519 
    520 // CpuFeatures keeps track of which features are supported by the target CPU.
    521 // Supported features must be enabled by a CpuFeatureScope before use.
    522 // Example:
    523 //   if (assembler->IsSupported(SSE2)) {
    524 //     CpuFeatureScope fscope(assembler, SSE2);
    525 //     // Generate SSE2 floating point code.
    526 //   } else {
    527 //     // Generate standard x87 floating point code.
    528 //   }
    529 class CpuFeatures : public AllStatic {
    530  public:
    531   // Detect features of the target CPU. Set safe defaults if the serializer
    532   // is enabled (snapshots must be portable).
    533   static void Probe();
    534 
    535   // Check whether a feature is supported by the target CPU.
    536   static bool IsSupported(CpuFeature f) {
    537     ASSERT(initialized_);
    538     if (Check(f, cross_compile_)) return true;
    539     if (f == SSE2 && !FLAG_enable_sse2) return false;
    540     if (f == SSE3 && !FLAG_enable_sse3) return false;
    541     if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
    542     if (f == CMOV && !FLAG_enable_cmov) return false;
    543     return Check(f, supported_);
    544   }
    545 
    546   static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
    547     ASSERT(initialized_);
    548     return Check(f, found_by_runtime_probing_only_);
    549   }
    550 
    551   static bool IsSafeForSnapshot(CpuFeature f) {
    552     return Check(f, cross_compile_) ||
    553            (IsSupported(f) &&
    554             (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
    555   }
    556 
    557   static bool VerifyCrossCompiling() {
    558     return cross_compile_ == 0;
    559   }
    560 
    561   static bool VerifyCrossCompiling(CpuFeature f) {
    562     uint64_t mask = flag2set(f);
    563     return cross_compile_ == 0 ||
    564            (cross_compile_ & mask) == mask;
    565   }
    566 
    567  private:
    568   static bool Check(CpuFeature f, uint64_t set) {
    569     return (set & flag2set(f)) != 0;
    570   }
    571 
    572   static uint64_t flag2set(CpuFeature f) {
    573     return static_cast<uint64_t>(1) << f;
    574   }
    575 
    576 #ifdef DEBUG
    577   static bool initialized_;
    578 #endif
    579   static uint64_t supported_;
    580   static uint64_t found_by_runtime_probing_only_;
    581 
    582   static uint64_t cross_compile_;
    583 
    584   friend class ExternalReference;
    585   friend class PlatformFeatureScope;
    586   DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
    587 };
    588 
    589 
    590 class Assembler : public AssemblerBase {
    591  private:
    592   // We check before assembling an instruction that there is sufficient
    593   // space to write an instruction and its relocation information.
    594   // The relocation writer's position must be kGap bytes above the end of
    595   // the generated instructions. This leaves enough space for the
    596   // longest possible ia32 instruction, 15 bytes, and the longest possible
    597   // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
    598   // (There is a 15 byte limit on ia32 instruction length that rules out some
    599   // otherwise valid instructions.)
    600   // This allows for a single, fast space check per instruction.
    601   static const int kGap = 32;
    602 
    603  public:
    604   // Create an assembler. Instructions and relocation information are emitted
    605   // into a buffer, with the instructions starting from the beginning and the
    606   // relocation information starting from the end of the buffer. See CodeDesc
    607   // for a detailed comment on the layout (globals.h).
    608   //
    609   // If the provided buffer is NULL, the assembler allocates and grows its own
    610   // buffer, and buffer_size determines the initial buffer size. The buffer is
    611   // owned by the assembler and deallocated upon destruction of the assembler.
    612   //
    613   // If the provided buffer is not NULL, the assembler uses the provided buffer
    614   // for code generation and assumes its size to be buffer_size. If the buffer
    615   // is too small, a fatal error occurs. No deallocation of the buffer is done
    616   // upon destruction of the assembler.
    617   // TODO(vitalyr): the assembler does not need an isolate.
    618   Assembler(Isolate* isolate, void* buffer, int buffer_size);
    619   virtual ~Assembler() { }
    620 
    621   // GetCode emits any pending (non-emitted) code and fills the descriptor
    622   // desc. GetCode() is idempotent; it returns the same result if no other
    623   // Assembler functions are invoked in between GetCode() calls.
    624   void GetCode(CodeDesc* desc);
    625 
    626   // Read/Modify the code target in the branch/call instruction at pc.
    627   inline static Address target_address_at(Address pc);
    628   inline static void set_target_address_at(Address pc, Address target);
    629 
    630   // Return the code target address at a call site from the return address
    631   // of that call in the instruction stream.
    632   inline static Address target_address_from_return_address(Address pc);
    633 
    634   // This sets the branch destination (which is in the instruction on x86).
    635   // This is for calls and branches within generated code.
    636   inline static void deserialization_set_special_target_at(
    637       Address instruction_payload, Address target) {
    638     set_target_address_at(instruction_payload, target);
    639   }
    640 
    641   static const int kSpecialTargetSize = kPointerSize;
    642 
    643   // Distance between the address of the code target in the call instruction
    644   // and the return address
    645   static const int kCallTargetAddressOffset = kPointerSize;
    646   // Distance between start of patched return sequence and the emitted address
    647   // to jump to.
    648   static const int kPatchReturnSequenceAddressOffset = 1;  // JMP imm32.
    649 
    650   // Distance between start of patched debug break slot and the emitted address
    651   // to jump to.
    652   static const int kPatchDebugBreakSlotAddressOffset = 1;  // JMP imm32.
    653 
    654   static const int kCallInstructionLength = 5;
    655   static const int kPatchDebugBreakSlotReturnOffset = kPointerSize;
    656   static const int kJSReturnSequenceLength = 6;
    657 
    658   // The debug break slot must be able to contain a call instruction.
    659   static const int kDebugBreakSlotLength = kCallInstructionLength;
    660 
    661   // One byte opcode for test al, 0xXX.
    662   static const byte kTestAlByte = 0xA8;
    663   // One byte opcode for nop.
    664   static const byte kNopByte = 0x90;
    665 
    666   // One byte opcode for a short unconditional jump.
    667   static const byte kJmpShortOpcode = 0xEB;
    668   // One byte prefix for a short conditional jump.
    669   static const byte kJccShortPrefix = 0x70;
    670   static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
    671   static const byte kJcShortOpcode = kJccShortPrefix | carry;
    672   static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
    673   static const byte kJzShortOpcode = kJccShortPrefix | zero;
    674 
    675 
    676   // ---------------------------------------------------------------------------
    677   // Code generation
    678   //
    679   // - function names correspond one-to-one to ia32 instruction mnemonics
    680   // - unless specified otherwise, instructions operate on 32bit operands
    681   // - instructions on 8bit (byte) operands/registers have a trailing '_b'
    682   // - instructions on 16bit (word) operands/registers have a trailing '_w'
    683   // - naming conflicts with C++ keywords are resolved via a trailing '_'
    684 
    685   // NOTE ON INTERFACE: Currently, the interface is not very consistent
    686   // in the sense that some operations (e.g. mov()) can be called in more
    687   // the one way to generate the same instruction: The Register argument
    688   // can in some cases be replaced with an Operand(Register) argument.
    689   // This should be cleaned up and made more orthogonal. The questions
    690   // is: should we always use Operands instead of Registers where an
    691   // Operand is possible, or should we have a Register (overloaded) form
    692   // instead? We must be careful to make sure that the selected instruction
    693   // is obvious from the parameters to avoid hard-to-find code generation
    694   // bugs.
    695 
    696   // Insert the smallest number of nop instructions
    697   // possible to align the pc offset to a multiple
    698   // of m. m must be a power of 2.
    699   void Align(int m);
    700   void Nop(int bytes = 1);
    701   // Aligns code to something that's optimal for a jump target for the platform.
    702   void CodeTargetAlign();
    703 
    704   // Stack
    705   void pushad();
    706   void popad();
    707 
    708   void pushfd();
    709   void popfd();
    710 
    711   void push(const Immediate& x);
    712   void push_imm32(int32_t imm32);
    713   void push(Register src);
    714   void push(const Operand& src);
    715 
    716   void pop(Register dst);
    717   void pop(const Operand& dst);
    718 
    719   void enter(const Immediate& size);
    720   void leave();
    721 
    722   // Moves
    723   void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); }
    724   void mov_b(Register dst, const Operand& src);
    725   void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); }
    726   void mov_b(const Operand& dst, int8_t imm8);
    727   void mov_b(const Operand& dst, Register src);
    728 
    729   void mov_w(Register dst, const Operand& src);
    730   void mov_w(const Operand& dst, Register src);
    731   void mov_w(const Operand& dst, int16_t imm16);
    732 
    733   void mov(Register dst, int32_t imm32);
    734   void mov(Register dst, const Immediate& x);
    735   void mov(Register dst, Handle<Object> handle);
    736   void mov(Register dst, const Operand& src);
    737   void mov(Register dst, Register src);
    738   void mov(const Operand& dst, const Immediate& x);
    739   void mov(const Operand& dst, Handle<Object> handle);
    740   void mov(const Operand& dst, Register src);
    741 
    742   void movsx_b(Register dst, Register src) { movsx_b(dst, Operand(src)); }
    743   void movsx_b(Register dst, const Operand& src);
    744 
    745   void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); }
    746   void movsx_w(Register dst, const Operand& src);
    747 
    748   void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); }
    749   void movzx_b(Register dst, const Operand& src);
    750 
    751   void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); }
    752   void movzx_w(Register dst, const Operand& src);
    753 
    754   // Conditional moves
    755   void cmov(Condition cc, Register dst, Register src) {
    756     cmov(cc, dst, Operand(src));
    757   }
    758   void cmov(Condition cc, Register dst, const Operand& src);
    759 
    760   // Flag management.
    761   void cld();
    762 
    763   // Repetitive string instructions.
    764   void rep_movs();
    765   void rep_stos();
    766   void stos();
    767 
    768   // Exchange two registers
    769   void xchg(Register dst, Register src);
    770 
    771   // Arithmetics
    772   void adc(Register dst, int32_t imm32);
    773   void adc(Register dst, const Operand& src);
    774 
    775   void add(Register dst, Register src) { add(dst, Operand(src)); }
    776   void add(Register dst, const Operand& src);
    777   void add(const Operand& dst, Register src);
    778   void add(Register dst, const Immediate& imm) { add(Operand(dst), imm); }
    779   void add(const Operand& dst, const Immediate& x);
    780 
    781   void and_(Register dst, int32_t imm32);
    782   void and_(Register dst, const Immediate& x);
    783   void and_(Register dst, Register src) { and_(dst, Operand(src)); }
    784   void and_(Register dst, const Operand& src);
    785   void and_(const Operand& dst, Register src);
    786   void and_(const Operand& dst, const Immediate& x);
    787 
    788   void cmpb(Register reg, int8_t imm8) { cmpb(Operand(reg), imm8); }
    789   void cmpb(const Operand& op, int8_t imm8);
    790   void cmpb(Register reg, const Operand& op);
    791   void cmpb(const Operand& op, Register reg);
    792   void cmpb_al(const Operand& op);
    793   void cmpw_ax(const Operand& op);
    794   void cmpw(const Operand& op, Immediate imm16);
    795   void cmp(Register reg, int32_t imm32);
    796   void cmp(Register reg, Handle<Object> handle);
    797   void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); }
    798   void cmp(Register reg, const Operand& op);
    799   void cmp(Register reg, const Immediate& imm) { cmp(Operand(reg), imm); }
    800   void cmp(const Operand& op, const Immediate& imm);
    801   void cmp(const Operand& op, Handle<Object> handle);
    802 
    803   void dec_b(Register dst);
    804   void dec_b(const Operand& dst);
    805 
    806   void dec(Register dst);
    807   void dec(const Operand& dst);
    808 
    809   void cdq();
    810 
    811   void idiv(Register src);
    812 
    813   // Signed multiply instructions.
    814   void imul(Register src);                               // edx:eax = eax * src.
    815   void imul(Register dst, Register src) { imul(dst, Operand(src)); }
    816   void imul(Register dst, const Operand& src);           // dst = dst * src.
    817   void imul(Register dst, Register src, int32_t imm32);  // dst = src * imm32.
    818 
    819   void inc(Register dst);
    820   void inc(const Operand& dst);
    821 
    822   void lea(Register dst, const Operand& src);
    823 
    824   // Unsigned multiply instruction.
    825   void mul(Register src);                                // edx:eax = eax * reg.
    826 
    827   void neg(Register dst);
    828 
    829   void not_(Register dst);
    830 
    831   void or_(Register dst, int32_t imm32);
    832   void or_(Register dst, Register src) { or_(dst, Operand(src)); }
    833   void or_(Register dst, const Operand& src);
    834   void or_(const Operand& dst, Register src);
    835   void or_(Register dst, const Immediate& imm) { or_(Operand(dst), imm); }
    836   void or_(const Operand& dst, const Immediate& x);
    837 
    838   void rcl(Register dst, uint8_t imm8);
    839   void rcr(Register dst, uint8_t imm8);
    840   void ror(Register dst, uint8_t imm8);
    841   void ror_cl(Register dst);
    842 
    843   void sar(Register dst, uint8_t imm8);
    844   void sar_cl(Register dst);
    845 
    846   void sbb(Register dst, const Operand& src);
    847 
    848   void shld(Register dst, Register src) { shld(dst, Operand(src)); }
    849   void shld(Register dst, const Operand& src);
    850 
    851   void shl(Register dst, uint8_t imm8);
    852   void shl_cl(Register dst);
    853 
    854   void shrd(Register dst, Register src) { shrd(dst, Operand(src)); }
    855   void shrd(Register dst, const Operand& src);
    856 
    857   void shr(Register dst, uint8_t imm8);
    858   void shr_cl(Register dst);
    859 
    860   void sub(Register dst, const Immediate& imm) { sub(Operand(dst), imm); }
    861   void sub(const Operand& dst, const Immediate& x);
    862   void sub(Register dst, Register src) { sub(dst, Operand(src)); }
    863   void sub(Register dst, const Operand& src);
    864   void sub(const Operand& dst, Register src);
    865 
    866   void test(Register reg, const Immediate& imm);
    867   void test(Register reg0, Register reg1) { test(reg0, Operand(reg1)); }
    868   void test(Register reg, const Operand& op);
    869   void test_b(Register reg, const Operand& op);
    870   void test(const Operand& op, const Immediate& imm);
    871   void test_b(Register reg, uint8_t imm8);
    872   void test_b(const Operand& op, uint8_t imm8);
    873 
    874   void xor_(Register dst, int32_t imm32);
    875   void xor_(Register dst, Register src) { xor_(dst, Operand(src)); }
    876   void xor_(Register dst, const Operand& src);
    877   void xor_(const Operand& dst, Register src);
    878   void xor_(Register dst, const Immediate& imm) { xor_(Operand(dst), imm); }
    879   void xor_(const Operand& dst, const Immediate& x);
    880 
    881   // Bit operations.
    882   void bt(const Operand& dst, Register src);
    883   void bts(Register dst, Register src) { bts(Operand(dst), src); }
    884   void bts(const Operand& dst, Register src);
    885 
    886   // Miscellaneous
    887   void hlt();
    888   void int3();
    889   void nop();
    890   void ret(int imm16);
    891 
    892   // Label operations & relative jumps (PPUM Appendix D)
    893   //
    894   // Takes a branch opcode (cc) and a label (L) and generates
    895   // either a backward branch or a forward branch and links it
    896   // to the label fixup chain. Usage:
    897   //
    898   // Label L;    // unbound label
    899   // j(cc, &L);  // forward branch to unbound label
    900   // bind(&L);   // bind label to the current pc
    901   // j(cc, &L);  // backward branch to bound label
    902   // bind(&L);   // illegal: a label may be bound only once
    903   //
    904   // Note: The same Label can be used for forward and backward branches
    905   // but it may be bound only once.
    906 
    907   void bind(Label* L);  // binds an unbound label L to the current code position
    908 
    909   // Calls
    910   void call(Label* L);
    911   void call(byte* entry, RelocInfo::Mode rmode);
    912   int CallSize(const Operand& adr);
    913   void call(Register reg) { call(Operand(reg)); }
    914   void call(const Operand& adr);
    915   int CallSize(Handle<Code> code, RelocInfo::Mode mode);
    916   void call(Handle<Code> code,
    917             RelocInfo::Mode rmode,
    918             TypeFeedbackId id = TypeFeedbackId::None());
    919 
    920   // Jumps
    921   // unconditional jump to L
    922   void jmp(Label* L, Label::Distance distance = Label::kFar);
    923   void jmp(byte* entry, RelocInfo::Mode rmode);
    924   void jmp(Register reg) { jmp(Operand(reg)); }
    925   void jmp(const Operand& adr);
    926   void jmp(Handle<Code> code, RelocInfo::Mode rmode);
    927 
    928   // Conditional jumps
    929   void j(Condition cc,
    930          Label* L,
    931          Label::Distance distance = Label::kFar);
    932   void j(Condition cc, byte* entry, RelocInfo::Mode rmode);
    933   void j(Condition cc, Handle<Code> code);
    934 
    935   // Floating-point operations
    936   void fld(int i);
    937   void fstp(int i);
    938 
    939   void fld1();
    940   void fldz();
    941   void fldpi();
    942   void fldln2();
    943 
    944   void fld_s(const Operand& adr);
    945   void fld_d(const Operand& adr);
    946 
    947   void fstp_s(const Operand& adr);
    948   void fst_s(const Operand& adr);
    949   void fstp_d(const Operand& adr);
    950   void fst_d(const Operand& adr);
    951 
    952   void fild_s(const Operand& adr);
    953   void fild_d(const Operand& adr);
    954 
    955   void fist_s(const Operand& adr);
    956 
    957   void fistp_s(const Operand& adr);
    958   void fistp_d(const Operand& adr);
    959 
    960   // The fisttp instructions require SSE3.
    961   void fisttp_s(const Operand& adr);
    962   void fisttp_d(const Operand& adr);
    963 
    964   void fabs();
    965   void fchs();
    966   void fcos();
    967   void fsin();
    968   void fptan();
    969   void fyl2x();
    970   void f2xm1();
    971   void fscale();
    972   void fninit();
    973 
    974   void fadd(int i);
    975   void fadd_i(int i);
    976   void fsub(int i);
    977   void fsub_i(int i);
    978   void fmul(int i);
    979   void fmul_i(int i);
    980   void fdiv(int i);
    981   void fdiv_i(int i);
    982 
    983   void fisub_s(const Operand& adr);
    984 
    985   void faddp(int i = 1);
    986   void fsubp(int i = 1);
    987   void fsubrp(int i = 1);
    988   void fmulp(int i = 1);
    989   void fdivp(int i = 1);
    990   void fprem();
    991   void fprem1();
    992 
    993   void fxch(int i = 1);
    994   void fincstp();
    995   void ffree(int i = 0);
    996 
    997   void ftst();
    998   void fucomp(int i);
    999   void fucompp();
   1000   void fucomi(int i);
   1001   void fucomip();
   1002   void fcompp();
   1003   void fnstsw_ax();
   1004   void fwait();
   1005   void fnclex();
   1006 
   1007   void frndint();
   1008 
   1009   void sahf();
   1010   void setcc(Condition cc, Register reg);
   1011 
   1012   void cpuid();
   1013 
   1014   // SSE instructions
   1015   void movaps(XMMRegister dst, XMMRegister src);
   1016   void shufps(XMMRegister dst, XMMRegister src, byte imm8);
   1017 
   1018   void andps(XMMRegister dst, const Operand& src);
   1019   void andps(XMMRegister dst, XMMRegister src) { andps(dst, Operand(src)); }
   1020   void xorps(XMMRegister dst, const Operand& src);
   1021   void xorps(XMMRegister dst, XMMRegister src) { xorps(dst, Operand(src)); }
   1022   void orps(XMMRegister dst, const Operand& src);
   1023   void orps(XMMRegister dst, XMMRegister src) { orps(dst, Operand(src)); }
   1024 
   1025   void addps(XMMRegister dst, const Operand& src);
   1026   void addps(XMMRegister dst, XMMRegister src) { addps(dst, Operand(src)); }
   1027   void subps(XMMRegister dst, const Operand& src);
   1028   void subps(XMMRegister dst, XMMRegister src) { subps(dst, Operand(src)); }
   1029   void mulps(XMMRegister dst, const Operand& src);
   1030   void mulps(XMMRegister dst, XMMRegister src) { mulps(dst, Operand(src)); }
   1031   void divps(XMMRegister dst, const Operand& src);
   1032   void divps(XMMRegister dst, XMMRegister src) { divps(dst, Operand(src)); }
   1033 
   1034   // SSE2 instructions
   1035   void cvttss2si(Register dst, const Operand& src);
   1036   void cvttss2si(Register dst, XMMRegister src) {
   1037     cvttss2si(dst, Operand(src));
   1038   }
   1039   void cvttsd2si(Register dst, const Operand& src);
   1040   void cvtsd2si(Register dst, XMMRegister src);
   1041 
   1042   void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); }
   1043   void cvtsi2sd(XMMRegister dst, const Operand& src);
   1044   void cvtss2sd(XMMRegister dst, XMMRegister src);
   1045   void cvtsd2ss(XMMRegister dst, XMMRegister src);
   1046 
   1047   void addsd(XMMRegister dst, XMMRegister src);
   1048   void addsd(XMMRegister dst, const Operand& src);
   1049   void subsd(XMMRegister dst, XMMRegister src);
   1050   void mulsd(XMMRegister dst, XMMRegister src);
   1051   void mulsd(XMMRegister dst, const Operand& src);
   1052   void divsd(XMMRegister dst, XMMRegister src);
   1053   void xorpd(XMMRegister dst, XMMRegister src);
   1054   void sqrtsd(XMMRegister dst, XMMRegister src);
   1055 
   1056   void andpd(XMMRegister dst, XMMRegister src);
   1057   void orpd(XMMRegister dst, XMMRegister src);
   1058 
   1059   void ucomisd(XMMRegister dst, XMMRegister src) { ucomisd(dst, Operand(src)); }
   1060   void ucomisd(XMMRegister dst, const Operand& src);
   1061 
   1062   enum RoundingMode {
   1063     kRoundToNearest = 0x0,
   1064     kRoundDown      = 0x1,
   1065     kRoundUp        = 0x2,
   1066     kRoundToZero    = 0x3
   1067   };
   1068 
   1069   void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
   1070 
   1071   void movmskpd(Register dst, XMMRegister src);
   1072   void movmskps(Register dst, XMMRegister src);
   1073 
   1074   void cmpltsd(XMMRegister dst, XMMRegister src);
   1075   void pcmpeqd(XMMRegister dst, XMMRegister src);
   1076 
   1077   void movdqa(XMMRegister dst, const Operand& src);
   1078   void movdqa(const Operand& dst, XMMRegister src);
   1079   void movdqu(XMMRegister dst, const Operand& src);
   1080   void movdqu(const Operand& dst, XMMRegister src);
   1081   void movdq(bool aligned, XMMRegister dst, const Operand& src) {
   1082     if (aligned) {
   1083       movdqa(dst, src);
   1084     } else {
   1085       movdqu(dst, src);
   1086     }
   1087   }
   1088 
   1089   void movd(XMMRegister dst, Register src) { movd(dst, Operand(src)); }
   1090   void movd(XMMRegister dst, const Operand& src);
   1091   void movd(Register dst, XMMRegister src) { movd(Operand(dst), src); }
   1092   void movd(const Operand& dst, XMMRegister src);
   1093   void movsd(XMMRegister dst, XMMRegister src) { movsd(dst, Operand(src)); }
   1094   void movsd(XMMRegister dst, const Operand& src);
   1095   void movsd(const Operand& dst, XMMRegister src);
   1096 
   1097 
   1098   void movss(XMMRegister dst, const Operand& src);
   1099   void movss(const Operand& dst, XMMRegister src);
   1100   void movss(XMMRegister dst, XMMRegister src) { movss(dst, Operand(src)); }
   1101   void extractps(Register dst, XMMRegister src, byte imm8);
   1102 
   1103   void pand(XMMRegister dst, XMMRegister src);
   1104   void pxor(XMMRegister dst, XMMRegister src);
   1105   void por(XMMRegister dst, XMMRegister src);
   1106   void ptest(XMMRegister dst, XMMRegister src);
   1107 
   1108   void psllq(XMMRegister reg, int8_t shift);
   1109   void psllq(XMMRegister dst, XMMRegister src);
   1110   void psrlq(XMMRegister reg, int8_t shift);
   1111   void psrlq(XMMRegister dst, XMMRegister src);
   1112   void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle);
   1113   void pextrd(Register dst, XMMRegister src, int8_t offset) {
   1114     pextrd(Operand(dst), src, offset);
   1115   }
   1116   void pextrd(const Operand& dst, XMMRegister src, int8_t offset);
   1117   void pinsrd(XMMRegister dst, Register src, int8_t offset) {
   1118     pinsrd(dst, Operand(src), offset);
   1119   }
   1120   void pinsrd(XMMRegister dst, const Operand& src, int8_t offset);
   1121 
   1122   // Parallel XMM operations.
   1123   void movntdqa(XMMRegister dst, const Operand& src);
   1124   void movntdq(const Operand& dst, XMMRegister src);
   1125   // Prefetch src position into cache level.
   1126   // Level 1, 2 or 3 specifies CPU cache level. Level 0 specifies a
   1127   // non-temporal
   1128   void prefetch(const Operand& src, int level);
   1129   // TODO(lrn): Need SFENCE for movnt?
   1130 
   1131   // Debugging
   1132   void Print();
   1133 
   1134   // Check the code size generated from label to here.
   1135   int SizeOfCodeGeneratedSince(Label* label) {
   1136     return pc_offset() - label->pos();
   1137   }
   1138 
   1139   // Mark address of the ExitJSFrame code.
   1140   void RecordJSReturn();
   1141 
   1142   // Mark address of a debug break slot.
   1143   void RecordDebugBreakSlot();
   1144 
   1145   // Record a comment relocation entry that can be used by a disassembler.
   1146   // Use --code-comments to enable, or provide "force = true" flag to always
   1147   // write a comment.
   1148   void RecordComment(const char* msg, bool force = false);
   1149 
   1150   // Writes a single byte or word of data in the code stream.  Used for
   1151   // inline tables, e.g., jump-tables.
   1152   void db(uint8_t data);
   1153   void dd(uint32_t data);
   1154 
   1155   // Check if there is less than kGap bytes available in the buffer.
   1156   // If this is the case, we need to grow the buffer before emitting
   1157   // an instruction or relocation information.
   1158   inline bool overflow() const { return pc_ >= reloc_info_writer.pos() - kGap; }
   1159 
   1160   // Get the number of bytes available in the buffer.
   1161   inline int available_space() const { return reloc_info_writer.pos() - pc_; }
   1162 
   1163   static bool IsNop(Address addr);
   1164 
   1165   PositionsRecorder* positions_recorder() { return &positions_recorder_; }
   1166 
   1167   int relocation_writer_size() {
   1168     return (buffer_ + buffer_size_) - reloc_info_writer.pos();
   1169   }
   1170 
   1171   // Avoid overflows for displacements etc.
   1172   static const int kMaximalBufferSize = 512*MB;
   1173 
   1174   byte byte_at(int pos) { return buffer_[pos]; }
   1175   void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
   1176 
   1177  protected:
   1178   void emit_sse_operand(XMMRegister reg, const Operand& adr);
   1179   void emit_sse_operand(XMMRegister dst, XMMRegister src);
   1180   void emit_sse_operand(Register dst, XMMRegister src);
   1181   void emit_sse_operand(XMMRegister dst, Register src);
   1182 
   1183   byte* addr_at(int pos) { return buffer_ + pos; }
   1184 
   1185 
   1186  private:
   1187   uint32_t long_at(int pos)  {
   1188     return *reinterpret_cast<uint32_t*>(addr_at(pos));
   1189   }
   1190   void long_at_put(int pos, uint32_t x)  {
   1191     *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
   1192   }
   1193 
   1194   // code emission
   1195   void GrowBuffer();
   1196   inline void emit(uint32_t x);
   1197   inline void emit(Handle<Object> handle);
   1198   inline void emit(uint32_t x,
   1199                    RelocInfo::Mode rmode,
   1200                    TypeFeedbackId id = TypeFeedbackId::None());
   1201   inline void emit(Handle<Code> code,
   1202                    RelocInfo::Mode rmode,
   1203                    TypeFeedbackId id = TypeFeedbackId::None());
   1204   inline void emit(const Immediate& x);
   1205   inline void emit_w(const Immediate& x);
   1206 
   1207   // Emit the code-object-relative offset of the label's position
   1208   inline void emit_code_relative_offset(Label* label);
   1209 
   1210   // instruction generation
   1211   void emit_arith_b(int op1, int op2, Register dst, int imm8);
   1212 
   1213   // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81)
   1214   // with a given destination expression and an immediate operand.  It attempts
   1215   // to use the shortest encoding possible.
   1216   // sel specifies the /n in the modrm byte (see the Intel PRM).
   1217   void emit_arith(int sel, Operand dst, const Immediate& x);
   1218 
   1219   void emit_operand(Register reg, const Operand& adr);
   1220 
   1221   void emit_farith(int b1, int b2, int i);
   1222 
   1223   // labels
   1224   void print(Label* L);
   1225   void bind_to(Label* L, int pos);
   1226 
   1227   // displacements
   1228   inline Displacement disp_at(Label* L);
   1229   inline void disp_at_put(Label* L, Displacement disp);
   1230   inline void emit_disp(Label* L, Displacement::Type type);
   1231   inline void emit_near_disp(Label* L);
   1232 
   1233   // record reloc info for current pc_
   1234   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
   1235 
   1236   friend class CodePatcher;
   1237   friend class EnsureSpace;
   1238 
   1239   // code generation
   1240   RelocInfoWriter reloc_info_writer;
   1241 
   1242   PositionsRecorder positions_recorder_;
   1243   friend class PositionsRecorder;
   1244 };
   1245 
   1246 
   1247 // Helper class that ensures that there is enough space for generating
   1248 // instructions and relocation information.  The constructor makes
   1249 // sure that there is enough space and (in debug mode) the destructor
   1250 // checks that we did not generate too much.
   1251 class EnsureSpace BASE_EMBEDDED {
   1252  public:
   1253   explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
   1254     if (assembler_->overflow()) assembler_->GrowBuffer();
   1255 #ifdef DEBUG
   1256     space_before_ = assembler_->available_space();
   1257 #endif
   1258   }
   1259 
   1260 #ifdef DEBUG
   1261   ~EnsureSpace() {
   1262     int bytes_generated = space_before_ - assembler_->available_space();
   1263     ASSERT(bytes_generated < assembler_->kGap);
   1264   }
   1265 #endif
   1266 
   1267  private:
   1268   Assembler* assembler_;
   1269 #ifdef DEBUG
   1270   int space_before_;
   1271 #endif
   1272 };
   1273 
   1274 } }  // namespace v8::internal
   1275 
   1276 #endif  // V8_IA32_ASSEMBLER_IA32_H_
   1277