v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
assembler-x64.h
Go to the documentation of this file.
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 2012 the V8 project authors. All rights reserved.
34 
35 // A lightweight X64 Assembler.
36 
37 #ifndef V8_X64_ASSEMBLER_X64_H_
38 #define V8_X64_ASSEMBLER_X64_H_
39 
40 #include "serialize.h"
41 
42 namespace v8 {
43 namespace internal {
44 
45 // Utility functions
46 
47 // Test whether a 64-bit value is in a specific range.
48 inline bool is_uint32(int64_t x) {
49  static const uint64_t kMaxUInt32 = V8_UINT64_C(0xffffffff);
50  return static_cast<uint64_t>(x) <= kMaxUInt32;
51 }
52 
53 inline bool is_int32(int64_t x) {
54  static const int64_t kMinInt32 = -V8_INT64_C(0x80000000);
55  return is_uint32(x - kMinInt32);
56 }
57 
58 inline bool uint_is_int32(uint64_t x) {
59  static const uint64_t kMaxInt32 = V8_UINT64_C(0x7fffffff);
60  return x <= kMaxInt32;
61 }
62 
63 inline bool is_uint32(uint64_t x) {
64  static const uint64_t kMaxUInt32 = V8_UINT64_C(0xffffffff);
65  return x <= kMaxUInt32;
66 }
67 
68 // CPU Registers.
69 //
70 // 1) We would prefer to use an enum, but enum values are assignment-
71 // compatible with int, which has caused code-generation bugs.
72 //
73 // 2) We would prefer to use a class instead of a struct but we don't like
74 // the register initialization to depend on the particular initialization
75 // order (which appears to be different on OS X, Linux, and Windows for the
76 // installed versions of C++ we tried). Using a struct permits C-style
77 // "initialization". Also, the Register objects cannot be const as this
78 // forces initialization stubs in MSVC, making us dependent on initialization
79 // order.
80 //
81 // 3) By not using an enum, we are possibly preventing the compiler from
82 // doing certain constant folds, which may significantly reduce the
83 // code generated for some assembly instructions (because they boil down
84 // to a few constants). If this is a problem, we could change the code
85 // such that we use an enum in optimized mode, and the struct in debug
86 // mode. This way we get the compile-time error checking in debug mode
87 // and best performance in optimized code.
88 //
89 
90 struct Register {
91  // The non-allocatable registers are:
92  // rsp - stack pointer
93  // rbp - frame pointer
94  // rsi - context register
95  // r10 - fixed scratch register
96  // r12 - smi constant register
97  // r13 - root register
98  static const int kNumRegisters = 16;
99  static const int kNumAllocatableRegisters = 10;
100 
101  static int ToAllocationIndex(Register reg) {
102  return kAllocationIndexByRegisterCode[reg.code()];
103  }
104 
105  static Register FromAllocationIndex(int index) {
106  ASSERT(index >= 0 && index < kNumAllocatableRegisters);
107  Register result = { kRegisterCodeByAllocationIndex[index] };
108  return result;
109  }
110 
111  static const char* AllocationIndexToString(int index) {
112  ASSERT(index >= 0 && index < kNumAllocatableRegisters);
113  const char* const names[] = {
114  "rax",
115  "rbx",
116  "rdx",
117  "rcx",
118  "rdi",
119  "r8",
120  "r9",
121  "r11",
122  "r14",
123  "r15"
124  };
125  return names[index];
126  }
127 
128  static Register from_code(int code) {
129  Register r = { code };
130  return r;
131  }
132  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
133  bool is(Register reg) const { return code_ == reg.code_; }
134  // rax, rbx, rcx and rdx are byte registers, the rest are not.
135  bool is_byte_register() const { return code_ <= 3; }
136  int code() const {
137  ASSERT(is_valid());
138  return code_;
139  }
140  int bit() const {
141  return 1 << code_;
142  }
143 
144  // Return the high bit of the register code as a 0 or 1. Used often
145  // when constructing the REX prefix byte.
146  int high_bit() const {
147  return code_ >> 3;
148  }
149  // Return the 3 low bits of the register code. Used when encoding registers
150  // in modR/M, SIB, and opcode bytes.
151  int low_bits() const {
152  return code_ & 0x7;
153  }
154 
155  // Unfortunately we can't make this private in a struct when initializing
156  // by assignment.
157  int code_;
158 
159  private:
160  static const int kRegisterCodeByAllocationIndex[kNumAllocatableRegisters];
161  static const int kAllocationIndexByRegisterCode[kNumRegisters];
162 };
163 
164 const int kRegister_rax_Code = 0;
165 const int kRegister_rcx_Code = 1;
166 const int kRegister_rdx_Code = 2;
167 const int kRegister_rbx_Code = 3;
168 const int kRegister_rsp_Code = 4;
169 const int kRegister_rbp_Code = 5;
170 const int kRegister_rsi_Code = 6;
171 const int kRegister_rdi_Code = 7;
172 const int kRegister_r8_Code = 8;
173 const int kRegister_r9_Code = 9;
174 const int kRegister_r10_Code = 10;
175 const int kRegister_r11_Code = 11;
176 const int kRegister_r12_Code = 12;
177 const int kRegister_r13_Code = 13;
178 const int kRegister_r14_Code = 14;
179 const int kRegister_r15_Code = 15;
180 const int kRegister_no_reg_Code = -1;
181 
190 const Register r8 = { kRegister_r8_Code };
191 const Register r9 = { kRegister_r9_Code };
192 const Register r10 = { kRegister_r10_Code };
198 const Register no_reg = { kRegister_no_reg_Code };
199 
200 
201 struct XMMRegister {
202  static const int kNumRegisters = 16;
203  static const int kNumAllocatableRegisters = 15;
204 
205  static int ToAllocationIndex(XMMRegister reg) {
206  ASSERT(reg.code() != 0);
207  return reg.code() - 1;
208  }
209 
210  static XMMRegister FromAllocationIndex(int index) {
211  ASSERT(0 <= index && index < kNumAllocatableRegisters);
212  XMMRegister result = { index + 1 };
213  return result;
214  }
215 
216  static const char* AllocationIndexToString(int index) {
217  ASSERT(index >= 0 && index < kNumAllocatableRegisters);
218  const char* const names[] = {
219  "xmm1",
220  "xmm2",
221  "xmm3",
222  "xmm4",
223  "xmm5",
224  "xmm6",
225  "xmm7",
226  "xmm8",
227  "xmm9",
228  "xmm10",
229  "xmm11",
230  "xmm12",
231  "xmm13",
232  "xmm14",
233  "xmm15"
234  };
235  return names[index];
236  }
237 
238  static XMMRegister from_code(int code) {
239  ASSERT(code >= 0);
240  ASSERT(code < kNumRegisters);
241  XMMRegister r = { code };
242  return r;
243  }
244  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
245  bool is(XMMRegister reg) const { return code_ == reg.code_; }
246  int code() const {
247  ASSERT(is_valid());
248  return code_;
249  }
250 
251  // Return the high bit of the register code as a 0 or 1. Used often
252  // when constructing the REX prefix byte.
253  int high_bit() const {
254  return code_ >> 3;
255  }
256  // Return the 3 low bits of the register code. Used when encoding registers
257  // in modR/M, SIB, and opcode bytes.
258  int low_bits() const {
259  return code_ & 0x7;
260  }
261 
262  int code_;
263 };
264 
265 const XMMRegister xmm0 = { 0 };
266 const XMMRegister xmm1 = { 1 };
267 const XMMRegister xmm2 = { 2 };
268 const XMMRegister xmm3 = { 3 };
269 const XMMRegister xmm4 = { 4 };
270 const XMMRegister xmm5 = { 5 };
271 const XMMRegister xmm6 = { 6 };
272 const XMMRegister xmm7 = { 7 };
273 const XMMRegister xmm8 = { 8 };
274 const XMMRegister xmm9 = { 9 };
275 const XMMRegister xmm10 = { 10 };
276 const XMMRegister xmm11 = { 11 };
277 const XMMRegister xmm12 = { 12 };
278 const XMMRegister xmm13 = { 13 };
279 const XMMRegister xmm14 = { 14 };
280 const XMMRegister xmm15 = { 15 };
281 
282 
283 typedef XMMRegister DoubleRegister;
284 
285 
286 enum Condition {
287  // any value < 0 is considered no_condition
288  no_condition = -1,
289 
290  overflow = 0,
291  no_overflow = 1,
292  below = 2,
293  above_equal = 3,
294  equal = 4,
295  not_equal = 5,
296  below_equal = 6,
297  above = 7,
298  negative = 8,
299  positive = 9,
300  parity_even = 10,
301  parity_odd = 11,
302  less = 12,
303  greater_equal = 13,
304  less_equal = 14,
305  greater = 15,
306 
307  // Fake conditions that are handled by the
308  // opcodes using them.
309  always = 16,
310  never = 17,
311  // aliases
312  carry = below,
314  zero = equal,
316  sign = negative,
317  not_sign = positive,
319 };
320 
321 
322 // Returns the equivalent of !cc.
323 // Negation of the default no_condition (-1) results in a non-default
324 // no_condition value (-2). As long as tests for no_condition check
325 // for condition < 0, this will work as expected.
327  return static_cast<Condition>(cc ^ 1);
328 }
329 
330 
331 // Corresponds to transposing the operands of a comparison.
333  switch (cc) {
334  case below:
335  return above;
336  case above:
337  return below;
338  case above_equal:
339  return below_equal;
340  case below_equal:
341  return above_equal;
342  case less:
343  return greater;
344  case greater:
345  return less;
346  case greater_equal:
347  return less_equal;
348  case less_equal:
349  return greater_equal;
350  default:
351  return cc;
352  };
353 }
354 
355 
356 // -----------------------------------------------------------------------------
357 // Machine instruction Immediates
358 
359 class Immediate BASE_EMBEDDED {
360  public:
361  explicit Immediate(int32_t value) : value_(value) {}
362 
363  private:
364  int32_t value_;
365 
366  friend class Assembler;
367 };
368 
369 
370 // -----------------------------------------------------------------------------
371 // Machine instruction Operands
372 
374  times_1 = 0,
375  times_2 = 1,
376  times_4 = 2,
377  times_8 = 3,
380 };
381 
382 
383 class Operand BASE_EMBEDDED {
384  public:
385  // [base + disp/r]
386  Operand(Register base, int32_t disp);
387 
388  // [base + index*scale + disp/r]
389  Operand(Register base,
390  Register index,
391  ScaleFactor scale,
392  int32_t disp);
393 
394  // [index*scale + disp/r]
395  Operand(Register index,
396  ScaleFactor scale,
397  int32_t disp);
398 
399  // Offset from existing memory operand.
400  // Offset is added to existing displacement as 32-bit signed values and
401  // this must not overflow.
402  Operand(const Operand& base, int32_t offset);
403 
404  // Checks whether either base or index register is the given register.
405  // Does not check the "reg" part of the Operand.
406  bool AddressUsesRegister(Register reg) const;
407 
408  // Queries related to the size of the generated instruction.
409  // Whether the generated instruction will have a REX prefix.
410  bool requires_rex() const { return rex_ != 0; }
411  // Size of the ModR/M, SIB and displacement parts of the generated
412  // instruction.
413  int operand_size() const { return len_; }
414 
415  private:
416  byte rex_;
417  byte buf_[6];
418  // The number of bytes of buf_ in use.
419  byte len_;
420 
421  // Set the ModR/M byte without an encoded 'reg' register. The
422  // register is encoded later as part of the emit_operand operation.
423  // set_modrm can be called before or after set_sib and set_disp*.
424  inline void set_modrm(int mod, Register rm);
425 
426  // Set the SIB byte if one is needed. Sets the length to 2 rather than 1.
427  inline void set_sib(ScaleFactor scale, Register index, Register base);
428 
429  // Adds operand displacement fields (offsets added to the memory address).
430  // Needs to be called after set_sib, not before it.
431  inline void set_disp8(int disp);
432  inline void set_disp32(int disp);
433 
434  friend class Assembler;
435 };
436 
437 
438 // CpuFeatures keeps track of which features are supported by the target CPU.
439 // Supported features must be enabled by a Scope before use.
440 // Example:
441 // if (CpuFeatures::IsSupported(SSE3)) {
442 // CpuFeatures::Scope fscope(SSE3);
443 // // Generate SSE3 floating point code.
444 // } else {
445 // // Generate standard x87 or SSE2 floating point code.
446 // }
447 class CpuFeatures : public AllStatic {
448  public:
449  // Detect features of the target CPU. Set safe defaults if the serializer
450  // is enabled (snapshots must be portable).
451  static void Probe();
452 
453  // Check whether a feature is supported by the target CPU.
454  static bool IsSupported(CpuFeature f) {
455  ASSERT(initialized_);
456  if (f == SSE2 && !FLAG_enable_sse2) return false;
457  if (f == SSE3 && !FLAG_enable_sse3) return false;
458  if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
459  if (f == CMOV && !FLAG_enable_cmov) return false;
460  if (f == RDTSC && !FLAG_enable_rdtsc) return false;
461  if (f == SAHF && !FLAG_enable_sahf) return false;
462  return (supported_ & (V8_UINT64_C(1) << f)) != 0;
463  }
464 
465 #ifdef DEBUG
466  // Check whether a feature is currently enabled.
467  static bool IsEnabled(CpuFeature f) {
468  ASSERT(initialized_);
469  Isolate* isolate = Isolate::UncheckedCurrent();
470  if (isolate == NULL) {
471  // When no isolate is available, work as if we're running in
472  // release mode.
473  return IsSupported(f);
474  }
475  uint64_t enabled = isolate->enabled_cpu_features();
476  return (enabled & (V8_UINT64_C(1) << f)) != 0;
477  }
478 #endif
479 
480  // Enable a specified feature within a scope.
481  class Scope BASE_EMBEDDED {
482 #ifdef DEBUG
483 
484  public:
485  explicit Scope(CpuFeature f) {
486  uint64_t mask = V8_UINT64_C(1) << f;
489  (CpuFeatures::found_by_runtime_probing_ & mask) == 0);
490  isolate_ = Isolate::UncheckedCurrent();
491  old_enabled_ = 0;
492  if (isolate_ != NULL) {
493  old_enabled_ = isolate_->enabled_cpu_features();
494  isolate_->set_enabled_cpu_features(old_enabled_ | mask);
495  }
496  }
497  ~Scope() {
498  ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_);
499  if (isolate_ != NULL) {
500  isolate_->set_enabled_cpu_features(old_enabled_);
501  }
502  }
503 
504  private:
505  Isolate* isolate_;
506  uint64_t old_enabled_;
507 #else
508 
509  public:
510  explicit Scope(CpuFeature f) {}
511 #endif
512  };
513 
514  private:
515  // Safe defaults include SSE2 and CMOV for X64. It is always available, if
516  // anyone checks, but they shouldn't need to check.
517  // The required user mode extensions in X64 are (from AMD64 ABI Table A.1):
518  // fpu, tsc, cx8, cmov, mmx, sse, sse2, fxsr, syscall
519  static const uint64_t kDefaultCpuFeatures = (1 << SSE2 | 1 << CMOV);
520 
521 #ifdef DEBUG
522  static bool initialized_;
523 #endif
524  static uint64_t supported_;
525  static uint64_t found_by_runtime_probing_;
526 
527  DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
528 };
529 
530 
531 class Assembler : public AssemblerBase {
532  private:
533  // We check before assembling an instruction that there is sufficient
534  // space to write an instruction and its relocation information.
535  // The relocation writer's position must be kGap bytes above the end of
536  // the generated instructions. This leaves enough space for the
537  // longest possible x64 instruction, 15 bytes, and the longest possible
538  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
539  // (There is a 15 byte limit on x64 instruction length that rules out some
540  // otherwise valid instructions.)
541  // This allows for a single, fast space check per instruction.
542  static const int kGap = 32;
543 
544  public:
545  // Create an assembler. Instructions and relocation information are emitted
546  // into a buffer, with the instructions starting from the beginning and the
547  // relocation information starting from the end of the buffer. See CodeDesc
548  // for a detailed comment on the layout (globals.h).
549  //
550  // If the provided buffer is NULL, the assembler allocates and grows its own
551  // buffer, and buffer_size determines the initial buffer size. The buffer is
552  // owned by the assembler and deallocated upon destruction of the assembler.
553  //
554  // If the provided buffer is not NULL, the assembler uses the provided buffer
555  // for code generation and assumes its size to be buffer_size. If the buffer
556  // is too small, a fatal error occurs. No deallocation of the buffer is done
557  // upon destruction of the assembler.
558  Assembler(Isolate* isolate, void* buffer, int buffer_size);
559  ~Assembler();
560 
561  // Overrides the default provided by FLAG_debug_code.
562  void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
563 
564  // Avoids using instructions that vary in size in unpredictable ways between
565  // the snapshot and the running VM. This is needed by the full compiler so
566  // that it can recompile code with debug support and fix the PC.
567  void set_predictable_code_size(bool value) { predictable_code_size_ = value; }
568 
569  // GetCode emits any pending (non-emitted) code and fills the descriptor
570  // desc. GetCode() is idempotent; it returns the same result if no other
571  // Assembler functions are invoked in between GetCode() calls.
572  void GetCode(CodeDesc* desc);
573 
574  // Read/Modify the code target in the relative branch/call instruction at pc.
575  // On the x64 architecture, we use relative jumps with a 32-bit displacement
576  // to jump to other Code objects in the Code space in the heap.
577  // Jumps to C functions are done indirectly through a 64-bit register holding
578  // the absolute address of the target.
579  // These functions convert between absolute Addresses of Code objects and
580  // the relative displacements stored in the code.
581  static inline Address target_address_at(Address pc);
582  static inline void set_target_address_at(Address pc, Address target);
583 
584  // Return the code target address at a call site from the return address
585  // of that call in the instruction stream.
587 
588  // This sets the branch destination (which is in the instruction on x64).
589  // This is for calls and branches within generated code.
591  Address instruction_payload, Address target) {
592  set_target_address_at(instruction_payload, target);
593  }
594 
595  // This sets the branch destination (which is a load instruction on x64).
596  // This is for calls and branches to runtime code.
597  inline static void set_external_target_at(Address instruction_payload,
598  Address target) {
599  *reinterpret_cast<Address*>(instruction_payload) = target;
600  }
601 
603  // Number of bytes taken up by the branch target in the code.
604  static const int kSpecialTargetSize = 4; // Use 32-bit displacement.
605  // Distance between the address of the code target in the call instruction
606  // and the return address pushed on the stack.
607  static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement.
608  // Distance between the start of the JS return sequence and where the
609  // 32-bit displacement of a near call would be, relative to the pushed
610  // return address. TODO: Use return sequence length instead.
611  // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset;
612  static const int kPatchReturnSequenceAddressOffset = 13 - 4;
613  // Distance between start of patched debug break slot and where the
614  // 32-bit displacement of a near call would be, relative to the pushed
615  // return address. TODO: Use return sequence length instead.
616  // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset;
617  static const int kPatchDebugBreakSlotAddressOffset = 13 - 4;
618  // TODO(X64): Rename this, removing the "Real", after changing the above.
620 
621  // Some x64 JS code is padded with int3 to make it large
622  // enough to hold an instruction when the debugger patches it.
623  static const int kJumpInstructionLength = 13;
624  static const int kCallInstructionLength = 13;
625  static const int kJSReturnSequenceLength = 13;
626  static const int kShortCallInstructionLength = 5;
627  static const int kPatchDebugBreakSlotReturnOffset = 4;
628 
629  // The debug break slot must be able to contain a call instruction.
631 
632  // One byte opcode for test eax,0xXXXXXXXX.
633  static const byte kTestEaxByte = 0xA9;
634  // One byte opcode for test al, 0xXX.
635  static const byte kTestAlByte = 0xA8;
636  // One byte opcode for nop.
637  static const byte kNopByte = 0x90;
638 
639  // One byte prefix for a short conditional jump.
640  static const byte kJccShortPrefix = 0x70;
642  static const byte kJcShortOpcode = kJccShortPrefix | carry;
643  static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
644  static const byte kJzShortOpcode = kJccShortPrefix | zero;
645 
646 
647  // ---------------------------------------------------------------------------
648  // Code generation
649  //
650  // Function names correspond one-to-one to x64 instruction mnemonics.
651  // Unless specified otherwise, instructions operate on 64-bit operands.
652  //
653  // If we need versions of an assembly instruction that operate on different
654  // width arguments, we add a single-letter suffix specifying the width.
655  // This is done for the following instructions: mov, cmp, inc, dec,
656  // add, sub, and test.
657  // There are no versions of these instructions without the suffix.
658  // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
659  // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
660  // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
661  // - Instructions on 64-bit (quadword) operands/registers use 'q'.
662  //
663  // Some mnemonics, such as "and", are the same as C++ keywords.
664  // Naming conflicts with C++ keywords are resolved by adding a trailing '_'.
665 
666  // Insert the smallest number of nop instructions
667  // possible to align the pc offset to a multiple
668  // of m, where m must be a power of 2.
669  void Align(int m);
670  void Nop(int bytes = 1);
671  // Aligns code to something that's optimal for a jump target for the platform.
672  void CodeTargetAlign();
673 
674  // Stack
675  void pushfq();
676  void popfq();
677 
678  void push(Immediate value);
679  // Push a 32 bit integer, and guarantee that it is actually pushed as a
680  // 32 bit value, the normal push will optimize the 8 bit case.
681  void push_imm32(int32_t imm32);
682  void push(Register src);
683  void push(const Operand& src);
684 
685  void pop(Register dst);
686  void pop(const Operand& dst);
687 
688  void enter(Immediate size);
689  void leave();
690 
691  // Moves
692  void movb(Register dst, const Operand& src);
693  void movb(Register dst, Immediate imm);
694  void movb(const Operand& dst, Register src);
695 
696  // Move the low 16 bits of a 64-bit register value to a 16-bit
697  // memory location.
698  void movw(const Operand& dst, Register src);
699 
700  void movl(Register dst, Register src);
701  void movl(Register dst, const Operand& src);
702  void movl(const Operand& dst, Register src);
703  void movl(const Operand& dst, Immediate imm);
704  // Load a 32-bit immediate value, zero-extended to 64 bits.
705  void movl(Register dst, Immediate imm32);
706 
707  // Move 64 bit register value to 64-bit memory location.
708  void movq(const Operand& dst, Register src);
709  // Move 64 bit memory location to 64-bit register value.
710  void movq(Register dst, const Operand& src);
711  void movq(Register dst, Register src);
712  // Sign extends immediate 32-bit value to 64 bits.
713  void movq(Register dst, Immediate x);
714  // Move the offset of the label location relative to the current
715  // position (after the move) to the destination.
716  void movl(const Operand& dst, Label* src);
717 
718  // Move sign extended immediate to memory location.
719  void movq(const Operand& dst, Immediate value);
720  // Instructions to load a 64-bit immediate into a register.
721  // All 64-bit immediates must have a relocation mode.
722  void movq(Register dst, void* ptr, RelocInfo::Mode rmode);
723  void movq(Register dst, int64_t value, RelocInfo::Mode rmode);
724  void movq(Register dst, const char* s, RelocInfo::Mode rmode);
725  // Moves the address of the external reference into the register.
726  void movq(Register dst, ExternalReference ext);
727  void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode);
728 
729  void movsxbq(Register dst, const Operand& src);
730  void movsxwq(Register dst, const Operand& src);
731  void movsxlq(Register dst, Register src);
732  void movsxlq(Register dst, const Operand& src);
733  void movzxbq(Register dst, const Operand& src);
734  void movzxbl(Register dst, const Operand& src);
735  void movzxwq(Register dst, const Operand& src);
736  void movzxwl(Register dst, const Operand& src);
737 
738  // Repeated moves.
739 
740  void repmovsb();
741  void repmovsw();
742  void repmovsl();
743  void repmovsq();
744 
745  // Instruction to load from an immediate 64-bit pointer into RAX.
746  void load_rax(void* ptr, RelocInfo::Mode rmode);
747  void load_rax(ExternalReference ext);
748 
749  // Conditional moves.
750  void cmovq(Condition cc, Register dst, Register src);
751  void cmovq(Condition cc, Register dst, const Operand& src);
752  void cmovl(Condition cc, Register dst, Register src);
753  void cmovl(Condition cc, Register dst, const Operand& src);
754 
755  // Exchange two registers
756  void xchg(Register dst, Register src);
757 
758  // Arithmetics
759  void addl(Register dst, Register src) {
760  arithmetic_op_32(0x03, dst, src);
761  }
762 
763  void addl(Register dst, Immediate src) {
764  immediate_arithmetic_op_32(0x0, dst, src);
765  }
766 
767  void addl(Register dst, const Operand& src) {
768  arithmetic_op_32(0x03, dst, src);
769  }
770 
771  void addl(const Operand& dst, Immediate src) {
772  immediate_arithmetic_op_32(0x0, dst, src);
773  }
774 
775  void addl(const Operand& dst, Register src) {
776  arithmetic_op_32(0x01, src, dst);
777  }
778 
779  void addq(Register dst, Register src) {
780  arithmetic_op(0x03, dst, src);
781  }
782 
783  void addq(Register dst, const Operand& src) {
784  arithmetic_op(0x03, dst, src);
785  }
786 
787  void addq(const Operand& dst, Register src) {
788  arithmetic_op(0x01, src, dst);
789  }
790 
791  void addq(Register dst, Immediate src) {
792  immediate_arithmetic_op(0x0, dst, src);
793  }
794 
795  void addq(const Operand& dst, Immediate src) {
796  immediate_arithmetic_op(0x0, dst, src);
797  }
798 
799  void sbbl(Register dst, Register src) {
800  arithmetic_op_32(0x1b, dst, src);
801  }
802 
803  void sbbq(Register dst, Register src) {
804  arithmetic_op(0x1b, dst, src);
805  }
806 
807  void cmpb(Register dst, Immediate src) {
808  immediate_arithmetic_op_8(0x7, dst, src);
809  }
810 
811  void cmpb_al(Immediate src);
812 
813  void cmpb(Register dst, Register src) {
814  arithmetic_op(0x3A, dst, src);
815  }
816 
817  void cmpb(Register dst, const Operand& src) {
818  arithmetic_op(0x3A, dst, src);
819  }
820 
821  void cmpb(const Operand& dst, Register src) {
822  arithmetic_op(0x38, src, dst);
823  }
824 
825  void cmpb(const Operand& dst, Immediate src) {
826  immediate_arithmetic_op_8(0x7, dst, src);
827  }
828 
829  void cmpw(const Operand& dst, Immediate src) {
830  immediate_arithmetic_op_16(0x7, dst, src);
831  }
832 
833  void cmpw(Register dst, Immediate src) {
834  immediate_arithmetic_op_16(0x7, dst, src);
835  }
836 
837  void cmpw(Register dst, const Operand& src) {
838  arithmetic_op_16(0x3B, dst, src);
839  }
840 
841  void cmpw(Register dst, Register src) {
842  arithmetic_op_16(0x3B, dst, src);
843  }
844 
845  void cmpw(const Operand& dst, Register src) {
846  arithmetic_op_16(0x39, src, dst);
847  }
848 
849  void cmpl(Register dst, Register src) {
850  arithmetic_op_32(0x3B, dst, src);
851  }
852 
853  void cmpl(Register dst, const Operand& src) {
854  arithmetic_op_32(0x3B, dst, src);
855  }
856 
857  void cmpl(const Operand& dst, Register src) {
858  arithmetic_op_32(0x39, src, dst);
859  }
860 
861  void cmpl(Register dst, Immediate src) {
862  immediate_arithmetic_op_32(0x7, dst, src);
863  }
864 
865  void cmpl(const Operand& dst, Immediate src) {
866  immediate_arithmetic_op_32(0x7, dst, src);
867  }
868 
869  void cmpq(Register dst, Register src) {
870  arithmetic_op(0x3B, dst, src);
871  }
872 
873  void cmpq(Register dst, const Operand& src) {
874  arithmetic_op(0x3B, dst, src);
875  }
876 
877  void cmpq(const Operand& dst, Register src) {
878  arithmetic_op(0x39, src, dst);
879  }
880 
881  void cmpq(Register dst, Immediate src) {
882  immediate_arithmetic_op(0x7, dst, src);
883  }
884 
885  void cmpq(const Operand& dst, Immediate src) {
886  immediate_arithmetic_op(0x7, dst, src);
887  }
888 
889  void and_(Register dst, Register src) {
890  arithmetic_op(0x23, dst, src);
891  }
892 
893  void and_(Register dst, const Operand& src) {
894  arithmetic_op(0x23, dst, src);
895  }
896 
897  void and_(const Operand& dst, Register src) {
898  arithmetic_op(0x21, src, dst);
899  }
900 
901  void and_(Register dst, Immediate src) {
902  immediate_arithmetic_op(0x4, dst, src);
903  }
904 
905  void and_(const Operand& dst, Immediate src) {
906  immediate_arithmetic_op(0x4, dst, src);
907  }
908 
909  void andl(Register dst, Immediate src) {
910  immediate_arithmetic_op_32(0x4, dst, src);
911  }
912 
913  void andl(Register dst, Register src) {
914  arithmetic_op_32(0x23, dst, src);
915  }
916 
917  void andl(Register dst, const Operand& src) {
918  arithmetic_op_32(0x23, dst, src);
919  }
920 
921  void andb(Register dst, Immediate src) {
922  immediate_arithmetic_op_8(0x4, dst, src);
923  }
924 
925  void decq(Register dst);
926  void decq(const Operand& dst);
927  void decl(Register dst);
928  void decl(const Operand& dst);
929  void decb(Register dst);
930  void decb(const Operand& dst);
931 
932  // Sign-extends rax into rdx:rax.
933  void cqo();
934  // Sign-extends eax into edx:eax.
935  void cdq();
936 
937  // Divide rdx:rax by src. Quotient in rax, remainder in rdx.
938  void idivq(Register src);
939  // Divide edx:eax by lower 32 bits of src. Quotient in eax, rem. in edx.
940  void idivl(Register src);
941 
942  // Signed multiply instructions.
943  void imul(Register src); // rdx:rax = rax * src.
944  void imul(Register dst, Register src); // dst = dst * src.
945  void imul(Register dst, const Operand& src); // dst = dst * src.
946  void imul(Register dst, Register src, Immediate imm); // dst = src * imm.
947  // Signed 32-bit multiply instructions.
948  void imull(Register dst, Register src); // dst = dst * src.
949  void imull(Register dst, const Operand& src); // dst = dst * src.
950  void imull(Register dst, Register src, Immediate imm); // dst = src * imm.
951 
952  void incq(Register dst);
953  void incq(const Operand& dst);
954  void incl(Register dst);
955  void incl(const Operand& dst);
956 
957  void lea(Register dst, const Operand& src);
958  void leal(Register dst, const Operand& src);
959 
960  // Multiply rax by src, put the result in rdx:rax.
961  void mul(Register src);
962 
963  void neg(Register dst);
964  void neg(const Operand& dst);
965  void negl(Register dst);
966 
967  void not_(Register dst);
968  void not_(const Operand& dst);
969  void notl(Register dst);
970 
971  void or_(Register dst, Register src) {
972  arithmetic_op(0x0B, dst, src);
973  }
974 
975  void orl(Register dst, Register src) {
976  arithmetic_op_32(0x0B, dst, src);
977  }
978 
979  void or_(Register dst, const Operand& src) {
980  arithmetic_op(0x0B, dst, src);
981  }
982 
983  void orl(Register dst, const Operand& src) {
984  arithmetic_op_32(0x0B, dst, src);
985  }
986 
987  void or_(const Operand& dst, Register src) {
988  arithmetic_op(0x09, src, dst);
989  }
990 
991  void or_(Register dst, Immediate src) {
992  immediate_arithmetic_op(0x1, dst, src);
993  }
994 
995  void orl(Register dst, Immediate src) {
996  immediate_arithmetic_op_32(0x1, dst, src);
997  }
998 
999  void or_(const Operand& dst, Immediate src) {
1000  immediate_arithmetic_op(0x1, dst, src);
1001  }
1002 
1003  void orl(const Operand& dst, Immediate src) {
1004  immediate_arithmetic_op_32(0x1, dst, src);
1005  }
1006 
1007 
1008  void rcl(Register dst, Immediate imm8) {
1009  shift(dst, imm8, 0x2);
1010  }
1011 
1012  void rol(Register dst, Immediate imm8) {
1013  shift(dst, imm8, 0x0);
1014  }
1015 
1016  void rcr(Register dst, Immediate imm8) {
1017  shift(dst, imm8, 0x3);
1018  }
1019 
1020  void ror(Register dst, Immediate imm8) {
1021  shift(dst, imm8, 0x1);
1022  }
1023 
1024  // Shifts dst:src left by cl bits, affecting only dst.
1025  void shld(Register dst, Register src);
1026 
1027  // Shifts src:dst right by cl bits, affecting only dst.
1028  void shrd(Register dst, Register src);
1029 
1030  // Shifts dst right, duplicating sign bit, by shift_amount bits.
1031  // Shifting by 1 is handled efficiently.
1032  void sar(Register dst, Immediate shift_amount) {
1033  shift(dst, shift_amount, 0x7);
1034  }
1035 
1036  // Shifts dst right, duplicating sign bit, by shift_amount bits.
1037  // Shifting by 1 is handled efficiently.
1038  void sarl(Register dst, Immediate shift_amount) {
1039  shift_32(dst, shift_amount, 0x7);
1040  }
1041 
1042  // Shifts dst right, duplicating sign bit, by cl % 64 bits.
1043  void sar_cl(Register dst) {
1044  shift(dst, 0x7);
1045  }
1046 
1047  // Shifts dst right, duplicating sign bit, by cl % 64 bits.
1048  void sarl_cl(Register dst) {
1049  shift_32(dst, 0x7);
1050  }
1051 
1052  void shl(Register dst, Immediate shift_amount) {
1053  shift(dst, shift_amount, 0x4);
1054  }
1055 
1056  void shl_cl(Register dst) {
1057  shift(dst, 0x4);
1058  }
1059 
1060  void shll_cl(Register dst) {
1061  shift_32(dst, 0x4);
1062  }
1063 
1064  void shll(Register dst, Immediate shift_amount) {
1065  shift_32(dst, shift_amount, 0x4);
1066  }
1067 
1068  void shr(Register dst, Immediate shift_amount) {
1069  shift(dst, shift_amount, 0x5);
1070  }
1071 
1072  void shr_cl(Register dst) {
1073  shift(dst, 0x5);
1074  }
1075 
1076  void shrl_cl(Register dst) {
1077  shift_32(dst, 0x5);
1078  }
1079 
1080  void shrl(Register dst, Immediate shift_amount) {
1081  shift_32(dst, shift_amount, 0x5);
1082  }
1083 
1084  void store_rax(void* dst, RelocInfo::Mode mode);
1085  void store_rax(ExternalReference ref);
1086 
1087  void subq(Register dst, Register src) {
1088  arithmetic_op(0x2B, dst, src);
1089  }
1090 
1091  void subq(Register dst, const Operand& src) {
1092  arithmetic_op(0x2B, dst, src);
1093  }
1094 
1095  void subq(const Operand& dst, Register src) {
1096  arithmetic_op(0x29, src, dst);
1097  }
1098 
1099  void subq(Register dst, Immediate src) {
1100  immediate_arithmetic_op(0x5, dst, src);
1101  }
1102 
1103  void subq(const Operand& dst, Immediate src) {
1104  immediate_arithmetic_op(0x5, dst, src);
1105  }
1106 
1107  void subl(Register dst, Register src) {
1108  arithmetic_op_32(0x2B, dst, src);
1109  }
1110 
1111  void subl(Register dst, const Operand& src) {
1112  arithmetic_op_32(0x2B, dst, src);
1113  }
1114 
1115  void subl(const Operand& dst, Immediate src) {
1116  immediate_arithmetic_op_32(0x5, dst, src);
1117  }
1118 
1119  void subl(Register dst, Immediate src) {
1120  immediate_arithmetic_op_32(0x5, dst, src);
1121  }
1122 
1123  void subb(Register dst, Immediate src) {
1124  immediate_arithmetic_op_8(0x5, dst, src);
1125  }
1126 
1127  void testb(Register dst, Register src);
1128  void testb(Register reg, Immediate mask);
1129  void testb(const Operand& op, Immediate mask);
1130  void testb(const Operand& op, Register reg);
1131  void testl(Register dst, Register src);
1132  void testl(Register reg, Immediate mask);
1133  void testl(const Operand& op, Immediate mask);
1134  void testq(const Operand& op, Register reg);
1135  void testq(Register dst, Register src);
1136  void testq(Register dst, Immediate mask);
1137 
1138  void xor_(Register dst, Register src) {
1139  if (dst.code() == src.code()) {
1140  arithmetic_op_32(0x33, dst, src);
1141  } else {
1142  arithmetic_op(0x33, dst, src);
1143  }
1144  }
1145 
1146  void xorl(Register dst, Register src) {
1147  arithmetic_op_32(0x33, dst, src);
1148  }
1149 
1150  void xorl(Register dst, const Operand& src) {
1151  arithmetic_op_32(0x33, dst, src);
1152  }
1153 
1154  void xorl(Register dst, Immediate src) {
1155  immediate_arithmetic_op_32(0x6, dst, src);
1156  }
1157 
1158  void xorl(const Operand& dst, Immediate src) {
1159  immediate_arithmetic_op_32(0x6, dst, src);
1160  }
1161 
1162  void xor_(Register dst, const Operand& src) {
1163  arithmetic_op(0x33, dst, src);
1164  }
1165 
1166  void xor_(const Operand& dst, Register src) {
1167  arithmetic_op(0x31, src, dst);
1168  }
1169 
1170  void xor_(Register dst, Immediate src) {
1171  immediate_arithmetic_op(0x6, dst, src);
1172  }
1173 
1174  void xor_(const Operand& dst, Immediate src) {
1175  immediate_arithmetic_op(0x6, dst, src);
1176  }
1177 
1178  // Bit operations.
1179  void bt(const Operand& dst, Register src);
1180  void bts(const Operand& dst, Register src);
1181 
1182  // Miscellaneous
1183  void clc();
1184  void cld();
1185  void cpuid();
1186  void hlt();
1187  void int3();
1188  void nop();
1189  void rdtsc();
1190  void ret(int imm16);
1191  void setcc(Condition cc, Register reg);
1192 
1193  // Label operations & relative jumps (PPUM Appendix D)
1194  //
1195  // Takes a branch opcode (cc) and a label (L) and generates
1196  // either a backward branch or a forward branch and links it
1197  // to the label fixup chain. Usage:
1198  //
1199  // Label L; // unbound label
1200  // j(cc, &L); // forward branch to unbound label
1201  // bind(&L); // bind label to the current pc
1202  // j(cc, &L); // backward branch to bound label
1203  // bind(&L); // illegal: a label may be bound only once
1204  //
1205  // Note: The same Label can be used for forward and backward branches
1206  // but it may be bound only once.
1207 
1208  void bind(Label* L); // binds an unbound label L to the current code position
1209 
1210  // Calls
1211  // Call near relative 32-bit displacement, relative to next instruction.
1212  void call(Label* L);
1213  void call(Handle<Code> target,
1214  RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
1216 
1217  // Calls directly to the given address using a relative offset.
1218  // Should only ever be used in Code objects for calls within the
1219  // same Code object. Should not be used when generating new code (use labels),
1220  // but only when patching existing code.
1221  void call(Address target);
1222 
1223  // Call near absolute indirect, address in register
1224  void call(Register adr);
1225 
1226  // Call near indirect
1227  void call(const Operand& operand);
1228 
1229  // Jumps
1230  // Jump short or near relative.
1231  // Use a 32-bit signed displacement.
1232  // Unconditional jump to L
1233  void jmp(Label* L, Label::Distance distance = Label::kFar);
1234  void jmp(Handle<Code> target, RelocInfo::Mode rmode);
1235 
1236  // Jump near absolute indirect (r64)
1237  void jmp(Register adr);
1238 
1239  // Jump near absolute indirect (m64)
1240  void jmp(const Operand& src);
1241 
1242  // Conditional jumps
1243  void j(Condition cc,
1244  Label* L,
1245  Label::Distance distance = Label::kFar);
1246  void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
1247 
1248  // Floating-point operations
1249  void fld(int i);
1250 
1251  void fld1();
1252  void fldz();
1253  void fldpi();
1254  void fldln2();
1255 
1256  void fld_s(const Operand& adr);
1257  void fld_d(const Operand& adr);
1258 
1259  void fstp_s(const Operand& adr);
1260  void fstp_d(const Operand& adr);
1261  void fstp(int index);
1262 
1263  void fild_s(const Operand& adr);
1264  void fild_d(const Operand& adr);
1265 
1266  void fist_s(const Operand& adr);
1267 
1268  void fistp_s(const Operand& adr);
1269  void fistp_d(const Operand& adr);
1270 
1271  void fisttp_s(const Operand& adr);
1272  void fisttp_d(const Operand& adr);
1273 
1274  void fabs();
1275  void fchs();
1276 
1277  void fadd(int i);
1278  void fsub(int i);
1279  void fmul(int i);
1280  void fdiv(int i);
1281 
1282  void fisub_s(const Operand& adr);
1283 
1284  void faddp(int i = 1);
1285  void fsubp(int i = 1);
1286  void fsubrp(int i = 1);
1287  void fmulp(int i = 1);
1288  void fdivp(int i = 1);
1289  void fprem();
1290  void fprem1();
1291 
1292  void fxch(int i = 1);
1293  void fincstp();
1294  void ffree(int i = 0);
1295 
1296  void ftst();
1297  void fucomp(int i);
1298  void fucompp();
1299  void fucomi(int i);
1300  void fucomip();
1301 
1302  void fcompp();
1303  void fnstsw_ax();
1304  void fwait();
1305  void fnclex();
1306 
1307  void fsin();
1308  void fcos();
1309  void fptan();
1310  void fyl2x();
1311  void f2xm1();
1312  void fscale();
1313  void fninit();
1314 
1315  void frndint();
1316 
1317  void sahf();
1318 
1319  // SSE2 instructions
1320  void movd(XMMRegister dst, Register src);
1321  void movd(Register dst, XMMRegister src);
1322  void movq(XMMRegister dst, Register src);
1323  void movq(Register dst, XMMRegister src);
1324  void movq(XMMRegister dst, XMMRegister src);
1325  void extractps(Register dst, XMMRegister src, byte imm8);
1326 
1327  // Don't use this unless it's important to keep the
1328  // top half of the destination register unchanged.
1329  // Used movaps when moving double values and movq for integer
1330  // values in xmm registers.
1331  void movsd(XMMRegister dst, XMMRegister src);
1332 
1333  void movsd(const Operand& dst, XMMRegister src);
1334  void movsd(XMMRegister dst, const Operand& src);
1335 
1336  void movdqa(const Operand& dst, XMMRegister src);
1337  void movdqa(XMMRegister dst, const Operand& src);
1338 
1339  void movapd(XMMRegister dst, XMMRegister src);
1340  void movaps(XMMRegister dst, XMMRegister src);
1341 
1342  void movss(XMMRegister dst, const Operand& src);
1343  void movss(const Operand& dst, XMMRegister src);
1344 
1345  void cvttss2si(Register dst, const Operand& src);
1346  void cvttss2si(Register dst, XMMRegister src);
1347  void cvttsd2si(Register dst, const Operand& src);
1348  void cvttsd2si(Register dst, XMMRegister src);
1349  void cvttsd2siq(Register dst, XMMRegister src);
1350 
1351  void cvtlsi2sd(XMMRegister dst, const Operand& src);
1352  void cvtlsi2sd(XMMRegister dst, Register src);
1353  void cvtqsi2sd(XMMRegister dst, const Operand& src);
1354  void cvtqsi2sd(XMMRegister dst, Register src);
1355 
1356  void cvtlsi2ss(XMMRegister dst, Register src);
1357 
1358  void cvtss2sd(XMMRegister dst, XMMRegister src);
1359  void cvtss2sd(XMMRegister dst, const Operand& src);
1360  void cvtsd2ss(XMMRegister dst, XMMRegister src);
1361 
1362  void cvtsd2si(Register dst, XMMRegister src);
1363  void cvtsd2siq(Register dst, XMMRegister src);
1364 
1365  void addsd(XMMRegister dst, XMMRegister src);
1366  void subsd(XMMRegister dst, XMMRegister src);
1367  void mulsd(XMMRegister dst, XMMRegister src);
1368  void divsd(XMMRegister dst, XMMRegister src);
1369 
1370  void andpd(XMMRegister dst, XMMRegister src);
1371  void orpd(XMMRegister dst, XMMRegister src);
1372  void xorpd(XMMRegister dst, XMMRegister src);
1373  void xorps(XMMRegister dst, XMMRegister src);
1374  void sqrtsd(XMMRegister dst, XMMRegister src);
1375 
1376  void ucomisd(XMMRegister dst, XMMRegister src);
1377  void ucomisd(XMMRegister dst, const Operand& src);
1378 
1380  kRoundToNearest = 0x0,
1381  kRoundDown = 0x1,
1382  kRoundUp = 0x2,
1383  kRoundToZero = 0x3
1384  };
1385 
1386  void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
1387 
1388  void movmskpd(Register dst, XMMRegister src);
1389 
1390  // The first argument is the reg field, the second argument is the r/m field.
1391  void emit_sse_operand(XMMRegister dst, XMMRegister src);
1392  void emit_sse_operand(XMMRegister reg, const Operand& adr);
1393  void emit_sse_operand(XMMRegister dst, Register src);
1394  void emit_sse_operand(Register dst, XMMRegister src);
1395 
1396  // Debugging
1397  void Print();
1398 
1399  // Check the code size generated from label to here.
1400  int SizeOfCodeGeneratedSince(Label* label) {
1401  return pc_offset() - label->pos();
1402  }
1403 
1404  // Mark address of the ExitJSFrame code.
1405  void RecordJSReturn();
1406 
1407  // Mark address of a debug break slot.
1408  void RecordDebugBreakSlot();
1409 
1410  // Record a comment relocation entry that can be used by a disassembler.
1411  // Use --code-comments to enable.
1412  void RecordComment(const char* msg, bool force = false);
1413 
1414  // Writes a single word of data in the code stream.
1415  // Used for inline tables, e.g., jump-tables.
1416  void db(uint8_t data);
1417  void dd(uint32_t data);
1418 
1419  int pc_offset() const { return static_cast<int>(pc_ - buffer_); }
1420 
1421  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
1422 
1423  // Check if there is less than kGap bytes available in the buffer.
1424  // If this is the case, we need to grow the buffer before emitting
1425  // an instruction or relocation information.
1426  inline bool buffer_overflow() const {
1427  return pc_ >= reloc_info_writer.pos() - kGap;
1428  }
1429 
1430  // Get the number of bytes available in the buffer.
1431  inline int available_space() const {
1432  return static_cast<int>(reloc_info_writer.pos() - pc_);
1433  }
1434 
1435  static bool IsNop(Address addr);
1436 
1437  // Avoid overflows for displacements etc.
1438  static const int kMaximalBufferSize = 512*MB;
1439  static const int kMinimalBufferSize = 4*KB;
1440 
1441  byte byte_at(int pos) { return buffer_[pos]; }
1442  void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
1443 
1444  protected:
1445  bool emit_debug_code() const { return emit_debug_code_; }
1446  bool predictable_code_size() const { return predictable_code_size_; }
1447 
1448  private:
1449  byte* addr_at(int pos) { return buffer_ + pos; }
1450  uint32_t long_at(int pos) {
1451  return *reinterpret_cast<uint32_t*>(addr_at(pos));
1452  }
1453  void long_at_put(int pos, uint32_t x) {
1454  *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
1455  }
1456 
1457  // code emission
1458  void GrowBuffer();
1459 
1460  void emit(byte x) { *pc_++ = x; }
1461  inline void emitl(uint32_t x);
1462  inline void emitq(uint64_t x, RelocInfo::Mode rmode);
1463  inline void emitw(uint16_t x);
1464  inline void emit_code_target(Handle<Code> target,
1465  RelocInfo::Mode rmode,
1466  TypeFeedbackId ast_id = TypeFeedbackId::None());
1467  void emit(Immediate x) { emitl(x.value_); }
1468 
1469  // Emits a REX prefix that encodes a 64-bit operand size and
1470  // the top bit of both register codes.
1471  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1472  // REX.W is set.
1473  inline void emit_rex_64(XMMRegister reg, Register rm_reg);
1474  inline void emit_rex_64(Register reg, XMMRegister rm_reg);
1475  inline void emit_rex_64(Register reg, Register rm_reg);
1476 
1477  // Emits a REX prefix that encodes a 64-bit operand size and
1478  // the top bit of the destination, index, and base register codes.
1479  // The high bit of reg is used for REX.R, the high bit of op's base
1480  // register is used for REX.B, and the high bit of op's index register
1481  // is used for REX.X. REX.W is set.
1482  inline void emit_rex_64(Register reg, const Operand& op);
1483  inline void emit_rex_64(XMMRegister reg, const Operand& op);
1484 
1485  // Emits a REX prefix that encodes a 64-bit operand size and
1486  // the top bit of the register code.
1487  // The high bit of register is used for REX.B.
1488  // REX.W is set and REX.R and REX.X are clear.
1489  inline void emit_rex_64(Register rm_reg);
1490 
1491  // Emits a REX prefix that encodes a 64-bit operand size and
1492  // the top bit of the index and base register codes.
1493  // The high bit of op's base register is used for REX.B, and the high
1494  // bit of op's index register is used for REX.X.
1495  // REX.W is set and REX.R clear.
1496  inline void emit_rex_64(const Operand& op);
1497 
1498  // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
1499  void emit_rex_64() { emit(0x48); }
1500 
1501  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1502  // REX.W is clear.
1503  inline void emit_rex_32(Register reg, Register rm_reg);
1504 
1505  // The high bit of reg is used for REX.R, the high bit of op's base
1506  // register is used for REX.B, and the high bit of op's index register
1507  // is used for REX.X. REX.W is cleared.
1508  inline void emit_rex_32(Register reg, const Operand& op);
1509 
1510  // High bit of rm_reg goes to REX.B.
1511  // REX.W, REX.R and REX.X are clear.
1512  inline void emit_rex_32(Register rm_reg);
1513 
1514  // High bit of base goes to REX.B and high bit of index to REX.X.
1515  // REX.W and REX.R are clear.
1516  inline void emit_rex_32(const Operand& op);
1517 
1518  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1519  // REX.W is cleared. If no REX bits are set, no byte is emitted.
1520  inline void emit_optional_rex_32(Register reg, Register rm_reg);
1521 
1522  // The high bit of reg is used for REX.R, the high bit of op's base
1523  // register is used for REX.B, and the high bit of op's index register
1524  // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing
1525  // is emitted.
1526  inline void emit_optional_rex_32(Register reg, const Operand& op);
1527 
1528  // As for emit_optional_rex_32(Register, Register), except that
1529  // the registers are XMM registers.
1530  inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
1531 
1532  // As for emit_optional_rex_32(Register, Register), except that
1533  // one of the registers is an XMM registers.
1534  inline void emit_optional_rex_32(XMMRegister reg, Register base);
1535 
1536  // As for emit_optional_rex_32(Register, Register), except that
1537  // one of the registers is an XMM registers.
1538  inline void emit_optional_rex_32(Register reg, XMMRegister base);
1539 
1540  // As for emit_optional_rex_32(Register, const Operand&), except that
1541  // the register is an XMM register.
1542  inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);
1543 
1544  // Optionally do as emit_rex_32(Register) if the register number has
1545  // the high bit set.
1546  inline void emit_optional_rex_32(Register rm_reg);
1547 
1548  // Optionally do as emit_rex_32(const Operand&) if the operand register
1549  // numbers have a high bit set.
1550  inline void emit_optional_rex_32(const Operand& op);
1551 
1552 
1553  // Emit the ModR/M byte, and optionally the SIB byte and
1554  // 1- or 4-byte offset for a memory operand. Also encodes
1555  // the second operand of the operation, a register or operation
1556  // subcode, into the reg field of the ModR/M byte.
1557  void emit_operand(Register reg, const Operand& adr) {
1558  emit_operand(reg.low_bits(), adr);
1559  }
1560 
1561  // Emit the ModR/M byte, and optionally the SIB byte and
1562  // 1- or 4-byte offset for a memory operand. Also used to encode
1563  // a three-bit opcode extension into the ModR/M byte.
1564  void emit_operand(int rm, const Operand& adr);
1565 
1566  // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
1567  void emit_modrm(Register reg, Register rm_reg) {
1568  emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
1569  }
1570 
1571  // Emit a ModR/M byte with an operation subcode in the reg field and
1572  // a register in the rm_reg field.
1573  void emit_modrm(int code, Register rm_reg) {
1574  ASSERT(is_uint3(code));
1575  emit(0xC0 | code << 3 | rm_reg.low_bits());
1576  }
1577 
1578  // Emit the code-object-relative offset of the label's position
1579  inline void emit_code_relative_offset(Label* label);
1580 
1581  // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
1582  // AND, OR, XOR, or CMP. The encodings of these operations are all
1583  // similar, differing just in the opcode or in the reg field of the
1584  // ModR/M byte.
1585  void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
1586  void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
1587  void arithmetic_op_32(byte opcode, Register reg, Register rm_reg);
1588  void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg);
1589  void arithmetic_op(byte opcode, Register reg, Register rm_reg);
1590  void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg);
1591  void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
1592  void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
1593  // Operate on a byte in memory or register.
1594  void immediate_arithmetic_op_8(byte subcode,
1595  Register dst,
1596  Immediate src);
1597  void immediate_arithmetic_op_8(byte subcode,
1598  const Operand& dst,
1599  Immediate src);
1600  // Operate on a word in memory or register.
1601  void immediate_arithmetic_op_16(byte subcode,
1602  Register dst,
1603  Immediate src);
1604  void immediate_arithmetic_op_16(byte subcode,
1605  const Operand& dst,
1606  Immediate src);
1607  // Operate on a 32-bit word in memory or register.
1608  void immediate_arithmetic_op_32(byte subcode,
1609  Register dst,
1610  Immediate src);
1611  void immediate_arithmetic_op_32(byte subcode,
1612  const Operand& dst,
1613  Immediate src);
1614 
1615  // Emit machine code for a shift operation.
1616  void shift(Register dst, Immediate shift_amount, int subcode);
1617  void shift_32(Register dst, Immediate shift_amount, int subcode);
1618  // Shift dst by cl % 64 bits.
1619  void shift(Register dst, int subcode);
1620  void shift_32(Register dst, int subcode);
1621 
1622  void emit_farith(int b1, int b2, int i);
1623 
1624  // labels
1625  // void print(Label* L);
1626  void bind_to(Label* L, int pos);
1627 
1628  // record reloc info for current pc_
1629  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1630 
1631  friend class CodePatcher;
1632  friend class EnsureSpace;
1634 
1635  // Code buffer:
1636  // The buffer into which code and relocation info are generated.
1637  byte* buffer_;
1638  int buffer_size_;
1639  // True if the assembler owns the buffer, false if buffer is external.
1640  bool own_buffer_;
1641 
1642  // code generation
1643  byte* pc_; // the program counter; moves forward
1644  RelocInfoWriter reloc_info_writer;
1645 
1646  List< Handle<Code> > code_targets_;
1647 
1648  PositionsRecorder positions_recorder_;
1649 
1650  bool emit_debug_code_;
1651  bool predictable_code_size_;
1652 
1653  friend class PositionsRecorder;
1654 };
1655 
1656 
1657 // Helper class that ensures that there is enough space for generating
1658 // instructions and relocation information. The constructor makes
1659 // sure that there is enough space and (in debug mode) the destructor
1660 // checks that we did not generate too much.
1661 class EnsureSpace BASE_EMBEDDED {
1662  public:
1663  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
1664  if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
1665 #ifdef DEBUG
1666  space_before_ = assembler_->available_space();
1667 #endif
1668  }
1669 
1670 #ifdef DEBUG
1671  ~EnsureSpace() {
1672  int bytes_generated = space_before_ - assembler_->available_space();
1673  ASSERT(bytes_generated < assembler_->kGap);
1674  }
1675 #endif
1676 
1677  private:
1678  Assembler* assembler_;
1679 #ifdef DEBUG
1680  int space_before_;
1681 #endif
1682 };
1683 
1684 } } // namespace v8::internal
1685 
1686 #endif // V8_X64_ASSEMBLER_X64_H_
byte * Address
Definition: globals.h:157
const Register rdx
void shl(Register dst, Immediate shift_amount)
void xor_(Register dst, Immediate src)
void cvtlsi2ss(XMMRegister dst, Register src)
const XMMRegister xmm13
void movapd(XMMRegister dst, XMMRegister src)
static const int kMaximalBufferSize
void cmpb(const Operand &dst, Register src)
void xorl(Register dst, const Operand &src)
void or_(Register dst, Immediate src)
const Register r14
void db(uint8_t data)
void addq(Register dst, Immediate src)
void load_rax(void *ptr, RelocInfo::Mode rmode)
const int kRegister_r14_Code
const int kRegister_rsp_Code
void addq(const Operand &dst, Register src)
static const byte kJccShortPrefix
void ucomisd(XMMRegister dst, XMMRegister src)
void cvttss2si(Register dst, const Operand &src)
void movzxbl(Register dst, const Operand &src)
void cmpw(Register dst, const Operand &src)
void or_(Register dst, Register src)
void ror(Register dst, Immediate imm8)
void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode)
const Register r11
void or_(const Operand &dst, Register src)
const XMMRegister xmm4
void addq(Register dst, const Operand &src)
bool buffer_overflow() const
void mulsd(XMMRegister dst, XMMRegister src)
const Register rbp
bool is_byte_register() const
const int KB
Definition: globals.h:207
void cvtsd2si(Register dst, XMMRegister src)
static TypeFeedbackId None()
Definition: utils.h:999
void cmpl(Register dst, Register src)
const int kRegister_r13_Code
void idivq(Register src)
void andl(Register dst, const Operand &src)
void and_(Register dst, const Operand &src)
const int kRegister_rbp_Code
void orpd(XMMRegister dst, XMMRegister src)
static const int kPatchDebugBreakSlotReturnOffset
int SizeOfCodeGeneratedSince(Label *label)
void cmpw(const Operand &dst, Immediate src)
const Register rsi
void addq(Register dst, Register src)
void dd(uint32_t data)
void push(Register src, Condition cond=al)
void subl(Register dst, Register src)
void xorl(const Operand &dst, Immediate src)
void cvtss2sd(XMMRegister dst, XMMRegister src)
void orl(Register dst, Immediate src)
void sqrtsd(XMMRegister dst, XMMRegister src)
int int32_t
Definition: unicode.cc:47
static XMMRegister FromAllocationIndex(int index)
void xorl(Register dst, Immediate src)
static bool IsSupported(CpuFeature f)
static bool enabled()
Definition: serialize.h:481
bool is_uint3(int x)
Definition: assembler.h:846
void andpd(XMMRegister dst, XMMRegister src)
static const int kCallInstructionLength
void subq(const Operand &dst, Register src)
bool predictable_code_size() const
void xor_(Register dst, const Operand &src)
void j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
static Register FromAllocationIndex(int index)
static const int kMinimalBufferSize
void cmpq(Register dst, const Operand &src)
#define ASSERT(condition)
Definition: checks.h:270
static const int kPatchReturnSequenceAddressOffset
void subq(Register dst, Register src)
void cvtlsi2sd(XMMRegister dst, const Operand &src)
static const int kShortCallInstructionLength
unsigned short uint16_t
Definition: unicode.cc:46
void and_(const Operand &dst, Register src)
void addl(Register dst, Register src)
void set_predictable_code_size(bool value)
static const char * AllocationIndexToString(int index)
const XMMRegister xmm6
void movsxlq(Register dst, Register src)
void xorpd(XMMRegister dst, XMMRegister src)
void cmpl(Register dst, Immediate src)
StringInputBuffer *const buffer_
void ret(int imm16)
void bt(const Operand &dst, Register src)
bool is_uint32(int64_t x)
Definition: assembler-x64.h:48
void sarl_cl(Register dst)
void orl(Register dst, const Operand &src)
const XMMRegister xmm12
void incl(Register dst)
static const byte kTestAlByte
void shll(Register dst, Immediate shift_amount)
void cmovl(Condition cc, Register dst, Register src)
void testb(Register dst, Register src)
const XMMRegister xmm5
const int kRegister_rcx_Code
void cmpb(Register dst, Register src)
void fistp_s(const Operand &adr)
void imul(Register src)
void addsd(XMMRegister dst, XMMRegister src)
const int kRegister_r12_Code
void shr_cl(Register dst)
void fld_d(const Operand &adr)
void addq(const Operand &dst, Immediate src)
static const int kNumRegisters
Definition: assembler-arm.h:73
void imull(Register dst, Register src)
void cmpb_al(const Operand &op)
void xchg(Register dst, Register src)
void fild_s(const Operand &adr)
EnsureSpace(Assembler *assembler)
void orl(Register dst, Register src)
void decl(Register dst)
void cmpl(const Operand &dst, Immediate src)
void shr(Register dst, Immediate shift_amount)
static const char * AllocationIndexToString(int index)
void idivl(Register src)
uint8_t byte
Definition: globals.h:156
const XMMRegister xmm14
void enter(const Immediate &size)
Condition ReverseCondition(Condition cond)
static const int kJumpInstructionLength
static const byte kJcShortOpcode
void testl(Register dst, Register src)
void movzxbq(Register dst, const Operand &src)
void shld(Register dst, Register src)
const XMMRegister xmm15
void subl(Register dst, const Operand &src)
void sbbl(Register dst, Register src)
DwVfpRegister DoubleRegister
void fisttp_d(const Operand &adr)
static const int kRealPatchReturnSequenceAddressOffset
void movss(XMMRegister dst, const Operand &src)
void movb(Register dst, const Operand &src)
void set_byte_at(int pos, byte value)
void cvtsd2ss(XMMRegister dst, XMMRegister src)
void negl(Register dst)
static const int kSpecialTargetSize
const XMMRegister xmm1
void cmpl(Register dst, const Operand &src)
const int kRegister_r11_Code
void or_(const Operand &dst, Immediate src)
void movsd(XMMRegister dst, XMMRegister src)
void GetCode(CodeDesc *desc)
const Register r9
void movdqa(XMMRegister dst, const Operand &src)
void andl(Register dst, Register src)
void rol(Register dst, Immediate imm8)
static const int kJSReturnSequenceLength
void sar(Register dst, Immediate shift_amount)
static const byte kNopByte
int available_space() const
void movsxbq(Register dst, const Operand &src)
static void set_target_address_at(Address pc, Address target)
static const byte kJzShortOpcode
void movmskpd(Register dst, XMMRegister src)
void subq(const Operand &dst, Immediate src)
void fisttp_s(const Operand &adr)
void subq(Register dst, Immediate src)
void addl(const Operand &dst, Register src)
void movzxwq(Register dst, const Operand &src)
const Register rbx
void subb(Register dst, Immediate src)
void cmpb(const Operand &dst, Immediate src)
static void set_external_target_at(Address instruction_payload, Address target)
void cmpq(Register dst, Immediate src)
const Register rsp
void movzxwl(Register dst, const Operand &src)
const XMMRegister xmm10
const Register pc
void addl(Register dst, Immediate src)
const Register r12
void not_(Register dst)
static Register from_code(int code)
void set_emit_debug_code(bool value)
const int kRegister_r8_Code
void cmpb(Register dst, Immediate src)
const Register rax
void emit_sse_operand(XMMRegister reg, const Operand &adr)
const Register r13
const Register rdi
void cvtqsi2sd(XMMRegister dst, const Operand &src)
const int kRegister_r15_Code
void xorps(XMMRegister dst, XMMRegister src)
static const int kCallTargetAddressOffset
#define BASE_EMBEDDED
Definition: allocation.h:68
const int kRegister_rsi_Code
void subl(const Operand &dst, Immediate src)
void andb(Register dst, Immediate src)
static const int kDebugBreakSlotLength
void Nop(int bytes=1)
void neg(Register dst)
void setcc(Condition cc, Register reg)
const int kRegister_rbx_Code
void fld_s(const Operand &adr)
static bool IsNop(Instr instr, int type=NON_MARKING_NOP)
const int kRegister_r10_Code
bool is_int32(int64_t x)
Definition: assembler-x64.h:53
void decq(Register dst)
const XMMRegister xmm3
void fstp_d(const Operand &adr)
void movw(Register reg, uint32_t immediate, Condition cond=al)
static const int kNumAllocatableRegisters
static int ToAllocationIndex(XMMRegister reg)
bool is_valid() const
void store_rax(void *dst, RelocInfo::Mode mode)
void cmpq(const Operand &dst, Immediate src)
void push_imm32(int32_t imm32)
void fistp_d(const Operand &adr)
bool is(Register reg) const
static Address target_address_at(Address pc)
void cvtsd2siq(Register dst, XMMRegister src)
static const byte kTestEaxByte
void orl(const Operand &dst, Immediate src)
static const byte kJncShortOpcode
void shrd(Register dst, Register src)
void movaps(XMMRegister dst, XMMRegister src)
void rcr(Register dst, Immediate imm8)
void RecordComment(const char *msg)
static void deserialization_set_special_target_at(Address instruction_payload, Address target)
const XMMRegister xmm11
void fstp_s(const Operand &adr)
void divsd(XMMRegister dst, XMMRegister src)
void shrl_cl(Register dst)
void lea(Register dst, const Operand &src)
static Address target_address_from_return_address(Address pc)
void fild_d(const Operand &adr)
void shll_cl(Register dst)
friend class PositionsRecorder
void shrl(Register dst, Immediate shift_amount)
const Register r8
static const int kNumAllocatableRegisters
Definition: assembler-arm.h:74
void andl(Register dst, Immediate src)
const Register rcx
Assembler(Isolate *isolate, void *buffer, int buffer_size)
void xorl(Register dst, Register src)
void movl(Register dst, Register src)
Condition NegateCondition(Condition cond)
#define ASSERT_EQ(v1, v2)
Definition: checks.h:271
void decb(Register dst)
const int kRegister_rdx_Code
static XMMRegister from_code(int code)
void cmpw(const Operand &dst, Register src)
const XMMRegister xmm9
void cmpq(Register dst, Register src)
void xor_(const Operand &dst, Register src)
void and_(Register dst, Immediate src)
void notl(Register dst)
void testq(const Operand &op, Register reg)
void sar_cl(Register dst)
void movd(XMMRegister dst, Register src)
void sbbq(Register dst, Register src)
PositionsRecorder * positions_recorder()
const uint32_t kMaxUInt32
Definition: globals.h:213
void fisub_s(const Operand &adr)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
void or_(Register dst, const Operand &src)
const Register r10
void extractps(Register dst, XMMRegister src, byte imm8)
static const byte kJnzShortOpcode
void cmpw(Register dst, Immediate src)
Handle< Object > code_target_object_handle_at(Address pc)
void subl(Register dst, Immediate src)
void cmpb(Register dst, const Operand &src)
const Register no_reg
void xor_(const Operand &dst, Immediate src)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
void subq(Register dst, const Operand &src)
static int ToAllocationIndex(Register reg)
const XMMRegister xmm8
void fist_s(const Operand &adr)
void cmpw(Register dst, Register src)
const XMMRegister xmm7
void rcl(Register dst, Immediate imm8)
bool is(XMMRegister reg) const
void and_(const Operand &dst, Immediate src)
const int kRegister_r9_Code
void movsxwq(Register dst, const Operand &src)
static const int kNumRegisters
const XMMRegister xmm2
void bts(Register dst, Register src)
void cmpq(const Operand &dst, Register src)
void sarl(Register dst, Immediate shift_amount)
void addl(Register dst, const Operand &src)
void cmovq(Condition cc, Register dst, Register src)
const int kRegister_rax_Code
static const int kPatchDebugBreakSlotAddressOffset
bool emit_debug_code() const
void subsd(XMMRegister dst, XMMRegister src)
const Register r15
bool uint_is_int32(uint64_t x)
Definition: assembler-x64.h:58
const int kRegister_rdi_Code
const int kRegister_no_reg_Code
void cvttsd2siq(Register dst, XMMRegister src)
void xor_(Register dst, Register src)
void movq(const Operand &dst, Register src)
void cmpl(const Operand &dst, Register src)
void addl(const Operand &dst, Immediate src)
void mul(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
void cvttsd2si(Register dst, const Operand &src)
void and_(Register dst, Register src)
void incq(Register dst)
void shl_cl(Register dst)
void leal(Register dst, const Operand &src)
const XMMRegister xmm0
const int MB
Definition: globals.h:208