V8 Project
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 "src/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  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
88  Register result = { kRegisterCodeByAllocationIndex[index] };
89  return result;
90  }
91 
92  static const char* AllocationIndexToString(int index) {
93  DCHECK(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  DCHECK(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:
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  // TODO(turbofan): Proper support for float32.
205  return NumAllocatableRegisters();
206  }
207 
208  static int ToAllocationIndex(XMMRegister reg) {
209  DCHECK(reg.code() != 0);
210  return reg.code() - 1;
211  }
212 
213  static XMMRegister FromAllocationIndex(int index) {
214  DCHECK(0 <= index && index < kMaxNumAllocatableRegisters);
215  XMMRegister result = { index + 1 };
216  return result;
217  }
218 
219  static const char* AllocationIndexToString(int index) {
220  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
221  const char* const names[] = {
222  "xmm1",
223  "xmm2",
224  "xmm3",
225  "xmm4",
226  "xmm5",
227  "xmm6",
228  "xmm7",
229  "xmm8",
230  "xmm9",
231  "xmm10",
232  "xmm11",
233  "xmm12",
234  "xmm13",
235  "xmm14",
236  "xmm15"
237  };
238  return names[index];
239  }
240 
241  static XMMRegister from_code(int code) {
242  DCHECK(code >= 0);
244  XMMRegister r = { code };
245  return r;
246  }
247  bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters; }
248  bool is(XMMRegister reg) const { return code_ == reg.code_; }
249  int code() const {
250  DCHECK(is_valid());
251  return code_;
252  }
253 
254  // Return the high bit of the register code as a 0 or 1. Used often
255  // when constructing the REX prefix byte.
256  int high_bit() const {
257  return code_ >> 3;
258  }
259  // Return the 3 low bits of the register code. Used when encoding registers
260  // in modR/M, SIB, and opcode bytes.
261  int low_bits() const {
262  return code_ & 0x7;
263  }
264 
265  int code_;
266 };
267 
268 const XMMRegister xmm0 = { 0 };
269 const XMMRegister xmm1 = { 1 };
270 const XMMRegister xmm2 = { 2 };
271 const XMMRegister xmm3 = { 3 };
272 const XMMRegister xmm4 = { 4 };
273 const XMMRegister xmm5 = { 5 };
274 const XMMRegister xmm6 = { 6 };
275 const XMMRegister xmm7 = { 7 };
276 const XMMRegister xmm8 = { 8 };
277 const XMMRegister xmm9 = { 9 };
278 const XMMRegister xmm10 = { 10 };
279 const XMMRegister xmm11 = { 11 };
280 const XMMRegister xmm12 = { 12 };
281 const XMMRegister xmm13 = { 13 };
282 const XMMRegister xmm14 = { 14 };
283 const XMMRegister xmm15 = { 15 };
284 
285 
286 typedef XMMRegister DoubleRegister;
287 
288 
289 enum Condition {
290  // any value < 0 is considered no_condition
291  no_condition = -1,
292 
293  overflow = 0,
294  no_overflow = 1,
295  below = 2,
296  above_equal = 3,
297  equal = 4,
298  not_equal = 5,
299  below_equal = 6,
300  above = 7,
301  negative = 8,
302  positive = 9,
303  parity_even = 10,
304  parity_odd = 11,
305  less = 12,
306  greater_equal = 13,
307  less_equal = 14,
308  greater = 15,
309 
310  // Fake conditions that are handled by the
311  // opcodes using them.
312  always = 16,
313  never = 17,
314  // aliases
315  carry = below,
317  zero = equal,
319  sign = negative,
320  not_sign = positive,
322 };
323 
324 
325 // Returns the equivalent of !cc.
326 // Negation of the default no_condition (-1) results in a non-default
327 // no_condition value (-2). As long as tests for no_condition check
328 // for condition < 0, this will work as expected.
330  return static_cast<Condition>(cc ^ 1);
331 }
332 
333 
334 // Commute a condition such that {a cond b == b cond' a}.
336  switch (cc) {
337  case below:
338  return above;
339  case above:
340  return below;
341  case above_equal:
342  return below_equal;
343  case below_equal:
344  return above_equal;
345  case less:
346  return greater;
347  case greater:
348  return less;
349  case greater_equal:
350  return less_equal;
351  case less_equal:
352  return greater_equal;
353  default:
354  return cc;
355  }
356 }
357 
358 
359 // -----------------------------------------------------------------------------
360 // Machine instruction Immediates
361 
362 class Immediate BASE_EMBEDDED {
363  public:
365  explicit Immediate(Smi* value) {
366  DCHECK(SmiValuesAre31Bits()); // Only available for 31-bit SMI.
367  value_ = static_cast<int32_t>(reinterpret_cast<intptr_t>(value));
368  }
369 
370  private:
372 
373  friend class Assembler;
374 };
375 
376 
377 // -----------------------------------------------------------------------------
378 // Machine instruction Operands
379 
381  times_1 = 0,
382  times_2 = 1,
383  times_4 = 2,
384  times_8 = 3,
387 };
388 
389 
390 class Operand BASE_EMBEDDED {
391  public:
392  // [base + disp/r]
393  Operand(Register base, int32_t disp);
394 
395  // [base + index*scale + disp/r]
397  Register index,
398  ScaleFactor scale,
399  int32_t disp);
400 
401  // [index*scale + disp/r]
403  ScaleFactor scale,
404  int32_t disp);
405 
406  // Offset from existing memory operand.
407  // Offset is added to existing displacement as 32-bit signed values and
408  // this must not overflow.
409  Operand(const Operand& base, int32_t offset);
410 
411  // Checks whether either base or index register is the given register.
412  // Does not check the "reg" part of the Operand.
414 
415  // Queries related to the size of the generated instruction.
416  // Whether the generated instruction will have a REX prefix.
417  bool requires_rex() const { return rex_ != 0; }
418  // Size of the ModR/M, SIB and displacement parts of the generated
419  // instruction.
420  int operand_size() const { return len_; }
421 
422  private:
423  byte rex_;
424  byte buf_[6];
425  // The number of bytes of buf_ in use.
426  byte len_;
427 
428  // Set the ModR/M byte without an encoded 'reg' register. The
429  // register is encoded later as part of the emit_operand operation.
430  // set_modrm can be called before or after set_sib and set_disp*.
431  inline void set_modrm(int mod, Register rm);
432 
433  // Set the SIB byte if one is needed. Sets the length to 2 rather than 1.
434  inline void set_sib(ScaleFactor scale, Register index, Register base);
435 
436  // Adds operand displacement fields (offsets added to the memory address).
437  // Needs to be called after set_sib, not before it.
438  inline void set_disp8(int disp);
439  inline void set_disp32(int disp);
440 
441  friend class Assembler;
442 };
443 
444 
445 #define ASSEMBLER_INSTRUCTION_LIST(V) \
446  V(add) \
447  V(and) \
448  V(cmp) \
449  V(dec) \
450  V(idiv) \
451  V(div) \
452  V(imul) \
453  V(inc) \
454  V(lea) \
455  V(mov) \
456  V(movzxb) \
457  V(movzxw) \
458  V(neg) \
459  V(not) \
460  V(or) \
461  V(repmovs) \
462  V(sbb) \
463  V(sub) \
464  V(test) \
465  V(xchg) \
466  V(xor)
467 
468 
469 // Shift instructions on operands/registers with kPointerSize, kInt32Size and
470 // kInt64Size.
471 #define SHIFT_INSTRUCTION_LIST(V) \
472  V(rol, 0x0) \
473  V(ror, 0x1) \
474  V(rcl, 0x2) \
475  V(rcr, 0x3) \
476  V(shl, 0x4) \
477  V(shr, 0x5) \
478  V(sar, 0x7) \
479 
480 
481 class Assembler : public AssemblerBase {
482  private:
483  // We check before assembling an instruction that there is sufficient
484  // space to write an instruction and its relocation information.
485  // The relocation writer's position must be kGap bytes above the end of
486  // the generated instructions. This leaves enough space for the
487  // longest possible x64 instruction, 15 bytes, and the longest possible
488  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
489  // (There is a 15 byte limit on x64 instruction length that rules out some
490  // otherwise valid instructions.)
491  // This allows for a single, fast space check per instruction.
492  static const int kGap = 32;
493 
494  public:
495  // Create an assembler. Instructions and relocation information are emitted
496  // into a buffer, with the instructions starting from the beginning and the
497  // relocation information starting from the end of the buffer. See CodeDesc
498  // for a detailed comment on the layout (globals.h).
499  //
500  // If the provided buffer is NULL, the assembler allocates and grows its own
501  // buffer, and buffer_size determines the initial buffer size. The buffer is
502  // owned by the assembler and deallocated upon destruction of the assembler.
503  //
504  // If the provided buffer is not NULL, the assembler uses the provided buffer
505  // for code generation and assumes its size to be buffer_size. If the buffer
506  // is too small, a fatal error occurs. No deallocation of the buffer is done
507  // upon destruction of the assembler.
508  Assembler(Isolate* isolate, void* buffer, int buffer_size);
509  virtual ~Assembler() { }
510 
511  // GetCode emits any pending (non-emitted) code and fills the descriptor
512  // desc. GetCode() is idempotent; it returns the same result if no other
513  // Assembler functions are invoked in between GetCode() calls.
514  void GetCode(CodeDesc* desc);
515 
516  // Read/Modify the code target in the relative branch/call instruction at pc.
517  // On the x64 architecture, we use relative jumps with a 32-bit displacement
518  // to jump to other Code objects in the Code space in the heap.
519  // Jumps to C functions are done indirectly through a 64-bit register holding
520  // the absolute address of the target.
521  // These functions convert between absolute Addresses of Code objects and
522  // the relative displacements stored in the code.
524  ConstantPoolArray* constant_pool);
525  static inline void set_target_address_at(Address pc,
526  ConstantPoolArray* constant_pool,
527  Address target,
528  ICacheFlushMode icache_flush_mode =
530  static inline Address target_address_at(Address pc, Code* code) {
531  ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
532  return target_address_at(pc, constant_pool);
533  }
534  static inline void set_target_address_at(Address pc,
535  Code* code,
536  Address target,
537  ICacheFlushMode icache_flush_mode =
539  ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
540  set_target_address_at(pc, constant_pool, target, icache_flush_mode);
541  }
542 
543  // Return the code target address at a call site from the return address
544  // of that call in the instruction stream.
546 
547  // Return the code target address of the patch debug break slot
549 
550  // This sets the branch destination (which is in the instruction on x64).
551  // This is for calls and branches within generated code.
553  Address instruction_payload, Code* code, Address target) {
554  set_target_address_at(instruction_payload, code, target);
555  }
556 
557  static inline RelocInfo::Mode RelocInfoNone() {
558  if (kPointerSize == kInt64Size) {
559  return RelocInfo::NONE64;
560  } else {
562  return RelocInfo::NONE32;
563  }
564  }
565 
568  // Number of bytes taken up by the branch target in the code.
569  static const int kSpecialTargetSize = 4; // Use 32-bit displacement.
570  // Distance between the address of the code target in the call instruction
571  // and the return address pushed on the stack.
572  static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement.
573  // The length of call(kScratchRegister).
575  // The length of call(Immediate32).
576  static const int kShortCallInstructionLength = 5;
577  // The length of movq(kScratchRegister, address).
579  2 + kPointerSize;
580  // The length of movq(kScratchRegister, address) and call(kScratchRegister).
581  static const int kCallSequenceLength =
584 
585  // The js return and debug break slot must be able to contain an indirect
586  // call sequence, some x64 JS code is padded with int3 to make it large
587  // enough to hold an instruction when the debugger patches it.
588  static const int kJSReturnSequenceLength = kCallSequenceLength;
589  static const int kDebugBreakSlotLength = kCallSequenceLength;
591  // Distance between the start of the JS return sequence and where the
592  // 32-bit displacement of a short call would be. The short call is from
593  // SetDebugBreakAtIC from debug-x64.cc.
594  static const int kPatchReturnSequenceAddressOffset =
596  // Distance between the start of the JS return sequence and where the
597  // 32-bit displacement of a short call would be. The short call is from
598  // SetDebugBreakAtIC from debug-x64.cc.
599  static const int kPatchDebugBreakSlotAddressOffset =
603 
604  // One byte opcode for test eax,0xXXXXXXXX.
605  static const byte kTestEaxByte = 0xA9;
606  // One byte opcode for test al, 0xXX.
607  static const byte kTestAlByte = 0xA8;
608  // One byte opcode for nop.
609  static const byte kNopByte = 0x90;
610 
611  // One byte prefix for a short conditional jump.
612  static const byte kJccShortPrefix = 0x70;
613  static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
614  static const byte kJcShortOpcode = kJccShortPrefix | carry;
615  static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
616  static const byte kJzShortOpcode = kJccShortPrefix | zero;
617 
618 
619  // ---------------------------------------------------------------------------
620  // Code generation
621  //
622  // Function names correspond one-to-one to x64 instruction mnemonics.
623  // Unless specified otherwise, instructions operate on 64-bit operands.
624  //
625  // If we need versions of an assembly instruction that operate on different
626  // width arguments, we add a single-letter suffix specifying the width.
627  // This is done for the following instructions: mov, cmp, inc, dec,
628  // add, sub, and test.
629  // There are no versions of these instructions without the suffix.
630  // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
631  // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
632  // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
633  // - Instructions on 64-bit (quadword) operands/registers use 'q'.
634  // - Instructions on operands/registers with pointer size use 'p'.
635 
637 
638 #define DECLARE_INSTRUCTION(instruction) \
639  template<class P1> \
640  void instruction##p(P1 p1) { \
641  emit_##instruction(p1, kPointerSize); \
642  } \
643  \
644  template<class P1> \
645  void instruction##l(P1 p1) { \
646  emit_##instruction(p1, kInt32Size); \
647  } \
648  \
649  template<class P1> \
650  void instruction##q(P1 p1) { \
651  emit_##instruction(p1, kInt64Size); \
652  } \
653  \
654  template<class P1, class P2> \
655  void instruction##p(P1 p1, P2 p2) { \
656  emit_##instruction(p1, p2, kPointerSize); \
657  } \
658  \
659  template<class P1, class P2> \
660  void instruction##l(P1 p1, P2 p2) { \
661  emit_##instruction(p1, p2, kInt32Size); \
662  } \
663  \
664  template<class P1, class P2> \
665  void instruction##q(P1 p1, P2 p2) { \
666  emit_##instruction(p1, p2, kInt64Size); \
667  } \
668  \
669  template<class P1, class P2, class P3> \
670  void instruction##p(P1 p1, P2 p2, P3 p3) { \
671  emit_##instruction(p1, p2, p3, kPointerSize); \
672  } \
673  \
674  template<class P1, class P2, class P3> \
675  void instruction##l(P1 p1, P2 p2, P3 p3) { \
676  emit_##instruction(p1, p2, p3, kInt32Size); \
677  } \
678  \
679  template<class P1, class P2, class P3> \
680  void instruction##q(P1 p1, P2 p2, P3 p3) { \
681  emit_##instruction(p1, p2, p3, kInt64Size); \
682  }
684 #undef DECLARE_INSTRUCTION
685 
686  // Insert the smallest number of nop instructions
687  // possible to align the pc offset to a multiple
688  // of m, where m must be a power of 2.
689  void Align(int m);
690  void Nop(int bytes = 1);
691  // Aligns code to something that's optimal for a jump target for the platform.
693 
694  // Stack
695  void pushfq();
696  void popfq();
697 
698  void pushq(Immediate value);
699  // Push a 32 bit integer, and guarantee that it is actually pushed as a
700  // 32 bit value, the normal push will optimize the 8 bit case.
701  void pushq_imm32(int32_t imm32);
702  void pushq(Register src);
703  void pushq(const Operand& src);
704 
705  void popq(Register dst);
706  void popq(const Operand& dst);
707 
709  void leave();
710 
711  // Moves
712  void movb(Register dst, const Operand& src);
713  void movb(Register dst, Immediate imm);
714  void movb(const Operand& dst, Register src);
715  void movb(const Operand& dst, Immediate imm);
716 
717  // Move the low 16 bits of a 64-bit register value to a 16-bit
718  // memory location.
719  void movw(Register dst, const Operand& src);
720  void movw(const Operand& dst, Register src);
721  void movw(const Operand& dst, Immediate imm);
722 
723  // Move the offset of the label location relative to the current
724  // position (after the move) to the destination.
725  void movl(const Operand& dst, Label* src);
726 
727  // Loads a pointer into a register with a relocation mode.
728  void movp(Register dst, void* ptr, RelocInfo::Mode rmode);
729 
730  // Loads a 64-bit immediate into a register.
731  void movq(Register dst, int64_t value);
732  void movq(Register dst, uint64_t value);
733 
734  void movsxbl(Register dst, const Operand& src);
735  void movsxbq(Register dst, const Operand& src);
736  void movsxwl(Register dst, const Operand& src);
737  void movsxwq(Register dst, const Operand& src);
738  void movsxlq(Register dst, Register src);
739  void movsxlq(Register dst, const Operand& src);
740 
741  // Repeated moves.
742 
743  void repmovsb();
744  void repmovsw();
748 
749  // Instruction to load from an immediate 64-bit pointer into RAX.
750  void load_rax(void* ptr, RelocInfo::Mode rmode);
751  void load_rax(ExternalReference ext);
752 
753  // Conditional moves.
754  void cmovq(Condition cc, Register dst, Register src);
755  void cmovq(Condition cc, Register dst, const Operand& src);
756  void cmovl(Condition cc, Register dst, Register src);
757  void cmovl(Condition cc, Register dst, const Operand& src);
758 
759  void cmpb(Register dst, Immediate src) {
760  immediate_arithmetic_op_8(0x7, dst, src);
761  }
762 
763  void cmpb_al(Immediate src);
764 
765  void cmpb(Register dst, Register src) {
766  arithmetic_op_8(0x3A, dst, src);
767  }
768 
769  void cmpb(Register dst, const Operand& src) {
770  arithmetic_op_8(0x3A, dst, src);
771  }
772 
773  void cmpb(const Operand& dst, Register src) {
774  arithmetic_op_8(0x38, src, dst);
775  }
776 
777  void cmpb(const Operand& dst, Immediate src) {
778  immediate_arithmetic_op_8(0x7, dst, src);
779  }
780 
781  void cmpw(const Operand& dst, Immediate src) {
782  immediate_arithmetic_op_16(0x7, dst, src);
783  }
784 
785  void cmpw(Register dst, Immediate src) {
786  immediate_arithmetic_op_16(0x7, dst, src);
787  }
788 
789  void cmpw(Register dst, const Operand& src) {
790  arithmetic_op_16(0x3B, dst, src);
791  }
792 
793  void cmpw(Register dst, Register src) {
794  arithmetic_op_16(0x3B, dst, src);
795  }
796 
797  void cmpw(const Operand& dst, Register src) {
798  arithmetic_op_16(0x39, src, dst);
799  }
800 
801  void andb(Register dst, Immediate src) {
802  immediate_arithmetic_op_8(0x4, dst, src);
803  }
804 
805  void decb(Register dst);
806  void decb(const Operand& dst);
807 
808  // Sign-extends rax into rdx:rax.
809  void cqo();
810  // Sign-extends eax into edx:eax.
811  void cdq();
812 
813  // Multiply rax by src, put the result in rdx:rax.
814  void mul(Register src);
815 
816 #define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \
817  void instruction##p(Register dst, Immediate imm8) { \
818  shift(dst, imm8, subcode, kPointerSize); \
819  } \
820  \
821  void instruction##l(Register dst, Immediate imm8) { \
822  shift(dst, imm8, subcode, kInt32Size); \
823  } \
824  \
825  void instruction##q(Register dst, Immediate imm8) { \
826  shift(dst, imm8, subcode, kInt64Size); \
827  } \
828  \
829  void instruction##p_cl(Register dst) { \
830  shift(dst, subcode, kPointerSize); \
831  } \
832  \
833  void instruction##l_cl(Register dst) { \
834  shift(dst, subcode, kInt32Size); \
835  } \
836  \
837  void instruction##q_cl(Register dst) { \
838  shift(dst, subcode, kInt64Size); \
839  }
841 #undef DECLARE_SHIFT_INSTRUCTION
842 
843  // Shifts dst:src left by cl bits, affecting only dst.
844  void shld(Register dst, Register src);
845 
846  // Shifts src:dst right by cl bits, affecting only dst.
847  void shrd(Register dst, Register src);
848 
849  void store_rax(void* dst, RelocInfo::Mode mode);
850  void store_rax(ExternalReference ref);
851 
852  void subb(Register dst, Immediate src) {
853  immediate_arithmetic_op_8(0x5, dst, src);
854  }
855 
856  void testb(Register dst, Register src);
857  void testb(Register reg, Immediate mask);
858  void testb(const Operand& op, Immediate mask);
859  void testb(const Operand& op, Register reg);
860 
861  // Bit operations.
862  void bt(const Operand& dst, Register src);
863  void bts(const Operand& dst, Register src);
864  void bsrl(Register dst, Register src);
865 
866  // Miscellaneous
867  void clc();
868  void cld();
869  void cpuid();
870  void hlt();
871  void int3();
872  void nop();
873  void ret(int imm16);
875 
876  // Label operations & relative jumps (PPUM Appendix D)
877  //
878  // Takes a branch opcode (cc) and a label (L) and generates
879  // either a backward branch or a forward branch and links it
880  // to the label fixup chain. Usage:
881  //
882  // Label L; // unbound label
883  // j(cc, &L); // forward branch to unbound label
884  // bind(&L); // bind label to the current pc
885  // j(cc, &L); // backward branch to bound label
886  // bind(&L); // illegal: a label may be bound only once
887  //
888  // Note: The same Label can be used for forward and backward branches
889  // but it may be bound only once.
890 
891  void bind(Label* L); // binds an unbound label L to the current code position
892 
893  // Calls
894  // Call near relative 32-bit displacement, relative to next instruction.
895  void call(Label* L);
896  void call(Address entry, RelocInfo::Mode rmode);
897  void call(Handle<Code> target,
900 
901  // Calls directly to the given address using a relative offset.
902  // Should only ever be used in Code objects for calls within the
903  // same Code object. Should not be used when generating new code (use labels),
904  // but only when patching existing code.
905  void call(Address target);
906 
907  // Call near absolute indirect, address in register
909 
910  // Jumps
911  // Jump short or near relative.
912  // Use a 32-bit signed displacement.
913  // Unconditional jump to L
914  void jmp(Label* L, Label::Distance distance = Label::kFar);
915  void jmp(Address entry, RelocInfo::Mode rmode);
916  void jmp(Handle<Code> target, RelocInfo::Mode rmode);
917 
918  // Jump near absolute indirect (r64)
919  void jmp(Register adr);
920 
921  // Conditional jumps
922  void j(Condition cc,
923  Label* L,
924  Label::Distance distance = Label::kFar);
925  void j(Condition cc, Address entry, RelocInfo::Mode rmode);
926  void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
927 
928  // Floating-point operations
929  void fld(int i);
930 
931  void fld1();
932  void fldz();
933  void fldpi();
934  void fldln2();
935 
936  void fld_s(const Operand& adr);
937  void fld_d(const Operand& adr);
938 
939  void fstp_s(const Operand& adr);
940  void fstp_d(const Operand& adr);
941  void fstp(int index);
942 
943  void fild_s(const Operand& adr);
944  void fild_d(const Operand& adr);
945 
946  void fist_s(const Operand& adr);
947 
948  void fistp_s(const Operand& adr);
949  void fistp_d(const Operand& adr);
950 
951  void fisttp_s(const Operand& adr);
952  void fisttp_d(const Operand& adr);
953 
954  void fabs();
955  void fchs();
956 
957  void fadd(int i);
958  void fsub(int i);
959  void fmul(int i);
960  void fdiv(int i);
961 
962  void fisub_s(const Operand& adr);
963 
964  void faddp(int i = 1);
965  void fsubp(int i = 1);
966  void fsubrp(int i = 1);
967  void fmulp(int i = 1);
968  void fdivp(int i = 1);
969  void fprem();
970  void fprem1();
971 
972  void fxch(int i = 1);
973  void fincstp();
974  void ffree(int i = 0);
975 
976  void ftst();
977  void fucomp(int i);
978  void fucompp();
979  void fucomi(int i);
980  void fucomip();
981 
982  void fcompp();
983  void fnstsw_ax();
984  void fwait();
985  void fnclex();
986 
987  void fsin();
988  void fcos();
989  void fptan();
990  void fyl2x();
991  void f2xm1();
992  void fscale();
993  void fninit();
994 
995  void frndint();
996 
997  void sahf();
998 
999  // SSE instructions
1001  void movss(XMMRegister dst, const Operand& src);
1002  void movss(const Operand& dst, XMMRegister src);
1003  void shufps(XMMRegister dst, XMMRegister src, byte imm8);
1004 
1005  void cvttss2si(Register dst, const Operand& src);
1008 
1010  void andps(XMMRegister dst, const Operand& src);
1011  void orps(XMMRegister dst, XMMRegister src);
1012  void orps(XMMRegister dst, const Operand& src);
1014  void xorps(XMMRegister dst, const Operand& src);
1015 
1017  void addps(XMMRegister dst, const Operand& src);
1019  void subps(XMMRegister dst, const Operand& src);
1021  void mulps(XMMRegister dst, const Operand& src);
1023  void divps(XMMRegister dst, const Operand& src);
1024 
1026 
1027  // SSE2 instructions
1028  void movd(XMMRegister dst, Register src);
1029  void movd(Register dst, XMMRegister src);
1030  void movq(XMMRegister dst, Register src);
1031  void movq(Register dst, XMMRegister src);
1032  void movq(XMMRegister dst, XMMRegister src);
1033 
1034  // Don't use this unless it's important to keep the
1035  // top half of the destination register unchanged.
1036  // Used movaps when moving double values and movq for integer
1037  // values in xmm registers.
1039 
1040  void movsd(const Operand& dst, XMMRegister src);
1041  void movsd(XMMRegister dst, const Operand& src);
1042 
1043  void movdqa(const Operand& dst, XMMRegister src);
1044  void movdqa(XMMRegister dst, const Operand& src);
1045 
1046  void movdqu(const Operand& dst, XMMRegister src);
1047  void movdqu(XMMRegister dst, const Operand& src);
1048 
1050 
1051  void psllq(XMMRegister reg, byte imm8);
1052 
1053  void cvttsd2si(Register dst, const Operand& src);
1056  void cvttsd2siq(Register dst, const Operand& src);
1057 
1058  void cvtlsi2sd(XMMRegister dst, const Operand& src);
1060  void cvtqsi2sd(XMMRegister dst, const Operand& src);
1062 
1063 
1065  void cvtss2sd(XMMRegister dst, const Operand& src);
1067 
1070 
1072  void addsd(XMMRegister dst, const Operand& src);
1075  void mulsd(XMMRegister dst, const Operand& src);
1077 
1079  void orpd(XMMRegister dst, XMMRegister src);
1082  void sqrtsd(XMMRegister dst, const Operand& src);
1083 
1085  void ucomisd(XMMRegister dst, const Operand& src);
1087 
1089 
1090  // SSE 4.1 instruction
1091  void extractps(Register dst, XMMRegister src, byte imm8);
1092 
1094  kRoundToNearest = 0x0,
1095  kRoundDown = 0x1,
1096  kRoundUp = 0x2,
1097  kRoundToZero = 0x3
1098  };
1099 
1101 
1102  // Debugging
1103  void Print();
1104 
1105  // Check the code size generated from label to here.
1106  int SizeOfCodeGeneratedSince(Label* label) {
1107  return pc_offset() - label->pos();
1108  }
1109 
1110  // Mark address of the ExitJSFrame code.
1112 
1113  // Mark address of a debug break slot.
1115 
1116  // Record a comment relocation entry that can be used by a disassembler.
1117  // Use --code-comments to enable.
1118  void RecordComment(const char* msg, bool force = false);
1119 
1120  // Allocate a constant pool of the correct size for the generated code.
1122 
1123  // Generate the constant pool for the generated code.
1125 
1126  // Writes a single word of data in the code stream.
1127  // Used for inline tables, e.g., jump-tables.
1128  void db(uint8_t data);
1129  void dd(uint32_t data);
1130 
1132 
1133  // Check if there is less than kGap bytes available in the buffer.
1134  // If this is the case, we need to grow the buffer before emitting
1135  // an instruction or relocation information.
1136  inline bool buffer_overflow() const {
1137  return pc_ >= reloc_info_writer.pos() - kGap;
1138  }
1139 
1140  // Get the number of bytes available in the buffer.
1141  inline int available_space() const {
1142  return static_cast<int>(reloc_info_writer.pos() - pc_);
1143  }
1144 
1145  static bool IsNop(Address addr);
1146 
1147  // Avoid overflows for displacements etc.
1148  static const int kMaximalBufferSize = 512*MB;
1149 
1150  byte byte_at(int pos) { return buffer_[pos]; }
1151  void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
1152 
1153  protected:
1154  // Call near indirect
1155  void call(const Operand& operand);
1156 
1157  // Jump near absolute indirect (m64)
1158  void jmp(const Operand& src);
1159 
1160  private:
1161  byte* addr_at(int pos) { return buffer_ + pos; }
1162  uint32_t long_at(int pos) {
1163  return *reinterpret_cast<uint32_t*>(addr_at(pos));
1164  }
1165  void long_at_put(int pos, uint32_t x) {
1166  *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
1167  }
1168 
1169  // code emission
1170  void GrowBuffer();
1171 
1172  void emit(byte x) { *pc_++ = x; }
1173  inline void emitl(uint32_t x);
1174  inline void emitp(void* x, RelocInfo::Mode rmode);
1175  inline void emitq(uint64_t x);
1176  inline void emitw(uint16_t x);
1177  inline void emit_code_target(Handle<Code> target,
1178  RelocInfo::Mode rmode,
1180  inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode);
1181  void emit(Immediate x) { emitl(x.value_); }
1182 
1183  // Emits a REX prefix that encodes a 64-bit operand size and
1184  // the top bit of both register codes.
1185  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1186  // REX.W is set.
1187  inline void emit_rex_64(XMMRegister reg, Register rm_reg);
1188  inline void emit_rex_64(Register reg, XMMRegister rm_reg);
1189  inline void emit_rex_64(Register reg, Register rm_reg);
1190 
1191  // Emits a REX prefix that encodes a 64-bit operand size and
1192  // the top bit of the destination, index, and base register codes.
1193  // The high bit of reg is used for REX.R, the high bit of op's base
1194  // register is used for REX.B, and the high bit of op's index register
1195  // is used for REX.X. REX.W is set.
1196  inline void emit_rex_64(Register reg, const Operand& op);
1197  inline void emit_rex_64(XMMRegister reg, const Operand& op);
1198 
1199  // Emits a REX prefix that encodes a 64-bit operand size and
1200  // the top bit of the register code.
1201  // The high bit of register is used for REX.B.
1202  // REX.W is set and REX.R and REX.X are clear.
1203  inline void emit_rex_64(Register rm_reg);
1204 
1205  // Emits a REX prefix that encodes a 64-bit operand size and
1206  // the top bit of the index and base register codes.
1207  // The high bit of op's base register is used for REX.B, and the high
1208  // bit of op's index register is used for REX.X.
1209  // REX.W is set and REX.R clear.
1210  inline void emit_rex_64(const Operand& op);
1211 
1212  // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
1213  void emit_rex_64() { emit(0x48); }
1214 
1215  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1216  // REX.W is clear.
1217  inline void emit_rex_32(Register reg, Register rm_reg);
1218 
1219  // The high bit of reg is used for REX.R, the high bit of op's base
1220  // register is used for REX.B, and the high bit of op's index register
1221  // is used for REX.X. REX.W is cleared.
1222  inline void emit_rex_32(Register reg, const Operand& op);
1223 
1224  // High bit of rm_reg goes to REX.B.
1225  // REX.W, REX.R and REX.X are clear.
1226  inline void emit_rex_32(Register rm_reg);
1227 
1228  // High bit of base goes to REX.B and high bit of index to REX.X.
1229  // REX.W and REX.R are clear.
1230  inline void emit_rex_32(const Operand& op);
1231 
1232  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1233  // REX.W is cleared. If no REX bits are set, no byte is emitted.
1234  inline void emit_optional_rex_32(Register reg, Register rm_reg);
1235 
1236  // The high bit of reg is used for REX.R, the high bit of op's base
1237  // register is used for REX.B, and the high bit of op's index register
1238  // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing
1239  // is emitted.
1240  inline void emit_optional_rex_32(Register reg, const Operand& op);
1241 
1242  // As for emit_optional_rex_32(Register, Register), except that
1243  // the registers are XMM registers.
1244  inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
1245 
1246  // As for emit_optional_rex_32(Register, Register), except that
1247  // one of the registers is an XMM registers.
1248  inline void emit_optional_rex_32(XMMRegister reg, Register base);
1249 
1250  // As for emit_optional_rex_32(Register, Register), except that
1251  // one of the registers is an XMM registers.
1252  inline void emit_optional_rex_32(Register reg, XMMRegister base);
1253 
1254  // As for emit_optional_rex_32(Register, const Operand&), except that
1255  // the register is an XMM register.
1256  inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);
1257 
1258  // Optionally do as emit_rex_32(Register) if the register number has
1259  // the high bit set.
1260  inline void emit_optional_rex_32(Register rm_reg);
1261 
1262  // Optionally do as emit_rex_32(const Operand&) if the operand register
1263  // numbers have a high bit set.
1264  inline void emit_optional_rex_32(const Operand& op);
1265 
1266  void emit_rex(int size) {
1267  if (size == kInt64Size) {
1268  emit_rex_64();
1269  } else {
1270  DCHECK(size == kInt32Size);
1271  }
1272  }
1273 
1274  template<class P1>
1275  void emit_rex(P1 p1, int size) {
1276  if (size == kInt64Size) {
1277  emit_rex_64(p1);
1278  } else {
1279  DCHECK(size == kInt32Size);
1281  }
1282  }
1283 
1284  template<class P1, class P2>
1285  void emit_rex(P1 p1, P2 p2, int size) {
1286  if (size == kInt64Size) {
1287  emit_rex_64(p1, p2);
1288  } else {
1289  DCHECK(size == kInt32Size);
1291  }
1292  }
1293 
1294  // Emit the ModR/M byte, and optionally the SIB byte and
1295  // 1- or 4-byte offset for a memory operand. Also encodes
1296  // the second operand of the operation, a register or operation
1297  // subcode, into the reg field of the ModR/M byte.
1298  void emit_operand(Register reg, const Operand& adr) {
1299  emit_operand(reg.low_bits(), adr);
1300  }
1301 
1302  // Emit the ModR/M byte, and optionally the SIB byte and
1303  // 1- or 4-byte offset for a memory operand. Also used to encode
1304  // a three-bit opcode extension into the ModR/M byte.
1305  void emit_operand(int rm, const Operand& adr);
1306 
1307  // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
1308  void emit_modrm(Register reg, Register rm_reg) {
1309  emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
1310  }
1311 
1312  // Emit a ModR/M byte with an operation subcode in the reg field and
1313  // a register in the rm_reg field.
1314  void emit_modrm(int code, Register rm_reg) {
1315  DCHECK(is_uint3(code));
1316  emit(0xC0 | code << 3 | rm_reg.low_bits());
1317  }
1318 
1319  // Emit the code-object-relative offset of the label's position
1320  inline void emit_code_relative_offset(Label* label);
1321 
1322  // The first argument is the reg field, the second argument is the r/m field.
1328 
1329  // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
1330  // AND, OR, XOR, or CMP. The encodings of these operations are all
1331  // similar, differing just in the opcode or in the reg field of the
1332  // ModR/M byte.
1333  void arithmetic_op_8(byte opcode, Register reg, Register rm_reg);
1334  void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg);
1335  void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
1336  void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
1337  // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
1338  void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size);
1339  void arithmetic_op(byte opcode,
1340  Register reg,
1341  const Operand& rm_reg,
1342  int size);
1343  // Operate on a byte in memory or register.
1344  void immediate_arithmetic_op_8(byte subcode,
1345  Register dst,
1346  Immediate src);
1347  void immediate_arithmetic_op_8(byte subcode,
1348  const Operand& dst,
1349  Immediate src);
1350  // Operate on a word in memory or register.
1351  void immediate_arithmetic_op_16(byte subcode,
1352  Register dst,
1353  Immediate src);
1354  void immediate_arithmetic_op_16(byte subcode,
1355  const Operand& dst,
1356  Immediate src);
1357  // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
1358  void immediate_arithmetic_op(byte subcode,
1359  Register dst,
1360  Immediate src,
1361  int size);
1362  void immediate_arithmetic_op(byte subcode,
1363  const Operand& dst,
1364  Immediate src,
1365  int size);
1366 
1367  // Emit machine code for a shift operation.
1368  void shift(Register dst, Immediate shift_amount, int subcode, int size);
1369  // Shift dst by cl % 64 bits.
1370  void shift(Register dst, int subcode, int size);
1371 
1372  void emit_farith(int b1, int b2, int i);
1373 
1374  // labels
1375  // void print(Label* L);
1376  void bind_to(Label* L, int pos);
1377 
1378  // record reloc info for current pc_
1379  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1380 
1381  // Arithmetics
1382  void emit_add(Register dst, Register src, int size) {
1383  arithmetic_op(0x03, dst, src, size);
1384  }
1385 
1386  void emit_add(Register dst, Immediate src, int size) {
1387  immediate_arithmetic_op(0x0, dst, src, size);
1388  }
1389 
1390  void emit_add(Register dst, const Operand& src, int size) {
1391  arithmetic_op(0x03, dst, src, size);
1392  }
1393 
1394  void emit_add(const Operand& dst, Register src, int size) {
1395  arithmetic_op(0x1, src, dst, size);
1396  }
1397 
1398  void emit_add(const Operand& dst, Immediate src, int size) {
1399  immediate_arithmetic_op(0x0, dst, src, size);
1400  }
1401 
1402  void emit_and(Register dst, Register src, int size) {
1403  arithmetic_op(0x23, dst, src, size);
1404  }
1405 
1406  void emit_and(Register dst, const Operand& src, int size) {
1407  arithmetic_op(0x23, dst, src, size);
1408  }
1409 
1410  void emit_and(const Operand& dst, Register src, int size) {
1411  arithmetic_op(0x21, src, dst, size);
1412  }
1413 
1414  void emit_and(Register dst, Immediate src, int size) {
1415  immediate_arithmetic_op(0x4, dst, src, size);
1416  }
1417 
1418  void emit_and(const Operand& dst, Immediate src, int size) {
1419  immediate_arithmetic_op(0x4, dst, src, size);
1420  }
1421 
1422  void emit_cmp(Register dst, Register src, int size) {
1423  arithmetic_op(0x3B, dst, src, size);
1424  }
1425 
1426  void emit_cmp(Register dst, const Operand& src, int size) {
1427  arithmetic_op(0x3B, dst, src, size);
1428  }
1429 
1430  void emit_cmp(const Operand& dst, Register src, int size) {
1431  arithmetic_op(0x39, src, dst, size);
1432  }
1433 
1434  void emit_cmp(Register dst, Immediate src, int size) {
1435  immediate_arithmetic_op(0x7, dst, src, size);
1436  }
1437 
1438  void emit_cmp(const Operand& dst, Immediate src, int size) {
1439  immediate_arithmetic_op(0x7, dst, src, size);
1440  }
1441 
1442  void emit_dec(Register dst, int size);
1443  void emit_dec(const Operand& dst, int size);
1444 
1445  // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64.
1446  // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx
1447  // when size is 32.
1448  void emit_idiv(Register src, int size);
1449  void emit_div(Register src, int size);
1450 
1451  // Signed multiply instructions.
1452  // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32.
1453  void emit_imul(Register src, int size);
1454  void emit_imul(Register dst, Register src, int size);
1455  void emit_imul(Register dst, const Operand& src, int size);
1456  void emit_imul(Register dst, Register src, Immediate imm, int size);
1457  void emit_imul(Register dst, const Operand& src, Immediate imm, int size);
1458 
1459  void emit_inc(Register dst, int size);
1460  void emit_inc(const Operand& dst, int size);
1461 
1462  void emit_lea(Register dst, const Operand& src, int size);
1463 
1464  void emit_mov(Register dst, const Operand& src, int size);
1465  void emit_mov(Register dst, Register src, int size);
1466  void emit_mov(const Operand& dst, Register src, int size);
1467  void emit_mov(Register dst, Immediate value, int size);
1468  void emit_mov(const Operand& dst, Immediate value, int size);
1469 
1470  void emit_movzxb(Register dst, const Operand& src, int size);
1471  void emit_movzxb(Register dst, Register src, int size);
1472  void emit_movzxw(Register dst, const Operand& src, int size);
1473  void emit_movzxw(Register dst, Register src, int size);
1474 
1475  void emit_neg(Register dst, int size);
1476  void emit_neg(const Operand& dst, int size);
1477 
1478  void emit_not(Register dst, int size);
1479  void emit_not(const Operand& dst, int size);
1480 
1481  void emit_or(Register dst, Register src, int size) {
1482  arithmetic_op(0x0B, dst, src, size);
1483  }
1484 
1485  void emit_or(Register dst, const Operand& src, int size) {
1486  arithmetic_op(0x0B, dst, src, size);
1487  }
1488 
1489  void emit_or(const Operand& dst, Register src, int size) {
1490  arithmetic_op(0x9, src, dst, size);
1491  }
1492 
1493  void emit_or(Register dst, Immediate src, int size) {
1494  immediate_arithmetic_op(0x1, dst, src, size);
1495  }
1496 
1497  void emit_or(const Operand& dst, Immediate src, int size) {
1498  immediate_arithmetic_op(0x1, dst, src, size);
1499  }
1500 
1501  void emit_repmovs(int size);
1502 
1503  void emit_sbb(Register dst, Register src, int size) {
1504  arithmetic_op(0x1b, dst, src, size);
1505  }
1506 
1507  void emit_sub(Register dst, Register src, int size) {
1508  arithmetic_op(0x2B, dst, src, size);
1509  }
1510 
1511  void emit_sub(Register dst, Immediate src, int size) {
1512  immediate_arithmetic_op(0x5, dst, src, size);
1513  }
1514 
1515  void emit_sub(Register dst, const Operand& src, int size) {
1516  arithmetic_op(0x2B, dst, src, size);
1517  }
1518 
1519  void emit_sub(const Operand& dst, Register src, int size) {
1520  arithmetic_op(0x29, src, dst, size);
1521  }
1522 
1523  void emit_sub(const Operand& dst, Immediate src, int size) {
1524  immediate_arithmetic_op(0x5, dst, src, size);
1525  }
1526 
1527  void emit_test(Register dst, Register src, int size);
1528  void emit_test(Register reg, Immediate mask, int size);
1529  void emit_test(const Operand& op, Register reg, int size);
1530  void emit_test(const Operand& op, Immediate mask, int size);
1531  void emit_test(Register reg, const Operand& op, int size) {
1532  return emit_test(op, reg, size);
1533  }
1534 
1535  void emit_xchg(Register dst, Register src, int size);
1536  void emit_xchg(Register dst, const Operand& src, int size);
1537 
1538  void emit_xor(Register dst, Register src, int size) {
1539  if (size == kInt64Size && dst.code() == src.code()) {
1540  // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1541  // there is no need to make this a 64 bit operation.
1542  arithmetic_op(0x33, dst, src, kInt32Size);
1543  } else {
1544  arithmetic_op(0x33, dst, src, size);
1545  }
1546  }
1547 
1548  void emit_xor(Register dst, const Operand& src, int size) {
1549  arithmetic_op(0x33, dst, src, size);
1550  }
1551 
1552  void emit_xor(Register dst, Immediate src, int size) {
1553  immediate_arithmetic_op(0x6, dst, src, size);
1554  }
1555 
1556  void emit_xor(const Operand& dst, Immediate src, int size) {
1557  immediate_arithmetic_op(0x6, dst, src, size);
1558  }
1559 
1560  void emit_xor(const Operand& dst, Register src, int size) {
1561  arithmetic_op(0x31, src, dst, size);
1562  }
1563 
1564  friend class CodePatcher;
1565  friend class EnsureSpace;
1567 
1568  // code generation
1569  RelocInfoWriter reloc_info_writer;
1570 
1572 
1574  friend class PositionsRecorder;
1575 };
1576 
1577 
1578 // Helper class that ensures that there is enough space for generating
1579 // instructions and relocation information. The constructor makes
1580 // sure that there is enough space and (in debug mode) the destructor
1581 // checks that we did not generate too much.
1582 class EnsureSpace BASE_EMBEDDED {
1583  public:
1584  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
1585  if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
1586 #ifdef DEBUG
1587  space_before_ = assembler_->available_space();
1588 #endif
1589  }
1590 
1591 #ifdef DEBUG
1592  ~EnsureSpace() {
1593  int bytes_generated = space_before_ - assembler_->available_space();
1594  DCHECK(bytes_generated < assembler_->kGap);
1595  }
1596 #endif
1597 
1598  private:
1599  Assembler* assembler_;
1600 #ifdef DEBUG
1601  int space_before_;
1602 #endif
1603 };
1604 
1605 } } // namespace v8::internal
1606 
1607 #endif // V8_X64_ASSEMBLER_X64_H_
#define BASE_EMBEDDED
Definition: allocation.h:45
#define DECLARE_INSTRUCTION(instruction)
#define ASSEMBLER_INSTRUCTION_LIST(V)
#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode)
#define SHIFT_INSTRUCTION_LIST(V)
Isolate * isolate() const
Definition: assembler.h:62
static const int kSpecialTargetSize
void bind_to(Label *L, int pos)
static Address target_address_at(Address pc, Code *code)
void store_rax(ExternalReference ref)
void emit_add(Register dst, const Operand &src, int size)
void popq(const Operand &dst)
RelocInfoWriter reloc_info_writer
void testb(const Operand &op, Immediate mask)
void shufps(XMMRegister dst, XMMRegister src, byte imm8)
void arithmetic_op_8(byte opcode, Register reg, const Operand &rm_reg)
void immediate_arithmetic_op(byte subcode, Register dst, Immediate src, int size)
void cmovq(Condition cc, Register dst, const Operand &src)
void cvttsd2si(Register dst, const Operand &src)
void shrd(Register dst, Register src)
void subsd(XMMRegister dst, XMMRegister src)
void emit_sse_operand(XMMRegister dst, XMMRegister src)
void call(Address entry, RelocInfo::Mode rmode)
void emit_imul(Register src, int size)
void Nop(int bytes=1)
void emit_sub(const Operand &dst, Register src, int size)
void cmpw(Register dst, Immediate src)
void cmpb(Register dst, Register src)
void movapd(XMMRegister dst, XMMRegister src)
void cvttss2si(Register dst, XMMRegister src)
void emit_repmovs(int size)
void emit_cmp(const Operand &dst, Register src, int size)
void psllq(XMMRegister reg, byte imm8)
Instruction * pc() const
void subps(XMMRegister dst, const Operand &src)
void movb(Register dst, Immediate imm)
void movdqu(XMMRegister dst, const Operand &src)
static const int kShortCallInstructionLength
void cvtlsi2sd(XMMRegister dst, Register src)
void emit_xor(Register dst, Immediate src, int size)
void emit_add(const Operand &dst, Immediate src, int size)
Address runtime_entry_at(Address pc)
static const byte kJnzShortOpcode
void jmp(Register adr)
void immediate_arithmetic_op_8(byte subcode, Register dst, Immediate src)
void movsd(const Operand &dst, XMMRegister src)
void emit_idiv(Register src, int size)
void sqrtsd(XMMRegister dst, const Operand &src)
static Address target_address_at(Address pc, ConstantPoolArray *constant_pool)
void movsxlq(Register dst, const Operand &src)
void emit_xor(Register dst, const Operand &src, int size)
static void set_target_address_at(Address pc, ConstantPoolArray *constant_pool, Address target, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
void fisttp_d(const Operand &adr)
void emit_sse_operand(XMMRegister dst, Register src)
void emit_cmp(const Operand &dst, Immediate src, int size)
void movq(Register dst, XMMRegister src)
void emit_inc(Register dst, int size)
void cmpb_al(Immediate src)
void cmpw(const Operand &dst, Immediate src)
static void deserialization_set_special_target_at(Address instruction_payload, Code *code, Address target)
void movdqa(XMMRegister dst, const Operand &src)
void jmp(Address entry, RelocInfo::Mode rmode)
void shift(Register dst, int subcode, int size)
void call(const Operand &operand)
static const byte kNopByte
void emit_xor(Register dst, Register src, int size)
void ucomisd(XMMRegister dst, XMMRegister src)
void cvtlsi2ss(XMMRegister dst, Register src)
void RecordComment(const char *msg, bool force=false)
void decb(Register dst)
void sqrtsd(XMMRegister dst, XMMRegister src)
void orpd(XMMRegister dst, XMMRegister src)
void pushq(Register src)
void movmskps(Register dst, XMMRegister src)
void fild_s(const Operand &adr)
void emit_code_relative_offset(Label *label)
void emit_or(Register dst, Register src, int size)
void emit_and(Register dst, const Operand &src, int size)
void movw(const Operand &dst, Register src)
static const int kCallSequenceLength
void emit_imul(Register dst, const Operand &src, int size)
void testb(Register dst, Register src)
void andps(XMMRegister dst, const Operand &src)
void j(Condition cc, Address entry, RelocInfo::Mode rmode)
void addsd(XMMRegister dst, XMMRegister src)
void emit_movzxw(Register dst, const Operand &src, int size)
void fstp(int index)
void j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
void mulsd(XMMRegister dst, const Operand &src)
void emit_not(Register dst, int size)
void mul(Register src)
void movd(XMMRegister dst, Register src)
void movss(const Operand &dst, XMMRegister src)
void emit_sub(Register dst, Register src, int size)
void cvttsd2siq(Register dst, const Operand &src)
void emit_and(Register dst, Register src, int size)
static const int kCallScratchRegisterInstructionLength
void GetCode(CodeDesc *desc)
void testb(Register reg, Immediate mask)
void cmovq(Condition cc, Register dst, Register src)
void db(uint8_t data)
byte * addr_at(int pos)
void movsxwq(Register dst, const Operand &src)
static const int kPatchDebugBreakSlotAddressOffset
void store_rax(void *dst, RelocInfo::Mode mode)
void xorpd(XMMRegister dst, XMMRegister src)
void emit_xchg(Register dst, Register src, int size)
static const byte kJccShortPrefix
void movp(Register dst, void *ptr, RelocInfo::Mode rmode)
void emit_sse_operand(XMMRegister reg, const Operand &adr)
void emit_xor(const Operand &dst, Register src, int size)
void long_at_put(int pos, uint32_t x)
void xorps(XMMRegister dst, XMMRegister src)
void emit_add(const Operand &dst, Register src, int size)
void emit_div(Register src, int size)
void emit_optional_rex_32(Register reg, Register rm_reg)
void ucomisd(XMMRegister dst, const Operand &src)
void emit_or(const Operand &dst, Register src, int size)
static const int kPatchDebugBreakSlotReturnOffset
void emit_sse_operand(Register reg, const Operand &adr)
void emit_modrm(int code, Register rm_reg)
void call(Register adr)
void cvtqsi2sd(XMMRegister dst, Register src)
List< Handle< Code > > code_targets_
static void set_target_address_at(Address pc, Code *code, Address target, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
void emit_and(Register dst, Immediate src, int size)
static const int kGap
void call(Address target)
void movsd(XMMRegister dst, const Operand &src)
void emit_test(Register reg, Immediate mask, int size)
void divsd(XMMRegister dst, XMMRegister src)
void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data=0)
void shift(Register dst, Immediate shift_amount, int subcode, int size)
void testb(const Operand &op, Register reg)
void cvttss2si(Register dst, const Operand &src)
void setcc(Condition cc, Register reg)
void emit_test(Register dst, Register src, int size)
void pushq(Immediate value)
void emit_cmp(Register dst, Immediate src, int size)
void fld_d(const Operand &adr)
static const int kMaximalBufferSize
static Address break_address_from_return_address(Address pc)
void immediate_arithmetic_op_8(byte subcode, const Operand &dst, Immediate src)
void movsxwl(Register dst, const Operand &src)
void movb(const Operand &dst, Register src)
void load_rax(ExternalReference ext)
void emit_dec(Register dst, int size)
void cmpb(Register dst, Immediate src)
void jmp(Handle< Code > target, RelocInfo::Mode rmode)
void emit_inc(const Operand &dst, int size)
void emit_or(const Operand &dst, Immediate src, int size)
void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size)
void cmpw(Register dst, Register src)
void cmpb(Register dst, const Operand &src)
void subb(Register dst, Immediate src)
void emit(Immediate x)
void emit_xchg(Register dst, const Operand &src, int size)
void immediate_arithmetic_op_16(byte subcode, const Operand &dst, Immediate src)
void fld_s(const Operand &adr)
void fist_s(const Operand &adr)
uint32_t long_at(int pos)
static RelocInfo::Mode RelocInfoNone()
void fisttp_s(const Operand &adr)
void emit_test(const Operand &op, Immediate mask, int size)
void emit_cmp(Register dst, const Operand &src, int size)
static const byte kTestEaxByte
void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode)
void movsxbq(Register dst, const Operand &src)
void movb(Register dst, const Operand &src)
void j(Condition cc, Handle< Code > target, RelocInfo::Mode rmode)
Handle< ConstantPoolArray > NewConstantPool(Isolate *isolate)
void immediate_arithmetic_op(byte subcode, const Operand &dst, Immediate src, int size)
void fistp_d(const Operand &adr)
void emit_code_target(Handle< Code > target, RelocInfo::Mode rmode, TypeFeedbackId ast_id=TypeFeedbackId::None())
void cmovl(Condition cc, Register dst, const Operand &src)
void arithmetic_op_8(byte opcode, Register reg, Register rm_reg)
void cmpw(const Operand &dst, Register src)
void cmpltsd(XMMRegister dst, XMMRegister src)
void emit_imul(Register dst, Register src, int size)
void fstp_d(const Operand &adr)
void extractps(Register dst, XMMRegister src, byte imm8)
void emit_rex_32(Register reg, Register rm_reg)
void andps(XMMRegister dst, XMMRegister src)
void adr(const Register &rd, Label *label)
void movsd(XMMRegister dst, XMMRegister src)
friend class PositionsRecorder
void pushq_imm32(int32_t imm32)
void emit_sub(Register dst, const Operand &src, int size)
void emit_imul(Register dst, Register src, Immediate imm, int size)
void emit_rex(P1 p1, P2 p2, int size)
void movaps(XMMRegister dst, XMMRegister src)
void movw(Register dst, const Operand &src)
void emit_operand(Register reg, const Operand &adr)
void load_rax(void *ptr, RelocInfo::Mode rmode)
void arithmetic_op_16(byte opcode, Register reg, const Operand &rm_reg)
void cvtss2sd(XMMRegister dst, const Operand &src)
void jmp(Label *L, Label::Distance distance=Label::kFar)
void emit_runtime_entry(Address entry, RelocInfo::Mode rmode)
void emit_imul(Register dst, const Operand &src, Immediate imm, int size)
void emit_sse_operand(Register dst, XMMRegister src)
static Address target_address_at(Address pc, ConstantPoolArray *constant_pool)
void divps(XMMRegister dst, const Operand &src)
void cvttsd2si(Register dst, XMMRegister src)
void andb(Register dst, Immediate src)
void movdqa(const Operand &dst, XMMRegister src)
static void set_target_address_at(Address pc, ConstantPoolArray *constant_pool, Address target, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
void cmovl(Condition cc, Register dst, Register src)
void shld(Register dst, Register src)
void emit_or(Register dst, const Operand &src, int size)
void ret(int imm16)
void movss(XMMRegister dst, const Operand &src)
void emit_neg(const Operand &dst, int size)
void divps(XMMRegister dst, XMMRegister src)
void addsd(XMMRegister dst, const Operand &src)
void cmpw(Register dst, const Operand &src)
void emit_sub(Register dst, Immediate src, int size)
void emit_operand(int rm, const Operand &adr)
Handle< Object > code_target_object_handle_at(Address pc)
void fisub_s(const Operand &adr)
void movb(const Operand &dst, Immediate imm)
static bool IsNop(Address addr)
void pushq(const Operand &src)
static const int kMoveAddressIntoScratchRegisterInstructionLength
void emit_modrm(Register reg, Register rm_reg)
void cvtsd2si(Register dst, XMMRegister src)
static const int kJSReturnSequenceLength
void emitp(void *x, RelocInfo::Mode rmode)
void emit_dec(const Operand &dst, int size)
void emit_test(const Operand &op, Register reg, int size)
static const int kDebugBreakSlotLength
static const byte kJncShortOpcode
void emit_cmp(Register dst, Register src, int size)
void movsxbl(Register dst, const Operand &src)
void andpd(XMMRegister dst, XMMRegister src)
void movq(Register dst, uint64_t value)
void emit_farith(int b1, int b2, int i)
void bsrl(Register dst, Register src)
void popq(Register dst)
void cvtsd2siq(Register dst, XMMRegister src)
void set_byte_at(int pos, byte value)
void bts(const Operand &dst, Register src)
static const byte kTestAlByte
void emit_and(const Operand &dst, Immediate src, int size)
void cmpb(const Operand &dst, Register src)
static const int kRealPatchReturnSequenceAddressOffset
void mulsd(XMMRegister dst, XMMRegister src)
void cmpb(const Operand &dst, Immediate src)
void orps(XMMRegister dst, XMMRegister src)
void cvttsd2siq(Register dst, XMMRegister src)
void emit_add(Register dst, Immediate src, int size)
void enter(Immediate size)
void mulps(XMMRegister dst, XMMRegister src)
void emit_not(const Operand &dst, int size)
STATIC_ASSERT(kPointerSize==kInt64Size||kPointerSize==kInt32Size)
void movdqu(const Operand &dst, XMMRegister src)
void fstp_s(const Operand &adr)
void mulps(XMMRegister dst, const Operand &src)
static const int kCallTargetAddressOffset
void movq(Register dst, int64_t value)
static const int kPatchReturnSequenceAddressOffset
void fistp_s(const Operand &adr)
void bt(const Operand &dst, Register src)
void cvtlsi2sd(XMMRegister dst, const Operand &src)
void immediate_arithmetic_op_16(byte subcode, Register dst, Immediate src)
void emit_mov(Register dst, Register src, int size)
void movq(XMMRegister dst, Register src)
void cvtqsi2sd(XMMRegister dst, const Operand &src)
void emit_or(Register dst, Immediate src, int size)
void movmskpd(Register dst, XMMRegister src)
void emit_rex(P1 p1, int size)
void arithmetic_op(byte opcode, Register reg, const Operand &rm_reg, int size)
void emit_sbb(Register dst, Register src, int size)
void movd(Register dst, XMMRegister src)
void movsxlq(Register dst, Register src)
void cvtsd2ss(XMMRegister dst, XMMRegister src)
void emit_add(Register dst, Register src, int size)
void dd(uint32_t data)
void decb(const Operand &dst)
void call(Handle< Code > target, RelocInfo::Mode rmode=RelocInfo::CODE_TARGET, TypeFeedbackId ast_id=TypeFeedbackId::None())
static const byte kJcShortOpcode
void emit_sub(const Operand &dst, Immediate src, int size)
void addps(XMMRegister dst, XMMRegister src)
void emit_neg(Register dst, int size)
void subps(XMMRegister dst, XMMRegister src)
void emit_movzxb(Register dst, Register src, int size)
void fild_d(const Operand &adr)
void emit_xor(const Operand &dst, Immediate src, int size)
void jmp(const Operand &src)
void emit_mov(Register dst, const Operand &src, int size)
PositionsRecorder positions_recorder_
Assembler(Isolate *isolate, void *buffer, int buffer_size)
void movl(const Operand &dst, Label *src)
PositionsRecorder * positions_recorder()
static Address target_address_from_return_address(Address pc)
bool buffer_overflow() const
void emit_mov(const Operand &dst, Immediate value, int size)
void addps(XMMRegister dst, const Operand &src)
int SizeOfCodeGeneratedSince(Label *label)
void movq(XMMRegister dst, XMMRegister src)
void emit_movzxb(Register dst, const Operand &src, int size)
void emit_movzxw(Register dst, Register src, int size)
void xorps(XMMRegister dst, const Operand &src)
void emit_and(const Operand &dst, Register src, int size)
void emit_test(Register reg, const Operand &op, int size)
void emit_lea(Register dst, const Operand &src, int size)
static const byte kJzShortOpcode
void PopulateConstantPool(ConstantPoolArray *constant_pool)
void cvtss2sd(XMMRegister dst, XMMRegister src)
void emit_mov(Register dst, Immediate value, int size)
void movw(const Operand &dst, Immediate imm)
void orps(XMMRegister dst, const Operand &src)
void arithmetic_op_16(byte opcode, Register reg, Register rm_reg)
void emit_mov(const Operand &dst, Register src, int size)
void set_modrm(int mod, Register rm)
Operand(const Operand &base, int32_t offset)
bool AddressUsesRegister(Register reg) const
Operand(Register index, ScaleFactor scale, int32_t disp)
void set_sib(ScaleFactor scale, Register index, Register base)
EnsureSpace(Assembler *assembler)
Operand(Register base, Register index, ScaleFactor scale, int32_t disp)
Operand(Register base, int32_t disp)
ConstantPoolArray * constant_pool()
Definition: objects-inl.h:4942
static TypeFeedbackId None()
Definition: utils.h:945
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS 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_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS 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 enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
unsigned short uint16_t
Definition: unicode.cc:23
int int32_t
Definition: unicode.cc:24
const XMMRegister xmm6
const int kPointerSize
Definition: globals.h:129
const XMMRegister xmm12
const XMMRegister xmm10
Condition CommuteCondition(Condition cond)
Definition: constants-arm.h:93
const XMMRegister xmm14
const XMMRegister xmm1
const int kRegister_rdx_Code
const Register r10
const int kRegister_rbp_Code
const XMMRegister xmm2
DwVfpRegister DoubleRegister
const int kRegister_r14_Code
const Register rsi
const Register arg_reg_4
const int kRegister_r12_Code
const int kRegister_rdi_Code
const Register rbp
const Register r11
const XMMRegister xmm3
const XMMRegister xmm9
const Register r12
const Register rdi
const int kRegister_rsp_Code
const Register r9
const int kInt64Size
Definition: globals.h:126
const XMMRegister xmm15
const int kRegister_r13_Code
const int kInt32Size
Definition: globals.h:125
const XMMRegister xmm0
const int kRegister_r8_Code
Definition: assembler-arm.h:84
const Register rbx
const int kRegister_r11_Code
Condition NegateCondition(Condition cond)
Definition: constants-arm.h:86
const int kRegister_rax_Code
const XMMRegister xmm7
byte * Address
Definition: globals.h:101
const Register r8
const XMMRegister xmm4
const int kRegister_r15_Code
const Register no_reg
const Register rdx
const Register r13
const Register arg_reg_1
static bool SmiValuesAre31Bits()
Definition: v8.h:5807
const int kRegister_rcx_Code
const int kRegister_r10_Code
Definition: assembler-arm.h:86
const Register rax
const XMMRegister xmm8
const Register r15
@ FLUSH_ICACHE_IF_NEEDED
Definition: assembler.h:293
const int MB
Definition: globals.h:107
const Register rcx
const int kRegister_no_reg_Code
Definition: assembler-arm.h:75
const XMMRegister xmm5
const Register r14
const int kRegister_r9_Code
Definition: assembler-arm.h:85
const XMMRegister xmm13
const int kRegister_rbx_Code
const int kRegister_rsi_Code
const Register rsp
const Register arg_reg_3
const XMMRegister xmm11
const Register arg_reg_2
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
static const int kNumRegisters
Definition: assembler-arm.h:95
static int NumAllocatableRegisters()
Definition: assembler-x64.h:77
static Register from_code(int code)
static int ToAllocationIndex(Register reg)
Definition: assembler-x64.h:82
bool is(Register reg) const
static const char * AllocationIndexToString(int index)
Definition: assembler-x64.h:92
bool is_byte_register() const
static const int kMaxNumAllocatableRegisters
Definition: assembler-arm.h:96
static const int kAllocationIndexByRegisterCode[kNumRegisters]
static const int kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters]
static Register FromAllocationIndex(int index)
Definition: assembler-x64.h:86
static XMMRegister FromAllocationIndex(int index)
static const int kMaxNumRegisters
static XMMRegister from_code(int code)
static const int kMaxNumAllocatableRegisters
static int NumAllocatableRegisters()
static int ToAllocationIndex(XMMRegister reg)
static const char * AllocationIndexToString(int index)
bool is(XMMRegister reg) const
static int NumAllocatableAliasedRegisters()