V8 Project
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 "src/arm/constants-arm.h"
47 #include "src/assembler.h"
48 #include "src/serialize.h"
49 
50 namespace v8 {
51 namespace internal {
52 
53 // CPU Registers.
54 //
55 // 1) We would prefer to use an enum, but enum values are assignment-
56 // compatible with int, which has caused code-generation bugs.
57 //
58 // 2) We would prefer to use a class instead of a struct but we don't like
59 // the register initialization to depend on the particular initialization
60 // order (which appears to be different on OS X, Linux, and Windows for the
61 // installed versions of C++ we tried). Using a struct permits C-style
62 // "initialization". Also, the Register objects cannot be const as this
63 // forces initialization stubs in MSVC, making us dependent on initialization
64 // order.
65 //
66 // 3) By not using an enum, we are possibly preventing the compiler from
67 // doing certain constant folds, which may significantly reduce the
68 // code generated for some assembly instructions (because they boil down
69 // to a few constants). If this is a problem, we could change the code
70 // such that we use an enum in optimized mode, and the struct in debug
71 // mode. This way we get the compile-time error checking in debug mode
72 // and best performance in optimized code.
73 
74 // These constants are used in several locations, including static initializers
75 const int kRegister_no_reg_Code = -1;
76 const int kRegister_r0_Code = 0;
77 const int kRegister_r1_Code = 1;
78 const int kRegister_r2_Code = 2;
79 const int kRegister_r3_Code = 3;
80 const int kRegister_r4_Code = 4;
81 const int kRegister_r5_Code = 5;
82 const int kRegister_r6_Code = 6;
83 const int kRegister_r7_Code = 7;
84 const int kRegister_r8_Code = 8;
85 const int kRegister_r9_Code = 9;
86 const int kRegister_r10_Code = 10;
87 const int kRegister_fp_Code = 11;
88 const int kRegister_ip_Code = 12;
89 const int kRegister_sp_Code = 13;
90 const int kRegister_lr_Code = 14;
91 const int kRegister_pc_Code = 15;
92 
93 // Core register
94 struct Register {
95  static const int kNumRegisters = 16;
96  static const int kMaxNumAllocatableRegisters =
97  FLAG_enable_ool_constant_pool ? 8 : 9;
98  static const int kSizeInBytes = 4;
99 
100  inline static int NumAllocatableRegisters();
101 
102  static int ToAllocationIndex(Register reg) {
104  return reg.code();
105  }
106 
107  static Register FromAllocationIndex(int index) {
108  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
109  return from_code(index);
110  }
111 
112  static const char* AllocationIndexToString(int index) {
113  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
114  const char* const names[] = {
115  "r0",
116  "r1",
117  "r2",
118  "r3",
119  "r4",
120  "r5",
121  "r6",
122  "r7",
123  "r8",
124  };
125  if (FLAG_enable_ool_constant_pool && (index >= 7)) {
126  return names[index + 1];
127  }
128  return names[index];
129  }
130 
131  static Register from_code(int code) {
132  Register r = { code };
133  return r;
134  }
135 
136  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
137  bool is(Register reg) const { return code_ == reg.code_; }
138  int code() const {
139  DCHECK(is_valid());
140  return code_;
141  }
142  int bit() const {
143  DCHECK(is_valid());
144  return 1 << code_;
145  }
146 
147  void set_code(int code) {
148  code_ = code;
149  DCHECK(is_valid());
150  }
151 
152  // Unfortunately we can't make this private in a struct.
153  int code_;
154 };
155 
157 
165 // Used as constant pool pointer register if FLAG_enable_ool_constant_pool.
167 // Used as context register.
169 // Used as lithium codegen scratch register.
171 // Used as roots register.
178 
179 // Single word VFP register.
181  static const int kSizeInBytes = 4;
182  bool is_valid() const { return 0 <= code_ && code_ < 32; }
183  bool is(SwVfpRegister reg) const { return code_ == reg.code_; }
184  int code() const {
185  DCHECK(is_valid());
186  return code_;
187  }
188  int bit() const {
189  DCHECK(is_valid());
190  return 1 << code_;
191  }
192  void split_code(int* vm, int* m) const {
193  DCHECK(is_valid());
194  *m = code_ & 0x1;
195  *vm = code_ >> 1;
196  }
197 
198  int code_;
199 };
200 
201 
202 // Double word VFP register.
204  static const int kMaxNumRegisters = 32;
205  // A few double registers are reserved: one as a scratch register and one to
206  // hold 0.0, that does not fit in the immediate field of vmov instructions.
207  // d14: 0.0
208  // d15: scratch register.
209  static const int kNumReservedRegisters = 2;
212  static const int kSizeInBytes = 8;
213 
214  // Note: the number of registers can be different at snapshot and run-time.
215  // Any code included in the snapshot must be able to run both with 16 or 32
216  // registers.
217  inline static int NumRegisters();
218  inline static int NumReservedRegisters();
219  inline static int NumAllocatableRegisters();
220 
221  // TODO(turbofan): This is a temporary work-around required because our
222  // register allocator does not yet support the aliasing of single/double
223  // registers on ARM.
224  inline static int NumAllocatableAliasedRegisters();
225 
226  inline static int ToAllocationIndex(DwVfpRegister reg);
227  static const char* AllocationIndexToString(int index);
228  inline static DwVfpRegister FromAllocationIndex(int index);
229 
231  DwVfpRegister r = { code };
232  return r;
233  }
234 
235  bool is_valid() const {
236  return 0 <= code_ && code_ < kMaxNumRegisters;
237  }
238  bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
239  int code() const {
240  DCHECK(is_valid());
241  return code_;
242  }
243  int bit() const {
244  DCHECK(is_valid());
245  return 1 << code_;
246  }
247  void split_code(int* vm, int* m) const {
248  DCHECK(is_valid());
249  *m = (code_ & 0x10) >> 4;
250  *vm = code_ & 0x0F;
251  }
252 
253  int code_;
254 };
255 
256 
258 
259 
260 // Double word VFP register d0-15.
262  public:
263  static const int kMaxNumLowRegisters = 16;
264  operator DwVfpRegister() const {
265  DwVfpRegister r = { code_ };
266  return r;
267  }
269  LowDwVfpRegister r = { code };
270  return r;
271  }
272 
273  bool is_valid() const {
274  return 0 <= code_ && code_ < kMaxNumLowRegisters;
275  }
276  bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
277  bool is(LowDwVfpRegister reg) const { return code_ == reg.code_; }
278  int code() const {
279  DCHECK(is_valid());
280  return code_;
281  }
282  SwVfpRegister low() const {
283  SwVfpRegister reg;
284  reg.code_ = code_ * 2;
285 
286  DCHECK(reg.is_valid());
287  return reg;
288  }
289  SwVfpRegister high() const {
290  SwVfpRegister reg;
291  reg.code_ = (code_ * 2) + 1;
292 
293  DCHECK(reg.is_valid());
294  return reg;
295  }
296 
297  int code_;
298 };
299 
300 
301 // Quad word NEON register.
303  static const int kMaxNumRegisters = 16;
304 
306  QwNeonRegister r = { code };
307  return r;
308  }
309 
310  bool is_valid() const {
311  return (0 <= code_) && (code_ < kMaxNumRegisters);
312  }
313  bool is(QwNeonRegister reg) const { return code_ == reg.code_; }
314  int code() const {
315  DCHECK(is_valid());
316  return code_;
317  }
318  void split_code(int* vm, int* m) const {
319  DCHECK(is_valid());
320  int encoded_code = code_ << 1;
321  *m = (encoded_code & 0x10) >> 4;
322  *vm = encoded_code & 0x0F;
323  }
324 
325  int code_;
326 };
327 
328 
330 
331 
332 // Support for the VFP registers s0 to s31 (d0 to d15).
333 // Note that "s(N):s(N+1)" is the same as "d(N/2)".
334 const SwVfpRegister s0 = { 0 };
335 const SwVfpRegister s1 = { 1 };
336 const SwVfpRegister s2 = { 2 };
337 const SwVfpRegister s3 = { 3 };
338 const SwVfpRegister s4 = { 4 };
339 const SwVfpRegister s5 = { 5 };
340 const SwVfpRegister s6 = { 6 };
341 const SwVfpRegister s7 = { 7 };
342 const SwVfpRegister s8 = { 8 };
343 const SwVfpRegister s9 = { 9 };
344 const SwVfpRegister s10 = { 10 };
345 const SwVfpRegister s11 = { 11 };
346 const SwVfpRegister s12 = { 12 };
347 const SwVfpRegister s13 = { 13 };
348 const SwVfpRegister s14 = { 14 };
349 const SwVfpRegister s15 = { 15 };
350 const SwVfpRegister s16 = { 16 };
351 const SwVfpRegister s17 = { 17 };
352 const SwVfpRegister s18 = { 18 };
353 const SwVfpRegister s19 = { 19 };
354 const SwVfpRegister s20 = { 20 };
355 const SwVfpRegister s21 = { 21 };
356 const SwVfpRegister s22 = { 22 };
357 const SwVfpRegister s23 = { 23 };
358 const SwVfpRegister s24 = { 24 };
359 const SwVfpRegister s25 = { 25 };
360 const SwVfpRegister s26 = { 26 };
361 const SwVfpRegister s27 = { 27 };
362 const SwVfpRegister s28 = { 28 };
363 const SwVfpRegister s29 = { 29 };
364 const SwVfpRegister s30 = { 30 };
365 const SwVfpRegister s31 = { 31 };
366 
367 const DwVfpRegister no_dreg = { -1 };
368 const LowDwVfpRegister d0 = { 0 };
369 const LowDwVfpRegister d1 = { 1 };
370 const LowDwVfpRegister d2 = { 2 };
371 const LowDwVfpRegister d3 = { 3 };
372 const LowDwVfpRegister d4 = { 4 };
373 const LowDwVfpRegister d5 = { 5 };
374 const LowDwVfpRegister d6 = { 6 };
375 const LowDwVfpRegister d7 = { 7 };
376 const LowDwVfpRegister d8 = { 8 };
377 const LowDwVfpRegister d9 = { 9 };
378 const LowDwVfpRegister d10 = { 10 };
379 const LowDwVfpRegister d11 = { 11 };
380 const LowDwVfpRegister d12 = { 12 };
381 const LowDwVfpRegister d13 = { 13 };
382 const LowDwVfpRegister d14 = { 14 };
383 const LowDwVfpRegister d15 = { 15 };
384 const DwVfpRegister d16 = { 16 };
385 const DwVfpRegister d17 = { 17 };
386 const DwVfpRegister d18 = { 18 };
387 const DwVfpRegister d19 = { 19 };
388 const DwVfpRegister d20 = { 20 };
389 const DwVfpRegister d21 = { 21 };
390 const DwVfpRegister d22 = { 22 };
391 const DwVfpRegister d23 = { 23 };
392 const DwVfpRegister d24 = { 24 };
393 const DwVfpRegister d25 = { 25 };
394 const DwVfpRegister d26 = { 26 };
395 const DwVfpRegister d27 = { 27 };
396 const DwVfpRegister d28 = { 28 };
397 const DwVfpRegister d29 = { 29 };
398 const DwVfpRegister d30 = { 30 };
399 const DwVfpRegister d31 = { 31 };
400 
401 const QwNeonRegister q0 = { 0 };
402 const QwNeonRegister q1 = { 1 };
403 const QwNeonRegister q2 = { 2 };
404 const QwNeonRegister q3 = { 3 };
405 const QwNeonRegister q4 = { 4 };
406 const QwNeonRegister q5 = { 5 };
407 const QwNeonRegister q6 = { 6 };
408 const QwNeonRegister q7 = { 7 };
409 const QwNeonRegister q8 = { 8 };
410 const QwNeonRegister q9 = { 9 };
411 const QwNeonRegister q10 = { 10 };
412 const QwNeonRegister q11 = { 11 };
413 const QwNeonRegister q12 = { 12 };
414 const QwNeonRegister q13 = { 13 };
415 const QwNeonRegister q14 = { 14 };
416 const QwNeonRegister q15 = { 15 };
417 
418 
419 // Aliases for double registers. Defined using #define instead of
420 // "static const DwVfpRegister&" because Clang complains otherwise when a
421 // compilation unit that includes this header doesn't use the variables.
422 #define kFirstCalleeSavedDoubleReg d8
423 #define kLastCalleeSavedDoubleReg d15
424 #define kDoubleRegZero d14
425 #define kScratchDoubleReg d15
426 
427 
428 // Coprocessor register
429 struct CRegister {
430  bool is_valid() const { return 0 <= code_ && code_ < 16; }
431  bool is(CRegister creg) const { return code_ == creg.code_; }
432  int code() const {
433  DCHECK(is_valid());
434  return code_;
435  }
436  int bit() const {
437  DCHECK(is_valid());
438  return 1 << code_;
439  }
440 
441  // Unfortunately we can't make this private in a struct.
442  int code_;
443 };
444 
445 
446 const CRegister no_creg = { -1 };
447 
448 const CRegister cr0 = { 0 };
449 const CRegister cr1 = { 1 };
450 const CRegister cr2 = { 2 };
451 const CRegister cr3 = { 3 };
452 const CRegister cr4 = { 4 };
453 const CRegister cr5 = { 5 };
454 const CRegister cr6 = { 6 };
455 const CRegister cr7 = { 7 };
456 const CRegister cr8 = { 8 };
457 const CRegister cr9 = { 9 };
458 const CRegister cr10 = { 10 };
459 const CRegister cr11 = { 11 };
460 const CRegister cr12 = { 12 };
461 const CRegister cr13 = { 13 };
462 const CRegister cr14 = { 14 };
463 const CRegister cr15 = { 15 };
464 
465 
466 // Coprocessor number
468  p0 = 0,
469  p1 = 1,
470  p2 = 2,
471  p3 = 3,
472  p4 = 4,
473  p5 = 5,
474  p6 = 6,
475  p7 = 7,
476  p8 = 8,
477  p9 = 9,
478  p10 = 10,
479  p11 = 11,
480  p12 = 12,
481  p13 = 13,
482  p14 = 14,
483  p15 = 15
484 };
485 
486 
487 // -----------------------------------------------------------------------------
488 // Machine instruction Operands
489 
490 // Class Operand represents a shifter operand in data processing instructions
491 class Operand BASE_EMBEDDED {
492  public:
493  // immediate
496  INLINE(static Operand Zero()) {
497  return Operand(static_cast<int32_t>(0));
498  }
499  INLINE(explicit Operand(const ExternalReference& f));
501  INLINE(explicit Operand(Smi* value));
502 
503  // rm
504  INLINE(explicit Operand(Register rm));
505 
506  // rm <shift_op> shift_imm
507  explicit Operand(Register rm, ShiftOp shift_op, int shift_imm);
508  INLINE(static Operand SmiUntag(Register rm)) {
509  return Operand(rm, ASR, kSmiTagSize);
510  }
511  INLINE(static Operand PointerOffsetFromSmiKey(Register key)) {
513  return Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize);
514  }
515  INLINE(static Operand DoubleOffsetFromSmiKey(Register key)) {
517  return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize);
518  }
519 
520  // rm <shift_op> rs
521  explicit Operand(Register rm, ShiftOp shift_op, Register rs);
522 
523  // Return true if this is a register operand.
524  INLINE(bool is_reg() const);
525 
526  // Return the number of actual instructions required to implement the given
527  // instruction for this particular operand. This can be a single instruction,
528  // if no load into the ip register is necessary, or anything between 2 and 4
529  // instructions when we need to load from the constant pool (depending upon
530  // whether the constant pool entry is in the small or extended section). If
531  // the instruction this operand is used for is a MOV or MVN instruction the
532  // actual instruction to use is required for this calculation. For other
533  // instructions instr is ignored.
534  //
535  // The value returned is only valid as long as no entries are added to the
536  // constant pool between this call and the actual instruction being emitted.
537  int instructions_required(const Assembler* assembler, Instr instr = 0) const;
538  bool must_output_reloc_info(const Assembler* assembler) const;
539 
540  inline int32_t immediate() const {
541  DCHECK(!rm_.is_valid());
542  return imm32_;
543  }
544 
545  Register rm() const { return rm_; }
546  Register rs() const { return rs_; }
547  ShiftOp shift_op() const { return shift_op_; }
548 
549  private:
553  int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg
554  int32_t imm32_; // valid if rm_ == no_reg
556 
557  friend class Assembler;
558 };
559 
560 
561 // Class MemOperand represents a memory operand in load and store instructions
563  public:
564  // [rn +/- offset] Offset/NegOffset
565  // [rn +/- offset]! PreIndex/NegPreIndex
566  // [rn], +/- offset PostIndex/NegPostIndex
567  // offset is any signed 32-bit value; offset is first loaded to register ip if
568  // it does not fit the addressing mode (12-bit unsigned and sign bit)
569  explicit MemOperand(Register rn, int32_t offset = 0, AddrMode am = Offset);
570 
571  // [rn +/- rm] Offset/NegOffset
572  // [rn +/- rm]! PreIndex/NegPreIndex
573  // [rn], +/- rm PostIndex/NegPostIndex
574  explicit MemOperand(Register rn, Register rm, AddrMode am = Offset);
575 
576  // [rn +/- rm <shift_op> shift_imm] Offset/NegOffset
577  // [rn +/- rm <shift_op> shift_imm]! PreIndex/NegPreIndex
578  // [rn], +/- rm <shift_op> shift_imm PostIndex/NegPostIndex
579  explicit MemOperand(Register rn, Register rm,
580  ShiftOp shift_op, int shift_imm, AddrMode am = Offset);
581  INLINE(static MemOperand PointerAddressFromSmiKey(Register array,
582  Register key,
583  AddrMode am = Offset)) {
585  return MemOperand(array, key, LSL, kPointerSizeLog2 - kSmiTagSize, am);
586  }
587 
589  DCHECK(rm_.is(no_reg));
590  offset_ = offset;
591  }
592 
593  uint32_t offset() const {
594  DCHECK(rm_.is(no_reg));
595  return offset_;
596  }
597 
598  Register rn() const { return rn_; }
599  Register rm() const { return rm_; }
600  AddrMode am() const { return am_; }
601 
602  bool OffsetIsUint12Encodable() const {
603  return offset_ >= 0 ? is_uint12(offset_) : is_uint12(-offset_);
604  }
605 
606  private:
607  Register rn_; // base
608  Register rm_; // register offset
609  int32_t offset_; // valid if rm_ == no_reg
610  ShiftOp shift_op_;
611  int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg
612  AddrMode am_; // bits P, U, and W
613 
614  friend class Assembler;
615 };
616 
617 
618 // Class NeonMemOperand represents a memory operand in load and
619 // store NEON instructions
620 class NeonMemOperand BASE_EMBEDDED {
621  public:
622  // [rn {:align}] Offset
623  // [rn {:align}]! PostIndex
624  explicit NeonMemOperand(Register rn, AddrMode am = Offset, int align = 0);
625 
626  // [rn {:align}], rm PostIndex
627  explicit NeonMemOperand(Register rn, Register rm, int align = 0);
628 
629  Register rn() const { return rn_; }
630  Register rm() const { return rm_; }
631  int align() const { return align_; }
632 
633  private:
634  void SetAlignment(int align);
635 
636  Register rn_; // base
637  Register rm_; // register increment
638  int align_;
639 };
640 
641 
642 // Class NeonListOperand represents a list of NEON registers
643 class NeonListOperand BASE_EMBEDDED {
644  public:
645  explicit NeonListOperand(DoubleRegister base, int registers_count = 1);
646  DoubleRegister base() const { return base_; }
647  NeonListType type() const { return type_; }
648  private:
651 };
652 
653 
654 // Class used to build a constant pool.
655 class ConstantPoolBuilder BASE_EMBEDDED {
656  public:
659  const RelocInfo& rinfo);
660  void Relocate(int pc_delta);
661  bool IsEmpty();
663  void Populate(Assembler* assm, ConstantPoolArray* constant_pool);
664 
666  return current_section_;
667  }
668 
669  inline ConstantPoolArray::NumberOfEntries* number_of_entries(
671  return &number_of_entries_[section];
672  }
673 
674  inline ConstantPoolArray::NumberOfEntries* small_entries() {
675  return number_of_entries(ConstantPoolArray::SMALL_SECTION);
676  }
677 
678  inline ConstantPoolArray::NumberOfEntries* extended_entries() {
679  return number_of_entries(ConstantPoolArray::EXTENDED_SECTION);
680  }
681 
682  private:
685  int merged_index)
686  : rinfo_(rinfo), section_(section), merged_index_(merged_index) {}
687 
691  };
692 
694 
695  std::vector<ConstantPoolEntry> entries_;
697  ConstantPoolArray::NumberOfEntries number_of_entries_[2];
698 };
699 
700 struct VmovIndex {
701  unsigned char index;
702 };
703 const VmovIndex VmovIndexLo = { 0 };
704 const VmovIndex VmovIndexHi = { 1 };
705 
706 class Assembler : public AssemblerBase {
707  public:
708  // Create an assembler. Instructions and relocation information are emitted
709  // into a buffer, with the instructions starting from the beginning and the
710  // relocation information starting from the end of the buffer. See CodeDesc
711  // for a detailed comment on the layout (globals.h).
712  //
713  // If the provided buffer is NULL, the assembler allocates and grows its own
714  // buffer, and buffer_size determines the initial buffer size. The buffer is
715  // owned by the assembler and deallocated upon destruction of the assembler.
716  //
717  // If the provided buffer is not NULL, the assembler uses the provided buffer
718  // for code generation and assumes its size to be buffer_size. If the buffer
719  // is too small, a fatal error occurs. No deallocation of the buffer is done
720  // upon destruction of the assembler.
721  Assembler(Isolate* isolate, void* buffer, int buffer_size);
722  virtual ~Assembler();
723 
724  // GetCode emits any pending (non-emitted) code and fills the descriptor
725  // desc. GetCode() is idempotent; it returns the same result if no other
726  // Assembler functions are invoked in between GetCode() calls.
727  void GetCode(CodeDesc* desc);
728 
729  // Label operations & relative jumps (PPUM Appendix D)
730  //
731  // Takes a branch opcode (cc) and a label (L) and generates
732  // either a backward branch or a forward branch and links it
733  // to the label fixup chain. Usage:
734  //
735  // Label L; // unbound label
736  // j(cc, &L); // forward branch to unbound label
737  // bind(&L); // bind label to the current pc
738  // j(cc, &L); // backward branch to bound label
739  // bind(&L); // illegal: a label may be bound only once
740  //
741  // Note: The same Label can be used for forward and backward branches
742  // but it may be bound only once.
743 
744  void bind(Label* L); // binds an unbound label L to the current code position
745 
746  // Returns the branch offset to the given label from the current code position
747  // Links the label to the current position if it is still unbound
748  // Manages the jump elimination optimization if the second parameter is true.
749  int branch_offset(Label* L, bool jump_elimination_allowed);
750 
751  // Returns true if the given pc address is the start of a constant pool load
752  // instruction sequence.
753  INLINE(static bool is_constant_pool_load(Address pc));
754 
755  // Return the address in the constant pool of the code target address used by
756  // the branch/call instruction at pc, or the object in a mov.
757  INLINE(static Address constant_pool_entry_address(
758  Address pc, ConstantPoolArray* constant_pool));
759 
760  // Read/Modify the code target address in the branch/call instruction at pc.
762  ConstantPoolArray* constant_pool));
764  ConstantPoolArray* constant_pool,
765  Address target,
766  ICacheFlushMode icache_flush_mode =
769  ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
770  return target_address_at(pc, constant_pool);
771  }
773  Code* code,
774  Address target,
775  ICacheFlushMode icache_flush_mode =
777  ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
778  set_target_address_at(pc, constant_pool, target, icache_flush_mode);
779  }
780 
781  // Return the code target address at a call site from the return address
782  // of that call in the instruction stream.
784 
785  // Given the address of the beginning of a call, return the address
786  // in the instruction stream that the call will return from.
788 
789  // Return the code target address of the patch debug break slot
791 
792  // This sets the branch destination (which is in the constant pool on ARM).
793  // This is for calls and branches within generated code.
794  inline static void deserialization_set_special_target_at(
795  Address constant_pool_entry, Code* code, Address target);
796 
797  // Here we are patching the address in the constant pool, not the actual call
798  // instruction. The address in the constant pool is the same size as a
799  // pointer.
800  static const int kSpecialTargetSize = kPointerSize;
801 
802  // Size of an instruction.
803  static const int kInstrSize = sizeof(Instr);
804 
805  // Distance between start of patched return sequence and the emitted address
806  // to jump to.
807  // Patched return sequence is:
808  // ldr ip, [pc, #0] @ emited address and start
809  // blx ip
811 
812  // Distance between start of patched debug break slot and the emitted address
813  // to jump to.
814  // Patched debug break slot code is:
815  // ldr ip, [pc, #0] @ emited address and start
816  // blx ip
818 
820 
821  // Difference between address of current opcode and value read from pc
822  // register.
823  static const int kPcLoadDelta = 8;
824 
825  static const int kJSReturnSequenceInstructions = 4;
826  static const int kDebugBreakSlotInstructions = 3;
827  static const int kDebugBreakSlotLength =
829 
830  // ---------------------------------------------------------------------------
831  // Code generation
832 
833  // Insert the smallest number of nop instructions
834  // possible to align the pc offset to a multiple
835  // of m. m must be a power of 2 (>= 4).
836  void Align(int m);
837  // Aligns code to something that's optimal for a jump target for the platform.
839 
840  // Branch instructions
841  void b(int branch_offset, Condition cond = al);
842  void bl(int branch_offset, Condition cond = al);
843  void blx(int branch_offset); // v5 and above
844  void blx(Register target, Condition cond = al); // v5 and above
845  void bx(Register target, Condition cond = al); // v5 and above, plus v4t
846 
847  // Convenience branch instructions using labels
848  void b(Label* L, Condition cond = al) {
849  b(branch_offset(L, cond == al), cond);
850  }
851  void b(Condition cond, Label* L) { b(branch_offset(L, cond == al), cond); }
852  void bl(Label* L, Condition cond = al) { bl(branch_offset(L, false), cond); }
853  void bl(Condition cond, Label* L) { bl(branch_offset(L, false), cond); }
854  void blx(Label* L) { blx(branch_offset(L, false)); } // v5 and above
855 
856  // Data-processing instructions
857 
858  void and_(Register dst, Register src1, const Operand& src2,
859  SBit s = LeaveCC, Condition cond = al);
860 
861  void eor(Register dst, Register src1, const Operand& src2,
862  SBit s = LeaveCC, Condition cond = al);
863 
864  void sub(Register dst, Register src1, const Operand& src2,
865  SBit s = LeaveCC, Condition cond = al);
866  void sub(Register dst, Register src1, Register src2,
867  SBit s = LeaveCC, Condition cond = al) {
868  sub(dst, src1, Operand(src2), s, cond);
869  }
870 
871  void rsb(Register dst, Register src1, const Operand& src2,
872  SBit s = LeaveCC, Condition cond = al);
873 
874  void add(Register dst, Register src1, const Operand& src2,
875  SBit s = LeaveCC, Condition cond = al);
876  void add(Register dst, Register src1, Register src2,
877  SBit s = LeaveCC, Condition cond = al) {
878  add(dst, src1, Operand(src2), s, cond);
879  }
880 
881  void adc(Register dst, Register src1, const Operand& src2,
882  SBit s = LeaveCC, Condition cond = al);
883 
884  void sbc(Register dst, Register src1, const Operand& src2,
885  SBit s = LeaveCC, Condition cond = al);
886 
887  void rsc(Register dst, Register src1, const Operand& src2,
888  SBit s = LeaveCC, Condition cond = al);
889 
890  void tst(Register src1, const Operand& src2, Condition cond = al);
891  void tst(Register src1, Register src2, Condition cond = al) {
892  tst(src1, Operand(src2), cond);
893  }
894 
895  void teq(Register src1, const Operand& src2, Condition cond = al);
896 
897  void cmp(Register src1, const Operand& src2, Condition cond = al);
898  void cmp(Register src1, Register src2, Condition cond = al) {
899  cmp(src1, Operand(src2), cond);
900  }
901  void cmp_raw_immediate(Register src1, int raw_immediate, Condition cond = al);
902 
903  void cmn(Register src1, const Operand& src2, Condition cond = al);
904 
905  void orr(Register dst, Register src1, const Operand& src2,
906  SBit s = LeaveCC, Condition cond = al);
907  void orr(Register dst, Register src1, Register src2,
908  SBit s = LeaveCC, Condition cond = al) {
909  orr(dst, src1, Operand(src2), s, cond);
910  }
911 
912  void mov(Register dst, const Operand& src,
913  SBit s = LeaveCC, Condition cond = al);
914  void mov(Register dst, Register src, SBit s = LeaveCC, Condition cond = al) {
915  mov(dst, Operand(src), s, cond);
916  }
917 
918  // Load the position of the label relative to the generated code object
919  // pointer in a register.
920  void mov_label_offset(Register dst, Label* label);
921 
922  // ARMv7 instructions for loading a 32 bit immediate in two instructions.
923  // The constant for movw and movt should be in the range 0-0xffff.
924  void movw(Register reg, uint32_t immediate, Condition cond = al);
925  void movt(Register reg, uint32_t immediate, Condition cond = al);
926 
927  void bic(Register dst, Register src1, const Operand& src2,
928  SBit s = LeaveCC, Condition cond = al);
929 
930  void mvn(Register dst, const Operand& src,
931  SBit s = LeaveCC, Condition cond = al);
932 
933  // Shift instructions
934 
935  void asr(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
936  Condition cond = al) {
937  if (src2.is_reg()) {
938  mov(dst, Operand(src1, ASR, src2.rm()), s, cond);
939  } else {
940  mov(dst, Operand(src1, ASR, src2.immediate()), s, cond);
941  }
942  }
943 
944  void lsl(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
945  Condition cond = al) {
946  if (src2.is_reg()) {
947  mov(dst, Operand(src1, LSL, src2.rm()), s, cond);
948  } else {
949  mov(dst, Operand(src1, LSL, src2.immediate()), s, cond);
950  }
951  }
952 
953  void lsr(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
954  Condition cond = al) {
955  if (src2.is_reg()) {
956  mov(dst, Operand(src1, LSR, src2.rm()), s, cond);
957  } else {
958  mov(dst, Operand(src1, LSR, src2.immediate()), s, cond);
959  }
960  }
961 
962  // Multiply instructions
963 
964  void mla(Register dst, Register src1, Register src2, Register srcA,
965  SBit s = LeaveCC, Condition cond = al);
966 
967  void mls(Register dst, Register src1, Register src2, Register srcA,
968  Condition cond = al);
969 
970  void sdiv(Register dst, Register src1, Register src2,
971  Condition cond = al);
972 
973  void udiv(Register dst, Register src1, Register src2, Condition cond = al);
974 
975  void mul(Register dst, Register src1, Register src2,
976  SBit s = LeaveCC, Condition cond = al);
977 
978  void smlal(Register dstL, Register dstH, Register src1, Register src2,
979  SBit s = LeaveCC, Condition cond = al);
980 
981  void smull(Register dstL, Register dstH, Register src1, Register src2,
982  SBit s = LeaveCC, Condition cond = al);
983 
984  void umlal(Register dstL, Register dstH, Register src1, Register src2,
985  SBit s = LeaveCC, Condition cond = al);
986 
987  void umull(Register dstL, Register dstH, Register src1, Register src2,
988  SBit s = LeaveCC, Condition cond = al);
989 
990  // Miscellaneous arithmetic instructions
991 
992  void clz(Register dst, Register src, Condition cond = al); // v5 and above
993 
994  // Saturating instructions. v6 and above.
995 
996  // Unsigned saturate.
997  //
998  // Saturate an optionally shifted signed value to an unsigned range.
999  //
1000  // usat dst, #satpos, src
1001  // usat dst, #satpos, src, lsl #sh
1002  // usat dst, #satpos, src, asr #sh
1003  //
1004  // Register dst will contain:
1005  //
1006  // 0, if s < 0
1007  // (1 << satpos) - 1, if s > ((1 << satpos) - 1)
1008  // s, otherwise
1009  //
1010  // where s is the contents of src after shifting (if used.)
1011  void usat(Register dst, int satpos, const Operand& src, Condition cond = al);
1012 
1013  // Bitfield manipulation instructions. v7 and above.
1014 
1015  void ubfx(Register dst, Register src, int lsb, int width,
1016  Condition cond = al);
1017 
1018  void sbfx(Register dst, Register src, int lsb, int width,
1019  Condition cond = al);
1020 
1021  void bfc(Register dst, int lsb, int width, Condition cond = al);
1022 
1023  void bfi(Register dst, Register src, int lsb, int width,
1024  Condition cond = al);
1025 
1026  void pkhbt(Register dst, Register src1, const Operand& src2,
1027  Condition cond = al);
1028 
1029  void pkhtb(Register dst, Register src1, const Operand& src2,
1030  Condition cond = al);
1031 
1032  void uxtb(Register dst, const Operand& src, Condition cond = al);
1033 
1034  void uxtab(Register dst, Register src1, const Operand& src2,
1035  Condition cond = al);
1036 
1037  void uxtb16(Register dst, const Operand& src, Condition cond = al);
1038 
1039  // Status register access instructions
1040 
1041  void mrs(Register dst, SRegister s, Condition cond = al);
1042  void msr(SRegisterFieldMask fields, const Operand& src, Condition cond = al);
1043 
1044  // Load/Store instructions
1045  void ldr(Register dst, const MemOperand& src, Condition cond = al);
1046  void str(Register src, const MemOperand& dst, Condition cond = al);
1047  void ldrb(Register dst, const MemOperand& src, Condition cond = al);
1048  void strb(Register src, const MemOperand& dst, Condition cond = al);
1049  void ldrh(Register dst, const MemOperand& src, Condition cond = al);
1050  void strh(Register src, const MemOperand& dst, Condition cond = al);
1051  void ldrsb(Register dst, const MemOperand& src, Condition cond = al);
1052  void ldrsh(Register dst, const MemOperand& src, Condition cond = al);
1053  void ldrd(Register dst1,
1054  Register dst2,
1055  const MemOperand& src, Condition cond = al);
1056  void strd(Register src1,
1057  Register src2,
1058  const MemOperand& dst, Condition cond = al);
1059 
1060  // Preload instructions
1061  void pld(const MemOperand& address);
1062 
1063  // Load/Store multiple instructions
1064  void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al);
1065  void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al);
1066 
1067  // Exception-generating instructions and debugging support
1068  void stop(const char* msg,
1069  Condition cond = al,
1070  int32_t code = kDefaultStopCode);
1071 
1072  void bkpt(uint32_t imm16); // v5 and above
1073  void svc(uint32_t imm24, Condition cond = al);
1074 
1075  // Coprocessor instructions
1076 
1077  void cdp(Coprocessor coproc, int opcode_1,
1078  CRegister crd, CRegister crn, CRegister crm,
1079  int opcode_2, Condition cond = al);
1080 
1081  void cdp2(Coprocessor coproc, int opcode_1,
1082  CRegister crd, CRegister crn, CRegister crm,
1083  int opcode_2); // v5 and above
1084 
1085  void mcr(Coprocessor coproc, int opcode_1,
1086  Register rd, CRegister crn, CRegister crm,
1087  int opcode_2 = 0, Condition cond = al);
1088 
1089  void mcr2(Coprocessor coproc, int opcode_1,
1090  Register rd, CRegister crn, CRegister crm,
1091  int opcode_2 = 0); // v5 and above
1092 
1093  void mrc(Coprocessor coproc, int opcode_1,
1094  Register rd, CRegister crn, CRegister crm,
1095  int opcode_2 = 0, Condition cond = al);
1096 
1097  void mrc2(Coprocessor coproc, int opcode_1,
1098  Register rd, CRegister crn, CRegister crm,
1099  int opcode_2 = 0); // v5 and above
1100 
1101  void ldc(Coprocessor coproc, CRegister crd, const MemOperand& src,
1102  LFlag l = Short, Condition cond = al);
1103  void ldc(Coprocessor coproc, CRegister crd, Register base, int option,
1104  LFlag l = Short, Condition cond = al);
1105 
1106  void ldc2(Coprocessor coproc, CRegister crd, const MemOperand& src,
1107  LFlag l = Short); // v5 and above
1108  void ldc2(Coprocessor coproc, CRegister crd, Register base, int option,
1109  LFlag l = Short); // v5 and above
1110 
1111  // Support for VFP.
1112  // All these APIs support S0 to S31 and D0 to D31.
1113 
1114  void vldr(const DwVfpRegister dst,
1115  const Register base,
1116  int offset,
1117  const Condition cond = al);
1118  void vldr(const DwVfpRegister dst,
1119  const MemOperand& src,
1120  const Condition cond = al);
1121 
1122  void vldr(const SwVfpRegister dst,
1123  const Register base,
1124  int offset,
1125  const Condition cond = al);
1126  void vldr(const SwVfpRegister dst,
1127  const MemOperand& src,
1128  const Condition cond = al);
1129 
1130  void vstr(const DwVfpRegister src,
1131  const Register base,
1132  int offset,
1133  const Condition cond = al);
1134  void vstr(const DwVfpRegister src,
1135  const MemOperand& dst,
1136  const Condition cond = al);
1137 
1138  void vstr(const SwVfpRegister src,
1139  const Register base,
1140  int offset,
1141  const Condition cond = al);
1142  void vstr(const SwVfpRegister src,
1143  const MemOperand& dst,
1144  const Condition cond = al);
1145 
1147  Register base,
1148  DwVfpRegister first,
1149  DwVfpRegister last,
1150  Condition cond = al);
1151 
1153  Register base,
1154  DwVfpRegister first,
1155  DwVfpRegister last,
1156  Condition cond = al);
1157 
1159  Register base,
1160  SwVfpRegister first,
1161  SwVfpRegister last,
1162  Condition cond = al);
1163 
1165  Register base,
1166  SwVfpRegister first,
1167  SwVfpRegister last,
1168  Condition cond = al);
1169 
1170  void vmov(const DwVfpRegister dst,
1171  double imm,
1172  const Register scratch = no_reg);
1173  void vmov(const SwVfpRegister dst,
1174  const SwVfpRegister src,
1175  const Condition cond = al);
1176  void vmov(const DwVfpRegister dst,
1177  const DwVfpRegister src,
1178  const Condition cond = al);
1179  void vmov(const DwVfpRegister dst,
1180  const VmovIndex index,
1181  const Register src,
1182  const Condition cond = al);
1183  void vmov(const Register dst,
1184  const VmovIndex index,
1185  const DwVfpRegister src,
1186  const Condition cond = al);
1187  void vmov(const DwVfpRegister dst,
1188  const Register src1,
1189  const Register src2,
1190  const Condition cond = al);
1191  void vmov(const Register dst1,
1192  const Register dst2,
1193  const DwVfpRegister src,
1194  const Condition cond = al);
1195  void vmov(const SwVfpRegister dst,
1196  const Register src,
1197  const Condition cond = al);
1198  void vmov(const Register dst,
1199  const SwVfpRegister src,
1200  const Condition cond = al);
1201  void vcvt_f64_s32(const DwVfpRegister dst,
1202  const SwVfpRegister src,
1204  const Condition cond = al);
1205  void vcvt_f32_s32(const SwVfpRegister dst,
1206  const SwVfpRegister src,
1208  const Condition cond = al);
1209  void vcvt_f64_u32(const DwVfpRegister dst,
1210  const SwVfpRegister src,
1212  const Condition cond = al);
1213  void vcvt_s32_f64(const SwVfpRegister dst,
1214  const DwVfpRegister src,
1216  const Condition cond = al);
1217  void vcvt_u32_f64(const SwVfpRegister dst,
1218  const DwVfpRegister src,
1220  const Condition cond = al);
1221  void vcvt_f64_f32(const DwVfpRegister dst,
1222  const SwVfpRegister src,
1224  const Condition cond = al);
1225  void vcvt_f32_f64(const SwVfpRegister dst,
1226  const DwVfpRegister src,
1228  const Condition cond = al);
1229  void vcvt_f64_s32(const DwVfpRegister dst,
1230  int fraction_bits,
1231  const Condition cond = al);
1232 
1233  void vneg(const DwVfpRegister dst,
1234  const DwVfpRegister src,
1235  const Condition cond = al);
1236  void vabs(const DwVfpRegister dst,
1237  const DwVfpRegister src,
1238  const Condition cond = al);
1239  void vadd(const DwVfpRegister dst,
1240  const DwVfpRegister src1,
1241  const DwVfpRegister src2,
1242  const Condition cond = al);
1243  void vsub(const DwVfpRegister dst,
1244  const DwVfpRegister src1,
1245  const DwVfpRegister src2,
1246  const Condition cond = al);
1247  void vmul(const DwVfpRegister dst,
1248  const DwVfpRegister src1,
1249  const DwVfpRegister src2,
1250  const Condition cond = al);
1251  void vmla(const DwVfpRegister dst,
1252  const DwVfpRegister src1,
1253  const DwVfpRegister src2,
1254  const Condition cond = al);
1255  void vmls(const DwVfpRegister dst,
1256  const DwVfpRegister src1,
1257  const DwVfpRegister src2,
1258  const Condition cond = al);
1259  void vdiv(const DwVfpRegister dst,
1260  const DwVfpRegister src1,
1261  const DwVfpRegister src2,
1262  const Condition cond = al);
1263  void vcmp(const DwVfpRegister src1,
1264  const DwVfpRegister src2,
1265  const Condition cond = al);
1266  void vcmp(const DwVfpRegister src1,
1267  const double src2,
1268  const Condition cond = al);
1269  void vmrs(const Register dst,
1270  const Condition cond = al);
1271  void vmsr(const Register dst,
1272  const Condition cond = al);
1273  void vsqrt(const DwVfpRegister dst,
1274  const DwVfpRegister src,
1275  const Condition cond = al);
1276 
1277  // Support for NEON.
1278  // All these APIs support D0 to D31 and Q0 to Q15.
1279 
1281  const NeonListOperand& dst,
1282  const NeonMemOperand& src);
1284  const NeonListOperand& src,
1285  const NeonMemOperand& dst);
1287 
1288  // Pseudo instructions
1289 
1290  // Different nop operations are used by the code generator to detect certain
1291  // states of the generated code.
1295  // IC markers.
1299  // Helper values.
1302  };
1303 
1304  void nop(int type = 0); // 0 is the default non-marking type.
1305 
1306  void push(Register src, Condition cond = al) {
1307  str(src, MemOperand(sp, 4, NegPreIndex), cond);
1308  }
1309 
1310  void pop(Register dst, Condition cond = al) {
1311  ldr(dst, MemOperand(sp, 4, PostIndex), cond);
1312  }
1313 
1314  void pop() {
1316  }
1317 
1318  // Jump unconditionally to given label.
1319  void jmp(Label* L) { b(L, al); }
1320 
1321  // Check the code size generated from label to here.
1322  int SizeOfCodeGeneratedSince(Label* label) {
1323  return pc_offset() - label->pos();
1324  }
1325 
1326  // Check the number of instructions generated from label to here.
1327  int InstructionsGeneratedSince(Label* label) {
1328  return SizeOfCodeGeneratedSince(label) / kInstrSize;
1329  }
1330 
1331  // Check whether an immediate fits an addressing mode 1 instruction.
1333 
1334  // Check whether an immediate fits an addressing mode 2 instruction.
1336 
1337  // Class for scoping postponing the constant pool generation.
1339  public:
1340  explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
1342  }
1345  }
1346 
1347  private:
1349 
1351  };
1352 
1353  // Debugging
1354 
1355  // Mark address of the ExitJSFrame code.
1357 
1358  // Mark address of a debug break slot.
1360 
1361  // Record the AST id of the CallIC being compiled, so that it can be placed
1362  // in the relocation information.
1365  recorded_ast_id_ = ast_id;
1366  }
1367 
1370  return recorded_ast_id_;
1371  }
1372 
1374 
1375  // Record a comment relocation entry that can be used by a disassembler.
1376  // Use --code-comments to enable.
1377  void RecordComment(const char* msg);
1378 
1379  // Record the emission of a constant pool.
1380  //
1381  // The emission of constant pool depends on the size of the code generated and
1382  // the number of RelocInfo recorded.
1383  // The Debug mechanism needs to map code offsets between two versions of a
1384  // function, compiled with and without debugger support (see for example
1385  // Debug::PrepareForBreakPoints()).
1386  // Compiling functions with debugger support generates additional code
1387  // (DebugCodegen::GenerateSlot()). This may affect the emission of the
1388  // constant pools and cause the version of the code with debugger support to
1389  // have constant pools generated in different places.
1390  // Recording the position and size of emitted constant pools allows to
1391  // correctly compute the offset mappings between the different versions of a
1392  // function in all situations.
1393  //
1394  // The parameter indicates the size of the constant pool (in bytes), including
1395  // the marker and branch over the data.
1397 
1398  // Writes a single byte or word of data in the code stream. Used
1399  // for inline tables, e.g., jump-tables. The constant pool should be
1400  // emitted before any use of db and dd to ensure that constant pools
1401  // are not emitted as part of the tables generated.
1402  void db(uint8_t data);
1403  void dd(uint32_t data);
1404 
1405  // Emits the address of the code stub's first instruction.
1407 
1409 
1410  // Read/patch instructions
1411  Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
1412  void instr_at_put(int pos, Instr instr) {
1413  *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
1414  }
1415  static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
1416  static void instr_at_put(byte* pc, Instr instr) {
1417  *reinterpret_cast<Instr*>(pc) = instr;
1418  }
1420  static bool IsBranch(Instr instr);
1421  static int GetBranchOffset(Instr instr);
1422  static bool IsLdrRegisterImmediate(Instr instr);
1423  static bool IsVldrDRegisterImmediate(Instr instr);
1426  static bool IsLdrPpRegOffset(Instr instr);
1428  static bool IsLdrPpImmediateOffset(Instr instr);
1429  static bool IsVldrDPpImmediateOffset(Instr instr);
1432  static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset);
1433  static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset);
1434  static bool IsStrRegisterImmediate(Instr instr);
1435  static Instr SetStrRegisterImmediateOffset(Instr instr, int offset);
1436  static bool IsAddRegisterImmediate(Instr instr);
1437  static Instr SetAddRegisterImmediateOffset(Instr instr, int offset);
1438  static Register GetRd(Instr instr);
1439  static Register GetRn(Instr instr);
1440  static Register GetRm(Instr instr);
1441  static bool IsPush(Instr instr);
1442  static bool IsPop(Instr instr);
1443  static bool IsStrRegFpOffset(Instr instr);
1444  static bool IsLdrRegFpOffset(Instr instr);
1445  static bool IsStrRegFpNegOffset(Instr instr);
1446  static bool IsLdrRegFpNegOffset(Instr instr);
1447  static bool IsLdrPcImmediateOffset(Instr instr);
1448  static bool IsVldrDPcImmediateOffset(Instr instr);
1449  static bool IsBlxReg(Instr instr);
1450  static bool IsBlxIp(Instr instr);
1451  static bool IsTstImmediate(Instr instr);
1452  static bool IsCmpRegister(Instr instr);
1453  static bool IsCmpImmediate(Instr instr);
1456  static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
1457  static bool IsMovImmed(Instr instr);
1458  static bool IsOrrImmed(Instr instr);
1459  static bool IsMovT(Instr instr);
1461  static bool IsMovW(Instr instr);
1464  static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate);
1465  static int DecodeShiftImm(Instr instr);
1466  static Instr PatchShiftImm(Instr instr, int immed);
1467 
1468  // Constants in pools are accessed via pc relative addressing, which can
1469  // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point
1470  // PC-relative loads, thereby defining a maximum distance between the
1471  // instruction and the accessed constant.
1472  static const int kMaxDistToIntPool = 4*KB;
1473  static const int kMaxDistToFPPool = 1*KB;
1474  // All relocations could be integer, it therefore acts as the limit.
1477 
1478  // Postpone the generation of the constant pool for the specified number of
1479  // instructions.
1480  void BlockConstPoolFor(int instructions);
1481 
1482  // Check if is time to emit a constant pool.
1483  void CheckConstPool(bool force_emit, bool require_jump);
1484 
1485  // Allocate a constant pool of the correct size for the generated code.
1487 
1488  // Generate the constant pool for the generated code.
1490 
1492 
1494  return constant_pool_builder_.current_section() ==
1496  }
1497 
1498 
1499  protected:
1500  // Relocation for a type-recording IC has the AST id added to it. This
1501  // member variable is a way to pass the information from the call site to
1502  // the relocation info.
1504 
1505  int buffer_space() const { return reloc_info_writer.pos() - pc_; }
1506 
1507  // Decode branch instruction at pos and return branch target pos
1508  int target_at(int pos);
1509 
1510  // Patch branch instruction at pos to branch to given branch target pos
1511  void target_at_put(int pos, int target_pos);
1512 
1513  // Prevent contant pool emission until EndBlockConstPool is called.
1514  // Call to this function can be nested but must be followed by an equal
1515  // number of call to EndBlockConstpool.
1517  if (const_pool_blocked_nesting_++ == 0) {
1518  // Prevent constant pool checks happening by setting the next check to
1519  // the biggest possible offset.
1521  }
1522  }
1523 
1524  // Resume constant pool emission. Need to be called as many time as
1525  // StartBlockConstPool to have an effect.
1527  if (--const_pool_blocked_nesting_ == 0) {
1528 #ifdef DEBUG
1529  // Max pool start (if we need a jump and an alignment).
1530  int start = pc_offset() + kInstrSize + 2 * kPointerSize;
1531  // Check the constant pool hasn't been blocked for too long.
1537 #endif
1538  // Two cases:
1539  // * no_const_pool_before_ >= next_buffer_check_ and the emission is
1540  // still blocked
1541  // * no_const_pool_before_ < next_buffer_check_ and the next emit will
1542  // trigger a check.
1544  }
1545  }
1546 
1547  bool is_const_pool_blocked() const {
1548  return (const_pool_blocked_nesting_ > 0) ||
1550  }
1551 
1554  }
1555 
1556  private:
1557  int next_buffer_check_; // pc offset of next buffer check
1558 
1559  // Code generation
1560  // The relocation writer's position is at least kGap bytes below the end of
1561  // the generated instructions. This is so that multi-instruction sequences do
1562  // not have to check for overflow. The same is true for writes of large
1563  // relocation info entries.
1564  static const int kGap = 32;
1565 
1566  // Constant pool generation
1567  // Pools are emitted in the instruction stream, preferably after unconditional
1568  // jumps or after returns from functions (in dead code locations).
1569  // If a long code sequence does not contain unconditional jumps, it is
1570  // necessary to emit the constant pool before the pool gets too far from the
1571  // location it is accessed from. In this case, we emit a jump over the emitted
1572  // constant pool.
1573  // Constants in the pool may be addresses of functions that gets relocated;
1574  // if so, a relocation info entry is associated to the constant pool entry.
1575 
1576  // Repeated checking whether the constant pool should be emitted is rather
1577  // expensive. By default we only check again once a number of instructions
1578  // has been generated. That also means that the sizing of the buffers is not
1579  // an exact science, and that we rely on some slop to not overrun buffers.
1580  static const int kCheckPoolIntervalInst = 32;
1582 
1583 
1584  // Emission of the constant pool may be blocked in some code sequences.
1585  int const_pool_blocked_nesting_; // Block emission if this is not zero.
1586  int no_const_pool_before_; // Block emission before this pc offset.
1587 
1588  // Keep track of the first instruction requiring a constant pool entry
1589  // since the previous constant pool was emitted.
1592 
1593  // Relocation info generation
1594  // Each relocation is encoded as a variable size value
1595  static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1596  RelocInfoWriter reloc_info_writer;
1597 
1598  // Relocation info records are also used during code generation as temporary
1599  // containers for constants and code target addresses until they are emitted
1600  // to the constant pool. These pending relocation info records are temporarily
1601  // stored in a separate buffer until a constant pool is emitted.
1602  // If every instruction in a long sequence is accessing the pool, we need one
1603  // pending relocation entry per instruction.
1604 
1605  // The buffers of pending relocation info.
1608  // Number of pending reloc info entries in the 32 bits buffer.
1610  // Number of pending reloc info entries in the 64 bits buffer.
1612 
1613  ConstantPoolBuilder constant_pool_builder_;
1614 
1615  // The bound position, before this we cannot do instruction elimination.
1617 
1618  // Indicates whether the constant pool can be accessed, which is only possible
1619  // if the pp register points to the current code object's constant pool.
1621 
1622  // Code emission
1623  inline void CheckBuffer();
1624  void GrowBuffer();
1625  inline void emit(Instr x);
1626 
1627  // 32-bit immediate values
1629  const Operand& x,
1630  Condition cond = al);
1631 
1632  // Instruction generation
1633  void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
1634  void addrmod2(Instr instr, Register rd, const MemOperand& x);
1635  void addrmod3(Instr instr, Register rd, const MemOperand& x);
1636  void addrmod4(Instr instr, Register rn, RegList rl);
1637  void addrmod5(Instr instr, CRegister crd, const MemOperand& x);
1638 
1639  // Labels
1640  void print(Label* L);
1641  void bind_to(Label* L, int pos);
1642  void next(Label* L);
1643 
1647  };
1648 
1649  // Record reloc info for current pc_
1650  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1651  void RecordRelocInfo(const RelocInfo& rinfo);
1653 
1654  friend class RelocInfo;
1655  friend class CodePatcher;
1656  friend class BlockConstPoolScope;
1659 
1661  friend class PositionsRecorder;
1662  friend class EnsureSpace;
1663 };
1664 
1665 
1666 class EnsureSpace BASE_EMBEDDED {
1667  public:
1668  explicit EnsureSpace(Assembler* assembler) {
1669  assembler->CheckBuffer();
1670  }
1671 };
1672 
1673 
1674 } } // namespace v8::internal
1675 
1676 #endif // V8_ARM_ASSEMBLER_ARM_H_
#define BASE_EMBEDDED
Definition: allocation.h:45
Isolate * isolate() const
Definition: assembler.h:62
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope)
static const int kSpecialTargetSize
void vcmp(const DwVfpRegister src1, const double src2, const Condition cond=al)
void bind_to(Label *L, int pos)
int branch_offset(Label *L, bool jump_elimination_allowed)
void rsb(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void vstr(const SwVfpRegister src, const Register base, int offset, const Condition cond=al)
RelocInfoWriter reloc_info_writer
void pkhtb(Register dst, Register src1, const Operand &src2, Condition cond=al)
void uxtb(Register dst, const Operand &src, Condition cond=al)
void cmp(Register src1, Register src2, Condition cond=al)
void vmrs(const Register dst, const Condition cond=al)
void vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src)
void umlal(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
void vcvt_u32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
static const int kMaxRelocSize
void ldrd(Register dst1, Register dst2, const MemOperand &src, Condition cond=al)
static const int kInstrSize
void b(Label *L, Condition cond=al)
Instruction * pc() const
static bool IsPush(Instr instr)
void usat(Register dst, int satpos, const Operand &src, Condition cond=al)
static bool IsLdrRegFpOffset(Instr instr)
INLINE(static Address constant_pool_entry_address(Address pc, ConstantPoolArray *constant_pool))
void and_(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void vldr(const SwVfpRegister dst, const MemOperand &src, const Condition cond=al)
void vneg(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond=al)
INLINE(static Address break_address_from_return_address(Address pc))
static bool IsCmpRegister(Instr instr)
void vldm(BlockAddrMode am, Register base, DwVfpRegister first, DwVfpRegister last, Condition cond=al)
void RecordConstPool(int size)
static int GetCmpImmediateRawImmediate(Instr instr)
static Address target_address_at(Address pc, ConstantPoolArray *constant_pool)
void bfi(Register dst, Register src, int lsb, int width, Condition cond=al)
void mov_label_offset(Register dst, Label *label)
void cdp(Coprocessor coproc, int opcode_1, CRegister crd, CRegister crn, CRegister crm, int opcode_2, Condition cond=al)
void cmp_raw_immediate(Register src1, int raw_immediate, Condition cond=al)
void ldc2(Coprocessor coproc, CRegister crd, const MemOperand &src, LFlag l=Short)
void mls(Register dst, Register src1, Register src2, Register srcA, Condition cond=al)
void smull(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
void addrmod4(Instr instr, Register rn, RegList rl)
void mcr(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0, Condition cond=al)
static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset)
static bool IsPop(Instr instr)
void mrc(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0, Condition cond=al)
void sbc(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
TypeFeedbackId RecordedAstId()
static bool IsStrRegisterImmediate(Instr instr)
static Instr GetConsantPoolLoadMask()
void stm(BlockAddrMode am, Register base, RegList src, Condition cond=al)
void vmsr(const Register dst, const Condition cond=al)
void addrmod3(Instr instr, Register rd, const MemOperand &x)
INLINE(static bool is_constant_pool_load(Address pc))
static bool IsCmpImmediate(Instr instr)
void vstr(const SwVfpRegister src, const MemOperand &dst, const Condition cond=al)
static void instr_at_put(byte *pc, Instr instr)
static bool IsVldrDPpImmediateOffset(Instr instr)
void mul(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
TypeFeedbackId recorded_ast_id_
void adc(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
RelocInfo pending_32_bit_reloc_info_[kMaxNumPending32RelocInfo]
void push(Register src, Condition cond=al)
static const int kDebugBreakSlotInstructions
void GetCode(CodeDesc *desc)
static bool IsTstImmediate(Instr instr)
static bool IsNop(Instr instr, int type=NON_MARKING_NOP)
int InstructionsGeneratedSince(Label *label)
bool ImmediateFitsAddrMode2Instruction(int32_t imm32)
void db(uint8_t data)
void bl(Condition cond, Label *L)
static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset)
void vldr(const DwVfpRegister dst, const MemOperand &src, const Condition cond=al)
void add(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void CheckConstPool(bool force_emit, bool require_jump)
static const int kPatchDebugBreakSlotAddressOffset
void instr_at_put(int pos, Instr instr)
void teq(Register src1, const Operand &src2, Condition cond=al)
void sub(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
void sbfx(Register dst, Register src, int lsb, int width, Condition cond=al)
void vldm(BlockAddrMode am, Register base, SwVfpRegister first, SwVfpRegister last, Condition cond=al)
void vsqrt(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond=al)
void msr(SRegisterFieldMask fields, const Operand &src, Condition cond=al)
void vcvt_f64_s32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
void set_constant_pool_available(bool available)
static Instr GetConsantPoolLoadPattern()
void vmls(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
static Instr SetAddRegisterImmediateOffset(Instr instr, int offset)
static const int kPatchDebugBreakSlotReturnOffset
void bl(Label *L, Condition cond=al)
void cmp(Register src1, const Operand &src2, Condition cond=al)
void BlockConstPoolFor(int instructions)
void rsc(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void mov(Register dst, Register src, SBit s=LeaveCC, Condition cond=al)
void print(Label *L)
static Address break_address_from_return_address(Address pc)
static const int kGap
bool use_extended_constant_pool() const
void lsr(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void vmla(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data=0)
static bool IsMovImmed(Instr instr)
static Instr SetStrRegisterImmediateOffset(Instr instr, int offset)
void vmov(const Register dst, const VmovIndex index, const DwVfpRegister src, const Condition cond=al)
static bool IsVldrDPcImmediateOffset(Instr instr)
static Register GetRn(Instr instr)
void blx(Register target, Condition cond=al)
static bool IsStrRegFpOffset(Instr instr)
void ldrsh(Register dst, const MemOperand &src, Condition cond=al)
void vcvt_f64_s32(const DwVfpRegister dst, int fraction_bits, const Condition cond=al)
void addrmod2(Instr instr, Register rd, const MemOperand &x)
INLINE(static Address return_address_from_call_start(Address pc))
void ldrsb(Register dst, const MemOperand &src, Condition cond=al)
void smlal(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
void RecordRelocInfo(const RelocInfo &rinfo)
void pop(Register dst, Condition cond=al)
void vcvt_f64_f32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
bool is_constant_pool_available() const
static Instr instr_at(byte *pc)
static Instr EncodeMovwImmediate(uint32_t immediate)
void str(Register src, const MemOperand &dst, Condition cond=al)
void vstm(BlockAddrMode am, Register base, DwVfpRegister first, DwVfpRegister last, Condition cond=al)
INLINE(static Address target_address_at(Address pc, Code *code))
INLINE(static Address target_address_at(Address pc, ConstantPoolArray *constant_pool))
void b(Condition cond, Label *L)
void ldrh(Register dst, const MemOperand &src, Condition cond=al)
void strd(Register src1, Register src2, const MemOperand &dst, Condition cond=al)
void clz(Register dst, Register src, Condition cond=al)
static Register GetRm(Instr instr)
void mrc2(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0)
static Instr GetMovWPattern()
void ldc2(Coprocessor coproc, CRegister crd, Register base, int option, LFlag l=Short)
void sub(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
Handle< ConstantPoolArray > NewConstantPool(Isolate *isolate)
void vmov(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond=al)
static Instr PatchShiftImm(Instr instr, int immed)
void movw(Register reg, uint32_t immediate, Condition cond=al)
void udiv(Register dst, Register src1, Register src2, Condition cond=al)
static Register GetRd(Instr instr)
static bool IsBranch(Instr instr)
void vmov(const DwVfpRegister dst, const Register src1, const Register src2, const Condition cond=al)
ConstantPoolArray::LayoutSection ConstantPoolAddEntry(const RelocInfo &rinfo)
void bl(int branch_offset, Condition cond=al)
void vld1(NeonSize size, const NeonListOperand &dst, const NeonMemOperand &src)
static bool IsMovW(Instr instr)
void pkhbt(Register dst, Register src1, const Operand &src2, Condition cond=al)
RelocInfo pending_64_bit_reloc_info_[kMaxNumPending64RelocInfo]
void RecordComment(const char *msg)
void vstr(const DwVfpRegister src, const MemOperand &dst, const Condition cond=al)
friend class PositionsRecorder
static Register GetCmpImmediateRegister(Instr instr)
void strb(Register src, const MemOperand &dst, Condition cond=al)
void blx(int branch_offset)
static bool IsMovT(Instr instr)
void lsl(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void addrmod5(Instr instr, CRegister crd, const MemOperand &x)
void ldrb(Register dst, const MemOperand &src, Condition cond=al)
void vcvt_f32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
void vmov(const DwVfpRegister dst, const VmovIndex index, const Register src, const Condition cond=al)
bool is_const_pool_blocked() const
static const int kJSReturnSequenceInstructions
void addrmod1(Instr instr, Register rn, Register rd, const Operand &x)
void vmov(const DwVfpRegister dst, double imm, const Register scratch=no_reg)
void mla(Register dst, Register src1, Register src2, Register srcA, SBit s=LeaveCC, Condition cond=al)
void eor(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void b(int branch_offset, Condition cond=al)
static bool IsVldrDRegisterImmediate(Instr instr)
void vabs(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond=al)
void mvn(Register dst, const Operand &src, SBit s=LeaveCC, Condition cond=al)
void mov(Register dst, const Operand &src, SBit s=LeaveCC, Condition cond=al)
INLINE(static void set_target_address_at(Address pc, Code *code, Address target, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED))
static void set_target_address_at(Address pc, ConstantPoolArray *constant_pool, Address target, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
static Address target_address_from_return_address(Address pc)
void vdiv(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
void svc(uint32_t imm24, Condition cond=al)
void SetRecordedAstId(TypeFeedbackId ast_id)
static const int kMaxNumPending64RelocInfo
void strh(Register src, const MemOperand &dst, Condition cond=al)
void ubfx(Register dst, Register src, int lsb, int width, Condition cond=al)
void vstm(BlockAddrMode am, Register base, SwVfpRegister first, SwVfpRegister last, Condition cond=al)
void stop(const char *msg, Condition cond=al, int32_t code=kDefaultStopCode)
void mrs(Register dst, SRegister s, Condition cond=al)
INLINE(static Address target_address_from_return_address(Address pc))
void ldc(Coprocessor coproc, CRegister crd, const MemOperand &src, LFlag l=Short, Condition cond=al)
void vcmp(const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
void vcvt_f64_u32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
void orr(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
static bool IsOrrImmed(Instr instr)
static int GetVldrDRegisterImmediateOffset(Instr instr)
static const int kMaxDistToIntPool
static Address return_address_from_call_start(Address pc)
void uxtb16(Register dst, const Operand &src, Condition cond=al)
static Instr GetLdrPpRegOffsetPattern()
static const int kDebugBreakSlotLength
void target_at_put(int pos, int target_pos)
void sdiv(Register dst, Register src1, Register src2, Condition cond=al)
void vcvt_s32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
INLINE(static void set_target_address_at(Address pc, ConstantPoolArray *constant_pool, Address target, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED))
static int DecodeShiftImm(Instr instr)
void move_32_bit_immediate(Register rd, const Operand &x, Condition cond=al)
void umull(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
static const int kMaxDistToFPPool
static bool IsLdrPpRegOffset(Instr instr)
void movt(Register reg, uint32_t immediate, Condition cond=al)
void orr(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond=al)
void vmov(const Register dst, const SwVfpRegister src, const Condition cond=al)
static bool IsLdrPcImmediateOffset(Instr instr)
void vstr(const DwVfpRegister src, const Register base, int offset, const Condition cond=al)
void vmov(const SwVfpRegister dst, const Register src, const Condition cond=al)
void vsub(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
void tst(Register src1, const Operand &src2, Condition cond=al)
void vcvt_f32_s32(const SwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
void pld(const MemOperand &address)
static bool ImmediateFitsAddrMode1Instruction(int32_t imm32)
void emit_code_stub_address(Code *stub)
static const int kPatchReturnSequenceAddressOffset
void ldr(Register dst, const MemOperand &src, Condition cond=al)
void bic(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void uxtab(Register dst, Register src1, const Operand &src2, Condition cond=al)
void vmul(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
static Condition GetCondition(Instr instr)
static bool IsBlxIp(Instr instr)
static void deserialization_set_special_target_at(Address constant_pool_entry, Code *code, Address target)
void mcr2(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0)
void tst(Register src1, Register src2, Condition cond=al)
void nop(int type=0)
static bool IsLdrPpImmediateOffset(Instr instr)
static bool IsBlxReg(Instr instr)
void vmov(const Register dst1, const Register dst2, const DwVfpRegister src, const Condition cond=al)
void vadd(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
void bkpt(uint32_t imm16)
void dd(uint32_t data)
static int GetBranchOffset(Instr instr)
void cdp2(Coprocessor coproc, int opcode_1, CRegister crd, CRegister crn, CRegister crm, int opcode_2)
void vmov(const SwVfpRegister dst, const SwVfpRegister src, const Condition cond=al)
void bx(Register target, Condition cond=al)
static const int kPcLoadDelta
void vst1(NeonSize size, const NeonListOperand &src, const NeonMemOperand &dst)
static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate)
static bool IsAddRegisterImmediate(Instr instr)
static const int kCheckPoolIntervalInst
void ldc(Coprocessor coproc, CRegister crd, Register base, int option, LFlag l=Short, Condition cond=al)
PositionsRecorder positions_recorder_
Assembler(Isolate *isolate, void *buffer, int buffer_size)
static bool IsStrRegFpNegOffset(Instr instr)
PositionsRecorder * positions_recorder()
static const int kMaxNumPending32RelocInfo
static bool IsLdrRegisterImmediate(Instr instr)
static int GetLdrRegisterImmediateOffset(Instr instr)
int SizeOfCodeGeneratedSince(Label *label)
void vldr(const DwVfpRegister dst, const Register base, int offset, const Condition cond=al)
void cmn(Register src1, const Operand &src2, Condition cond=al)
static bool IsLdrRegFpNegOffset(Instr instr)
static Instr GetMovTPattern()
void bfc(Register dst, int lsb, int width, Condition cond=al)
void add(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
void asr(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void PopulateConstantPool(ConstantPoolArray *constant_pool)
void vldr(const SwVfpRegister dst, const Register base, int offset, const Condition cond=al)
static const int kCheckPoolInterval
ConstantPoolBuilder constant_pool_builder_
bool OffsetIsUint12Encodable() const
INLINE(static Operand Zero())
Operand(Register rm, ShiftOp shift_op, Register rs)
std::vector< ConstantPoolEntry > entries_
DoubleRegister base() const
MemOperand(Register rn, Register rm, AddrMode am=Offset)
ConstantPoolArray::LayoutSection current_section_
void set_offset(int32_t offset)
void Relocate(int pc_delta)
INLINE(static Operand DoubleOffsetFromSmiKey(Register key))
MemOperand(Register rn, Register rm, ShiftOp shift_op, int shift_imm, AddrMode am=Offset)
INLINE(explicit Operand(const ExternalReference &f))
bool must_output_reloc_info(const Assembler *assembler) const
INLINE(static Operand PointerOffsetFromSmiKey(Register key))
NeonMemOperand(Register rn, Register rm, int align=0)
int instructions_required(const Assembler *assembler, Instr instr=0) const
ConstantPoolArray::NumberOfEntries * number_of_entries(ConstantPoolArray::LayoutSection section)
INLINE(explicit Operand(int32_t immediate, RelocInfo::Mode rmode=RelocInfo::NONE32))
ConstantPoolArray::Type GetConstantPoolType(RelocInfo::Mode rmode)
INLINE(bool is_reg() const)
void Populate(Assembler *assm, ConstantPoolArray *constant_pool)
ConstantPoolArray::NumberOfEntries * extended_entries()
Operand(Register rm, ShiftOp shift_op, int shift_imm)
Operand(Handle< Object > handle)
EnsureSpace(Assembler *assembler)
NeonMemOperand(Register rn, AddrMode am=Offset, int align=0)
INLINE(explicit Operand(Smi *value))
void SetAlignment(int align)
ConstantPoolArray::LayoutSection current_section() const
INLINE(explicit Operand(Register rm))
Handle< ConstantPoolArray > New(Isolate *isolate)
MemOperand(Register rn, int32_t offset=0, AddrMode am=Offset)
ConstantPoolArray::LayoutSection AddEntry(Assembler *assm, const RelocInfo &rinfo)
INLINE(static MemOperand PointerAddressFromSmiKey(Register array, Register key, AddrMode am=Offset))
ConstantPoolArray::NumberOfEntries * small_entries()
INLINE(static Operand SmiUntag(Register rm))
NeonListType type() const
NeonListOperand(DoubleRegister base, int registers_count=1)
ConstantPoolArray * constant_pool()
Definition: objects-inl.h:4942
Operand(Register reg, Shift shift=LSL, unsigned shift_amount=0)
Immediate immediate() const
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 available(X64 only)") DEFINE_BOOL(enable_vfp3
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
int int32_t
Definition: unicode.cc:24
const int kPointerSize
Definition: globals.h:129
const CRegister cr1
const DwVfpRegister d27
const LowDwVfpRegister d2
const SwVfpRegister s18
const int kRegister_r2_Code
Definition: assembler-arm.h:78
const Register r2
const int32_t kDefaultStopCode
const CRegister cr13
const QwNeonRegister q13
const int KB
Definition: globals.h:106
const LowDwVfpRegister d7
const SwVfpRegister s27
const LowDwVfpRegister d6
const QwNeonRegister q8
const SwVfpRegister s13
const CRegister cr8
const SwVfpRegister s29
const LowDwVfpRegister d9
const Register r10
const SwVfpRegister s17
const LowDwVfpRegister d1
const Register r6
const SwVfpRegister s11
const CRegister cr6
const VmovIndex VmovIndexHi
const SwVfpRegister s1
const LowDwVfpRegister d5
const Register r0
const int kSmiTagSize
Definition: v8.h:5743
const CRegister no_creg
const QwNeonRegister q5
const int kRegister_pc_Code
Definition: assembler-arm.h:91
const SwVfpRegister s25
const LowDwVfpRegister d0
const SwVfpRegister s24
const SwVfpRegister s2
const int kDoubleSizeLog2
Definition: globals.h:138
const Register ip
const int kDoubleSize
Definition: globals.h:127
const SwVfpRegister s0
const Register r3
const QwNeonRegister q10
const DwVfpRegister d31
const DwVfpRegister d21
const Register fp
DwVfpRegister DoubleRegister
const QwNeonRegister q1
const DwVfpRegister d18
const DwVfpRegister d20
const LowDwVfpRegister d8
const LowDwVfpRegister d12
const QwNeonRegister q3
const int kRegister_r5_Code
Definition: assembler-arm.h:81
const int kRegister_ip_Code
Definition: assembler-arm.h:88
const int kMaxInt
Definition: globals.h:109
const CRegister cr12
const Register sp
const int kRegister_r1_Code
Definition: assembler-arm.h:77
const int kPointerSizeLog2
Definition: globals.h:147
const QwNeonRegister q6
const SwVfpRegister s19
const int kRegister_r7_Code
Definition: assembler-arm.h:83
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:146
const CRegister cr5
const SwVfpRegister s20
const SwVfpRegister s22
const Register r4
const SwVfpRegister s28
const SwVfpRegister s23
const QwNeonRegister q15
const SwVfpRegister s26
const Register r9
const SwVfpRegister s15
const QwNeonRegister q7
const SwVfpRegister s3
const Register pc
QwNeonRegister QuadRegister
const DwVfpRegister d29
const SwVfpRegister s9
const SwVfpRegister s16
const SwVfpRegister s30
const int kRegister_r8_Code
Definition: assembler-arm.h:84
const Register r5
const CRegister cr3
const CRegister cr15
const LowDwVfpRegister d11
const CRegister cr0
const int kRegister_r6_Code
Definition: assembler-arm.h:82
const Register lr
const SwVfpRegister s6
byte * Address
Definition: globals.h:101
const Register r8
const DwVfpRegister no_dreg
const int kRegister_r0_Code
Definition: assembler-arm.h:76
const Register r1
const SwVfpRegister s7
const VmovIndex VmovIndexLo
const int kRegister_r3_Code
Definition: assembler-arm.h:79
const int kRegister_lr_Code
Definition: assembler-arm.h:90
const DwVfpRegister d16
const DwVfpRegister d17
const Register no_reg
const CRegister cr9
const QwNeonRegister q2
const int kRegister_r4_Code
Definition: assembler-arm.h:80
const int kRegister_r10_Code
Definition: assembler-arm.h:86
const DwVfpRegister d26
const QwNeonRegister q0
const SwVfpRegister s31
const QwNeonRegister q4
const int kRegister_fp_Code
Definition: assembler-arm.h:87
const DwVfpRegister d23
const QwNeonRegister q11
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
const SwVfpRegister s14
@ FLUSH_ICACHE_IF_NEEDED
Definition: assembler.h:293
const SwVfpRegister s10
const CRegister cr4
const DwVfpRegister d30
const DwVfpRegister d28
const LowDwVfpRegister d13
const int kSmiTag
Definition: v8.h:5742
const SwVfpRegister s4
const LowDwVfpRegister d3
const int kRegister_no_reg_Code
Definition: assembler-arm.h:75
const CRegister cr14
const int kRegister_r9_Code
Definition: assembler-arm.h:85
const DwVfpRegister d22
const DwVfpRegister d25
const SwVfpRegister s21
const CRegister cr2
const SwVfpRegister s12
const LowDwVfpRegister d10
const CRegister cr10
const CRegister cr11
const QwNeonRegister q14
const LowDwVfpRegister d15
const CRegister cr7
const DwVfpRegister d24
const SwVfpRegister s8
const SwVfpRegister s5
const LowDwVfpRegister d14
const QwNeonRegister q12
const LowDwVfpRegister d4
const DwVfpRegister d19
const QwNeonRegister q9
const int kRegister_sp_Code
Definition: assembler-arm.h:89
const Register r7
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
ConstantPoolArray::LayoutSection section_
ConstantPoolEntry(RelocInfo rinfo, ConstantPoolArray::LayoutSection section, int merged_index)
bool is(CRegister creg) const
static const int kNumReservedRegisters
static const char * AllocationIndexToString(int index)
bool is(DwVfpRegister reg) const
static DwVfpRegister from_code(int code)
static int ToAllocationIndex(DwVfpRegister reg)
static const int kMaxNumAllocatableRegisters
void split_code(int *vm, int *m) const
static const int kSizeInBytes
static int NumAllocatableAliasedRegisters()
static const int kMaxNumRegisters
static DwVfpRegister FromAllocationIndex(int index)
bool is(LowDwVfpRegister reg) const
static LowDwVfpRegister from_code(int code)
SwVfpRegister high() const
SwVfpRegister low() const
bool is(DwVfpRegister reg) const
static const int kMaxNumLowRegisters
void split_code(int *vm, int *m) const
static const int kMaxNumRegisters
bool is(QwNeonRegister reg) const
static QwNeonRegister from_code(int code)
static const int kNumRegisters
Definition: assembler-arm.h:95
static const int kSizeInBytes
Definition: assembler-arm.h:98
static Register from_code(int code)
static Register FromAllocationIndex(int index)
bool is(Register reg) const
void set_code(int code)
static int NumAllocatableRegisters()
static int ToAllocationIndex(Register reg)
static const char * AllocationIndexToString(int index)
static const int kMaxNumAllocatableRegisters
Definition: assembler-arm.h:96
static const int kSizeInBytes
bool is(SwVfpRegister reg) const
void split_code(int *vm, int *m) const