v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
assembler-arm.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
6 // are 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
14 // distribution.
15 //
16 // - Neither the name of Sun Microsystems or the names of contributors may
17 // be used to endorse or promote products derived from this software without
18 // specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 // OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 // The original source code covered by the above license above has been
34 // modified significantly by Google Inc.
35 // Copyright 2012 the V8 project authors. All rights reserved.
36 
37 // A light-weight ARM Assembler
38 // Generates user mode instructions for the ARM architecture up to version 5
39 
40 #ifndef V8_ARM_ASSEMBLER_ARM_H_
41 #define V8_ARM_ASSEMBLER_ARM_H_
42 
43 #include <stdio.h>
44 #include <vector>
45 
46 #include "assembler.h"
47 #include "constants-arm.h"
48 #include "serialize.h"
49 
50 namespace v8 {
51 namespace internal {
52 
53 // CpuFeatures keeps track of which features are supported by the target CPU.
54 // Supported features must be enabled by a CpuFeatureScope before use.
55 class CpuFeatures : public AllStatic {
56  public:
57  // Detect features of the target CPU. Set safe defaults if the serializer
58  // is enabled (snapshots must be portable).
59  static void Probe();
60 
61  // Display target use when compiling.
62  static void PrintTarget();
63 
64  // Display features.
65  static void PrintFeatures();
66 
67  // Check whether a feature is supported by the target CPU.
68  static bool IsSupported(CpuFeature f) {
69  ASSERT(initialized_);
70  return Check(f, supported_);
71  }
72 
74  ASSERT(initialized_);
75  return Check(f, found_by_runtime_probing_only_);
76  }
77 
78  static bool IsSafeForSnapshot(CpuFeature f) {
79  return Check(f, cross_compile_) ||
80  (IsSupported(f) &&
82  }
83 
84  static unsigned cache_line_size() { return cache_line_size_; }
85 
86  static bool VerifyCrossCompiling() {
87  return cross_compile_ == 0;
88  }
89 
91  unsigned mask = flag2set(f);
92  return cross_compile_ == 0 ||
93  (cross_compile_ & mask) == mask;
94  }
95 
96  private:
97  static bool Check(CpuFeature f, unsigned set) {
98  return (set & flag2set(f)) != 0;
99  }
100 
101  static unsigned flag2set(CpuFeature f) {
102  return 1u << f;
103  }
104 
105 #ifdef DEBUG
106  static bool initialized_;
107 #endif
108  static unsigned supported_;
109  static unsigned found_by_runtime_probing_only_;
110  static unsigned cache_line_size_;
111 
112  static unsigned cross_compile_;
113 
114  friend class ExternalReference;
115  friend class PlatformFeatureScope;
117 };
118 
119 
120 // CPU Registers.
121 //
122 // 1) We would prefer to use an enum, but enum values are assignment-
123 // compatible with int, which has caused code-generation bugs.
124 //
125 // 2) We would prefer to use a class instead of a struct but we don't like
126 // the register initialization to depend on the particular initialization
127 // order (which appears to be different on OS X, Linux, and Windows for the
128 // installed versions of C++ we tried). Using a struct permits C-style
129 // "initialization". Also, the Register objects cannot be const as this
130 // forces initialization stubs in MSVC, making us dependent on initialization
131 // order.
132 //
133 // 3) By not using an enum, we are possibly preventing the compiler from
134 // doing certain constant folds, which may significantly reduce the
135 // code generated for some assembly instructions (because they boil down
136 // to a few constants). If this is a problem, we could change the code
137 // such that we use an enum in optimized mode, and the struct in debug
138 // mode. This way we get the compile-time error checking in debug mode
139 // and best performance in optimized code.
140 
141 // These constants are used in several locations, including static initializers
142 const int kRegister_no_reg_Code = -1;
143 const int kRegister_r0_Code = 0;
144 const int kRegister_r1_Code = 1;
145 const int kRegister_r2_Code = 2;
146 const int kRegister_r3_Code = 3;
147 const int kRegister_r4_Code = 4;
148 const int kRegister_r5_Code = 5;
149 const int kRegister_r6_Code = 6;
150 const int kRegister_r7_Code = 7;
151 const int kRegister_r8_Code = 8;
152 const int kRegister_r9_Code = 9;
153 const int kRegister_r10_Code = 10;
154 const int kRegister_fp_Code = 11;
155 const int kRegister_ip_Code = 12;
156 const int kRegister_sp_Code = 13;
157 const int kRegister_lr_Code = 14;
158 const int kRegister_pc_Code = 15;
159 
160 // Core register
161 struct Register {
162  static const int kNumRegisters = 16;
163  static const int kMaxNumAllocatableRegisters =
164  FLAG_enable_ool_constant_pool ? 8 : 9;
165  static const int kSizeInBytes = 4;
166 
167  inline static int NumAllocatableRegisters();
168 
169  static int ToAllocationIndex(Register reg) {
171  return reg.code();
172  }
173 
174  static Register FromAllocationIndex(int index) {
175  ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
176  return from_code(index);
177  }
178 
179  static const char* AllocationIndexToString(int index) {
180  ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
181  const char* const names[] = {
182  "r0",
183  "r1",
184  "r2",
185  "r3",
186  "r4",
187  "r5",
188  "r6",
189  "r7",
190  "r8",
191  };
192  if (FLAG_enable_ool_constant_pool && (index >= 7)) {
193  return names[index + 1];
194  }
195  return names[index];
196  }
197 
198  static Register from_code(int code) {
199  Register r = { code };
200  return r;
201  }
202 
203  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
204  bool is(Register reg) const { return code_ == reg.code_; }
205  int code() const {
206  ASSERT(is_valid());
207  return code_;
208  }
209  int bit() const {
210  ASSERT(is_valid());
211  return 1 << code_;
212  }
213 
214  void set_code(int code) {
215  code_ = code;
216  ASSERT(is_valid());
217  }
218 
219  // Unfortunately we can't make this private in a struct.
220  int code_;
221 };
222 
224 
232 // Used as constant pool pointer register if FLAG_enable_ool_constant_pool.
234 // Used as context register.
236 // Used as lithium codegen scratch register.
238 // Used as roots register.
245 
246 // Single word VFP register.
248  static const int kSizeInBytes = 4;
249  bool is_valid() const { return 0 <= code_ && code_ < 32; }
250  bool is(SwVfpRegister reg) const { return code_ == reg.code_; }
251  int code() const {
252  ASSERT(is_valid());
253  return code_;
254  }
255  int bit() const {
256  ASSERT(is_valid());
257  return 1 << code_;
258  }
259  void split_code(int* vm, int* m) const {
260  ASSERT(is_valid());
261  *m = code_ & 0x1;
262  *vm = code_ >> 1;
263  }
264 
265  int code_;
266 };
267 
268 
269 // Double word VFP register.
271  static const int kMaxNumRegisters = 32;
272  // A few double registers are reserved: one as a scratch register and one to
273  // hold 0.0, that does not fit in the immediate field of vmov instructions.
274  // d14: 0.0
275  // d15: scratch register.
276  static const int kNumReservedRegisters = 2;
279  static const int kSizeInBytes = 8;
280 
281  // Note: the number of registers can be different at snapshot and run-time.
282  // Any code included in the snapshot must be able to run both with 16 or 32
283  // registers.
284  inline static int NumRegisters();
285  inline static int NumReservedRegisters();
286  inline static int NumAllocatableRegisters();
287 
288  inline static int ToAllocationIndex(DwVfpRegister reg);
289  static const char* AllocationIndexToString(int index);
290  inline static DwVfpRegister FromAllocationIndex(int index);
291 
293  DwVfpRegister r = { code };
294  return r;
295  }
296 
297  bool is_valid() const {
298  return 0 <= code_ && code_ < kMaxNumRegisters;
299  }
300  bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
301  int code() const {
302  ASSERT(is_valid());
303  return code_;
304  }
305  int bit() const {
306  ASSERT(is_valid());
307  return 1 << code_;
308  }
309  void split_code(int* vm, int* m) const {
310  ASSERT(is_valid());
311  *m = (code_ & 0x10) >> 4;
312  *vm = code_ & 0x0F;
313  }
314 
315  int code_;
316 };
317 
318 
320 
321 
322 // Double word VFP register d0-15.
324  public:
325  static const int kMaxNumLowRegisters = 16;
326  operator DwVfpRegister() const {
327  DwVfpRegister r = { code_ };
328  return r;
329  }
331  LowDwVfpRegister r = { code };
332  return r;
333  }
334 
335  bool is_valid() const {
336  return 0 <= code_ && code_ < kMaxNumLowRegisters;
337  }
338  bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
339  bool is(LowDwVfpRegister reg) const { return code_ == reg.code_; }
340  int code() const {
341  ASSERT(is_valid());
342  return code_;
343  }
344  SwVfpRegister low() const {
345  SwVfpRegister reg;
346  reg.code_ = code_ * 2;
347 
348  ASSERT(reg.is_valid());
349  return reg;
350  }
351  SwVfpRegister high() const {
352  SwVfpRegister reg;
353  reg.code_ = (code_ * 2) + 1;
354 
355  ASSERT(reg.is_valid());
356  return reg;
357  }
358 
359  int code_;
360 };
361 
362 
363 // Quad word NEON register.
365  static const int kMaxNumRegisters = 16;
366 
368  QwNeonRegister r = { code };
369  return r;
370  }
371 
372  bool is_valid() const {
373  return (0 <= code_) && (code_ < kMaxNumRegisters);
374  }
375  bool is(QwNeonRegister reg) const { return code_ == reg.code_; }
376  int code() const {
377  ASSERT(is_valid());
378  return code_;
379  }
380  void split_code(int* vm, int* m) const {
381  ASSERT(is_valid());
382  int encoded_code = code_ << 1;
383  *m = (encoded_code & 0x10) >> 4;
384  *vm = encoded_code & 0x0F;
385  }
386 
387  int code_;
388 };
389 
390 
392 
393 
394 // Support for the VFP registers s0 to s31 (d0 to d15).
395 // Note that "s(N):s(N+1)" is the same as "d(N/2)".
396 const SwVfpRegister s0 = { 0 };
397 const SwVfpRegister s1 = { 1 };
398 const SwVfpRegister s2 = { 2 };
399 const SwVfpRegister s3 = { 3 };
400 const SwVfpRegister s4 = { 4 };
401 const SwVfpRegister s5 = { 5 };
402 const SwVfpRegister s6 = { 6 };
403 const SwVfpRegister s7 = { 7 };
404 const SwVfpRegister s8 = { 8 };
405 const SwVfpRegister s9 = { 9 };
406 const SwVfpRegister s10 = { 10 };
407 const SwVfpRegister s11 = { 11 };
408 const SwVfpRegister s12 = { 12 };
409 const SwVfpRegister s13 = { 13 };
410 const SwVfpRegister s14 = { 14 };
411 const SwVfpRegister s15 = { 15 };
412 const SwVfpRegister s16 = { 16 };
413 const SwVfpRegister s17 = { 17 };
414 const SwVfpRegister s18 = { 18 };
415 const SwVfpRegister s19 = { 19 };
416 const SwVfpRegister s20 = { 20 };
417 const SwVfpRegister s21 = { 21 };
418 const SwVfpRegister s22 = { 22 };
419 const SwVfpRegister s23 = { 23 };
420 const SwVfpRegister s24 = { 24 };
421 const SwVfpRegister s25 = { 25 };
422 const SwVfpRegister s26 = { 26 };
423 const SwVfpRegister s27 = { 27 };
424 const SwVfpRegister s28 = { 28 };
425 const SwVfpRegister s29 = { 29 };
426 const SwVfpRegister s30 = { 30 };
427 const SwVfpRegister s31 = { 31 };
428 
429 const DwVfpRegister no_dreg = { -1 };
430 const LowDwVfpRegister d0 = { 0 };
431 const LowDwVfpRegister d1 = { 1 };
432 const LowDwVfpRegister d2 = { 2 };
433 const LowDwVfpRegister d3 = { 3 };
434 const LowDwVfpRegister d4 = { 4 };
435 const LowDwVfpRegister d5 = { 5 };
436 const LowDwVfpRegister d6 = { 6 };
437 const LowDwVfpRegister d7 = { 7 };
438 const LowDwVfpRegister d8 = { 8 };
439 const LowDwVfpRegister d9 = { 9 };
440 const LowDwVfpRegister d10 = { 10 };
441 const LowDwVfpRegister d11 = { 11 };
442 const LowDwVfpRegister d12 = { 12 };
443 const LowDwVfpRegister d13 = { 13 };
444 const LowDwVfpRegister d14 = { 14 };
445 const LowDwVfpRegister d15 = { 15 };
446 const DwVfpRegister d16 = { 16 };
447 const DwVfpRegister d17 = { 17 };
448 const DwVfpRegister d18 = { 18 };
449 const DwVfpRegister d19 = { 19 };
450 const DwVfpRegister d20 = { 20 };
451 const DwVfpRegister d21 = { 21 };
452 const DwVfpRegister d22 = { 22 };
453 const DwVfpRegister d23 = { 23 };
454 const DwVfpRegister d24 = { 24 };
455 const DwVfpRegister d25 = { 25 };
456 const DwVfpRegister d26 = { 26 };
457 const DwVfpRegister d27 = { 27 };
458 const DwVfpRegister d28 = { 28 };
459 const DwVfpRegister d29 = { 29 };
460 const DwVfpRegister d30 = { 30 };
461 const DwVfpRegister d31 = { 31 };
462 
463 const QwNeonRegister q0 = { 0 };
464 const QwNeonRegister q1 = { 1 };
465 const QwNeonRegister q2 = { 2 };
466 const QwNeonRegister q3 = { 3 };
467 const QwNeonRegister q4 = { 4 };
468 const QwNeonRegister q5 = { 5 };
469 const QwNeonRegister q6 = { 6 };
470 const QwNeonRegister q7 = { 7 };
471 const QwNeonRegister q8 = { 8 };
472 const QwNeonRegister q9 = { 9 };
473 const QwNeonRegister q10 = { 10 };
474 const QwNeonRegister q11 = { 11 };
475 const QwNeonRegister q12 = { 12 };
476 const QwNeonRegister q13 = { 13 };
477 const QwNeonRegister q14 = { 14 };
478 const QwNeonRegister q15 = { 15 };
479 
480 
481 // Aliases for double registers. Defined using #define instead of
482 // "static const DwVfpRegister&" because Clang complains otherwise when a
483 // compilation unit that includes this header doesn't use the variables.
484 #define kFirstCalleeSavedDoubleReg d8
485 #define kLastCalleeSavedDoubleReg d15
486 #define kDoubleRegZero d14
487 #define kScratchDoubleReg d15
488 
489 
490 // Coprocessor register
491 struct CRegister {
492  bool is_valid() const { return 0 <= code_ && code_ < 16; }
493  bool is(CRegister creg) const { return code_ == creg.code_; }
494  int code() const {
495  ASSERT(is_valid());
496  return code_;
497  }
498  int bit() const {
499  ASSERT(is_valid());
500  return 1 << code_;
501  }
502 
503  // Unfortunately we can't make this private in a struct.
504  int code_;
505 };
506 
507 
508 const CRegister no_creg = { -1 };
509 
510 const CRegister cr0 = { 0 };
511 const CRegister cr1 = { 1 };
512 const CRegister cr2 = { 2 };
513 const CRegister cr3 = { 3 };
514 const CRegister cr4 = { 4 };
515 const CRegister cr5 = { 5 };
516 const CRegister cr6 = { 6 };
517 const CRegister cr7 = { 7 };
518 const CRegister cr8 = { 8 };
519 const CRegister cr9 = { 9 };
520 const CRegister cr10 = { 10 };
521 const CRegister cr11 = { 11 };
522 const CRegister cr12 = { 12 };
523 const CRegister cr13 = { 13 };
524 const CRegister cr14 = { 14 };
525 const CRegister cr15 = { 15 };
526 
527 
528 // Coprocessor number
530  p0 = 0,
531  p1 = 1,
532  p2 = 2,
533  p3 = 3,
534  p4 = 4,
535  p5 = 5,
536  p6 = 6,
537  p7 = 7,
538  p8 = 8,
539  p9 = 9,
540  p10 = 10,
541  p11 = 11,
542  p12 = 12,
543  p13 = 13,
544  p14 = 14,
545  p15 = 15
546 };
547 
548 
549 // -----------------------------------------------------------------------------
550 // Machine instruction Operands
551 
552 // Class Operand represents a shifter operand in data processing instructions
553 class Operand BASE_EMBEDDED {
554  public:
555  // immediate
556  INLINE(explicit Operand(int32_t immediate,
557  RelocInfo::Mode rmode = RelocInfo::NONE32));
558  INLINE(static Operand Zero()) {
559  return Operand(static_cast<int32_t>(0));
560  }
561  INLINE(explicit Operand(const ExternalReference& f));
562  explicit Operand(Handle<Object> handle);
563  INLINE(explicit Operand(Smi* value));
564 
565  // rm
566  INLINE(explicit Operand(Register rm));
567 
568  // rm <shift_op> shift_imm
569  explicit Operand(Register rm, ShiftOp shift_op, int shift_imm);
570  INLINE(static Operand SmiUntag(Register rm)) {
571  return Operand(rm, ASR, kSmiTagSize);
572  }
573  INLINE(static Operand PointerOffsetFromSmiKey(Register key)) {
575  return Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize);
576  }
577  INLINE(static Operand DoubleOffsetFromSmiKey(Register key)) {
579  return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize);
580  }
581 
582  // rm <shift_op> rs
583  explicit Operand(Register rm, ShiftOp shift_op, Register rs);
584 
585  // Return true if this is a register operand.
586  INLINE(bool is_reg() const);
587 
588  // Return true if this operand fits in one instruction so that no
589  // 2-instruction solution with a load into the ip register is necessary. If
590  // the instruction this operand is used for is a MOV or MVN instruction the
591  // actual instruction to use is required for this calculation. For other
592  // instructions instr is ignored.
593  bool is_single_instruction(const Assembler* assembler, Instr instr = 0) const;
594  bool must_output_reloc_info(const Assembler* assembler) const;
595 
596  inline int32_t immediate() const {
597  ASSERT(!rm_.is_valid());
598  return imm32_;
599  }
600 
601  Register rm() const { return rm_; }
602  Register rs() const { return rs_; }
603  ShiftOp shift_op() const { return shift_op_; }
604 
605  private:
606  Register rm_;
607  Register rs_;
608  ShiftOp shift_op_;
609  int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg
610  int32_t imm32_; // valid if rm_ == no_reg
611  RelocInfo::Mode rmode_;
612 
613  friend class Assembler;
614 };
615 
616 
617 // Class MemOperand represents a memory operand in load and store instructions
619  public:
620  // [rn +/- offset] Offset/NegOffset
621  // [rn +/- offset]! PreIndex/NegPreIndex
622  // [rn], +/- offset PostIndex/NegPostIndex
623  // offset is any signed 32-bit value; offset is first loaded to register ip if
624  // it does not fit the addressing mode (12-bit unsigned and sign bit)
625  explicit MemOperand(Register rn, int32_t offset = 0, AddrMode am = Offset);
626 
627  // [rn +/- rm] Offset/NegOffset
628  // [rn +/- rm]! PreIndex/NegPreIndex
629  // [rn], +/- rm PostIndex/NegPostIndex
630  explicit MemOperand(Register rn, Register rm, AddrMode am = Offset);
631 
632  // [rn +/- rm <shift_op> shift_imm] Offset/NegOffset
633  // [rn +/- rm <shift_op> shift_imm]! PreIndex/NegPreIndex
634  // [rn], +/- rm <shift_op> shift_imm PostIndex/NegPostIndex
635  explicit MemOperand(Register rn, Register rm,
636  ShiftOp shift_op, int shift_imm, AddrMode am = Offset);
637  INLINE(static MemOperand PointerAddressFromSmiKey(Register array,
638  Register key,
639  AddrMode am = Offset)) {
641  return MemOperand(array, key, LSL, kPointerSizeLog2 - kSmiTagSize, am);
642  }
643 
645  ASSERT(rm_.is(no_reg));
646  offset_ = offset;
647  }
648 
649  uint32_t offset() const {
650  ASSERT(rm_.is(no_reg));
651  return offset_;
652  }
653 
654  Register rn() const { return rn_; }
655  Register rm() const { return rm_; }
656  AddrMode am() const { return am_; }
657 
658  bool OffsetIsUint12Encodable() const {
659  return offset_ >= 0 ? is_uint12(offset_) : is_uint12(-offset_);
660  }
661 
662  private:
663  Register rn_; // base
664  Register rm_; // register offset
665  int32_t offset_; // valid if rm_ == no_reg
666  ShiftOp shift_op_;
667  int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg
668  AddrMode am_; // bits P, U, and W
669 
670  friend class Assembler;
671 };
672 
673 
674 // Class NeonMemOperand represents a memory operand in load and
675 // store NEON instructions
676 class NeonMemOperand BASE_EMBEDDED {
677  public:
678  // [rn {:align}] Offset
679  // [rn {:align}]! PostIndex
680  explicit NeonMemOperand(Register rn, AddrMode am = Offset, int align = 0);
681 
682  // [rn {:align}], rm PostIndex
683  explicit NeonMemOperand(Register rn, Register rm, int align = 0);
684 
685  Register rn() const { return rn_; }
686  Register rm() const { return rm_; }
687  int align() const { return align_; }
688 
689  private:
690  void SetAlignment(int align);
691 
692  Register rn_; // base
693  Register rm_; // register increment
694  int align_;
695 };
696 
697 
698 // Class NeonListOperand represents a list of NEON registers
699 class NeonListOperand BASE_EMBEDDED {
700  public:
701  explicit NeonListOperand(DoubleRegister base, int registers_count = 1);
702  DoubleRegister base() const { return base_; }
703  NeonListType type() const { return type_; }
704  private:
705  DoubleRegister base_;
706  NeonListType type_;
707 };
708 
709 
710 // Class used to build a constant pool.
711 class ConstantPoolBuilder BASE_EMBEDDED {
712  public:
713  explicit ConstantPoolBuilder();
714  void AddEntry(Assembler* assm, const RelocInfo& rinfo);
715  void Relocate(int pc_delta);
716  bool IsEmpty();
717  MaybeObject* Allocate(Heap* heap);
718  void Populate(Assembler* assm, ConstantPoolArray* constant_pool);
719 
720  inline int count_of_64bit() const { return count_of_64bit_; }
721  inline int count_of_code_ptr() const { return count_of_code_ptr_; }
722  inline int count_of_heap_ptr() const { return count_of_heap_ptr_; }
723  inline int count_of_32bit() const { return count_of_32bit_; }
724 
725  private:
726  bool Is64BitEntry(RelocInfo::Mode rmode);
727  bool Is32BitEntry(RelocInfo::Mode rmode);
728  bool IsCodePtrEntry(RelocInfo::Mode rmode);
729  bool IsHeapPtrEntry(RelocInfo::Mode rmode);
730 
731  std::vector<RelocInfo> entries_;
732  std::vector<int> merged_indexes_;
733  int count_of_64bit_;
734  int count_of_code_ptr_;
735  int count_of_heap_ptr_;
736  int count_of_32bit_;
737 };
738 
739 
740 extern const Instr kMovLrPc;
741 extern const Instr kLdrPCMask;
742 extern const Instr kLdrPCPattern;
743 extern const Instr kLdrPpMask;
744 extern const Instr kLdrPpPattern;
745 extern const Instr kBlxRegMask;
746 extern const Instr kBlxRegPattern;
747 extern const Instr kBlxIp;
748 
749 extern const Instr kMovMvnMask;
750 extern const Instr kMovMvnPattern;
751 extern const Instr kMovMvnFlip;
752 
753 extern const Instr kMovLeaveCCMask;
754 extern const Instr kMovLeaveCCPattern;
755 extern const Instr kMovwMask;
756 extern const Instr kMovwPattern;
757 extern const Instr kMovwLeaveCCFlip;
758 
759 extern const Instr kCmpCmnMask;
760 extern const Instr kCmpCmnPattern;
761 extern const Instr kCmpCmnFlip;
762 extern const Instr kAddSubFlip;
763 extern const Instr kAndBicFlip;
764 
765 struct VmovIndex {
766  unsigned char index;
767 };
768 const VmovIndex VmovIndexLo = { 0 };
769 const VmovIndex VmovIndexHi = { 1 };
770 
771 class Assembler : public AssemblerBase {
772  public:
773  // Create an assembler. Instructions and relocation information are emitted
774  // into a buffer, with the instructions starting from the beginning and the
775  // relocation information starting from the end of the buffer. See CodeDesc
776  // for a detailed comment on the layout (globals.h).
777  //
778  // If the provided buffer is NULL, the assembler allocates and grows its own
779  // buffer, and buffer_size determines the initial buffer size. The buffer is
780  // owned by the assembler and deallocated upon destruction of the assembler.
781  //
782  // If the provided buffer is not NULL, the assembler uses the provided buffer
783  // for code generation and assumes its size to be buffer_size. If the buffer
784  // is too small, a fatal error occurs. No deallocation of the buffer is done
785  // upon destruction of the assembler.
786  Assembler(Isolate* isolate, void* buffer, int buffer_size);
787  virtual ~Assembler();
788 
789  // GetCode emits any pending (non-emitted) code and fills the descriptor
790  // desc. GetCode() is idempotent; it returns the same result if no other
791  // Assembler functions are invoked in between GetCode() calls.
792  void GetCode(CodeDesc* desc);
793 
794  // Label operations & relative jumps (PPUM Appendix D)
795  //
796  // Takes a branch opcode (cc) and a label (L) and generates
797  // either a backward branch or a forward branch and links it
798  // to the label fixup chain. Usage:
799  //
800  // Label L; // unbound label
801  // j(cc, &L); // forward branch to unbound label
802  // bind(&L); // bind label to the current pc
803  // j(cc, &L); // backward branch to bound label
804  // bind(&L); // illegal: a label may be bound only once
805  //
806  // Note: The same Label can be used for forward and backward branches
807  // but it may be bound only once.
808 
809  void bind(Label* L); // binds an unbound label L to the current code position
810 
811  // Returns the branch offset to the given label from the current code position
812  // Links the label to the current position if it is still unbound
813  // Manages the jump elimination optimization if the second parameter is true.
814  int branch_offset(Label* L, bool jump_elimination_allowed);
815 
816  // Return the address in the constant pool of the code target address used by
817  // the branch/call instruction at pc, or the object in a mov.
819 
820  // Return the address in the constant pool of the code target address used by
821  // the branch/call instruction at pc, or the object in a mov.
822  INLINE(static Address target_constant_pool_address_at(
823  Address pc, ConstantPoolArray* constant_pool));
824 
825  // Read/Modify the code target address in the branch/call instruction at pc.
827  ConstantPoolArray* constant_pool));
828  INLINE(static void set_target_address_at(Address pc,
829  ConstantPoolArray* constant_pool,
830  Address target));
832  ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
833  return target_address_at(pc, constant_pool);
834  }
836  Code* code,
837  Address target)) {
838  ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
839  set_target_address_at(pc, constant_pool, target);
840  }
841 
842  // Return the code target address at a call site from the return address
843  // of that call in the instruction stream.
845 
846  // Given the address of the beginning of a call, return the address
847  // in the instruction stream that the call will return from.
849 
850  // This sets the branch destination (which is in the constant pool on ARM).
851  // This is for calls and branches within generated code.
852  inline static void deserialization_set_special_target_at(
853  Address constant_pool_entry, Code* code, Address target);
854 
855  // Here we are patching the address in the constant pool, not the actual call
856  // instruction. The address in the constant pool is the same size as a
857  // pointer.
858  static const int kSpecialTargetSize = kPointerSize;
859 
860  // Size of an instruction.
861  static const int kInstrSize = sizeof(Instr);
862 
863  // Distance between start of patched return sequence and the emitted address
864  // to jump to.
865  // Patched return sequence is:
866  // ldr ip, [pc, #0] @ emited address and start
867  // blx ip
869 
870  // Distance between start of patched debug break slot and the emitted address
871  // to jump to.
872  // Patched debug break slot code is:
873  // ldr ip, [pc, #0] @ emited address and start
874  // blx ip
876 
878 
879  // Difference between address of current opcode and value read from pc
880  // register.
881  static const int kPcLoadDelta = 8;
882 
883  static const int kJSReturnSequenceInstructions = 4;
884  static const int kDebugBreakSlotInstructions = 3;
885  static const int kDebugBreakSlotLength =
887 
888  // ---------------------------------------------------------------------------
889  // Code generation
890 
891  // Insert the smallest number of nop instructions
892  // possible to align the pc offset to a multiple
893  // of m. m must be a power of 2 (>= 4).
894  void Align(int m);
895  // Aligns code to something that's optimal for a jump target for the platform.
896  void CodeTargetAlign();
897 
898  // Branch instructions
899  void b(int branch_offset, Condition cond = al);
900  void bl(int branch_offset, Condition cond = al);
901  void blx(int branch_offset); // v5 and above
902  void blx(Register target, Condition cond = al); // v5 and above
903  void bx(Register target, Condition cond = al); // v5 and above, plus v4t
904 
905  // Convenience branch instructions using labels
906  void b(Label* L, Condition cond = al) {
907  b(branch_offset(L, cond == al), cond);
908  }
909  void b(Condition cond, Label* L) { b(branch_offset(L, cond == al), cond); }
910  void bl(Label* L, Condition cond = al) { bl(branch_offset(L, false), cond); }
911  void bl(Condition cond, Label* L) { bl(branch_offset(L, false), cond); }
912  void blx(Label* L) { blx(branch_offset(L, false)); } // v5 and above
913 
914  // Data-processing instructions
915 
916  void and_(Register dst, Register src1, const Operand& src2,
917  SBit s = LeaveCC, Condition cond = al);
918 
919  void eor(Register dst, Register src1, const Operand& src2,
920  SBit s = LeaveCC, Condition cond = al);
921 
922  void sub(Register dst, Register src1, const Operand& src2,
923  SBit s = LeaveCC, Condition cond = al);
924  void sub(Register dst, Register src1, Register src2,
925  SBit s = LeaveCC, Condition cond = al) {
926  sub(dst, src1, Operand(src2), s, cond);
927  }
928 
929  void rsb(Register dst, Register src1, const Operand& src2,
930  SBit s = LeaveCC, Condition cond = al);
931 
932  void add(Register dst, Register src1, const Operand& src2,
933  SBit s = LeaveCC, Condition cond = al);
934  void add(Register dst, Register src1, Register src2,
935  SBit s = LeaveCC, Condition cond = al) {
936  add(dst, src1, Operand(src2), s, cond);
937  }
938 
939  void adc(Register dst, Register src1, const Operand& src2,
940  SBit s = LeaveCC, Condition cond = al);
941 
942  void sbc(Register dst, Register src1, const Operand& src2,
943  SBit s = LeaveCC, Condition cond = al);
944 
945  void rsc(Register dst, Register src1, const Operand& src2,
946  SBit s = LeaveCC, Condition cond = al);
947 
948  void tst(Register src1, const Operand& src2, Condition cond = al);
949  void tst(Register src1, Register src2, Condition cond = al) {
950  tst(src1, Operand(src2), cond);
951  }
952 
953  void teq(Register src1, const Operand& src2, Condition cond = al);
954 
955  void cmp(Register src1, const Operand& src2, Condition cond = al);
956  void cmp(Register src1, Register src2, Condition cond = al) {
957  cmp(src1, Operand(src2), cond);
958  }
959  void cmp_raw_immediate(Register src1, int raw_immediate, Condition cond = al);
960 
961  void cmn(Register src1, const Operand& src2, Condition cond = al);
962 
963  void orr(Register dst, Register src1, const Operand& src2,
964  SBit s = LeaveCC, Condition cond = al);
965  void orr(Register dst, Register src1, Register src2,
966  SBit s = LeaveCC, Condition cond = al) {
967  orr(dst, src1, Operand(src2), s, cond);
968  }
969 
970  void mov(Register dst, const Operand& src,
971  SBit s = LeaveCC, Condition cond = al);
972  void mov(Register dst, Register src, SBit s = LeaveCC, Condition cond = al) {
973  mov(dst, Operand(src), s, cond);
974  }
975 
976  // Load the position of the label relative to the generated code object
977  // pointer in a register.
978  void mov_label_offset(Register dst, Label* label);
979 
980  // ARMv7 instructions for loading a 32 bit immediate in two instructions.
981  // This may actually emit a different mov instruction, but on an ARMv7 it
982  // is guaranteed to only emit one instruction.
983  void movw(Register reg, uint32_t immediate, Condition cond = al);
984  // The constant for movt should be in the range 0-0xffff.
985  void movt(Register reg, uint32_t immediate, Condition cond = al);
986 
987  void bic(Register dst, Register src1, const Operand& src2,
988  SBit s = LeaveCC, Condition cond = al);
989 
990  void mvn(Register dst, const Operand& src,
991  SBit s = LeaveCC, Condition cond = al);
992 
993  // Multiply instructions
994 
995  void mla(Register dst, Register src1, Register src2, Register srcA,
996  SBit s = LeaveCC, Condition cond = al);
997 
998  void mls(Register dst, Register src1, Register src2, Register srcA,
999  Condition cond = al);
1000 
1001  void sdiv(Register dst, Register src1, Register src2,
1002  Condition cond = al);
1003 
1004  void mul(Register dst, Register src1, Register src2,
1005  SBit s = LeaveCC, Condition cond = al);
1006 
1007  void smlal(Register dstL, Register dstH, Register src1, Register src2,
1008  SBit s = LeaveCC, Condition cond = al);
1009 
1010  void smull(Register dstL, Register dstH, Register src1, Register src2,
1011  SBit s = LeaveCC, Condition cond = al);
1012 
1013  void umlal(Register dstL, Register dstH, Register src1, Register src2,
1014  SBit s = LeaveCC, Condition cond = al);
1015 
1016  void umull(Register dstL, Register dstH, Register src1, Register src2,
1017  SBit s = LeaveCC, Condition cond = al);
1018 
1019  // Miscellaneous arithmetic instructions
1020 
1021  void clz(Register dst, Register src, Condition cond = al); // v5 and above
1022 
1023  // Saturating instructions. v6 and above.
1024 
1025  // Unsigned saturate.
1026  //
1027  // Saturate an optionally shifted signed value to an unsigned range.
1028  //
1029  // usat dst, #satpos, src
1030  // usat dst, #satpos, src, lsl #sh
1031  // usat dst, #satpos, src, asr #sh
1032  //
1033  // Register dst will contain:
1034  //
1035  // 0, if s < 0
1036  // (1 << satpos) - 1, if s > ((1 << satpos) - 1)
1037  // s, otherwise
1038  //
1039  // where s is the contents of src after shifting (if used.)
1040  void usat(Register dst, int satpos, const Operand& src, Condition cond = al);
1041 
1042  // Bitfield manipulation instructions. v7 and above.
1043 
1044  void ubfx(Register dst, Register src, int lsb, int width,
1045  Condition cond = al);
1046 
1047  void sbfx(Register dst, Register src, int lsb, int width,
1048  Condition cond = al);
1049 
1050  void bfc(Register dst, int lsb, int width, Condition cond = al);
1051 
1052  void bfi(Register dst, Register src, int lsb, int width,
1053  Condition cond = al);
1054 
1055  void pkhbt(Register dst, Register src1, const Operand& src2,
1056  Condition cond = al);
1057 
1058  void pkhtb(Register dst, Register src1, const Operand& src2,
1059  Condition cond = al);
1060 
1061  void uxtb(Register dst, const Operand& src, Condition cond = al);
1062 
1063  void uxtab(Register dst, Register src1, const Operand& src2,
1064  Condition cond = al);
1065 
1066  void uxtb16(Register dst, const Operand& src, Condition cond = al);
1067 
1068  // Status register access instructions
1069 
1070  void mrs(Register dst, SRegister s, Condition cond = al);
1071  void msr(SRegisterFieldMask fields, const Operand& src, Condition cond = al);
1072 
1073  // Load/Store instructions
1074  void ldr(Register dst, const MemOperand& src, Condition cond = al);
1075  void str(Register src, const MemOperand& dst, Condition cond = al);
1076  void ldrb(Register dst, const MemOperand& src, Condition cond = al);
1077  void strb(Register src, const MemOperand& dst, Condition cond = al);
1078  void ldrh(Register dst, const MemOperand& src, Condition cond = al);
1079  void strh(Register src, const MemOperand& dst, Condition cond = al);
1080  void ldrsb(Register dst, const MemOperand& src, Condition cond = al);
1081  void ldrsh(Register dst, const MemOperand& src, Condition cond = al);
1082  void ldrd(Register dst1,
1083  Register dst2,
1084  const MemOperand& src, Condition cond = al);
1085  void strd(Register src1,
1086  Register src2,
1087  const MemOperand& dst, Condition cond = al);
1088 
1089  // Preload instructions
1090  void pld(const MemOperand& address);
1091 
1092  // Load/Store multiple instructions
1093  void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al);
1094  void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al);
1095 
1096  // Exception-generating instructions and debugging support
1097  void stop(const char* msg,
1098  Condition cond = al,
1100 
1101  void bkpt(uint32_t imm16); // v5 and above
1102  void svc(uint32_t imm24, Condition cond = al);
1103 
1104  // Coprocessor instructions
1105 
1106  void cdp(Coprocessor coproc, int opcode_1,
1107  CRegister crd, CRegister crn, CRegister crm,
1108  int opcode_2, Condition cond = al);
1109 
1110  void cdp2(Coprocessor coproc, int opcode_1,
1111  CRegister crd, CRegister crn, CRegister crm,
1112  int opcode_2); // v5 and above
1113 
1114  void mcr(Coprocessor coproc, int opcode_1,
1115  Register rd, CRegister crn, CRegister crm,
1116  int opcode_2 = 0, Condition cond = al);
1117 
1118  void mcr2(Coprocessor coproc, int opcode_1,
1119  Register rd, CRegister crn, CRegister crm,
1120  int opcode_2 = 0); // v5 and above
1121 
1122  void mrc(Coprocessor coproc, int opcode_1,
1123  Register rd, CRegister crn, CRegister crm,
1124  int opcode_2 = 0, Condition cond = al);
1125 
1126  void mrc2(Coprocessor coproc, int opcode_1,
1127  Register rd, CRegister crn, CRegister crm,
1128  int opcode_2 = 0); // v5 and above
1129 
1130  void ldc(Coprocessor coproc, CRegister crd, const MemOperand& src,
1131  LFlag l = Short, Condition cond = al);
1132  void ldc(Coprocessor coproc, CRegister crd, Register base, int option,
1133  LFlag l = Short, Condition cond = al);
1134 
1135  void ldc2(Coprocessor coproc, CRegister crd, const MemOperand& src,
1136  LFlag l = Short); // v5 and above
1137  void ldc2(Coprocessor coproc, CRegister crd, Register base, int option,
1138  LFlag l = Short); // v5 and above
1139 
1140  // Support for VFP.
1141  // All these APIs support S0 to S31 and D0 to D31.
1142 
1143  void vldr(const DwVfpRegister dst,
1144  const Register base,
1145  int offset,
1146  const Condition cond = al);
1147  void vldr(const DwVfpRegister dst,
1148  const MemOperand& src,
1149  const Condition cond = al);
1150 
1151  void vldr(const SwVfpRegister dst,
1152  const Register base,
1153  int offset,
1154  const Condition cond = al);
1155  void vldr(const SwVfpRegister dst,
1156  const MemOperand& src,
1157  const Condition cond = al);
1158 
1159  void vstr(const DwVfpRegister src,
1160  const Register base,
1161  int offset,
1162  const Condition cond = al);
1163  void vstr(const DwVfpRegister src,
1164  const MemOperand& dst,
1165  const Condition cond = al);
1166 
1167  void vstr(const SwVfpRegister src,
1168  const Register base,
1169  int offset,
1170  const Condition cond = al);
1171  void vstr(const SwVfpRegister src,
1172  const MemOperand& dst,
1173  const Condition cond = al);
1174 
1175  void vldm(BlockAddrMode am,
1176  Register base,
1177  DwVfpRegister first,
1178  DwVfpRegister last,
1179  Condition cond = al);
1180 
1181  void vstm(BlockAddrMode am,
1182  Register base,
1183  DwVfpRegister first,
1184  DwVfpRegister last,
1185  Condition cond = al);
1186 
1187  void vldm(BlockAddrMode am,
1188  Register base,
1189  SwVfpRegister first,
1190  SwVfpRegister last,
1191  Condition cond = al);
1192 
1193  void vstm(BlockAddrMode am,
1194  Register base,
1195  SwVfpRegister first,
1196  SwVfpRegister last,
1197  Condition cond = al);
1198 
1199  void vmov(const DwVfpRegister dst,
1200  double imm,
1201  const Register scratch = no_reg);
1202  void vmov(const SwVfpRegister dst,
1203  const SwVfpRegister src,
1204  const Condition cond = al);
1205  void vmov(const DwVfpRegister dst,
1206  const DwVfpRegister src,
1207  const Condition cond = al);
1208  void vmov(const DwVfpRegister dst,
1209  const VmovIndex index,
1210  const Register src,
1211  const Condition cond = al);
1212  void vmov(const Register dst,
1213  const VmovIndex index,
1214  const DwVfpRegister src,
1215  const Condition cond = al);
1216  void vmov(const DwVfpRegister dst,
1217  const Register src1,
1218  const Register src2,
1219  const Condition cond = al);
1220  void vmov(const Register dst1,
1221  const Register dst2,
1222  const DwVfpRegister src,
1223  const Condition cond = al);
1224  void vmov(const SwVfpRegister dst,
1225  const Register src,
1226  const Condition cond = al);
1227  void vmov(const Register dst,
1228  const SwVfpRegister src,
1229  const Condition cond = al);
1230  void vcvt_f64_s32(const DwVfpRegister dst,
1231  const SwVfpRegister src,
1233  const Condition cond = al);
1234  void vcvt_f32_s32(const SwVfpRegister dst,
1235  const SwVfpRegister src,
1237  const Condition cond = al);
1238  void vcvt_f64_u32(const DwVfpRegister dst,
1239  const SwVfpRegister src,
1241  const Condition cond = al);
1242  void vcvt_s32_f64(const SwVfpRegister dst,
1243  const DwVfpRegister src,
1245  const Condition cond = al);
1246  void vcvt_u32_f64(const SwVfpRegister dst,
1247  const DwVfpRegister src,
1249  const Condition cond = al);
1250  void vcvt_f64_f32(const DwVfpRegister dst,
1251  const SwVfpRegister src,
1253  const Condition cond = al);
1254  void vcvt_f32_f64(const SwVfpRegister dst,
1255  const DwVfpRegister src,
1257  const Condition cond = al);
1258  void vcvt_f64_s32(const DwVfpRegister dst,
1259  int fraction_bits,
1260  const Condition cond = al);
1261 
1262  void vneg(const DwVfpRegister dst,
1263  const DwVfpRegister src,
1264  const Condition cond = al);
1265  void vabs(const DwVfpRegister dst,
1266  const DwVfpRegister src,
1267  const Condition cond = al);
1268  void vadd(const DwVfpRegister dst,
1269  const DwVfpRegister src1,
1270  const DwVfpRegister src2,
1271  const Condition cond = al);
1272  void vsub(const DwVfpRegister dst,
1273  const DwVfpRegister src1,
1274  const DwVfpRegister src2,
1275  const Condition cond = al);
1276  void vmul(const DwVfpRegister dst,
1277  const DwVfpRegister src1,
1278  const DwVfpRegister src2,
1279  const Condition cond = al);
1280  void vmla(const DwVfpRegister dst,
1281  const DwVfpRegister src1,
1282  const DwVfpRegister src2,
1283  const Condition cond = al);
1284  void vmls(const DwVfpRegister dst,
1285  const DwVfpRegister src1,
1286  const DwVfpRegister src2,
1287  const Condition cond = al);
1288  void vdiv(const DwVfpRegister dst,
1289  const DwVfpRegister src1,
1290  const DwVfpRegister src2,
1291  const Condition cond = al);
1292  void vcmp(const DwVfpRegister src1,
1293  const DwVfpRegister src2,
1294  const Condition cond = al);
1295  void vcmp(const DwVfpRegister src1,
1296  const double src2,
1297  const Condition cond = al);
1298  void vmrs(const Register dst,
1299  const Condition cond = al);
1300  void vmsr(const Register dst,
1301  const Condition cond = al);
1302  void vsqrt(const DwVfpRegister dst,
1303  const DwVfpRegister src,
1304  const Condition cond = al);
1305 
1306  // Support for NEON.
1307  // All these APIs support D0 to D31 and Q0 to Q15.
1308 
1309  void vld1(NeonSize size,
1310  const NeonListOperand& dst,
1311  const NeonMemOperand& src);
1312  void vst1(NeonSize size,
1313  const NeonListOperand& src,
1314  const NeonMemOperand& dst);
1315  void vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src);
1316 
1317  // Pseudo instructions
1318 
1319  // Different nop operations are used by the code generator to detect certain
1320  // states of the generated code.
1324  // IC markers.
1328  // Helper values.
1331  };
1332 
1333  void nop(int type = 0); // 0 is the default non-marking type.
1334 
1335  void push(Register src, Condition cond = al) {
1336  str(src, MemOperand(sp, 4, NegPreIndex), cond);
1337  }
1338 
1339  void pop(Register dst, Condition cond = al) {
1340  ldr(dst, MemOperand(sp, 4, PostIndex), cond);
1341  }
1342 
1343  void pop() {
1345  }
1346 
1347  // Jump unconditionally to given label.
1348  void jmp(Label* L) { b(L, al); }
1349 
1350  // Check the code size generated from label to here.
1351  int SizeOfCodeGeneratedSince(Label* label) {
1352  return pc_offset() - label->pos();
1353  }
1354 
1355  // Check the number of instructions generated from label to here.
1356  int InstructionsGeneratedSince(Label* label) {
1357  return SizeOfCodeGeneratedSince(label) / kInstrSize;
1358  }
1359 
1360  // Check whether an immediate fits an addressing mode 1 instruction.
1362 
1363  // Check whether an immediate fits an addressing mode 2 instruction.
1365 
1366  // Class for scoping postponing the constant pool generation.
1368  public:
1369  explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
1370  assem_->StartBlockConstPool();
1371  }
1373  assem_->EndBlockConstPool();
1374  }
1375 
1376  private:
1377  Assembler* assem_;
1378 
1379  DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
1380  };
1381 
1382  // Debugging
1383 
1384  // Mark address of the ExitJSFrame code.
1385  void RecordJSReturn();
1386 
1387  // Mark address of a debug break slot.
1388  void RecordDebugBreakSlot();
1389 
1390  // Record the AST id of the CallIC being compiled, so that it can be placed
1391  // in the relocation information.
1394  recorded_ast_id_ = ast_id;
1395  }
1396 
1399  return recorded_ast_id_;
1400  }
1401 
1403 
1404  // Record a comment relocation entry that can be used by a disassembler.
1405  // Use --code-comments to enable.
1406  void RecordComment(const char* msg);
1407 
1408  // Record the emission of a constant pool.
1409  //
1410  // The emission of constant pool depends on the size of the code generated and
1411  // the number of RelocInfo recorded.
1412  // The Debug mechanism needs to map code offsets between two versions of a
1413  // function, compiled with and without debugger support (see for example
1414  // Debug::PrepareForBreakPoints()).
1415  // Compiling functions with debugger support generates additional code
1416  // (Debug::GenerateSlot()). This may affect the emission of the constant
1417  // pools and cause the version of the code with debugger support to have
1418  // constant pools generated in different places.
1419  // Recording the position and size of emitted constant pools allows to
1420  // correctly compute the offset mappings between the different versions of a
1421  // function in all situations.
1422  //
1423  // The parameter indicates the size of the constant pool (in bytes), including
1424  // the marker and branch over the data.
1425  void RecordConstPool(int size);
1426 
1427  // Writes a single byte or word of data in the code stream. Used
1428  // for inline tables, e.g., jump-tables. The constant pool should be
1429  // emitted before any use of db and dd to ensure that constant pools
1430  // are not emitted as part of the tables generated.
1431  void db(uint8_t data);
1432  void dd(uint32_t data);
1433 
1434  // Emits the address of the code stub's first instruction.
1435  void emit_code_stub_address(Code* stub);
1436 
1437  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
1438 
1439  // Read/patch instructions
1440  Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
1441  void instr_at_put(int pos, Instr instr) {
1442  *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
1443  }
1444  static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
1445  static void instr_at_put(byte* pc, Instr instr) {
1446  *reinterpret_cast<Instr*>(pc) = instr;
1447  }
1448  static Condition GetCondition(Instr instr);
1449  static bool IsBranch(Instr instr);
1450  static int GetBranchOffset(Instr instr);
1451  static bool IsLdrRegisterImmediate(Instr instr);
1452  static bool IsVldrDRegisterImmediate(Instr instr);
1453  static bool IsLdrPpImmediateOffset(Instr instr);
1454  static bool IsVldrDPpImmediateOffset(Instr instr);
1455  static int GetLdrRegisterImmediateOffset(Instr instr);
1456  static int GetVldrDRegisterImmediateOffset(Instr instr);
1457  static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset);
1458  static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset);
1459  static bool IsStrRegisterImmediate(Instr instr);
1460  static Instr SetStrRegisterImmediateOffset(Instr instr, int offset);
1461  static bool IsAddRegisterImmediate(Instr instr);
1462  static Instr SetAddRegisterImmediateOffset(Instr instr, int offset);
1463  static Register GetRd(Instr instr);
1464  static Register GetRn(Instr instr);
1465  static Register GetRm(Instr instr);
1466  static bool IsPush(Instr instr);
1467  static bool IsPop(Instr instr);
1468  static bool IsStrRegFpOffset(Instr instr);
1469  static bool IsLdrRegFpOffset(Instr instr);
1470  static bool IsStrRegFpNegOffset(Instr instr);
1471  static bool IsLdrRegFpNegOffset(Instr instr);
1472  static bool IsLdrPcImmediateOffset(Instr instr);
1473  static bool IsVldrDPcImmediateOffset(Instr instr);
1474  static bool IsTstImmediate(Instr instr);
1475  static bool IsCmpRegister(Instr instr);
1476  static bool IsCmpImmediate(Instr instr);
1477  static Register GetCmpImmediateRegister(Instr instr);
1478  static int GetCmpImmediateRawImmediate(Instr instr);
1479  static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
1480  static bool IsMovT(Instr instr);
1481  static bool IsMovW(Instr instr);
1482 
1483  // Constants in pools are accessed via pc relative addressing, which can
1484  // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point
1485  // PC-relative loads, thereby defining a maximum distance between the
1486  // instruction and the accessed constant.
1487  static const int kMaxDistToIntPool = 4*KB;
1488  static const int kMaxDistToFPPool = 1*KB;
1489  // All relocations could be integer, it therefore acts as the limit.
1492 
1493  // Postpone the generation of the constant pool for the specified number of
1494  // instructions.
1495  void BlockConstPoolFor(int instructions);
1496 
1497  // Check if is time to emit a constant pool.
1498  void CheckConstPool(bool force_emit, bool require_jump);
1499 
1500  // Allocate a constant pool of the correct size for the generated code.
1501  MaybeObject* AllocateConstantPool(Heap* heap);
1502 
1503  // Generate the constant pool for the generated code.
1504  void PopulateConstantPool(ConstantPoolArray* constant_pool);
1505 
1506  bool can_use_constant_pool() const {
1507  return is_constant_pool_available() && !constant_pool_full_;
1508  }
1509 
1511  constant_pool_full_ = true;
1512  }
1513 
1514  protected:
1515  // Relocation for a type-recording IC has the AST id added to it. This
1516  // member variable is a way to pass the information from the call site to
1517  // the relocation info.
1519 
1520  int buffer_space() const { return reloc_info_writer.pos() - pc_; }
1521 
1522  // Decode branch instruction at pos and return branch target pos
1523  int target_at(int pos);
1524 
1525  // Patch branch instruction at pos to branch to given branch target pos
1526  void target_at_put(int pos, int target_pos);
1527 
1528  // Prevent contant pool emission until EndBlockConstPool is called.
1529  // Call to this function can be nested but must be followed by an equal
1530  // number of call to EndBlockConstpool.
1532  if (const_pool_blocked_nesting_++ == 0) {
1533  // Prevent constant pool checks happening by setting the next check to
1534  // the biggest possible offset.
1535  next_buffer_check_ = kMaxInt;
1536  }
1537  }
1538 
1539  // Resume constant pool emission. Need to be called as many time as
1540  // StartBlockConstPool to have an effect.
1542  if (--const_pool_blocked_nesting_ == 0) {
1543 #ifdef DEBUG
1544  // Max pool start (if we need a jump and an alignment).
1545  int start = pc_offset() + kInstrSize + 2 * kPointerSize;
1546  // Check the constant pool hasn't been blocked for too long.
1547  ASSERT((num_pending_32_bit_reloc_info_ == 0) ||
1548  (start + num_pending_64_bit_reloc_info_ * kDoubleSize <
1549  (first_const_pool_32_use_ + kMaxDistToIntPool)));
1550  ASSERT((num_pending_64_bit_reloc_info_ == 0) ||
1551  (start < (first_const_pool_64_use_ + kMaxDistToFPPool)));
1552 #endif
1553  // Two cases:
1554  // * no_const_pool_before_ >= next_buffer_check_ and the emission is
1555  // still blocked
1556  // * no_const_pool_before_ < next_buffer_check_ and the next emit will
1557  // trigger a check.
1558  next_buffer_check_ = no_const_pool_before_;
1559  }
1560  }
1561 
1562  bool is_const_pool_blocked() const {
1563  return (const_pool_blocked_nesting_ > 0) ||
1564  (pc_offset() < no_const_pool_before_);
1565  }
1566 
1568  return constant_pool_available_;
1569  }
1570 
1572  constant_pool_available_ = available;
1573  }
1574 
1575  private:
1576  int next_buffer_check_; // pc offset of next buffer check
1577 
1578  // Code generation
1579  // The relocation writer's position is at least kGap bytes below the end of
1580  // the generated instructions. This is so that multi-instruction sequences do
1581  // not have to check for overflow. The same is true for writes of large
1582  // relocation info entries.
1583  static const int kGap = 32;
1584 
1585  // Constant pool generation
1586  // Pools are emitted in the instruction stream, preferably after unconditional
1587  // jumps or after returns from functions (in dead code locations).
1588  // If a long code sequence does not contain unconditional jumps, it is
1589  // necessary to emit the constant pool before the pool gets too far from the
1590  // location it is accessed from. In this case, we emit a jump over the emitted
1591  // constant pool.
1592  // Constants in the pool may be addresses of functions that gets relocated;
1593  // if so, a relocation info entry is associated to the constant pool entry.
1594 
1595  // Repeated checking whether the constant pool should be emitted is rather
1596  // expensive. By default we only check again once a number of instructions
1597  // has been generated. That also means that the sizing of the buffers is not
1598  // an exact science, and that we rely on some slop to not overrun buffers.
1599  static const int kCheckPoolIntervalInst = 32;
1600  static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize;
1601 
1602 
1603  // Emission of the constant pool may be blocked in some code sequences.
1604  int const_pool_blocked_nesting_; // Block emission if this is not zero.
1605  int no_const_pool_before_; // Block emission before this pc offset.
1606 
1607  // Keep track of the first instruction requiring a constant pool entry
1608  // since the previous constant pool was emitted.
1609  int first_const_pool_32_use_;
1610  int first_const_pool_64_use_;
1611 
1612  // Relocation info generation
1613  // Each relocation is encoded as a variable size value
1614  static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1615  RelocInfoWriter reloc_info_writer;
1616 
1617  // Relocation info records are also used during code generation as temporary
1618  // containers for constants and code target addresses until they are emitted
1619  // to the constant pool. These pending relocation info records are temporarily
1620  // stored in a separate buffer until a constant pool is emitted.
1621  // If every instruction in a long sequence is accessing the pool, we need one
1622  // pending relocation entry per instruction.
1623 
1624  // The buffers of pending relocation info.
1625  RelocInfo pending_32_bit_reloc_info_[kMaxNumPending32RelocInfo];
1626  RelocInfo pending_64_bit_reloc_info_[kMaxNumPending64RelocInfo];
1627  // Number of pending reloc info entries in the 32 bits buffer.
1628  int num_pending_32_bit_reloc_info_;
1629  // Number of pending reloc info entries in the 64 bits buffer.
1630  int num_pending_64_bit_reloc_info_;
1631 
1632  ConstantPoolBuilder constant_pool_builder_;
1633 
1634  // The bound position, before this we cannot do instruction elimination.
1635  int last_bound_pos_;
1636 
1637  // Indicates whether the constant pool can be accessed, which is only possible
1638  // if the pp register points to the current code object's constant pool.
1639  bool constant_pool_available_;
1640  // Indicates whether the constant pool is too full to accept new entries due
1641  // to the ldr instruction's limitted immediate offset range.
1642  bool constant_pool_full_;
1643 
1644  // Code emission
1645  inline void CheckBuffer();
1646  void GrowBuffer();
1647  inline void emit(Instr x);
1648 
1649  // 32-bit immediate values
1650  void move_32_bit_immediate(Register rd,
1651  const Operand& x,
1652  Condition cond = al);
1653 
1654  // Instruction generation
1655  void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
1656  void addrmod2(Instr instr, Register rd, const MemOperand& x);
1657  void addrmod3(Instr instr, Register rd, const MemOperand& x);
1658  void addrmod4(Instr instr, Register rn, RegList rl);
1659  void addrmod5(Instr instr, CRegister crd, const MemOperand& x);
1660 
1661  // Labels
1662  void print(Label* L);
1663  void bind_to(Label* L, int pos);
1664  void next(Label* L);
1665 
1666  enum UseConstantPoolMode {
1667  USE_CONSTANT_POOL,
1668  DONT_USE_CONSTANT_POOL
1669  };
1670 
1671  // Record reloc info for current pc_
1672  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1673  void RecordRelocInfo(const RelocInfo& rinfo);
1674  void ConstantPoolAddEntry(const RelocInfo& rinfo);
1675 
1676  friend class RelocInfo;
1677  friend class CodePatcher;
1678  friend class BlockConstPoolScope;
1681 
1682  PositionsRecorder positions_recorder_;
1683  friend class PositionsRecorder;
1684  friend class EnsureSpace;
1685 };
1686 
1687 
1688 class EnsureSpace BASE_EMBEDDED {
1689  public:
1690  explicit EnsureSpace(Assembler* assembler) {
1691  assembler->CheckBuffer();
1692  }
1693 };
1694 
1695 
1696 } } // namespace v8::internal
1697 
1698 #endif // V8_ARM_ASSEMBLER_ARM_H_
byte * Address
Definition: globals.h:186
INLINE(static Operand PointerOffsetFromSmiKey(Register key))
void cmp(Register src1, const Operand &src2, Condition cond=al)
const QwNeonRegister q0
const DwVfpRegister d19
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
INLINE(static MemOperand PointerAddressFromSmiKey(Register array, Register key, AddrMode am=Offset))
static bool IsBranch(Instr instr)
static const int kMaxDistToFPPool
const SwVfpRegister s2
static DwVfpRegister FromAllocationIndex(int index)
void ldrsb(Register dst, const MemOperand &src, Condition cond=al)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if available(ARM only)") DEFINE_bool(enable_sudiv
const Instr kCmpCmnMask
bool ImmediateFitsAddrMode1Instruction(int32_t imm32)
const SwVfpRegister s28
void sdiv(Register dst, Register src1, Register src2, Condition cond=al)
Isolate * isolate() const
Definition: assembler.h:62
static bool IsVldrDPcImmediateOffset(Instr instr)
void vcvt_f64_u32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
void mrc(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0, Condition cond=al)
int InstructionsGeneratedSince(Label *label)
static int GetBranchOffset(Instr instr)
const Instr kMovwMask
const SwVfpRegister s12
const SwVfpRegister s29
static const int kDebugBreakSlotInstructions
INLINE(static Address target_pointer_address_at(Address pc))
void db(uint8_t data)
void vcvt_f32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
const SwVfpRegister s25
const SwVfpRegister s26
const CRegister cr10
const Instr kLdrPCMask
const SwVfpRegister s17
static bool IsCmpRegister(Instr instr)
const Register r3
void PopulateConstantPool(ConstantPoolArray *constant_pool)
static void PrintFeatures()
const Instr kMovwLeaveCCFlip
void strh(Register src, const MemOperand &dst, Condition cond=al)
const int kDoubleSizeLog2
Definition: globals.h:273
const QwNeonRegister q4
void bic(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void mov_label_offset(Register dst, Label *label)
void mrs(Register dst, SRegister s, Condition cond=al)
const Instr kLdrPCPattern
const Instr kMovMvnPattern
const LowDwVfpRegister d11
static bool IsStrRegFpNegOffset(Instr instr)
void instr_at_put(int pos, Instr instr)
const SwVfpRegister s7
const LowDwVfpRegister d0
void vabs(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond=al)
const DwVfpRegister d23
void set_code(int code)
const QwNeonRegister q6
const SwVfpRegister s8
const SwVfpRegister s10
ptrdiff_t offset() const
const DwVfpRegister d31
const int kRegister_r7_Code
void sbc(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
const Instr kMovLrPc
static const int kMaxNumAllocatableRegisters
static bool IsStrRegisterImmediate(Instr instr)
const int KB
Definition: globals.h:245
void cmp_raw_immediate(Register src1, int raw_immediate, Condition cond=al)
static TypeFeedbackId None()
Definition: utils.h:1149
static bool IsMovW(Instr instr)
const DwVfpRegister d24
void pop(Register dst, Condition cond=al)
void mla(Register dst, Register src1, Register src2, Register srcA, SBit s=LeaveCC, Condition cond=al)
static bool IsVldrDPpImmediateOffset(Instr instr)
const QwNeonRegister q8
const int kRegister_pc_Code
static const int kPatchDebugBreakSlotReturnOffset
int SizeOfCodeGeneratedSince(Label *label)
const SwVfpRegister s16
void bfi(Register dst, Register src, int lsb, int width, Condition cond=al)
const Register r6
static int GetCmpImmediateRawImmediate(Instr instr)
int32_t immediate() const
bool is(QwNeonRegister reg) const
void dd(uint32_t data)
static int NumAllocatableRegisters()
bool is(LowDwVfpRegister reg) const
void push(Register src, Condition cond=al)
void tst(Register src1, Register src2, Condition cond=al)
void b(int branch_offset, Condition cond=al)
INLINE(static Operand DoubleOffsetFromSmiKey(Register key))
void vld1(NeonSize size, const NeonListOperand &dst, const NeonMemOperand &src)
const QwNeonRegister q15
int int32_t
Definition: unicode.cc:47
void cmn(Register src1, const Operand &src2, Condition cond=al)
uint32_t RegList
Definition: frames.h:41
void ldrb(Register dst, const MemOperand &src, Condition cond=al)
const Instr kAddSubFlip
const QwNeonRegister q12
void smull(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
static bool IsSupported(CpuFeature f)
Definition: assembler-arm.h:68
static bool IsLdrPpImmediateOffset(Instr instr)
void clz(Register dst, Register src, Condition cond=al)
const int kMaxInt
Definition: globals.h:248
static bool enabled()
Definition: serialize.h:485
void vmul(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
bool IsNone() const
Definition: utils.h:1150
const QwNeonRegister q13
static Address target_address_at(Address pc, ConstantPoolArray *constant_pool)
const SwVfpRegister s14
const SwVfpRegister s21
static bool IsStrRegFpOffset(Instr instr)
void vsqrt(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond=al)
void RecordConstPool(int size)
static Register GetRm(Instr instr)
void bl(Label *L, Condition cond=al)
const LowDwVfpRegister d15
const Instr kLdrPpMask
static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset)
TypeFeedbackId RecordedAstId()
#define ASSERT(condition)
Definition: checks.h:329
static const int kPatchReturnSequenceAddressOffset
void bl(Condition cond, Label *L)
void svc(uint32_t imm24, Condition cond=al)
static bool IsCmpImmediate(Instr instr)
const int kPointerSizeLog2
Definition: globals.h:281
void SetRecordedAstId(TypeFeedbackId ast_id)
static bool IsSafeForSnapshot(CpuFeature f)
Definition: assembler-arm.h:78
void stm(BlockAddrMode am, Register base, RegList src, Condition cond=al)
static Instr instr_at(byte *pc)
static const int kMaxNumRegisters
const DwVfpRegister d22
const Instr kBlxRegMask
const LowDwVfpRegister d3
void ldrd(Register dst1, Register dst2, const MemOperand &src, Condition cond=al)
void ldc2(Coprocessor coproc, CRegister crd, const MemOperand &src, LFlag l=Short)
static void instr_at_put(byte *pc, Instr instr)
const Register r2
static DwVfpRegister from_code(int code)
const Instr kCmpCmnPattern
void blx(int branch_offset)
void target_at_put(int pos, int target_pos)
void vdiv(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
const SwVfpRegister s23
void vst1(NeonSize size, const NeonListOperand &src, const NeonMemOperand &dst)
const QwNeonRegister q2
const int kRegister_r3_Code
void vcvt_s32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
const DwVfpRegister d25
bool is(SwVfpRegister reg) const
static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset)
const LowDwVfpRegister d10
void strb(Register src, const MemOperand &dst, Condition cond=al)
MemOperand(Register base, ptrdiff_t offset=0, AddrMode addrmode=Offset)
const QwNeonRegister q11
const SwVfpRegister s22
void ldrh(Register dst, const MemOperand &src, Condition cond=al)
void BlockConstPoolFor(int instructions)
ConstantPoolArray * constant_pool()
Definition: objects-inl.h:4589
const VmovIndex VmovIndexHi
static const char * AllocationIndexToString(int index)
const SwVfpRegister s6
bool is(CRegister creg) const
static const int kMaxNumPending32RelocInfo
static const int kNumRegisters
const DwVfpRegister d28
const CRegister cr12
EnsureSpace(Assembler *assembler)
void mvn(Register dst, const Operand &src, SBit s=LeaveCC, Condition cond=al)
static Condition GetCondition(Instr instr)
const SwVfpRegister s31
uint8_t byte
Definition: globals.h:185
const CRegister cr8
void vneg(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond=al)
static void deserialization_set_special_target_at(Address constant_pool_entry, Code *code, Address target)
const SwVfpRegister s18
void vcvt_f64_s32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
const int kRegister_r2_Code
static bool IsPush(Instr instr)
void vldm(BlockAddrMode am, Register base, DwVfpRegister first, DwVfpRegister last, Condition cond=al)
bool is(DwVfpRegister reg) const
const DwVfpRegister d16
const Register sp
const SwVfpRegister s3
static const int kMaxNumAllocatableRegisters
bool OffsetIsUint12Encodable() const
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_string(expose_natives_as
DwVfpRegister DoubleRegister
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object size
Definition: flags.cc:211
const DwVfpRegister d18
void vmls(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
const LowDwVfpRegister d14
const int32_t kDefaultStopCode
const DwVfpRegister d17
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
const LowDwVfpRegister d7
const LowDwVfpRegister d4
void pkhtb(Register dst, Register src1, const Operand &src2, Condition cond=al)
void vsub(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
const int kDoubleSize
Definition: globals.h:266
const LowDwVfpRegister d13
static const int kSpecialTargetSize
const SwVfpRegister s13
friend class ExternalReference
const int kRegister_r5_Code
const Register ip
void GetCode(CodeDesc *desc)
const LowDwVfpRegister d6
const Register r9
const int kPointerSize
Definition: globals.h:268
void strd(Register src1, Register src2, const MemOperand &dst, Condition cond=al)
void orr(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
const SwVfpRegister s27
const QwNeonRegister q10
static const int kPcLoadDelta
void teq(Register src1, const Operand &src2, Condition cond=al)
const Instr kAndBicFlip
int branch_offset(Label *L, bool jump_elimination_allowed)
const int kRegister_r4_Code
const DwVfpRegister d27
void umlal(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
static bool IsPop(Instr instr)
const Instr kMovLeaveCCMask
void movt(Register reg, uint32_t immediate, Condition cond=al)
const CRegister cr11
void cdp2(Coprocessor coproc, int opcode_1, CRegister crd, CRegister crn, CRegister crm, int opcode_2)
const LowDwVfpRegister d5
INLINE(static Operand SmiUntag(Register rm))
const Instr kBlxIp
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
static Register FromAllocationIndex(int index)
static const int kMaxNumRegisters
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:359
static bool IsMovT(Instr instr)
void vadd(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
const Register pc
NeonListType type() const
INLINE(static Address target_address_at(Address pc, Code *code))
static Register from_code(int code)
const QwNeonRegister q9
const int kRegister_r8_Code
void vmrs(const Register dst, const Condition cond=al)
static int ToAllocationIndex(Register reg)
MaybeObject * AllocateConstantPool(Heap *heap)
void vmla(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
static bool IsFoundByRuntimeProbingOnly(CpuFeature f)
Definition: assembler-arm.h:73
void str(Register src, const MemOperand &dst, Condition cond=al)
static const int kMaxDistToIntPool
const SwVfpRegister s0
void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond=al)
const int kRegister_fp_Code
void split_code(int *vm, int *m) const
void vmov(const DwVfpRegister dst, double imm, const Register scratch=no_reg)
void CheckConstPool(bool force_emit, bool require_jump)
void mrc2(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0)
const int kRegister_lr_Code
const DwVfpRegister no_dreg
const Register r0
static Register GetRn(Instr instr)
static Address target_pointer_address_at(Address pc)
void uxtb16(Register dst, const Operand &src, Condition cond=al)
void mov(Register dst, Register src, SBit s=LeaveCC, Condition cond=al)
void pld(const MemOperand &address)
const SwVfpRegister s19
#define BASE_EMBEDDED
Definition: allocation.h:68
void eor(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
const DwVfpRegister d26
const SwVfpRegister s5
bool is_constant_pool_available() const
void add(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
const QwNeonRegister q1
static Instr SetStrRegisterImmediateOffset(Instr instr, int offset)
void set_offset(int32_t offset)
static const int kDebugBreakSlotLength
static bool IsTstImmediate(Instr instr)
const LowDwVfpRegister d9
void vcvt_f64_f32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
static Register GetRd(Instr instr)
SwVfpRegister low() const
DoubleRegister base() const
void uxtb(Register dst, const Operand &src, Condition cond=al)
static bool IsNop(Instr instr, int type=NON_MARKING_NOP)
const int kRegister_r10_Code
void vcvt_u32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
const SwVfpRegister s1
void ldr(Register dst, const MemOperand &src, Condition cond=al)
const QwNeonRegister q5
void stop(const char *msg, Condition cond=al, int32_t code=kDefaultStopCode)
const CRegister cr6
const CRegister cr15
const Register lr
void b(Condition cond, Label *L)
void movw(Register reg, uint32_t immediate, Condition cond=al)
void sub(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
bool is_valid() const
bool is(Register reg) const
const LowDwVfpRegister d2
static Instr SetAddRegisterImmediateOffset(Instr instr, int offset)
const Instr kMovLeaveCCPattern
const CRegister cr7
friend class PlatformFeatureScope
const Register r1
void smlal(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
const DwVfpRegister d29
SwVfpRegister high() const
const int kRegister_r6_Code
Operand(Register reg, Shift shift=LSL, unsigned shift_amount=0)
void vldr(const DwVfpRegister dst, const Register base, int offset, const Condition cond=al)
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:103
const CRegister cr2
const Instr kLdrPpPattern
void RecordComment(const char *msg)
const CRegister cr14
const QwNeonRegister q3
void bl(int branch_offset, Condition cond=al)
INLINE(static HeapObject *EnsureDoubleAligned(Heap *heap, HeapObject *object, int size))
static const int kMaxNumPending64RelocInfo
static int ToAllocationIndex(DwVfpRegister reg)
void emit_code_stub_address(Code *stub)
static bool IsVldrDRegisterImmediate(Instr instr)
void rsb(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
const VmovIndex VmovIndexLo
static Register GetCmpImmediateRegister(Instr instr)
void sbfx(Register dst, Register src, int lsb, int width, Condition cond=al)
const Instr kBlxRegPattern
uint32_t offset() const
const SwVfpRegister s30
const Instr kMovMvnMask
static Address target_address_from_return_address(Address pc)
bool is_const_pool_blocked() const
friend class PositionsRecorder
INLINE(static Operand Zero())
static bool IsAddRegisterImmediate(Instr instr)
void vcmp(const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
void mov(Register dst, const Operand &src, SBit s=LeaveCC, Condition cond=al)
const int kSmiTagSize
Definition: v8.h:5479
static const int kSizeInBytes
const Register r8
const CRegister cr13
QwNeonRegister QuadRegister
static bool VerifyCrossCompiling()
Definition: assembler-arm.h:86
void vmsr(const Register dst, const Condition cond=al)
void vstr(const DwVfpRegister src, const Register base, int offset, const Condition cond=al)
static LowDwVfpRegister from_code(int code)
Assembler(Isolate *isolate, void *buffer, int buffer_size)
void usat(Register dst, int satpos, const Operand &src, Condition cond=al)
void ubfx(Register dst, Register src, int lsb, int width, Condition cond=al)
const QwNeonRegister q7
const Instr kMovwPattern
void bx(Register target, Condition cond=al)
void ldrsh(Register dst, const MemOperand &src, Condition cond=al)
static const int kJSReturnSequenceInstructions
const SwVfpRegister s4
uint32_t SRegisterFieldMask
INLINE(static void set_target_address_at(Address pc, Code *code, Address target))
const CRegister no_creg
static int GetVldrDRegisterImmediateOffset(Instr instr)
void orr(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
static Address return_address_from_call_start(Address pc)
const int kSmiTag
Definition: v8.h:5478
const DwVfpRegister d30
static const int kSizeInBytes
const SwVfpRegister s20
bool is(DwVfpRegister reg) const
const DwVfpRegister d20
bool ImmediateFitsAddrMode2Instruction(int32_t imm32)
PositionsRecorder * positions_recorder()
const int kRegister_r0_Code
static const int kInstrSize
void cdp(Coprocessor coproc, int opcode_1, CRegister crd, CRegister crn, CRegister crm, int opcode_2, Condition cond=al)
static const char * AllocationIndexToString(int index)
static const int kSizeInBytes
const int kRegister_r1_Code
const CRegister cr3
const SwVfpRegister s9
static void set_target_address_at(Address pc, ConstantPoolArray *constant_pool, Address target)
const LowDwVfpRegister d12
void cmp(Register src1, Register src2, Condition cond=al)
const Register r10
const Instr kMovMvnFlip
void bfc(Register dst, int lsb, int width, Condition cond=al)
static unsigned cache_line_size()
Definition: assembler-arm.h:84
void mls(Register dst, Register src1, Register src2, Register srcA, Condition cond=al)
const Register no_reg
const LowDwVfpRegister d1
void and_(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
const CRegister cr0
const CRegister cr5
const Register fp
const CRegister cr9
bool can_use_constant_pool() const
const int kRegister_r9_Code
const int kRegister_ip_Code
const int kRegister_sp_Code
void umull(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
const CRegister cr1
static bool IsLdrRegisterImmediate(Instr instr)
void msr(SRegisterFieldMask fields, const Operand &src, Condition cond=al)
const LowDwVfpRegister d8
int64_t immediate() const
void set_constant_pool_available(bool available)
void split_code(int *vm, int *m) const
const SwVfpRegister s11
static QwNeonRegister from_code(int code)
void vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src)
void ldc(Coprocessor coproc, CRegister crd, const MemOperand &src, LFlag l=Short, Condition cond=al)
static bool VerifyCrossCompiling(CpuFeature f)
Definition: assembler-arm.h:90
const CRegister cr4
const SwVfpRegister s15
static bool IsLdrRegFpNegOffset(Instr instr)
void bkpt(uint32_t imm16)
static const int kPatchDebugBreakSlotAddressOffset
void vstm(BlockAddrMode am, Register base, DwVfpRegister first, DwVfpRegister last, Condition cond=al)
void uxtab(Register dst, Register src1, const Operand &src2, Condition cond=al)
static int GetLdrRegisterImmediateOffset(Instr instr)
void b(Label *L, Condition cond=al)
const DwVfpRegister d21
TypeFeedbackId recorded_ast_id_
void sub(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
const QwNeonRegister q14
void vcvt_f32_s32(const SwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
void rsc(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void tst(Register src1, const Operand &src2, Condition cond=al)
static const int kMaxNumLowRegisters
RelocInfo::Mode rmode() const
static bool IsLdrRegFpOffset(Instr instr)
void add(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
const Register r5
const int kRegister_no_reg_Code
const Instr kCmpCmnFlip
static const int kNumReservedRegisters
void mcr2(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0)
void mul(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
static bool IsLdrPcImmediateOffset(Instr instr)
void mcr(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0, Condition cond=al)
const SwVfpRegister s24
void split_code(int *vm, int *m) const
void pkhbt(Register dst, Register src1, const Operand &src2, Condition cond=al)
const Register r4
void adc(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
const Register r7