Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / src / arm / assembler-arm.h
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) {
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
156 const Register no_reg = { kRegister_no_reg_Code };
157
158 const Register r0  = { kRegister_r0_Code };
159 const Register r1  = { kRegister_r1_Code };
160 const Register r2  = { kRegister_r2_Code };
161 const Register r3  = { kRegister_r3_Code };
162 const Register r4  = { kRegister_r4_Code };
163 const Register r5  = { kRegister_r5_Code };
164 const Register r6  = { kRegister_r6_Code };
165 // Used as constant pool pointer register if FLAG_enable_ool_constant_pool.
166 const Register r7  = { kRegister_r7_Code };
167 // Used as context register.
168 const Register r8  = { kRegister_r8_Code };
169 // Used as lithium codegen scratch register.
170 const Register r9  = { kRegister_r9_Code };
171 // Used as roots register.
172 const Register r10 = { kRegister_r10_Code };
173 const Register fp  = { kRegister_fp_Code };
174 const Register ip  = { kRegister_ip_Code };
175 const Register sp  = { kRegister_sp_Code };
176 const Register lr  = { kRegister_lr_Code };
177 const Register pc  = { kRegister_pc_Code };
178
179 // Single word VFP register.
180 struct 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.
203 struct 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   // 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
230   static DwVfpRegister from_code(int code) {
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
257 typedef DwVfpRegister DoubleRegister;
258
259
260 // Double word VFP register d0-15.
261 struct LowDwVfpRegister {
262  public:
263   static const int kMaxNumLowRegisters = 16;
264   operator DwVfpRegister() const {
265     DwVfpRegister r = { code_ };
266     return r;
267   }
268   static LowDwVfpRegister from_code(int code) {
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.
302 struct QwNeonRegister {
303   static const int kMaxNumRegisters = 16;
304
305   static QwNeonRegister from_code(int code) {
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
329 typedef QwNeonRegister QuadRegister;
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
467 enum Coprocessor {
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
494   INLINE(explicit Operand(int32_t immediate,
495          RelocInfo::Mode rmode = RelocInfo::NONE32));
496   INLINE(static Operand Zero()) {
497     return Operand(static_cast<int32_t>(0));
498   }
499   INLINE(explicit Operand(const ExternalReference& f));
500   explicit Operand(Handle<Object> handle);
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)) {
512     STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
513     return Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize);
514   }
515   INLINE(static Operand DoubleOffsetFromSmiKey(Register key)) {
516     STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2);
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:
550   Register rm_;
551   Register rs_;
552   ShiftOp shift_op_;
553   int shift_imm_;  // valid if rm_ != no_reg && rs_ == no_reg
554   int32_t imm32_;  // valid if rm_ == no_reg
555   RelocInfo::Mode rmode_;
556
557   friend class Assembler;
558 };
559
560
561 // Class MemOperand represents a memory operand in load and store instructions
562 class MemOperand BASE_EMBEDDED {
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)) {
584     STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
585     return MemOperand(array, key, LSL, kPointerSizeLog2 - kSmiTagSize, am);
586   }
587
588   void set_offset(int32_t offset) {
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:
649   DoubleRegister base_;
650   NeonListType type_;
651 };
652
653
654 // Class used to build a constant pool.
655 class ConstantPoolBuilder BASE_EMBEDDED {
656  public:
657   ConstantPoolBuilder();
658   ConstantPoolArray::LayoutSection AddEntry(Assembler* assm,
659                                             const RelocInfo& rinfo);
660   void Relocate(int pc_delta);
661   bool IsEmpty();
662   Handle<ConstantPoolArray> New(Isolate* isolate);
663   void Populate(Assembler* assm, ConstantPoolArray* constant_pool);
664
665   inline ConstantPoolArray::LayoutSection current_section() const {
666     return current_section_;
667   }
668
669   inline ConstantPoolArray::NumberOfEntries* number_of_entries(
670       ConstantPoolArray::LayoutSection section) {
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:
683   struct ConstantPoolEntry {
684     ConstantPoolEntry(RelocInfo rinfo, ConstantPoolArray::LayoutSection section,
685                       int merged_index)
686         : rinfo_(rinfo), section_(section), merged_index_(merged_index) {}
687
688     RelocInfo rinfo_;
689     ConstantPoolArray::LayoutSection section_;
690     int merged_index_;
691   };
692
693   ConstantPoolArray::Type GetConstantPoolType(RelocInfo::Mode rmode);
694
695   std::vector<ConstantPoolEntry> entries_;
696   ConstantPoolArray::LayoutSection current_section_;
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.
761   INLINE(static Address target_address_at(Address pc,
762                                           ConstantPoolArray* constant_pool));
763   INLINE(static void set_target_address_at(Address pc,
764                                            ConstantPoolArray* constant_pool,
765                                            Address target,
766                                            ICacheFlushMode icache_flush_mode =
767                                                FLUSH_ICACHE_IF_NEEDED));
768   INLINE(static Address target_address_at(Address pc, Code* code)) {
769     ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
770     return target_address_at(pc, constant_pool);
771   }
772   INLINE(static void set_target_address_at(Address pc,
773                                            Code* code,
774                                            Address target,
775                                            ICacheFlushMode icache_flush_mode =
776                                                FLUSH_ICACHE_IF_NEEDED)) {
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.
783   INLINE(static Address target_address_from_return_address(Address pc));
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.
787   INLINE(static Address return_address_from_call_start(Address pc));
788
789   // Return the code target address of the patch debug break slot
790   INLINE(static Address break_address_from_return_address(Address pc));
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
810   static const int kPatchReturnSequenceAddressOffset =  0 * kInstrSize;
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
817   static const int kPatchDebugBreakSlotAddressOffset =  0 * kInstrSize;
818
819   static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize;
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 =
828       kDebugBreakSlotInstructions * kInstrSize;
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.
838   void CodeTargetAlign();
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 smmla(Register dst, Register src1, Register src2, Register srcA,
979              Condition cond = al);
980
981   void smmul(Register dst, Register src1, Register src2, Condition cond = al);
982
983   void smlal(Register dstL, Register dstH, Register src1, Register src2,
984              SBit s = LeaveCC, Condition cond = al);
985
986   void smull(Register dstL, Register dstH, Register src1, Register src2,
987              SBit s = LeaveCC, Condition cond = al);
988
989   void umlal(Register dstL, Register dstH, Register src1, Register src2,
990              SBit s = LeaveCC, Condition cond = al);
991
992   void umull(Register dstL, Register dstH, Register src1, Register src2,
993              SBit s = LeaveCC, Condition cond = al);
994
995   // Miscellaneous arithmetic instructions
996
997   void clz(Register dst, Register src, Condition cond = al);  // v5 and above
998
999   // Saturating instructions. v6 and above.
1000
1001   // Unsigned saturate.
1002   //
1003   // Saturate an optionally shifted signed value to an unsigned range.
1004   //
1005   //   usat dst, #satpos, src
1006   //   usat dst, #satpos, src, lsl #sh
1007   //   usat dst, #satpos, src, asr #sh
1008   //
1009   // Register dst will contain:
1010   //
1011   //   0,                 if s < 0
1012   //   (1 << satpos) - 1, if s > ((1 << satpos) - 1)
1013   //   s,                 otherwise
1014   //
1015   // where s is the contents of src after shifting (if used.)
1016   void usat(Register dst, int satpos, const Operand& src, Condition cond = al);
1017
1018   // Bitfield manipulation instructions. v7 and above.
1019
1020   void ubfx(Register dst, Register src, int lsb, int width,
1021             Condition cond = al);
1022
1023   void sbfx(Register dst, Register src, int lsb, int width,
1024             Condition cond = al);
1025
1026   void bfc(Register dst, int lsb, int width, Condition cond = al);
1027
1028   void bfi(Register dst, Register src, int lsb, int width,
1029            Condition cond = al);
1030
1031   void pkhbt(Register dst, Register src1, const Operand& src2,
1032              Condition cond = al);
1033
1034   void pkhtb(Register dst, Register src1, const Operand& src2,
1035              Condition cond = al);
1036
1037   void uxtb(Register dst, const Operand& src, Condition cond = al);
1038
1039   void uxtab(Register dst, Register src1, const Operand& src2,
1040              Condition cond = al);
1041
1042   void uxtb16(Register dst, const Operand& src, Condition cond = al);
1043
1044   // Status register access instructions
1045
1046   void mrs(Register dst, SRegister s, Condition cond = al);
1047   void msr(SRegisterFieldMask fields, const Operand& src, Condition cond = al);
1048
1049   // Load/Store instructions
1050   void ldr(Register dst, const MemOperand& src, Condition cond = al);
1051   void str(Register src, const MemOperand& dst, Condition cond = al);
1052   void ldrb(Register dst, const MemOperand& src, Condition cond = al);
1053   void strb(Register src, const MemOperand& dst, Condition cond = al);
1054   void ldrh(Register dst, const MemOperand& src, Condition cond = al);
1055   void strh(Register src, const MemOperand& dst, Condition cond = al);
1056   void ldrsb(Register dst, const MemOperand& src, Condition cond = al);
1057   void ldrsh(Register dst, const MemOperand& src, Condition cond = al);
1058   void ldrd(Register dst1,
1059             Register dst2,
1060             const MemOperand& src, Condition cond = al);
1061   void strd(Register src1,
1062             Register src2,
1063             const MemOperand& dst, Condition cond = al);
1064
1065   // Preload instructions
1066   void pld(const MemOperand& address);
1067
1068   // Load/Store multiple instructions
1069   void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al);
1070   void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al);
1071
1072   // Exception-generating instructions and debugging support
1073   void stop(const char* msg,
1074             Condition cond = al,
1075             int32_t code = kDefaultStopCode);
1076
1077   void bkpt(uint32_t imm16);  // v5 and above
1078   void svc(uint32_t imm24, Condition cond = al);
1079
1080   // Coprocessor instructions
1081
1082   void cdp(Coprocessor coproc, int opcode_1,
1083            CRegister crd, CRegister crn, CRegister crm,
1084            int opcode_2, Condition cond = al);
1085
1086   void cdp2(Coprocessor coproc, int opcode_1,
1087             CRegister crd, CRegister crn, CRegister crm,
1088             int opcode_2);  // v5 and above
1089
1090   void mcr(Coprocessor coproc, int opcode_1,
1091            Register rd, CRegister crn, CRegister crm,
1092            int opcode_2 = 0, Condition cond = al);
1093
1094   void mcr2(Coprocessor coproc, int opcode_1,
1095             Register rd, CRegister crn, CRegister crm,
1096             int opcode_2 = 0);  // v5 and above
1097
1098   void mrc(Coprocessor coproc, int opcode_1,
1099            Register rd, CRegister crn, CRegister crm,
1100            int opcode_2 = 0, Condition cond = al);
1101
1102   void mrc2(Coprocessor coproc, int opcode_1,
1103             Register rd, CRegister crn, CRegister crm,
1104             int opcode_2 = 0);  // v5 and above
1105
1106   void ldc(Coprocessor coproc, CRegister crd, const MemOperand& src,
1107            LFlag l = Short, Condition cond = al);
1108   void ldc(Coprocessor coproc, CRegister crd, Register base, int option,
1109            LFlag l = Short, Condition cond = al);
1110
1111   void ldc2(Coprocessor coproc, CRegister crd, const MemOperand& src,
1112             LFlag l = Short);  // v5 and above
1113   void ldc2(Coprocessor coproc, CRegister crd, Register base, int option,
1114             LFlag l = Short);  // v5 and above
1115
1116   // Support for VFP.
1117   // All these APIs support S0 to S31 and D0 to D31.
1118
1119   void vldr(const DwVfpRegister dst,
1120             const Register base,
1121             int offset,
1122             const Condition cond = al);
1123   void vldr(const DwVfpRegister dst,
1124             const MemOperand& src,
1125             const Condition cond = al);
1126
1127   void vldr(const SwVfpRegister dst,
1128             const Register base,
1129             int offset,
1130             const Condition cond = al);
1131   void vldr(const SwVfpRegister dst,
1132             const MemOperand& src,
1133             const Condition cond = al);
1134
1135   void vstr(const DwVfpRegister src,
1136             const Register base,
1137             int offset,
1138             const Condition cond = al);
1139   void vstr(const DwVfpRegister src,
1140             const MemOperand& dst,
1141             const Condition cond = al);
1142
1143   void vstr(const SwVfpRegister src,
1144             const Register base,
1145             int offset,
1146             const Condition cond = al);
1147   void vstr(const SwVfpRegister src,
1148             const MemOperand& dst,
1149             const Condition cond = al);
1150
1151   void vldm(BlockAddrMode am,
1152             Register base,
1153             DwVfpRegister first,
1154             DwVfpRegister last,
1155             Condition cond = al);
1156
1157   void vstm(BlockAddrMode am,
1158             Register base,
1159             DwVfpRegister first,
1160             DwVfpRegister last,
1161             Condition cond = al);
1162
1163   void vldm(BlockAddrMode am,
1164             Register base,
1165             SwVfpRegister first,
1166             SwVfpRegister last,
1167             Condition cond = al);
1168
1169   void vstm(BlockAddrMode am,
1170             Register base,
1171             SwVfpRegister first,
1172             SwVfpRegister last,
1173             Condition cond = al);
1174
1175   void vmov(const DwVfpRegister dst,
1176             double imm,
1177             const Register scratch = no_reg);
1178   void vmov(const SwVfpRegister dst,
1179             const SwVfpRegister src,
1180             const Condition cond = al);
1181   void vmov(const DwVfpRegister dst,
1182             const DwVfpRegister src,
1183             const Condition cond = al);
1184   void vmov(const DwVfpRegister dst,
1185             const VmovIndex index,
1186             const Register src,
1187             const Condition cond = al);
1188   void vmov(const Register dst,
1189             const VmovIndex index,
1190             const DwVfpRegister src,
1191             const Condition cond = al);
1192   void vmov(const DwVfpRegister dst,
1193             const Register src1,
1194             const Register src2,
1195             const Condition cond = al);
1196   void vmov(const Register dst1,
1197             const Register dst2,
1198             const DwVfpRegister src,
1199             const Condition cond = al);
1200   void vmov(const SwVfpRegister dst,
1201             const Register src,
1202             const Condition cond = al);
1203   void vmov(const Register dst,
1204             const SwVfpRegister src,
1205             const Condition cond = al);
1206   void vcvt_f64_s32(const DwVfpRegister dst,
1207                     const SwVfpRegister src,
1208                     VFPConversionMode mode = kDefaultRoundToZero,
1209                     const Condition cond = al);
1210   void vcvt_f32_s32(const SwVfpRegister dst,
1211                     const SwVfpRegister src,
1212                     VFPConversionMode mode = kDefaultRoundToZero,
1213                     const Condition cond = al);
1214   void vcvt_f64_u32(const DwVfpRegister dst,
1215                     const SwVfpRegister src,
1216                     VFPConversionMode mode = kDefaultRoundToZero,
1217                     const Condition cond = al);
1218   void vcvt_s32_f64(const SwVfpRegister dst,
1219                     const DwVfpRegister src,
1220                     VFPConversionMode mode = kDefaultRoundToZero,
1221                     const Condition cond = al);
1222   void vcvt_u32_f64(const SwVfpRegister dst,
1223                     const DwVfpRegister src,
1224                     VFPConversionMode mode = kDefaultRoundToZero,
1225                     const Condition cond = al);
1226   void vcvt_f64_f32(const DwVfpRegister dst,
1227                     const SwVfpRegister src,
1228                     VFPConversionMode mode = kDefaultRoundToZero,
1229                     const Condition cond = al);
1230   void vcvt_f32_f64(const SwVfpRegister dst,
1231                     const DwVfpRegister src,
1232                     VFPConversionMode mode = kDefaultRoundToZero,
1233                     const Condition cond = al);
1234   void vcvt_f64_s32(const DwVfpRegister dst,
1235                     int fraction_bits,
1236                     const Condition cond = al);
1237
1238   void vneg(const DwVfpRegister dst,
1239             const DwVfpRegister src,
1240             const Condition cond = al);
1241   void vabs(const DwVfpRegister dst,
1242             const DwVfpRegister src,
1243             const Condition cond = al);
1244   void vadd(const DwVfpRegister dst,
1245             const DwVfpRegister src1,
1246             const DwVfpRegister src2,
1247             const Condition cond = al);
1248   void vsub(const DwVfpRegister dst,
1249             const DwVfpRegister src1,
1250             const DwVfpRegister src2,
1251             const Condition cond = al);
1252   void vmul(const DwVfpRegister dst,
1253             const DwVfpRegister src1,
1254             const DwVfpRegister src2,
1255             const Condition cond = al);
1256   void vmla(const DwVfpRegister dst,
1257             const DwVfpRegister src1,
1258             const DwVfpRegister src2,
1259             const Condition cond = al);
1260   void vmls(const DwVfpRegister dst,
1261             const DwVfpRegister src1,
1262             const DwVfpRegister src2,
1263             const Condition cond = al);
1264   void vdiv(const DwVfpRegister dst,
1265             const DwVfpRegister src1,
1266             const DwVfpRegister src2,
1267             const Condition cond = al);
1268   void vcmp(const DwVfpRegister src1,
1269             const DwVfpRegister src2,
1270             const Condition cond = al);
1271   void vcmp(const DwVfpRegister src1,
1272             const double src2,
1273             const Condition cond = al);
1274   void vmrs(const Register dst,
1275             const Condition cond = al);
1276   void vmsr(const Register dst,
1277             const Condition cond = al);
1278   void vsqrt(const DwVfpRegister dst,
1279              const DwVfpRegister src,
1280              const Condition cond = al);
1281
1282   // ARMv8 rounding instructions.
1283   void vrinta(const DwVfpRegister dst, const DwVfpRegister src);
1284   void vrintn(const DwVfpRegister dst, const DwVfpRegister src);
1285   void vrintm(const DwVfpRegister dst, const DwVfpRegister src);
1286   void vrintp(const DwVfpRegister dst, const DwVfpRegister src);
1287   void vrintz(const DwVfpRegister dst, const DwVfpRegister src,
1288               const Condition cond = al);
1289
1290   // Support for NEON.
1291   // All these APIs support D0 to D31 and Q0 to Q15.
1292
1293   void vld1(NeonSize size,
1294             const NeonListOperand& dst,
1295             const NeonMemOperand& src);
1296   void vst1(NeonSize size,
1297             const NeonListOperand& src,
1298             const NeonMemOperand& dst);
1299   void vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src);
1300
1301   // Pseudo instructions
1302
1303   // Different nop operations are used by the code generator to detect certain
1304   // states of the generated code.
1305   enum NopMarkerTypes {
1306     NON_MARKING_NOP = 0,
1307     DEBUG_BREAK_NOP,
1308     // IC markers.
1309     PROPERTY_ACCESS_INLINED,
1310     PROPERTY_ACCESS_INLINED_CONTEXT,
1311     PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
1312     // Helper values.
1313     LAST_CODE_MARKER,
1314     FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
1315   };
1316
1317   void nop(int type = 0);   // 0 is the default non-marking type.
1318
1319   void push(Register src, Condition cond = al) {
1320     str(src, MemOperand(sp, 4, NegPreIndex), cond);
1321   }
1322
1323   void pop(Register dst, Condition cond = al) {
1324     ldr(dst, MemOperand(sp, 4, PostIndex), cond);
1325   }
1326
1327   void pop() {
1328     add(sp, sp, Operand(kPointerSize));
1329   }
1330
1331   // Jump unconditionally to given label.
1332   void jmp(Label* L) { b(L, al); }
1333
1334   // Check the code size generated from label to here.
1335   int SizeOfCodeGeneratedSince(Label* label) {
1336     return pc_offset() - label->pos();
1337   }
1338
1339   // Check the number of instructions generated from label to here.
1340   int InstructionsGeneratedSince(Label* label) {
1341     return SizeOfCodeGeneratedSince(label) / kInstrSize;
1342   }
1343
1344   // Check whether an immediate fits an addressing mode 1 instruction.
1345   static bool ImmediateFitsAddrMode1Instruction(int32_t imm32);
1346
1347   // Check whether an immediate fits an addressing mode 2 instruction.
1348   bool ImmediateFitsAddrMode2Instruction(int32_t imm32);
1349
1350   // Class for scoping postponing the constant pool generation.
1351   class BlockConstPoolScope {
1352    public:
1353     explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
1354       assem_->StartBlockConstPool();
1355     }
1356     ~BlockConstPoolScope() {
1357       assem_->EndBlockConstPool();
1358     }
1359
1360    private:
1361     Assembler* assem_;
1362
1363     DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
1364   };
1365
1366   // Debugging
1367
1368   // Mark address of the ExitJSFrame code.
1369   void RecordJSReturn();
1370
1371   // Mark address of a debug break slot.
1372   void RecordDebugBreakSlot();
1373
1374   // Record the AST id of the CallIC being compiled, so that it can be placed
1375   // in the relocation information.
1376   void SetRecordedAstId(TypeFeedbackId ast_id) {
1377     DCHECK(recorded_ast_id_.IsNone());
1378     recorded_ast_id_ = ast_id;
1379   }
1380
1381   TypeFeedbackId RecordedAstId() {
1382     DCHECK(!recorded_ast_id_.IsNone());
1383     return recorded_ast_id_;
1384   }
1385
1386   void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
1387
1388   // Record a comment relocation entry that can be used by a disassembler.
1389   // Use --code-comments to enable.
1390   void RecordComment(const char* msg);
1391
1392   // Record the emission of a constant pool.
1393   //
1394   // The emission of constant pool depends on the size of the code generated and
1395   // the number of RelocInfo recorded.
1396   // The Debug mechanism needs to map code offsets between two versions of a
1397   // function, compiled with and without debugger support (see for example
1398   // Debug::PrepareForBreakPoints()).
1399   // Compiling functions with debugger support generates additional code
1400   // (DebugCodegen::GenerateSlot()). This may affect the emission of the
1401   // constant pools and cause the version of the code with debugger support to
1402   // have constant pools generated in different places.
1403   // Recording the position and size of emitted constant pools allows to
1404   // correctly compute the offset mappings between the different versions of a
1405   // function in all situations.
1406   //
1407   // The parameter indicates the size of the constant pool (in bytes), including
1408   // the marker and branch over the data.
1409   void RecordConstPool(int size);
1410
1411   // Writes a single byte or word of data in the code stream.  Used
1412   // for inline tables, e.g., jump-tables. The constant pool should be
1413   // emitted before any use of db and dd to ensure that constant pools
1414   // are not emitted as part of the tables generated.
1415   void db(uint8_t data);
1416   void dd(uint32_t data);
1417
1418   // Emits the address of the code stub's first instruction.
1419   void emit_code_stub_address(Code* stub);
1420
1421   PositionsRecorder* positions_recorder() { return &positions_recorder_; }
1422
1423   // Read/patch instructions
1424   Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
1425   void instr_at_put(int pos, Instr instr) {
1426     *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
1427   }
1428   static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
1429   static void instr_at_put(byte* pc, Instr instr) {
1430     *reinterpret_cast<Instr*>(pc) = instr;
1431   }
1432   static Condition GetCondition(Instr instr);
1433   static bool IsBranch(Instr instr);
1434   static int GetBranchOffset(Instr instr);
1435   static bool IsLdrRegisterImmediate(Instr instr);
1436   static bool IsVldrDRegisterImmediate(Instr instr);
1437   static Instr GetConsantPoolLoadPattern();
1438   static Instr GetConsantPoolLoadMask();
1439   static bool IsLdrPpRegOffset(Instr instr);
1440   static Instr GetLdrPpRegOffsetPattern();
1441   static bool IsLdrPpImmediateOffset(Instr instr);
1442   static bool IsVldrDPpImmediateOffset(Instr instr);
1443   static int GetLdrRegisterImmediateOffset(Instr instr);
1444   static int GetVldrDRegisterImmediateOffset(Instr instr);
1445   static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset);
1446   static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset);
1447   static bool IsStrRegisterImmediate(Instr instr);
1448   static Instr SetStrRegisterImmediateOffset(Instr instr, int offset);
1449   static bool IsAddRegisterImmediate(Instr instr);
1450   static Instr SetAddRegisterImmediateOffset(Instr instr, int offset);
1451   static Register GetRd(Instr instr);
1452   static Register GetRn(Instr instr);
1453   static Register GetRm(Instr instr);
1454   static bool IsPush(Instr instr);
1455   static bool IsPop(Instr instr);
1456   static bool IsStrRegFpOffset(Instr instr);
1457   static bool IsLdrRegFpOffset(Instr instr);
1458   static bool IsStrRegFpNegOffset(Instr instr);
1459   static bool IsLdrRegFpNegOffset(Instr instr);
1460   static bool IsLdrPcImmediateOffset(Instr instr);
1461   static bool IsVldrDPcImmediateOffset(Instr instr);
1462   static bool IsBlxReg(Instr instr);
1463   static bool IsBlxIp(Instr instr);
1464   static bool IsTstImmediate(Instr instr);
1465   static bool IsCmpRegister(Instr instr);
1466   static bool IsCmpImmediate(Instr instr);
1467   static Register GetCmpImmediateRegister(Instr instr);
1468   static int GetCmpImmediateRawImmediate(Instr instr);
1469   static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
1470   static bool IsMovImmed(Instr instr);
1471   static bool IsOrrImmed(Instr instr);
1472   static bool IsMovT(Instr instr);
1473   static Instr GetMovTPattern();
1474   static bool IsMovW(Instr instr);
1475   static Instr GetMovWPattern();
1476   static Instr EncodeMovwImmediate(uint32_t immediate);
1477   static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate);
1478   static int DecodeShiftImm(Instr instr);
1479   static Instr PatchShiftImm(Instr instr, int immed);
1480
1481   // Constants in pools are accessed via pc relative addressing, which can
1482   // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point
1483   // PC-relative loads, thereby defining a maximum distance between the
1484   // instruction and the accessed constant.
1485   static const int kMaxDistToIntPool = 4*KB;
1486   static const int kMaxDistToFPPool = 1*KB;
1487   // All relocations could be integer, it therefore acts as the limit.
1488   static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize;
1489   static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize;
1490
1491   // Postpone the generation of the constant pool for the specified number of
1492   // instructions.
1493   void BlockConstPoolFor(int instructions);
1494
1495   // Check if is time to emit a constant pool.
1496   void CheckConstPool(bool force_emit, bool require_jump);
1497
1498   // Allocate a constant pool of the correct size for the generated code.
1499   Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
1500
1501   // Generate the constant pool for the generated code.
1502   void PopulateConstantPool(ConstantPoolArray* constant_pool);
1503
1504   bool use_extended_constant_pool() const {
1505     return constant_pool_builder_.current_section() ==
1506            ConstantPoolArray::EXTENDED_SECTION;
1507   }
1508
1509
1510  protected:
1511   // Relocation for a type-recording IC has the AST id added to it.  This
1512   // member variable is a way to pass the information from the call site to
1513   // the relocation info.
1514   TypeFeedbackId recorded_ast_id_;
1515
1516   int buffer_space() const { return reloc_info_writer.pos() - pc_; }
1517
1518   // Decode branch instruction at pos and return branch target pos
1519   int target_at(int pos);
1520
1521   // Patch branch instruction at pos to branch to given branch target pos
1522   void target_at_put(int pos, int target_pos);
1523
1524   // Prevent contant pool emission until EndBlockConstPool is called.
1525   // Call to this function can be nested but must be followed by an equal
1526   // number of call to EndBlockConstpool.
1527   void StartBlockConstPool() {
1528     if (const_pool_blocked_nesting_++ == 0) {
1529       // Prevent constant pool checks happening by setting the next check to
1530       // the biggest possible offset.
1531       next_buffer_check_ = kMaxInt;
1532     }
1533   }
1534
1535   // Resume constant pool emission. Need to be called as many time as
1536   // StartBlockConstPool to have an effect.
1537   void EndBlockConstPool() {
1538     if (--const_pool_blocked_nesting_ == 0) {
1539 #ifdef DEBUG
1540       // Max pool start (if we need a jump and an alignment).
1541       int start = pc_offset() + kInstrSize + 2 * kPointerSize;
1542       // Check the constant pool hasn't been blocked for too long.
1543       DCHECK((num_pending_32_bit_reloc_info_ == 0) ||
1544              (start + num_pending_64_bit_reloc_info_ * kDoubleSize <
1545               (first_const_pool_32_use_ + kMaxDistToIntPool)));
1546       DCHECK((num_pending_64_bit_reloc_info_ == 0) ||
1547              (start < (first_const_pool_64_use_ + kMaxDistToFPPool)));
1548 #endif
1549       // Two cases:
1550       //  * no_const_pool_before_ >= next_buffer_check_ and the emission is
1551       //    still blocked
1552       //  * no_const_pool_before_ < next_buffer_check_ and the next emit will
1553       //    trigger a check.
1554       next_buffer_check_ = no_const_pool_before_;
1555     }
1556   }
1557
1558   bool is_const_pool_blocked() const {
1559     return (const_pool_blocked_nesting_ > 0) ||
1560            (pc_offset() < no_const_pool_before_);
1561   }
1562
1563  private:
1564   int next_buffer_check_;  // pc offset of next buffer check
1565
1566   // Code generation
1567   // The relocation writer's position is at least kGap bytes below the end of
1568   // the generated instructions. This is so that multi-instruction sequences do
1569   // not have to check for overflow. The same is true for writes of large
1570   // relocation info entries.
1571   static const int kGap = 32;
1572
1573   // Constant pool generation
1574   // Pools are emitted in the instruction stream, preferably after unconditional
1575   // jumps or after returns from functions (in dead code locations).
1576   // If a long code sequence does not contain unconditional jumps, it is
1577   // necessary to emit the constant pool before the pool gets too far from the
1578   // location it is accessed from. In this case, we emit a jump over the emitted
1579   // constant pool.
1580   // Constants in the pool may be addresses of functions that gets relocated;
1581   // if so, a relocation info entry is associated to the constant pool entry.
1582
1583   // Repeated checking whether the constant pool should be emitted is rather
1584   // expensive. By default we only check again once a number of instructions
1585   // has been generated. That also means that the sizing of the buffers is not
1586   // an exact science, and that we rely on some slop to not overrun buffers.
1587   static const int kCheckPoolIntervalInst = 32;
1588   static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize;
1589
1590
1591   // Emission of the constant pool may be blocked in some code sequences.
1592   int const_pool_blocked_nesting_;  // Block emission if this is not zero.
1593   int no_const_pool_before_;  // Block emission before this pc offset.
1594
1595   // Keep track of the first instruction requiring a constant pool entry
1596   // since the previous constant pool was emitted.
1597   int first_const_pool_32_use_;
1598   int first_const_pool_64_use_;
1599
1600   // Relocation info generation
1601   // Each relocation is encoded as a variable size value
1602   static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1603   RelocInfoWriter reloc_info_writer;
1604
1605   // Relocation info records are also used during code generation as temporary
1606   // containers for constants and code target addresses until they are emitted
1607   // to the constant pool. These pending relocation info records are temporarily
1608   // stored in a separate buffer until a constant pool is emitted.
1609   // If every instruction in a long sequence is accessing the pool, we need one
1610   // pending relocation entry per instruction.
1611
1612   // The buffers of pending relocation info.
1613   RelocInfo pending_32_bit_reloc_info_[kMaxNumPending32RelocInfo];
1614   RelocInfo pending_64_bit_reloc_info_[kMaxNumPending64RelocInfo];
1615   // Number of pending reloc info entries in the 32 bits buffer.
1616   int num_pending_32_bit_reloc_info_;
1617   // Number of pending reloc info entries in the 64 bits buffer.
1618   int num_pending_64_bit_reloc_info_;
1619
1620   ConstantPoolBuilder constant_pool_builder_;
1621
1622   // The bound position, before this we cannot do instruction elimination.
1623   int last_bound_pos_;
1624
1625   // Code emission
1626   inline void CheckBuffer();
1627   void GrowBuffer();
1628   inline void emit(Instr x);
1629
1630   // 32-bit immediate values
1631   void move_32_bit_immediate(Register rd,
1632                              const Operand& x,
1633                              Condition cond = al);
1634
1635   // Instruction generation
1636   void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
1637   void addrmod2(Instr instr, Register rd, const MemOperand& x);
1638   void addrmod3(Instr instr, Register rd, const MemOperand& x);
1639   void addrmod4(Instr instr, Register rn, RegList rl);
1640   void addrmod5(Instr instr, CRegister crd, const MemOperand& x);
1641
1642   // Labels
1643   void print(Label* L);
1644   void bind_to(Label* L, int pos);
1645   void next(Label* L);
1646
1647   enum UseConstantPoolMode {
1648     USE_CONSTANT_POOL,
1649     DONT_USE_CONSTANT_POOL
1650   };
1651
1652   // Record reloc info for current pc_
1653   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1654   void RecordRelocInfo(const RelocInfo& rinfo);
1655   ConstantPoolArray::LayoutSection ConstantPoolAddEntry(const RelocInfo& rinfo);
1656
1657   friend class RelocInfo;
1658   friend class CodePatcher;
1659   friend class BlockConstPoolScope;
1660   PositionsRecorder positions_recorder_;
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_