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