• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
is_uint32(int64_t x)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 
is_int32(int64_t x)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 
uint_is_int32(uint64_t x)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 
is_uint32(uint64_t x)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 {
toRegisterRegister91   static Register toRegister(int code) {
92     Register r = { code };
93     return r;
94   }
is_validRegister95   bool is_valid() const  { return 0 <= code_ && code_ < 16; }
isRegister96   bool is(Register reg) const  { return code_ == reg.code_; }
codeRegister97   int code() const  {
98     ASSERT(is_valid());
99     return code_;
100   }
bitRegister101   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.
high_bitRegister107   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.
low_bitsRegister112   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 {
is_validXMMRegister141   bool is_valid() const  { return 0 <= code_ && code_ < 16; }
codeXMMRegister142   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.
high_bitXMMRegister149   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.
low_bitsXMMRegister154   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.
ReverseCondition(Condition cc)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.
NegateHint(Hint hint)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:
Immediate(int32_t value)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.
IsSupported(CpuFeature f)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.
IsEnabled(CpuFeature f)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:
Scope(CpuFeature f)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     }
~Scope()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.
set_target_at(Address instruction_payload,Address target)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.
set_external_target_at(Address instruction_payload,Address target)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
addl(Register dst,Register src)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 
addl(Register dst,Immediate src)577   void addl(Register dst, Immediate src) {
578     immediate_arithmetic_op_32(0x0, dst, src);
579   }
580 
addl(Register dst,const Operand & src)581   void addl(Register dst, const Operand& src) {
582     arithmetic_op_32(0x03, dst, src);
583   }
584 
addl(const Operand & dst,Immediate src)585   void addl(const Operand& dst, Immediate src) {
586     immediate_arithmetic_op_32(0x0, dst, src);
587   }
588 
addq(Register dst,Register src)589   void addq(Register dst, Register src) {
590     arithmetic_op(0x03, dst, src);
591   }
592 
addq(Register dst,const Operand & src)593   void addq(Register dst, const Operand& src) {
594     arithmetic_op(0x03, dst, src);
595   }
596 
addq(const Operand & dst,Register src)597   void addq(const Operand& dst, Register src) {
598     arithmetic_op(0x01, src, dst);
599   }
600 
addq(Register dst,Immediate src)601   void addq(Register dst, Immediate src) {
602     immediate_arithmetic_op(0x0, dst, src);
603   }
604 
addq(const Operand & dst,Immediate src)605   void addq(const Operand& dst, Immediate src) {
606     immediate_arithmetic_op(0x0, dst, src);
607   }
608 
cmpb(Register dst,Immediate src)609   void cmpb(Register dst, Immediate src) {
610     immediate_arithmetic_op_8(0x7, dst, src);
611   }
612 
613   void cmpb_al(Immediate src);
614 
cmpb(Register dst,Register src)615   void cmpb(Register dst, Register src) {
616     arithmetic_op(0x3A, dst, src);
617   }
618 
cmpb(Register dst,const Operand & src)619   void cmpb(Register dst, const Operand& src) {
620     arithmetic_op(0x3A, dst, src);
621   }
622 
cmpb(const Operand & dst,Register src)623   void cmpb(const Operand& dst, Register src) {
624     arithmetic_op(0x38, src, dst);
625   }
626 
cmpb(const Operand & dst,Immediate src)627   void cmpb(const Operand& dst, Immediate src) {
628     immediate_arithmetic_op_8(0x7, dst, src);
629   }
630 
cmpw(const Operand & dst,Immediate src)631   void cmpw(const Operand& dst, Immediate src) {
632     immediate_arithmetic_op_16(0x7, dst, src);
633   }
634 
cmpw(Register dst,Immediate src)635   void cmpw(Register dst, Immediate src) {
636     immediate_arithmetic_op_16(0x7, dst, src);
637   }
638 
cmpw(Register dst,const Operand & src)639   void cmpw(Register dst, const Operand& src) {
640     arithmetic_op_16(0x3B, dst, src);
641   }
642 
cmpw(Register dst,Register src)643   void cmpw(Register dst, Register src) {
644     arithmetic_op_16(0x3B, dst, src);
645   }
646 
cmpw(const Operand & dst,Register src)647   void cmpw(const Operand& dst, Register src) {
648     arithmetic_op_16(0x39, src, dst);
649   }
650 
cmpl(Register dst,Register src)651   void cmpl(Register dst, Register src) {
652     arithmetic_op_32(0x3B, dst, src);
653   }
654 
cmpl(Register dst,const Operand & src)655   void cmpl(Register dst, const Operand& src) {
656     arithmetic_op_32(0x3B, dst, src);
657   }
658 
cmpl(const Operand & dst,Register src)659   void cmpl(const Operand& dst, Register src) {
660     arithmetic_op_32(0x39, src, dst);
661   }
662 
cmpl(Register dst,Immediate src)663   void cmpl(Register dst, Immediate src) {
664     immediate_arithmetic_op_32(0x7, dst, src);
665   }
666 
cmpl(const Operand & dst,Immediate src)667   void cmpl(const Operand& dst, Immediate src) {
668     immediate_arithmetic_op_32(0x7, dst, src);
669   }
670 
cmpq(Register dst,Register src)671   void cmpq(Register dst, Register src) {
672     arithmetic_op(0x3B, dst, src);
673   }
674 
cmpq(Register dst,const Operand & src)675   void cmpq(Register dst, const Operand& src) {
676     arithmetic_op(0x3B, dst, src);
677   }
678 
cmpq(const Operand & dst,Register src)679   void cmpq(const Operand& dst, Register src) {
680     arithmetic_op(0x39, src, dst);
681   }
682 
cmpq(Register dst,Immediate src)683   void cmpq(Register dst, Immediate src) {
684     immediate_arithmetic_op(0x7, dst, src);
685   }
686 
cmpq(const Operand & dst,Immediate src)687   void cmpq(const Operand& dst, Immediate src) {
688     immediate_arithmetic_op(0x7, dst, src);
689   }
690 
and_(Register dst,Register src)691   void and_(Register dst, Register src) {
692     arithmetic_op(0x23, dst, src);
693   }
694 
and_(Register dst,const Operand & src)695   void and_(Register dst, const Operand& src) {
696     arithmetic_op(0x23, dst, src);
697   }
698 
and_(const Operand & dst,Register src)699   void and_(const Operand& dst, Register src) {
700     arithmetic_op(0x21, src, dst);
701   }
702 
and_(Register dst,Immediate src)703   void and_(Register dst, Immediate src) {
704     immediate_arithmetic_op(0x4, dst, src);
705   }
706 
and_(const Operand & dst,Immediate src)707   void and_(const Operand& dst, Immediate src) {
708     immediate_arithmetic_op(0x4, dst, src);
709   }
710 
andl(Register dst,Immediate src)711   void andl(Register dst, Immediate src) {
712     immediate_arithmetic_op_32(0x4, dst, src);
713   }
714 
andl(Register dst,Register src)715   void andl(Register dst, Register src) {
716     arithmetic_op_32(0x23, dst, src);
717   }
718 
andb(Register dst,Immediate src)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 
or_(Register dst,Register src)764   void or_(Register dst, Register src) {
765     arithmetic_op(0x0B, dst, src);
766   }
767 
orl(Register dst,Register src)768   void orl(Register dst, Register src) {
769     arithmetic_op_32(0x0B, dst, src);
770   }
771 
or_(Register dst,const Operand & src)772   void or_(Register dst, const Operand& src) {
773     arithmetic_op(0x0B, dst, src);
774   }
775 
or_(const Operand & dst,Register src)776   void or_(const Operand& dst, Register src) {
777     arithmetic_op(0x09, src, dst);
778   }
779 
or_(Register dst,Immediate src)780   void or_(Register dst, Immediate src) {
781     immediate_arithmetic_op(0x1, dst, src);
782   }
783 
orl(Register dst,Immediate src)784   void orl(Register dst, Immediate src) {
785     immediate_arithmetic_op_32(0x1, dst, src);
786   }
787 
or_(const Operand & dst,Immediate src)788   void or_(const Operand& dst, Immediate src) {
789     immediate_arithmetic_op(0x1, dst, src);
790   }
791 
orl(const Operand & dst,Immediate src)792   void orl(const Operand& dst, Immediate src) {
793     immediate_arithmetic_op_32(0x1, dst, src);
794   }
795 
796 
rcl(Register dst,Immediate imm8)797   void rcl(Register dst, Immediate imm8) {
798     shift(dst, imm8, 0x2);
799   }
800 
rol(Register dst,Immediate imm8)801   void rol(Register dst, Immediate imm8) {
802     shift(dst, imm8, 0x0);
803   }
804 
rcr(Register dst,Immediate imm8)805   void rcr(Register dst, Immediate imm8) {
806     shift(dst, imm8, 0x3);
807   }
808 
ror(Register dst,Immediate imm8)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.
sar(Register dst,Immediate shift_amount)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.
sarl(Register dst,Immediate shift_amount)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.
sar_cl(Register dst)832   void sar_cl(Register dst) {
833     shift(dst, 0x7);
834   }
835 
836   // Shifts dst right, duplicating sign bit, by cl % 64 bits.
sarl_cl(Register dst)837   void sarl_cl(Register dst) {
838     shift_32(dst, 0x7);
839   }
840 
shl(Register dst,Immediate shift_amount)841   void shl(Register dst, Immediate shift_amount) {
842     shift(dst, shift_amount, 0x4);
843   }
844 
shl_cl(Register dst)845   void shl_cl(Register dst) {
846     shift(dst, 0x4);
847   }
848 
shll_cl(Register dst)849   void shll_cl(Register dst) {
850     shift_32(dst, 0x4);
851   }
852 
shll(Register dst,Immediate shift_amount)853   void shll(Register dst, Immediate shift_amount) {
854     shift_32(dst, shift_amount, 0x4);
855   }
856 
shr(Register dst,Immediate shift_amount)857   void shr(Register dst, Immediate shift_amount) {
858     shift(dst, shift_amount, 0x5);
859   }
860 
shr_cl(Register dst)861   void shr_cl(Register dst) {
862     shift(dst, 0x5);
863   }
864 
shrl_cl(Register dst)865   void shrl_cl(Register dst) {
866     shift_32(dst, 0x5);
867   }
868 
shrl(Register dst,Immediate shift_amount)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 
subq(Register dst,Register src)876   void subq(Register dst, Register src) {
877     arithmetic_op(0x2B, dst, src);
878   }
879 
subq(Register dst,const Operand & src)880   void subq(Register dst, const Operand& src) {
881     arithmetic_op(0x2B, dst, src);
882   }
883 
subq(const Operand & dst,Register src)884   void subq(const Operand& dst, Register src) {
885     arithmetic_op(0x29, src, dst);
886   }
887 
subq(Register dst,Immediate src)888   void subq(Register dst, Immediate src) {
889     immediate_arithmetic_op(0x5, dst, src);
890   }
891 
subq(const Operand & dst,Immediate src)892   void subq(const Operand& dst, Immediate src) {
893     immediate_arithmetic_op(0x5, dst, src);
894   }
895 
subl(Register dst,Register src)896   void subl(Register dst, Register src) {
897     arithmetic_op_32(0x2B, dst, src);
898   }
899 
subl(Register dst,const Operand & src)900   void subl(Register dst, const Operand& src) {
901     arithmetic_op_32(0x2B, dst, src);
902   }
903 
subl(const Operand & dst,Immediate src)904   void subl(const Operand& dst, Immediate src) {
905     immediate_arithmetic_op_32(0x5, dst, src);
906   }
907 
subl(Register dst,Immediate src)908   void subl(Register dst, Immediate src) {
909     immediate_arithmetic_op_32(0x5, dst, src);
910   }
911 
subb(Register dst,Immediate src)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 
xor_(Register dst,Register src)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 
xorl(Register dst,Register src)935   void xorl(Register dst, Register src) {
936     arithmetic_op_32(0x33, dst, src);
937   }
938 
xor_(Register dst,const Operand & src)939   void xor_(Register dst, const Operand& src) {
940     arithmetic_op(0x33, dst, src);
941   }
942 
xor_(const Operand & dst,Register src)943   void xor_(const Operand& dst, Register src) {
944     arithmetic_op(0x31, src, dst);
945   }
946 
xor_(Register dst,Immediate src)947   void xor_(Register dst, Immediate src) {
948     immediate_arithmetic_op(0x6, dst, src);
949   }
950 
xor_(const Operand & dst,Immediate src)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.
SizeOfCodeGeneratedSince(Label * l)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 
pc_offset()1126   int pc_offset() const  { return static_cast<int>(pc_ - buffer_); }
current_statement_position()1127   int current_statement_position() const { return current_statement_position_; }
current_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.
buffer_overflow()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.
available_space()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:
addr_at(int pos)1147   byte* addr_at(int pos)  { return buffer_ + pos; }
byte_at(int pos)1148   byte byte_at(int pos)  { return buffer_[pos]; }
long_at(int pos)1149   uint32_t long_at(int pos)  {
1150     return *reinterpret_cast<uint32_t*>(addr_at(pos));
1151   }
long_at_put(int pos,uint32_t x)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 
emit(byte x)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);
emit(Immediate x)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.
emit_rex_64()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.
emit_operand(Register reg,const Operand & adr)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.
emit_modrm(Register reg,Register rm_reg)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.
emit_modrm(int code,Register rm_reg)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:
EnsureSpace(Assembler * assembler)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
~EnsureSpace()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