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