V8 Project
assembler-x87.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 2011 the V8 project authors. All rights reserved.
34 
35 // A light-weight IA32 Assembler.
36 
37 #ifndef V8_X87_ASSEMBLER_X87_H_
38 #define V8_X87_ASSEMBLER_X87_H_
39 
40 #include "src/isolate.h"
41 #include "src/serialize.h"
42 
43 namespace v8 {
44 namespace internal {
45 
46 // CPU Registers.
47 //
48 // 1) We would prefer to use an enum, but enum values are assignment-
49 // compatible with int, which has caused code-generation bugs.
50 //
51 // 2) We would prefer to use a class instead of a struct but we don't like
52 // the register initialization to depend on the particular initialization
53 // order (which appears to be different on OS X, Linux, and Windows for the
54 // installed versions of C++ we tried). Using a struct permits C-style
55 // "initialization". Also, the Register objects cannot be const as this
56 // forces initialization stubs in MSVC, making us dependent on initialization
57 // order.
58 //
59 // 3) By not using an enum, we are possibly preventing the compiler from
60 // doing certain constant folds, which may significantly reduce the
61 // code generated for some assembly instructions (because they boil down
62 // to a few constants). If this is a problem, we could change the code
63 // such that we use an enum in optimized mode, and the struct in debug
64 // mode. This way we get the compile-time error checking in debug mode
65 // and best performance in optimized code.
66 //
67 struct Register {
68  static const int kMaxNumAllocatableRegisters = 6;
69  static int NumAllocatableRegisters() {
71  }
72  static const int kNumRegisters = 8;
73 
74  static inline const char* AllocationIndexToString(int index);
75 
76  static inline int ToAllocationIndex(Register reg);
77 
78  static inline Register FromAllocationIndex(int index);
79 
80  static Register from_code(int code) {
81  DCHECK(code >= 0);
83  Register r = { code };
84  return r;
85  }
86  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
87  bool is(Register reg) const { return code_ == reg.code_; }
88  // eax, ebx, ecx and edx are byte registers, the rest are not.
89  bool is_byte_register() const { return code_ <= 3; }
90  int code() const {
91  DCHECK(is_valid());
92  return code_;
93  }
94  int bit() const {
95  DCHECK(is_valid());
96  return 1 << code_;
97  }
98 
99  // Unfortunately we can't make this private in a struct.
100  int code_;
101 };
102 
103 const int kRegister_eax_Code = 0;
104 const int kRegister_ecx_Code = 1;
105 const int kRegister_edx_Code = 2;
106 const int kRegister_ebx_Code = 3;
107 const int kRegister_esp_Code = 4;
108 const int kRegister_ebp_Code = 5;
109 const int kRegister_esi_Code = 6;
110 const int kRegister_edi_Code = 7;
111 const int kRegister_no_reg_Code = -1;
112 
113 const Register eax = { kRegister_eax_Code };
114 const Register ecx = { kRegister_ecx_Code };
115 const Register edx = { kRegister_edx_Code };
116 const Register ebx = { kRegister_ebx_Code };
117 const Register esp = { kRegister_esp_Code };
118 const Register ebp = { kRegister_ebp_Code };
119 const Register esi = { kRegister_esi_Code };
120 const Register edi = { kRegister_edi_Code };
121 const Register no_reg = { kRegister_no_reg_Code };
122 
123 
124 inline const char* Register::AllocationIndexToString(int index) {
125  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
126  // This is the mapping of allocation indices to registers.
127  const char* const kNames[] = { "eax", "ecx", "edx", "ebx", "esi", "edi" };
128  return kNames[index];
129 }
130 
131 
132 inline int Register::ToAllocationIndex(Register reg) {
133  DCHECK(reg.is_valid() && !reg.is(esp) && !reg.is(ebp));
134  return (reg.code() >= 6) ? reg.code() - 2 : reg.code();
135 }
136 
137 
138 inline Register Register::FromAllocationIndex(int index) {
139  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
140  return (index >= 4) ? from_code(index + 2) : from_code(index);
141 }
142 
143 
144 struct X87Register {
145  static const int kMaxNumAllocatableRegisters = 6;
146  static const int kMaxNumRegisters = 8;
147  static int NumAllocatableRegisters() {
149  }
150 
151 
152  // TODO(turbofan): Proper support for float32.
154  return NumAllocatableRegisters();
155  }
156 
157 
158  static int ToAllocationIndex(X87Register reg) {
159  return reg.code_;
160  }
161 
162  static const char* AllocationIndexToString(int index) {
163  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
164  const char* const names[] = {
165  "stX_0", "stX_1", "stX_2", "stX_3", "stX_4",
166  "stX_5", "stX_6", "stX_7"
167  };
168  return names[index];
169  }
170 
171  static X87Register FromAllocationIndex(int index) {
172  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
173  X87Register result;
174  result.code_ = index;
175  return result;
176  }
177 
178  bool is_valid() const {
179  return 0 <= code_ && code_ < kMaxNumRegisters;
180  }
181 
182  int code() const {
183  DCHECK(is_valid());
184  return code_;
185  }
186 
187  bool is(X87Register reg) const {
188  return code_ == reg.code_;
189  }
190 
191  int code_;
192 };
193 
194 
196 
197 
198 const X87Register stX_0 = { 0 };
199 const X87Register stX_1 = { 1 };
200 const X87Register stX_2 = { 2 };
201 const X87Register stX_3 = { 3 };
202 const X87Register stX_4 = { 4 };
203 const X87Register stX_5 = { 5 };
204 const X87Register stX_6 = { 6 };
205 const X87Register stX_7 = { 7 };
206 
207 
208 enum Condition {
209  // any value < 0 is considered no_condition
210  no_condition = -1,
211 
212  overflow = 0,
213  no_overflow = 1,
214  below = 2,
215  above_equal = 3,
216  equal = 4,
217  not_equal = 5,
218  below_equal = 6,
219  above = 7,
220  negative = 8,
221  positive = 9,
222  parity_even = 10,
223  parity_odd = 11,
224  less = 12,
225  greater_equal = 13,
226  less_equal = 14,
227  greater = 15,
228 
229  // aliases
230  carry = below,
232  zero = equal,
234  sign = negative,
236 };
237 
238 
239 // Returns the equivalent of !cc.
240 // Negation of the default no_condition (-1) results in a non-default
241 // no_condition value (-2). As long as tests for no_condition check
242 // for condition < 0, this will work as expected.
244  return static_cast<Condition>(cc ^ 1);
245 }
246 
247 
248 // Commute a condition such that {a cond b == b cond' a}.
250  switch (cc) {
251  case below:
252  return above;
253  case above:
254  return below;
255  case above_equal:
256  return below_equal;
257  case below_equal:
258  return above_equal;
259  case less:
260  return greater;
261  case greater:
262  return less;
263  case greater_equal:
264  return less_equal;
265  case less_equal:
266  return greater_equal;
267  default:
268  return cc;
269  }
270 }
271 
272 
273 // -----------------------------------------------------------------------------
274 // Machine instruction Immediates
275 
276 class Immediate BASE_EMBEDDED {
277  public:
278  inline explicit Immediate(int x);
279  inline explicit Immediate(const ExternalReference& ext);
280  inline explicit Immediate(Handle<Object> handle);
281  inline explicit Immediate(Smi* value);
282  inline explicit Immediate(Address addr);
283 
284  static Immediate CodeRelativeOffset(Label* label) {
285  return Immediate(label);
286  }
287 
288  bool is_zero() const { return x_ == 0 && RelocInfo::IsNone(rmode_); }
289  bool is_int8() const {
290  return -128 <= x_ && x_ < 128 && RelocInfo::IsNone(rmode_);
291  }
292  bool is_int16() const {
293  return -32768 <= x_ && x_ < 32768 && RelocInfo::IsNone(rmode_);
294  }
295 
296  private:
297  inline explicit Immediate(Label* value);
298 
299  int x_;
301 
302  friend class Operand;
303  friend class Assembler;
304  friend class MacroAssembler;
305 };
306 
307 
308 // -----------------------------------------------------------------------------
309 // Machine instruction Operands
310 
312  times_1 = 0,
313  times_2 = 1,
314  times_4 = 2,
315  times_8 = 3,
320 };
321 
322 
323 class Operand BASE_EMBEDDED {
324  public:
325  // reg
327 
328  // [disp/r]
329  INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode));
330 
331  // [disp/r]
332  INLINE(explicit Operand(Immediate imm));
333 
334  // [base + disp/r]
335  explicit Operand(Register base, int32_t disp,
337 
338  // [base + index*scale + disp/r]
339  explicit Operand(Register base,
340  Register index,
341  ScaleFactor scale,
342  int32_t disp,
344 
345  // [index*scale + disp/r]
346  explicit Operand(Register index,
347  ScaleFactor scale,
348  int32_t disp,
350 
351  static Operand StaticVariable(const ExternalReference& ext) {
352  return Operand(reinterpret_cast<int32_t>(ext.address()),
354  }
355 
357  ScaleFactor scale,
358  const ExternalReference& arr) {
359  return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()),
361  }
362 
363  static Operand ForCell(Handle<Cell> cell) {
364  AllowDeferredHandleDereference embedding_raw_address;
365  return Operand(reinterpret_cast<int32_t>(cell.location()),
367  }
368 
370  return Operand(base, imm.x_, imm.rmode_);
371  }
372 
373  // Returns true if this Operand is a wrapper for the specified register.
374  bool is_reg(Register reg) const;
375 
376  // Returns true if this Operand is a wrapper for one register.
377  bool is_reg_only() const;
378 
379  // Asserts that this Operand is a wrapper for one register and returns the
380  // register.
381  Register reg() const;
382 
383  private:
384  // Set the ModRM byte without an encoded 'reg' register. The
385  // register is encoded later as part of the emit_operand operation.
386  inline void set_modrm(int mod, Register rm);
387 
388  inline void set_sib(ScaleFactor scale, Register index, Register base);
389  inline void set_disp8(int8_t disp);
390  inline void set_dispr(int32_t disp, RelocInfo::Mode rmode);
391 
392  byte buf_[6];
393  // The number of bytes in buf_.
394  unsigned int len_;
395  // Only valid if len_ > 4.
396  RelocInfo::Mode rmode_;
397 
398  friend class Assembler;
399  friend class MacroAssembler;
400 };
401 
402 
403 // -----------------------------------------------------------------------------
404 // A Displacement describes the 32bit immediate field of an instruction which
405 // may be used together with a Label in order to refer to a yet unknown code
406 // position. Displacements stored in the instruction stream are used to describe
407 // the instruction and to chain a list of instructions using the same Label.
408 // A Displacement contains 2 different fields:
409 //
410 // next field: position of next displacement in the chain (0 = end of list)
411 // type field: instruction type
412 //
413 // A next value of null (0) indicates the end of a chain (note that there can
414 // be no displacement at position zero, because there is always at least one
415 // instruction byte before the displacement).
416 //
417 // Displacement _data field layout
418 //
419 // |31.....2|1......0|
420 // [ next | type |
421 
422 class Displacement BASE_EMBEDDED {
423  public:
424  enum Type {
425  UNCONDITIONAL_JUMP,
426  CODE_RELATIVE,
427  OTHER
428  };
429 
430  int data() const { return data_; }
431  Type type() const { return TypeField::decode(data_); }
432  void next(Label* L) const {
433  int n = NextField::decode(data_);
434  n > 0 ? L->link_to(n) : L->Unuse();
435  }
436  void link_to(Label* L) { init(L, type()); }
437 
438  explicit Displacement(int data) { data_ = data; }
439 
440  Displacement(Label* L, Type type) { init(L, type); }
441 
442  void print() {
443  PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"),
444  NextField::decode(data_));
445  }
446 
447  private:
448  int data_;
449 
450  class TypeField: public BitField<Type, 0, 2> {};
451  class NextField: public BitField<int, 2, 32-2> {};
452 
453  void init(Label* L, Type type);
454 };
455 
456 
457 class Assembler : public AssemblerBase {
458  private:
459  // We check before assembling an instruction that there is sufficient
460  // space to write an instruction and its relocation information.
461  // The relocation writer's position must be kGap bytes above the end of
462  // the generated instructions. This leaves enough space for the
463  // longest possible ia32 instruction, 15 bytes, and the longest possible
464  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
465  // (There is a 15 byte limit on ia32 instruction length that rules out some
466  // otherwise valid instructions.)
467  // This allows for a single, fast space check per instruction.
468  static const int kGap = 32;
469 
470  public:
471  // Create an assembler. Instructions and relocation information are emitted
472  // into a buffer, with the instructions starting from the beginning and the
473  // relocation information starting from the end of the buffer. See CodeDesc
474  // for a detailed comment on the layout (globals.h).
475  //
476  // If the provided buffer is NULL, the assembler allocates and grows its own
477  // buffer, and buffer_size determines the initial buffer size. The buffer is
478  // owned by the assembler and deallocated upon destruction of the assembler.
479  //
480  // If the provided buffer is not NULL, the assembler uses the provided buffer
481  // for code generation and assumes its size to be buffer_size. If the buffer
482  // is too small, a fatal error occurs. No deallocation of the buffer is done
483  // upon destruction of the assembler.
484  // TODO(vitalyr): the assembler does not need an isolate.
485  Assembler(Isolate* isolate, void* buffer, int buffer_size);
486  virtual ~Assembler() { }
487 
488  // GetCode emits any pending (non-emitted) code and fills the descriptor
489  // desc. GetCode() is idempotent; it returns the same result if no other
490  // Assembler functions are invoked in between GetCode() calls.
491  void GetCode(CodeDesc* desc);
492 
493  // Read/Modify the code target in the branch/call instruction at pc.
495  ConstantPoolArray* constant_pool);
496  inline static void set_target_address_at(Address pc,
497  ConstantPoolArray* constant_pool,
498  Address target,
499  ICacheFlushMode icache_flush_mode =
501  static inline Address target_address_at(Address pc, Code* code) {
502  ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
503  return target_address_at(pc, constant_pool);
504  }
505  static inline void set_target_address_at(Address pc,
506  Code* code,
507  Address target,
508  ICacheFlushMode icache_flush_mode =
510  ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
511  set_target_address_at(pc, constant_pool, target);
512  }
513 
514  // Return the code target address at a call site from the return address
515  // of that call in the instruction stream.
517 
518  // Return the code target address of the patch debug break slot
520 
521  // This sets the branch destination (which is in the instruction on x86).
522  // This is for calls and branches within generated code.
524  Address instruction_payload, Code* code, Address target) {
525  set_target_address_at(instruction_payload, code, target);
526  }
527 
528  static const int kSpecialTargetSize = kPointerSize;
529 
530  // Distance between the address of the code target in the call instruction
531  // and the return address
532  static const int kCallTargetAddressOffset = kPointerSize;
533  // Distance between start of patched return sequence and the emitted address
534  // to jump to.
535  static const int kPatchReturnSequenceAddressOffset = 1; // JMP imm32.
536 
537  // Distance between start of patched debug break slot and the emitted address
538  // to jump to.
539  static const int kPatchDebugBreakSlotAddressOffset = 1; // JMP imm32.
540 
541  static const int kCallInstructionLength = 5;
543  static const int kJSReturnSequenceLength = 6;
544 
545  // The debug break slot must be able to contain a call instruction.
547 
548  // One byte opcode for test al, 0xXX.
549  static const byte kTestAlByte = 0xA8;
550  // One byte opcode for nop.
551  static const byte kNopByte = 0x90;
552 
553  // One byte opcode for a short unconditional jump.
554  static const byte kJmpShortOpcode = 0xEB;
555  // One byte prefix for a short conditional jump.
556  static const byte kJccShortPrefix = 0x70;
557  static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
558  static const byte kJcShortOpcode = kJccShortPrefix | carry;
559  static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
560  static const byte kJzShortOpcode = kJccShortPrefix | zero;
561 
562 
563  // ---------------------------------------------------------------------------
564  // Code generation
565  //
566  // - function names correspond one-to-one to ia32 instruction mnemonics
567  // - unless specified otherwise, instructions operate on 32bit operands
568  // - instructions on 8bit (byte) operands/registers have a trailing '_b'
569  // - instructions on 16bit (word) operands/registers have a trailing '_w'
570  // - naming conflicts with C++ keywords are resolved via a trailing '_'
571 
572  // NOTE ON INTERFACE: Currently, the interface is not very consistent
573  // in the sense that some operations (e.g. mov()) can be called in more
574  // the one way to generate the same instruction: The Register argument
575  // can in some cases be replaced with an Operand(Register) argument.
576  // This should be cleaned up and made more orthogonal. The questions
577  // is: should we always use Operands instead of Registers where an
578  // Operand is possible, or should we have a Register (overloaded) form
579  // instead? We must be careful to make sure that the selected instruction
580  // is obvious from the parameters to avoid hard-to-find code generation
581  // bugs.
582 
583  // Insert the smallest number of nop instructions
584  // possible to align the pc offset to a multiple
585  // of m. m must be a power of 2.
586  void Align(int m);
587  void Nop(int bytes = 1);
588  // Aligns code to something that's optimal for a jump target for the platform.
590 
591  // Stack
592  void pushad();
593  void popad();
594 
595  void pushfd();
596  void popfd();
597 
598  void push(const Immediate& x);
599  void push_imm32(int32_t imm32);
600  void push(Register src);
601  void push(const Operand& src);
602 
603  void pop(Register dst);
604  void pop(const Operand& dst);
605 
606  void enter(const Immediate& size);
607  void leave();
608 
609  // Moves
610  void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); }
611  void mov_b(Register dst, const Operand& src);
612  void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); }
613  void mov_b(const Operand& dst, int8_t imm8);
614  void mov_b(const Operand& dst, Register src);
615 
616  void mov_w(Register dst, const Operand& src);
617  void mov_w(const Operand& dst, Register src);
618  void mov_w(const Operand& dst, int16_t imm16);
619 
620  void mov(Register dst, int32_t imm32);
621  void mov(Register dst, const Immediate& x);
623  void mov(Register dst, const Operand& src);
624  void mov(Register dst, Register src);
625  void mov(const Operand& dst, const Immediate& x);
626  void mov(const Operand& dst, Handle<Object> handle);
627  void mov(const Operand& dst, Register src);
628 
629  void movsx_b(Register dst, Register src) { movsx_b(dst, Operand(src)); }
630  void movsx_b(Register dst, const Operand& src);
631 
632  void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); }
633  void movsx_w(Register dst, const Operand& src);
634 
635  void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); }
636  void movzx_b(Register dst, const Operand& src);
637 
638  void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); }
639  void movzx_w(Register dst, const Operand& src);
640 
641  // Flag management.
642  void cld();
643 
644  // Repetitive string instructions.
645  void rep_movs();
646  void rep_stos();
647  void stos();
648 
649  // Exchange
650  void xchg(Register dst, Register src);
651  void xchg(Register dst, const Operand& src);
652 
653  // Arithmetics
654  void adc(Register dst, int32_t imm32);
655  void adc(Register dst, const Operand& src);
656 
657  void add(Register dst, Register src) { add(dst, Operand(src)); }
658  void add(Register dst, const Operand& src);
659  void add(const Operand& dst, Register src);
660  void add(Register dst, const Immediate& imm) { add(Operand(dst), imm); }
661  void add(const Operand& dst, const Immediate& x);
662 
663  void and_(Register dst, int32_t imm32);
664  void and_(Register dst, const Immediate& x);
665  void and_(Register dst, Register src) { and_(dst, Operand(src)); }
666  void and_(Register dst, const Operand& src);
667  void and_(const Operand& dst, Register src);
668  void and_(const Operand& dst, const Immediate& x);
669 
670  void cmpb(Register reg, int8_t imm8) { cmpb(Operand(reg), imm8); }
671  void cmpb(const Operand& op, int8_t imm8);
672  void cmpb(Register reg, const Operand& op);
673  void cmpb(const Operand& op, Register reg);
674  void cmpb_al(const Operand& op);
675  void cmpw_ax(const Operand& op);
676  void cmpw(const Operand& op, Immediate imm16);
677  void cmp(Register reg, int32_t imm32);
679  void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); }
680  void cmp(Register reg, const Operand& op);
681  void cmp(Register reg, const Immediate& imm) { cmp(Operand(reg), imm); }
682  void cmp(const Operand& op, const Immediate& imm);
683  void cmp(const Operand& op, Handle<Object> handle);
684 
685  void dec_b(Register dst);
686  void dec_b(const Operand& dst);
687 
688  void dec(Register dst);
689  void dec(const Operand& dst);
690 
691  void cdq();
692 
693  void idiv(Register src) { idiv(Operand(src)); }
694  void idiv(const Operand& src);
695  void div(Register src) { div(Operand(src)); }
696  void div(const Operand& src);
697 
698  // Signed multiply instructions.
699  void imul(Register src); // edx:eax = eax * src.
700  void imul(Register dst, Register src) { imul(dst, Operand(src)); }
701  void imul(Register dst, const Operand& src); // dst = dst * src.
702  void imul(Register dst, Register src, int32_t imm32); // dst = src * imm32.
703  void imul(Register dst, const Operand& src, int32_t imm32);
704 
705  void inc(Register dst);
706  void inc(const Operand& dst);
707 
708  void lea(Register dst, const Operand& src);
709 
710  // Unsigned multiply instruction.
711  void mul(Register src); // edx:eax = eax * reg.
712 
713  void neg(Register dst);
714  void neg(const Operand& dst);
715 
716  void not_(Register dst);
717  void not_(const Operand& dst);
718 
719  void or_(Register dst, int32_t imm32);
720  void or_(Register dst, Register src) { or_(dst, Operand(src)); }
721  void or_(Register dst, const Operand& src);
722  void or_(const Operand& dst, Register src);
723  void or_(Register dst, const Immediate& imm) { or_(Operand(dst), imm); }
724  void or_(const Operand& dst, const Immediate& x);
725 
726  void rcl(Register dst, uint8_t imm8);
727  void rcr(Register dst, uint8_t imm8);
728  void ror(Register dst, uint8_t imm8);
729  void ror_cl(Register dst);
730 
731  void sar(Register dst, uint8_t imm8) { sar(Operand(dst), imm8); }
732  void sar(const Operand& dst, uint8_t imm8);
733  void sar_cl(Register dst) { sar_cl(Operand(dst)); }
734  void sar_cl(const Operand& dst);
735 
736  void sbb(Register dst, const Operand& src);
737 
738  void shld(Register dst, Register src) { shld(dst, Operand(src)); }
739  void shld(Register dst, const Operand& src);
740 
741  void shl(Register dst, uint8_t imm8) { shl(Operand(dst), imm8); }
742  void shl(const Operand& dst, uint8_t imm8);
743  void shl_cl(Register dst) { shl_cl(Operand(dst)); }
744  void shl_cl(const Operand& dst);
745 
746  void shrd(Register dst, Register src) { shrd(dst, Operand(src)); }
747  void shrd(Register dst, const Operand& src);
748 
749  void shr(Register dst, uint8_t imm8) { shr(Operand(dst), imm8); }
750  void shr(const Operand& dst, uint8_t imm8);
751  void shr_cl(Register dst) { shr_cl(Operand(dst)); }
752  void shr_cl(const Operand& dst);
753 
754  void sub(Register dst, const Immediate& imm) { sub(Operand(dst), imm); }
755  void sub(const Operand& dst, const Immediate& x);
756  void sub(Register dst, Register src) { sub(dst, Operand(src)); }
757  void sub(Register dst, const Operand& src);
758  void sub(const Operand& dst, Register src);
759 
760  void test(Register reg, const Immediate& imm);
761  void test(Register reg0, Register reg1) { test(reg0, Operand(reg1)); }
762  void test(Register reg, const Operand& op);
763  void test_b(Register reg, const Operand& op);
764  void test(const Operand& op, const Immediate& imm);
765  void test_b(Register reg, uint8_t imm8);
766  void test_b(const Operand& op, uint8_t imm8);
767 
768  void xor_(Register dst, int32_t imm32);
769  void xor_(Register dst, Register src) { xor_(dst, Operand(src)); }
770  void xor_(Register dst, const Operand& src);
771  void xor_(const Operand& dst, Register src);
772  void xor_(Register dst, const Immediate& imm) { xor_(Operand(dst), imm); }
773  void xor_(const Operand& dst, const Immediate& x);
774 
775  // Bit operations.
776  void bt(const Operand& dst, Register src);
777  void bts(Register dst, Register src) { bts(Operand(dst), src); }
778  void bts(const Operand& dst, Register src);
779  void bsr(Register dst, Register src) { bsr(dst, Operand(src)); }
780  void bsr(Register dst, const Operand& src);
781 
782  // Miscellaneous
783  void hlt();
784  void int3();
785  void nop();
786  void ret(int imm16);
787 
788  // Label operations & relative jumps (PPUM Appendix D)
789  //
790  // Takes a branch opcode (cc) and a label (L) and generates
791  // either a backward branch or a forward branch and links it
792  // to the label fixup chain. Usage:
793  //
794  // Label L; // unbound label
795  // j(cc, &L); // forward branch to unbound label
796  // bind(&L); // bind label to the current pc
797  // j(cc, &L); // backward branch to bound label
798  // bind(&L); // illegal: a label may be bound only once
799  //
800  // Note: The same Label can be used for forward and backward branches
801  // but it may be bound only once.
802 
803  void bind(Label* L); // binds an unbound label L to the current code position
804 
805  // Calls
806  void call(Label* L);
807  void call(byte* entry, RelocInfo::Mode rmode);
808  int CallSize(const Operand& adr);
809  void call(Register reg) { call(Operand(reg)); }
810  void call(const Operand& adr);
812  void call(Handle<Code> code,
813  RelocInfo::Mode rmode,
815 
816  // Jumps
817  // unconditional jump to L
818  void jmp(Label* L, Label::Distance distance = Label::kFar);
819  void jmp(byte* entry, RelocInfo::Mode rmode);
820  void jmp(Register reg) { jmp(Operand(reg)); }
821  void jmp(const Operand& adr);
822  void jmp(Handle<Code> code, RelocInfo::Mode rmode);
823 
824  // Conditional jumps
825  void j(Condition cc,
826  Label* L,
827  Label::Distance distance = Label::kFar);
828  void j(Condition cc, byte* entry, RelocInfo::Mode rmode);
829  void j(Condition cc, Handle<Code> code);
830 
831  // Floating-point operations
832  void fld(int i);
833  void fstp(int i);
834 
835  void fld1();
836  void fldz();
837  void fldpi();
838  void fldln2();
839 
840  void fld_s(const Operand& adr);
841  void fld_d(const Operand& adr);
842 
843  void fstp_s(const Operand& adr);
844  void fst_s(const Operand& adr);
845  void fstp_d(const Operand& adr);
846  void fst_d(const Operand& adr);
847 
848  void fild_s(const Operand& adr);
849  void fild_d(const Operand& adr);
850 
851  void fist_s(const Operand& adr);
852 
853  void fistp_s(const Operand& adr);
854  void fistp_d(const Operand& adr);
855 
856  // The fisttp instructions require SSE3.
857  void fisttp_s(const Operand& adr);
858  void fisttp_d(const Operand& adr);
859 
860  void fabs();
861  void fchs();
862  void fsqrt();
863  void fcos();
864  void fsin();
865  void fptan();
866  void fyl2x();
867  void f2xm1();
868  void fscale();
869  void fninit();
870 
871  void fadd(int i);
872  void fadd_i(int i);
873  void fadd_d(const Operand& adr);
874  void fsub(int i);
875  void fsub_i(int i);
876  void fmul(int i);
877  void fmul_i(int i);
878  void fdiv(int i);
879  void fdiv_i(int i);
880 
881  void fisub_s(const Operand& adr);
882 
883  void faddp(int i = 1);
884  void fsubp(int i = 1);
885  void fsubrp(int i = 1);
886  void fmulp(int i = 1);
887  void fdivp(int i = 1);
888  void fprem();
889  void fprem1();
890 
891  void fxch(int i = 1);
892  void fincstp();
893  void ffree(int i = 0);
894 
895  void ftst();
896  void fxam();
897  void fucomp(int i);
898  void fucompp();
899  void fucomi(int i);
900  void fucomip();
901  void fcompp();
902  void fnstsw_ax();
903  void fldcw(const Operand& adr);
904  void fnstcw(const Operand& adr);
905  void fwait();
906  void fnclex();
907  void fnsave(const Operand& adr);
908  void frstor(const Operand& adr);
909 
910  void frndint();
911 
912  void sahf();
914 
915  void cpuid();
916 
917  // TODO(lrn): Need SFENCE for movnt?
918 
919  // Check the code size generated from label to here.
920  int SizeOfCodeGeneratedSince(Label* label) {
921  return pc_offset() - label->pos();
922  }
923 
924  // Mark address of the ExitJSFrame code.
926 
927  // Mark address of a debug break slot.
929 
930  // Record a comment relocation entry that can be used by a disassembler.
931  // Use --code-comments to enable, or provide "force = true" flag to always
932  // write a comment.
933  void RecordComment(const char* msg, bool force = false);
934 
935  // Writes a single byte or word of data in the code stream. Used for
936  // inline tables, e.g., jump-tables.
937  void db(uint8_t data);
938  void dd(uint32_t data);
939 
940  // Check if there is less than kGap bytes available in the buffer.
941  // If this is the case, we need to grow the buffer before emitting
942  // an instruction or relocation information.
943  inline bool buffer_overflow() const {
944  return pc_ >= reloc_info_writer.pos() - kGap;
945  }
946 
947  // Get the number of bytes available in the buffer.
948  inline int available_space() const { return reloc_info_writer.pos() - pc_; }
949 
950  static bool IsNop(Address addr);
951 
953 
955  return (buffer_ + buffer_size_) - reloc_info_writer.pos();
956  }
957 
958  // Avoid overflows for displacements etc.
959  static const int kMaximalBufferSize = 512*MB;
960 
961  byte byte_at(int pos) { return buffer_[pos]; }
962  void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
963 
964  // Allocate a constant pool of the correct size for the generated code.
966 
967  // Generate the constant pool for the generated code.
969 
970  protected:
971  byte* addr_at(int pos) { return buffer_ + pos; }
972 
973 
974  private:
975  uint32_t long_at(int pos) {
976  return *reinterpret_cast<uint32_t*>(addr_at(pos));
977  }
978  void long_at_put(int pos, uint32_t x) {
979  *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
980  }
981 
982  // code emission
983  void GrowBuffer();
984  inline void emit(uint32_t x);
985  inline void emit(Handle<Object> handle);
986  inline void emit(uint32_t x,
987  RelocInfo::Mode rmode,
989  inline void emit(Handle<Code> code,
990  RelocInfo::Mode rmode,
992  inline void emit(const Immediate& x);
993  inline void emit_w(const Immediate& x);
994 
995  // Emit the code-object-relative offset of the label's position
996  inline void emit_code_relative_offset(Label* label);
997 
998  // instruction generation
999  void emit_arith_b(int op1, int op2, Register dst, int imm8);
1000 
1001  // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81)
1002  // with a given destination expression and an immediate operand. It attempts
1003  // to use the shortest encoding possible.
1004  // sel specifies the /n in the modrm byte (see the Intel PRM).
1005  void emit_arith(int sel, Operand dst, const Immediate& x);
1006 
1007  void emit_operand(Register reg, const Operand& adr);
1008 
1009  void emit_farith(int b1, int b2, int i);
1010 
1011  // labels
1012  void print(Label* L);
1013  void bind_to(Label* L, int pos);
1014 
1015  // displacements
1016  inline Displacement disp_at(Label* L);
1017  inline void disp_at_put(Label* L, Displacement disp);
1018  inline void emit_disp(Label* L, Displacement::Type type);
1019  inline void emit_near_disp(Label* L);
1020 
1021  // record reloc info for current pc_
1022  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1023 
1024  friend class CodePatcher;
1025  friend class EnsureSpace;
1026 
1027  // code generation
1028  RelocInfoWriter reloc_info_writer;
1029 
1031  friend class PositionsRecorder;
1032 };
1033 
1034 
1035 // Helper class that ensures that there is enough space for generating
1036 // instructions and relocation information. The constructor makes
1037 // sure that there is enough space and (in debug mode) the destructor
1038 // checks that we did not generate too much.
1039 class EnsureSpace BASE_EMBEDDED {
1040  public:
1041  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
1042  if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
1043 #ifdef DEBUG
1044  space_before_ = assembler_->available_space();
1045 #endif
1046  }
1047 
1048 #ifdef DEBUG
1049  ~EnsureSpace() {
1050  int bytes_generated = space_before_ - assembler_->available_space();
1051  DCHECK(bytes_generated < assembler_->kGap);
1052  }
1053 #endif
1054 
1055  private:
1056  Assembler* assembler_;
1057 #ifdef DEBUG
1058  int space_before_;
1059 #endif
1060 };
1061 
1062 } } // namespace v8::internal
1063 
1064 #endif // V8_X87_ASSEMBLER_X87_H_
#define BASE_EMBEDDED
Definition: allocation.h:45
Isolate * isolate() const
Definition: assembler.h:62
static const int kSpecialTargetSize
void bind_to(Label *L, int pos)
void neg(Register dst)
static Address target_address_at(Address pc, Code *code)
void sar_cl(const Operand &dst)
void movsx_w(Register dst, const Operand &src)
void cmp(const Operand &op, const Immediate &imm)
static const int kCallInstructionLength
int CallSize(const Operand &adr)
RelocInfoWriter reloc_info_writer
void shrd(Register dst, Register src)
void and_(const Operand &dst, const Immediate &x)
void j(Condition cc, Handle< Code > code)
void fadd_d(const Operand &adr)
void fst_s(const Operand &adr)
void Nop(int bytes=1)
void div(const Operand &src)
void shld(Register dst, const Operand &src)
void adc(Register dst, int32_t imm32)
void cmpb(const Operand &op, int8_t imm8)
void emit_w(const Immediate &x)
void or_(Register dst, Register src)
void sub(Register dst, Register src)
Instruction * pc() const
void sub(const Operand &dst, Register src)
void shr_cl(const Operand &dst)
void mov(Register dst, Handle< Object > handle)
void emit(const Immediate &x)
void test_b(Register reg, uint8_t imm8)
void ror_cl(Register dst)
void imul(Register dst, const Operand &src)
void rcr(Register dst, uint8_t imm8)
void j(Condition cc, byte *entry, RelocInfo::Mode rmode)
void and_(Register dst, const Immediate &x)
void fst_d(const Operand &adr)
void sub(Register dst, const Immediate &imm)
static const byte kJnzShortOpcode
void fnstcw(const Operand &adr)
static Address target_address_at(Address pc, ConstantPoolArray *constant_pool)
void enter(const Immediate &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 add(Register dst, const Operand &src)
void not_(Register dst)
void sar(Register dst, uint8_t imm8)
void adc(Register dst, const Operand &src)
void jmp(const Operand &adr)
static void deserialization_set_special_target_at(Address instruction_payload, Code *code, Address target)
static const byte kNopByte
void imul(Register dst, Register src, int32_t imm32)
void RecordComment(const char *msg, bool force=false)
void xor_(const Operand &dst, const Immediate &x)
void disp_at_put(Label *L, Displacement disp)
void fild_s(const Operand &adr)
void emit_code_relative_offset(Label *label)
static const byte kJmpShortOpcode
void div(Register src)
void mov_b(Register dst, int8_t imm8)
void cmpw_ax(const Operand &op)
void j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
void sar(const Operand &dst, uint8_t imm8)
void mul(Register src)
void pop(const Operand &dst)
void sbb(Register dst, const Operand &src)
void fnsave(const Operand &adr)
void emit_disp(Label *L, Displacement::Type type)
void idiv(Register src)
void GetCode(CodeDesc *desc)
void test_b(Register reg, const Operand &op)
void add(const Operand &dst, Register src)
void ror(Register dst, uint8_t imm8)
void jmp(Handle< Code > code, RelocInfo::Mode rmode)
void db(uint8_t data)
byte * addr_at(int pos)
void or_(const Operand &dst, const Immediate &x)
static const int kPatchDebugBreakSlotAddressOffset
void lea(Register dst, const Operand &src)
void fldcw(const Operand &adr)
void and_(Register dst, int32_t imm32)
void jmp(Register reg)
static const byte kJccShortPrefix
void emit_near_disp(Label *L)
void dec(Register dst)
void long_at_put(int pos, uint32_t x)
void shr(Register dst, uint8_t imm8)
void add(Register dst, const Immediate &imm)
void shl_cl(Register dst)
static const int kPatchDebugBreakSlotReturnOffset
void and_(const Operand &dst, Register src)
void or_(Register dst, const Operand &src)
static void set_target_address_at(Address pc, Code *code, Address target, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
void cmp(const Operand &op, Handle< Object > handle)
void print(Label *L)
static const int kGap
void dec_b(const Operand &dst)
void pop(Register dst)
Displacement disp_at(Label *L)
void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data=0)
void shl(const Operand &dst, uint8_t imm8)
void shr(const Operand &dst, uint8_t imm8)
void shl(Register dst, uint8_t imm8)
void mov_b(Register dst, const Operand &src)
void setcc(Condition cc, Register reg)
void cmpw(const Operand &op, Immediate imm16)
void fld_d(const Operand &adr)
static const int kMaximalBufferSize
static Address break_address_from_return_address(Address pc)
void movsx_b(Register dst, const Operand &src)
void add(Register dst, Register src)
void mov(Register dst, const Operand &src)
void mov_b(Register dst, Register src)
void test(const Operand &op, const Immediate &imm)
void fld_s(const Operand &adr)
void inc(Register dst)
void fist_s(const Operand &adr)
uint32_t long_at(int pos)
void push(Register src)
void fisttp_s(const Operand &adr)
void call(Register reg)
void or_(Register dst, int32_t imm32)
void test(Register reg, const Immediate &imm)
void movzx_w(Register dst, Register src)
void cmpb(Register reg, int8_t imm8)
void mov(const Operand &dst, const Immediate &x)
void cmp(Register reg, int32_t imm32)
Handle< ConstantPoolArray > NewConstantPool(Isolate *isolate)
void jmp(byte *entry, RelocInfo::Mode rmode)
void movzx_b(Register dst, Register src)
void mov(Register dst, const Immediate &x)
void xor_(Register dst, int32_t imm32)
void fistp_d(const Operand &adr)
void sub(const Operand &dst, const Immediate &x)
void cmp(Register reg, Handle< Object > handle)
void call(byte *entry, RelocInfo::Mode rmode)
void fstp_d(const Operand &adr)
void mov_b(const Operand &dst, int8_t imm8)
void cmp(Register reg, const Immediate &imm)
void adr(const Register &rd, Label *label)
void imul(Register dst, Register src)
friend class PositionsRecorder
void and_(Register dst, Register src)
void emit_operand(Register reg, const Operand &adr)
void test_b(const Operand &op, uint8_t imm8)
void jmp(Label *L, Label::Distance distance=Label::kFar)
void emit(Handle< Object > handle)
void test(Register reg, const Operand &op)
static Address target_address_at(Address pc, ConstantPoolArray *constant_pool)
void movsx_w(Register dst, Register src)
void sub(Register dst, const Operand &src)
void xchg(Register dst, Register src)
void frstor(const Operand &adr)
static void set_target_address_at(Address pc, ConstantPoolArray *constant_pool, Address target, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
void shld(Register dst, Register src)
void ret(int imm16)
void test(Register reg0, Register reg1)
void fisub_s(const Operand &adr)
static bool IsNop(Address addr)
static const int kJSReturnSequenceLength
void mov_w(const Operand &dst, int16_t imm16)
void cmpb_al(const Operand &op)
void call(const Operand &adr)
void bsr(Register dst, const Operand &src)
void inc(const Operand &dst)
static const int kDebugBreakSlotLength
static const byte kJncShortOpcode
void mov(const Operand &dst, Handle< Object > handle)
void and_(Register dst, const Operand &src)
void xchg(Register dst, const Operand &src)
void sel(SecondaryField fmt, FPURegister fd, FPURegister ft, FPURegister fs, uint8_t sel)
void emit_farith(int b1, int b2, int i)
void shr_cl(Register dst)
void set_byte_at(int pos, byte value)
void bts(const Operand &dst, Register src)
static const byte kTestAlByte
void or_(Register dst, const Immediate &imm)
void emit(Handle< Code > code, RelocInfo::Mode rmode, TypeFeedbackId id=TypeFeedbackId::None())
void push(const Immediate &x)
void xor_(const Operand &dst, Register src)
void mov_w(const Operand &dst, Register src)
void rcl(Register dst, uint8_t imm8)
void cmpb(const Operand &op, Register reg)
void emit_arith_b(int op1, int op2, Register dst, int imm8)
int CallSize(Handle< Code > code, RelocInfo::Mode mode)
void movzx_w(Register dst, const Operand &src)
void fstp_s(const Operand &adr)
static const int kCallTargetAddressOffset
void call(Handle< Code > code, RelocInfo::Mode rmode, TypeFeedbackId id=TypeFeedbackId::None())
static const int kPatchReturnSequenceAddressOffset
void fistp_s(const Operand &adr)
void bt(const Operand &dst, Register src)
void mov_b(const Operand &dst, Register src)
void cmpb(Register reg, const Operand &op)
void bsr(Register dst, Register src)
void shrd(Register dst, const Operand &src)
void neg(const Operand &dst)
void xor_(Register dst, const Immediate &imm)
void idiv(const Operand &src)
void movsx_b(Register dst, Register src)
void cmp(Register reg0, Register reg1)
void bts(Register dst, Register src)
void sar_cl(Register dst)
void push_imm32(int32_t imm32)
void dd(uint32_t data)
static const byte kJcShortOpcode
void mov(const Operand &dst, Register src)
void xor_(Register dst, const Operand &src)
void imul(Register src)
void xor_(Register dst, Register src)
void dec(const Operand &dst)
void fild_d(const Operand &adr)
void cmp(Register reg, const Operand &op)
void imul(Register dst, const Operand &src, int32_t imm32)
void movzx_b(Register dst, const Operand &src)
PositionsRecorder positions_recorder_
Assembler(Isolate *isolate, void *buffer, int buffer_size)
void mov(Register dst, int32_t imm32)
void add(const Operand &dst, const Immediate &x)
PositionsRecorder * positions_recorder()
void mov(Register dst, Register src)
static Address target_address_from_return_address(Address pc)
bool buffer_overflow() const
void emit(uint32_t x)
void or_(const Operand &dst, Register src)
void emit(uint32_t x, RelocInfo::Mode rmode, TypeFeedbackId id=TypeFeedbackId::None())
void mov_w(Register dst, const Operand &src)
int SizeOfCodeGeneratedSince(Label *label)
void not_(const Operand &dst)
void shl_cl(const Operand &dst)
void emit_arith(int sel, Operand dst, const Immediate &x)
static const byte kJzShortOpcode
void PopulateConstantPool(ConstantPoolArray *constant_pool)
void dec_b(Register dst)
void push(const Operand &src)
Displacement(Label *L, Type type)
Operand(Register base, int32_t disp, RelocInfo::Mode rmode=RelocInfo::NONE32)
static Operand ForCell(Handle< Cell > cell)
void set_modrm(int mod, Register rm)
static Operand ForRegisterPlusImmediate(Register base, Immediate imm)
INLINE(explicit Operand(Register reg))
INLINE(explicit Operand(Immediate imm))
void set_sib(ScaleFactor scale, Register index, Register base)
void set_disp8(int8_t disp)
INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode))
EnsureSpace(Assembler *assembler)
bool is_reg(Register reg) const
static Operand StaticVariable(const ExternalReference &ext)
void set_dispr(int32_t disp, RelocInfo::Mode rmode)
Operand(Register index, ScaleFactor scale, int32_t disp, RelocInfo::Mode rmode=RelocInfo::NONE32)
void next(Label *L) const
Operand(Register base, Register index, ScaleFactor scale, int32_t disp, RelocInfo::Mode rmode=RelocInfo::NONE32)
void init(Label *L, Type type)
static Operand StaticArray(Register index, ScaleFactor scale, const ExternalReference &arr)
Immediate(const ExternalReference &ext)
static Immediate CodeRelativeOffset(Label *label)
Immediate(Handle< Object > handle)
ConstantPoolArray * constant_pool()
Definition: objects-inl.h:4942
Immediate(Handle< T > handle)
Operand(Register reg, Shift shift=LSL, unsigned shift_amount=0)
static bool IsNone(Mode mode)
Definition: assembler.h:439
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
signed short int16_t
Definition: unicode.cc:22
int int32_t
Definition: unicode.cc:24
const int kPointerSize
Definition: globals.h:129
const Register edx
const X87Register stX_1
const Register edi
const int kRegister_ebx_Code
const int kRegister_ecx_Code
const int kRegister_edx_Code
Condition CommuteCondition(Condition cond)
Definition: constants-arm.h:93
const X87Register stX_6
const Register esp
TypeImpl< ZoneTypeConfig > Type
const X87Register stX_3
const int kRegister_esi_Code
const int kRegister_edi_Code
DwVfpRegister DoubleRegister
const int kRegister_esp_Code
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:146
const Register esi
const Register eax
const Register ebx
const X87Register stX_4
const X87Register stX_2
Condition NegateCondition(Condition cond)
Definition: constants-arm.h:86
const int kRegister_ebp_Code
byte * Address
Definition: globals.h:101
void PrintF(const char *format,...)
Definition: utils.cc:80
const Register no_reg
@ FLUSH_ICACHE_IF_NEEDED
Definition: assembler.h:293
const Register ebp
const X87Register stX_7
const int MB
Definition: globals.h:107
const int kRegister_no_reg_Code
Definition: assembler-arm.h:75
const int kRegister_eax_Code
const X87Register stX_5
const X87Register stX_0
const Register ecx
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-x87.h:69
static Register from_code(int code)
Definition: assembler-x87.h:80
static int ToAllocationIndex(Register reg)
static Register FromAllocationIndex(int index)
bool is(Register reg) const
Definition: assembler-x87.h:87
static const char * AllocationIndexToString(int index)
static int ToAllocationIndex(Register reg)
bool is_byte_register() const
Definition: assembler-x87.h:89
static const char * AllocationIndexToString(int index)
static const int kMaxNumAllocatableRegisters
Definition: assembler-arm.h:96
static Register FromAllocationIndex(int index)
static int NumAllocatableAliasedRegisters()
static const char * AllocationIndexToString(int index)
static int NumAllocatableRegisters()
static const int kMaxNumAllocatableRegisters
static int ToAllocationIndex(X87Register reg)
static X87Register FromAllocationIndex(int index)
bool is(X87Register reg) const
static const int kMaxNumRegisters