1d1cc485d5064b23f15333f78626305c3bfef3b6
[platform/upstream/v8.git] / 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/compiler.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_embedded_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_embedded_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 context register.
166 const Register r7 = {kRegister_r7_Code};
167 // Used as constant pool pointer register if FLAG_enable_embedded_constant_pool.
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 struct VmovIndex {
655   unsigned char index;
656 };
657 const VmovIndex VmovIndexLo = { 0 };
658 const VmovIndex VmovIndexHi = { 1 };
659
660 class Assembler : public AssemblerBase {
661  public:
662   // Create an assembler. Instructions and relocation information are emitted
663   // into a buffer, with the instructions starting from the beginning and the
664   // relocation information starting from the end of the buffer. See CodeDesc
665   // for a detailed comment on the layout (globals.h).
666   //
667   // If the provided buffer is NULL, the assembler allocates and grows its own
668   // buffer, and buffer_size determines the initial buffer size. The buffer is
669   // owned by the assembler and deallocated upon destruction of the assembler.
670   //
671   // If the provided buffer is not NULL, the assembler uses the provided buffer
672   // for code generation and assumes its size to be buffer_size. If the buffer
673   // is too small, a fatal error occurs. No deallocation of the buffer is done
674   // upon destruction of the assembler.
675   Assembler(Isolate* isolate, void* buffer, int buffer_size);
676   virtual ~Assembler();
677
678   // GetCode emits any pending (non-emitted) code and fills the descriptor
679   // desc. GetCode() is idempotent; it returns the same result if no other
680   // Assembler functions are invoked in between GetCode() calls.
681   void GetCode(CodeDesc* desc);
682
683   // Label operations & relative jumps (PPUM Appendix D)
684   //
685   // Takes a branch opcode (cc) and a label (L) and generates
686   // either a backward branch or a forward branch and links it
687   // to the label fixup chain. Usage:
688   //
689   // Label L;    // unbound label
690   // j(cc, &L);  // forward branch to unbound label
691   // bind(&L);   // bind label to the current pc
692   // j(cc, &L);  // backward branch to bound label
693   // bind(&L);   // illegal: a label may be bound only once
694   //
695   // Note: The same Label can be used for forward and backward branches
696   // but it may be bound only once.
697
698   void bind(Label* L);  // binds an unbound label L to the current code position
699
700   // Returns the branch offset to the given label from the current code position
701   // Links the label to the current position if it is still unbound
702   // Manages the jump elimination optimization if the second parameter is true.
703   int branch_offset(Label* L);
704
705   // Returns true if the given pc address is the start of a constant pool load
706   // instruction sequence.
707   INLINE(static bool is_constant_pool_load(Address pc));
708
709   // Return the address in the constant pool of the code target address used by
710   // the branch/call instruction at pc, or the object in a mov.
711   INLINE(static Address constant_pool_entry_address(Address pc,
712                                                     Address constant_pool));
713
714   // Read/Modify the code target address in the branch/call instruction at pc.
715   INLINE(static Address target_address_at(Address pc, Address constant_pool));
716   INLINE(static void set_target_address_at(
717       Address pc, Address constant_pool, Address target,
718       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
719   INLINE(static Address target_address_at(Address pc, Code* code)) {
720     Address constant_pool = code ? code->constant_pool() : NULL;
721     return target_address_at(pc, constant_pool);
722   }
723   INLINE(static void set_target_address_at(Address pc,
724                                            Code* code,
725                                            Address target,
726                                            ICacheFlushMode icache_flush_mode =
727                                                FLUSH_ICACHE_IF_NEEDED)) {
728     Address constant_pool = code ? code->constant_pool() : NULL;
729     set_target_address_at(pc, constant_pool, target, icache_flush_mode);
730   }
731
732   // Return the code target address at a call site from the return address
733   // of that call in the instruction stream.
734   INLINE(static Address target_address_from_return_address(Address pc));
735
736   // Given the address of the beginning of a call, return the address
737   // in the instruction stream that the call will return from.
738   INLINE(static Address return_address_from_call_start(Address pc));
739
740   // This sets the branch destination (which is in the constant pool on ARM).
741   // This is for calls and branches within generated code.
742   inline static void deserialization_set_special_target_at(
743       Address constant_pool_entry, Code* code, Address target);
744
745   // This sets the internal reference at the pc.
746   inline static void deserialization_set_target_internal_reference_at(
747       Address pc, Address target,
748       RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
749
750   // Here we are patching the address in the constant pool, not the actual call
751   // instruction.  The address in the constant pool is the same size as a
752   // pointer.
753   static const int kSpecialTargetSize = kPointerSize;
754
755   // Size of an instruction.
756   static const int kInstrSize = sizeof(Instr);
757
758   // Distance between start of patched debug break slot and the emitted address
759   // to jump to.
760   // Patched debug break slot code is:
761   //  ldr  ip, [pc, #0]   @ emited address and start
762   //  blx  ip
763   static const int kPatchDebugBreakSlotAddressOffset = 2 * kInstrSize;
764
765   // Difference between address of current opcode and value read from pc
766   // register.
767   static const int kPcLoadDelta = 8;
768
769   static const int kDebugBreakSlotInstructions = 4;
770   static const int kDebugBreakSlotLength =
771       kDebugBreakSlotInstructions * kInstrSize;
772
773   // ---------------------------------------------------------------------------
774   // Code generation
775
776   // Insert the smallest number of nop instructions
777   // possible to align the pc offset to a multiple
778   // of m. m must be a power of 2 (>= 4).
779   void Align(int m);
780   // Insert the smallest number of zero bytes possible to align the pc offset
781   // to a mulitple of m. m must be a power of 2 (>= 2).
782   void DataAlign(int m);
783   // Aligns code to something that's optimal for a jump target for the platform.
784   void CodeTargetAlign();
785
786   // Branch instructions
787   void b(int branch_offset, Condition cond = al);
788   void bl(int branch_offset, Condition cond = al);
789   void blx(int branch_offset);  // v5 and above
790   void blx(Register target, Condition cond = al);  // v5 and above
791   void bx(Register target, Condition cond = al);  // v5 and above, plus v4t
792
793   // Convenience branch instructions using labels
794   void b(Label* L, Condition cond = al);
795   void b(Condition cond, Label* L) { b(L, cond); }
796   void bl(Label* L, Condition cond = al);
797   void bl(Condition cond, Label* L) { bl(L, cond); }
798   void blx(Label* L);  // v5 and above
799
800   // Data-processing instructions
801
802   void and_(Register dst, Register src1, const Operand& src2,
803             SBit s = LeaveCC, Condition cond = al);
804
805   void eor(Register dst, Register src1, const Operand& src2,
806            SBit s = LeaveCC, Condition cond = al);
807
808   void sub(Register dst, Register src1, const Operand& src2,
809            SBit s = LeaveCC, Condition cond = al);
810   void sub(Register dst, Register src1, Register src2,
811            SBit s = LeaveCC, Condition cond = al) {
812     sub(dst, src1, Operand(src2), s, cond);
813   }
814
815   void rsb(Register dst, Register src1, const Operand& src2,
816            SBit s = LeaveCC, Condition cond = al);
817
818   void add(Register dst, Register src1, const Operand& src2,
819            SBit s = LeaveCC, Condition cond = al);
820   void add(Register dst, Register src1, Register src2,
821            SBit s = LeaveCC, Condition cond = al) {
822     add(dst, src1, Operand(src2), s, cond);
823   }
824
825   void adc(Register dst, Register src1, const Operand& src2,
826            SBit s = LeaveCC, Condition cond = al);
827
828   void sbc(Register dst, Register src1, const Operand& src2,
829            SBit s = LeaveCC, Condition cond = al);
830
831   void rsc(Register dst, Register src1, const Operand& src2,
832            SBit s = LeaveCC, Condition cond = al);
833
834   void tst(Register src1, const Operand& src2, Condition cond = al);
835   void tst(Register src1, Register src2, Condition cond = al) {
836     tst(src1, Operand(src2), cond);
837   }
838
839   void teq(Register src1, const Operand& src2, Condition cond = al);
840
841   void cmp(Register src1, const Operand& src2, Condition cond = al);
842   void cmp(Register src1, Register src2, Condition cond = al) {
843     cmp(src1, Operand(src2), cond);
844   }
845   void cmp_raw_immediate(Register src1, int raw_immediate, Condition cond = al);
846
847   void cmn(Register src1, const Operand& src2, Condition cond = al);
848
849   void orr(Register dst, Register src1, const Operand& src2,
850            SBit s = LeaveCC, Condition cond = al);
851   void orr(Register dst, Register src1, Register src2,
852            SBit s = LeaveCC, Condition cond = al) {
853     orr(dst, src1, Operand(src2), s, cond);
854   }
855
856   void mov(Register dst, const Operand& src,
857            SBit s = LeaveCC, Condition cond = al);
858   void mov(Register dst, Register src, SBit s = LeaveCC, Condition cond = al) {
859     mov(dst, Operand(src), s, cond);
860   }
861
862   // Load the position of the label relative to the generated code object
863   // pointer in a register.
864   void mov_label_offset(Register dst, Label* label);
865
866   // ARMv7 instructions for loading a 32 bit immediate in two instructions.
867   // The constant for movw and movt should be in the range 0-0xffff.
868   void movw(Register reg, uint32_t immediate, Condition cond = al);
869   void movt(Register reg, uint32_t immediate, Condition cond = al);
870
871   void bic(Register dst, Register src1, const Operand& src2,
872            SBit s = LeaveCC, Condition cond = al);
873
874   void mvn(Register dst, const Operand& src,
875            SBit s = LeaveCC, Condition cond = al);
876
877   // Shift instructions
878
879   void asr(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
880            Condition cond = al) {
881     if (src2.is_reg()) {
882       mov(dst, Operand(src1, ASR, src2.rm()), s, cond);
883     } else {
884       mov(dst, Operand(src1, ASR, src2.immediate()), s, cond);
885     }
886   }
887
888   void lsl(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
889            Condition cond = al) {
890     if (src2.is_reg()) {
891       mov(dst, Operand(src1, LSL, src2.rm()), s, cond);
892     } else {
893       mov(dst, Operand(src1, LSL, src2.immediate()), s, cond);
894     }
895   }
896
897   void lsr(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
898            Condition cond = al) {
899     if (src2.is_reg()) {
900       mov(dst, Operand(src1, LSR, src2.rm()), s, cond);
901     } else {
902       mov(dst, Operand(src1, LSR, src2.immediate()), s, cond);
903     }
904   }
905
906   // Multiply instructions
907
908   void mla(Register dst, Register src1, Register src2, Register srcA,
909            SBit s = LeaveCC, Condition cond = al);
910
911   void mls(Register dst, Register src1, Register src2, Register srcA,
912            Condition cond = al);
913
914   void sdiv(Register dst, Register src1, Register src2,
915             Condition cond = al);
916
917   void udiv(Register dst, Register src1, Register src2, Condition cond = al);
918
919   void mul(Register dst, Register src1, Register src2,
920            SBit s = LeaveCC, Condition cond = al);
921
922   void smmla(Register dst, Register src1, Register src2, Register srcA,
923              Condition cond = al);
924
925   void smmul(Register dst, Register src1, Register src2, Condition cond = al);
926
927   void smlal(Register dstL, Register dstH, Register src1, Register src2,
928              SBit s = LeaveCC, Condition cond = al);
929
930   void smull(Register dstL, Register dstH, Register src1, Register src2,
931              SBit s = LeaveCC, Condition cond = al);
932
933   void umlal(Register dstL, Register dstH, Register src1, Register src2,
934              SBit s = LeaveCC, Condition cond = al);
935
936   void umull(Register dstL, Register dstH, Register src1, Register src2,
937              SBit s = LeaveCC, Condition cond = al);
938
939   // Miscellaneous arithmetic instructions
940
941   void clz(Register dst, Register src, Condition cond = al);  // v5 and above
942
943   // Saturating instructions. v6 and above.
944
945   // Unsigned saturate.
946   //
947   // Saturate an optionally shifted signed value to an unsigned range.
948   //
949   //   usat dst, #satpos, src
950   //   usat dst, #satpos, src, lsl #sh
951   //   usat dst, #satpos, src, asr #sh
952   //
953   // Register dst will contain:
954   //
955   //   0,                 if s < 0
956   //   (1 << satpos) - 1, if s > ((1 << satpos) - 1)
957   //   s,                 otherwise
958   //
959   // where s is the contents of src after shifting (if used.)
960   void usat(Register dst, int satpos, const Operand& src, Condition cond = al);
961
962   // Bitfield manipulation instructions. v7 and above.
963
964   void ubfx(Register dst, Register src, int lsb, int width,
965             Condition cond = al);
966
967   void sbfx(Register dst, Register src, int lsb, int width,
968             Condition cond = al);
969
970   void bfc(Register dst, int lsb, int width, Condition cond = al);
971
972   void bfi(Register dst, Register src, int lsb, int width,
973            Condition cond = al);
974
975   void pkhbt(Register dst, Register src1, const Operand& src2,
976              Condition cond = al);
977
978   void pkhtb(Register dst, Register src1, const Operand& src2,
979              Condition cond = al);
980
981   void sxtb(Register dst, Register src, int rotate = 0, Condition cond = al);
982   void sxtab(Register dst, Register src1, Register src2, int rotate = 0,
983              Condition cond = al);
984   void sxth(Register dst, Register src, int rotate = 0, Condition cond = al);
985   void sxtah(Register dst, Register src1, Register src2, int rotate = 0,
986              Condition cond = al);
987
988   void uxtb(Register dst, Register src, int rotate = 0, Condition cond = al);
989   void uxtab(Register dst, Register src1, Register src2, int rotate = 0,
990              Condition cond = al);
991   void uxtb16(Register dst, Register src, int rotate = 0, Condition cond = al);
992   void uxth(Register dst, Register src, int rotate = 0, Condition cond = al);
993   void uxtah(Register dst, Register src1, Register src2, int rotate = 0,
994              Condition cond = al);
995
996   // Status register access instructions
997
998   void mrs(Register dst, SRegister s, Condition cond = al);
999   void msr(SRegisterFieldMask fields, const Operand& src, Condition cond = al);
1000
1001   // Load/Store instructions
1002   void ldr(Register dst, const MemOperand& src, Condition cond = al);
1003   void str(Register src, const MemOperand& dst, Condition cond = al);
1004   void ldrb(Register dst, const MemOperand& src, Condition cond = al);
1005   void strb(Register src, const MemOperand& dst, Condition cond = al);
1006   void ldrh(Register dst, const MemOperand& src, Condition cond = al);
1007   void strh(Register src, const MemOperand& dst, Condition cond = al);
1008   void ldrsb(Register dst, const MemOperand& src, Condition cond = al);
1009   void ldrsh(Register dst, const MemOperand& src, Condition cond = al);
1010   void ldrd(Register dst1,
1011             Register dst2,
1012             const MemOperand& src, Condition cond = al);
1013   void strd(Register src1,
1014             Register src2,
1015             const MemOperand& dst, Condition cond = al);
1016
1017   // Preload instructions
1018   void pld(const MemOperand& address);
1019
1020   // Load/Store multiple instructions
1021   void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al);
1022   void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al);
1023
1024   // Exception-generating instructions and debugging support
1025   void stop(const char* msg,
1026             Condition cond = al,
1027             int32_t code = kDefaultStopCode);
1028
1029   void bkpt(uint32_t imm16);  // v5 and above
1030   void svc(uint32_t imm24, Condition cond = al);
1031
1032   // Coprocessor instructions
1033
1034   void cdp(Coprocessor coproc, int opcode_1,
1035            CRegister crd, CRegister crn, CRegister crm,
1036            int opcode_2, Condition cond = al);
1037
1038   void cdp2(Coprocessor coproc, int opcode_1,
1039             CRegister crd, CRegister crn, CRegister crm,
1040             int opcode_2);  // v5 and above
1041
1042   void mcr(Coprocessor coproc, int opcode_1,
1043            Register rd, CRegister crn, CRegister crm,
1044            int opcode_2 = 0, Condition cond = al);
1045
1046   void mcr2(Coprocessor coproc, int opcode_1,
1047             Register rd, CRegister crn, CRegister crm,
1048             int opcode_2 = 0);  // v5 and above
1049
1050   void mrc(Coprocessor coproc, int opcode_1,
1051            Register rd, CRegister crn, CRegister crm,
1052            int opcode_2 = 0, Condition cond = al);
1053
1054   void mrc2(Coprocessor coproc, int opcode_1,
1055             Register rd, CRegister crn, CRegister crm,
1056             int opcode_2 = 0);  // v5 and above
1057
1058   void ldc(Coprocessor coproc, CRegister crd, const MemOperand& src,
1059            LFlag l = Short, Condition cond = al);
1060   void ldc(Coprocessor coproc, CRegister crd, Register base, int option,
1061            LFlag l = Short, Condition cond = al);
1062
1063   void ldc2(Coprocessor coproc, CRegister crd, const MemOperand& src,
1064             LFlag l = Short);  // v5 and above
1065   void ldc2(Coprocessor coproc, CRegister crd, Register base, int option,
1066             LFlag l = Short);  // v5 and above
1067
1068   // Support for VFP.
1069   // All these APIs support S0 to S31 and D0 to D31.
1070
1071   void vldr(const DwVfpRegister dst,
1072             const Register base,
1073             int offset,
1074             const Condition cond = al);
1075   void vldr(const DwVfpRegister dst,
1076             const MemOperand& src,
1077             const Condition cond = al);
1078
1079   void vldr(const SwVfpRegister dst,
1080             const Register base,
1081             int offset,
1082             const Condition cond = al);
1083   void vldr(const SwVfpRegister dst,
1084             const MemOperand& src,
1085             const Condition cond = al);
1086
1087   void vstr(const DwVfpRegister src,
1088             const Register base,
1089             int offset,
1090             const Condition cond = al);
1091   void vstr(const DwVfpRegister src,
1092             const MemOperand& dst,
1093             const Condition cond = al);
1094
1095   void vstr(const SwVfpRegister src,
1096             const Register base,
1097             int offset,
1098             const Condition cond = al);
1099   void vstr(const SwVfpRegister src,
1100             const MemOperand& dst,
1101             const Condition cond = al);
1102
1103   void vldm(BlockAddrMode am,
1104             Register base,
1105             DwVfpRegister first,
1106             DwVfpRegister last,
1107             Condition cond = al);
1108
1109   void vstm(BlockAddrMode am,
1110             Register base,
1111             DwVfpRegister first,
1112             DwVfpRegister last,
1113             Condition cond = al);
1114
1115   void vldm(BlockAddrMode am,
1116             Register base,
1117             SwVfpRegister first,
1118             SwVfpRegister last,
1119             Condition cond = al);
1120
1121   void vstm(BlockAddrMode am,
1122             Register base,
1123             SwVfpRegister first,
1124             SwVfpRegister last,
1125             Condition cond = al);
1126
1127   void vmov(const SwVfpRegister dst, float imm);
1128   void vmov(const DwVfpRegister dst,
1129             double imm,
1130             const Register scratch = no_reg);
1131   void vmov(const SwVfpRegister dst,
1132             const SwVfpRegister src,
1133             const Condition cond = al);
1134   void vmov(const DwVfpRegister dst,
1135             const DwVfpRegister src,
1136             const Condition cond = al);
1137   void vmov(const DwVfpRegister dst,
1138             const VmovIndex index,
1139             const Register src,
1140             const Condition cond = al);
1141   void vmov(const Register dst,
1142             const VmovIndex index,
1143             const DwVfpRegister src,
1144             const Condition cond = al);
1145   void vmov(const DwVfpRegister dst,
1146             const Register src1,
1147             const Register src2,
1148             const Condition cond = al);
1149   void vmov(const Register dst1,
1150             const Register dst2,
1151             const DwVfpRegister src,
1152             const Condition cond = al);
1153   void vmov(const SwVfpRegister dst,
1154             const Register src,
1155             const Condition cond = al);
1156   void vmov(const Register dst,
1157             const SwVfpRegister src,
1158             const Condition cond = al);
1159   void vcvt_f64_s32(const DwVfpRegister dst,
1160                     const SwVfpRegister src,
1161                     VFPConversionMode mode = kDefaultRoundToZero,
1162                     const Condition cond = al);
1163   void vcvt_f32_s32(const SwVfpRegister dst,
1164                     const SwVfpRegister src,
1165                     VFPConversionMode mode = kDefaultRoundToZero,
1166                     const Condition cond = al);
1167   void vcvt_f64_u32(const DwVfpRegister dst,
1168                     const SwVfpRegister src,
1169                     VFPConversionMode mode = kDefaultRoundToZero,
1170                     const Condition cond = al);
1171   void vcvt_s32_f64(const SwVfpRegister dst,
1172                     const DwVfpRegister src,
1173                     VFPConversionMode mode = kDefaultRoundToZero,
1174                     const Condition cond = al);
1175   void vcvt_u32_f64(const SwVfpRegister dst,
1176                     const DwVfpRegister src,
1177                     VFPConversionMode mode = kDefaultRoundToZero,
1178                     const Condition cond = al);
1179   void vcvt_f64_f32(const DwVfpRegister dst,
1180                     const SwVfpRegister src,
1181                     VFPConversionMode mode = kDefaultRoundToZero,
1182                     const Condition cond = al);
1183   void vcvt_f32_f64(const SwVfpRegister dst,
1184                     const DwVfpRegister src,
1185                     VFPConversionMode mode = kDefaultRoundToZero,
1186                     const Condition cond = al);
1187   void vcvt_f64_s32(const DwVfpRegister dst,
1188                     int fraction_bits,
1189                     const Condition cond = al);
1190
1191   void vmrs(const Register dst, const Condition cond = al);
1192   void vmsr(const Register dst, const Condition cond = al);
1193
1194   void vneg(const DwVfpRegister dst,
1195             const DwVfpRegister src,
1196             const Condition cond = al);
1197   void vneg(const SwVfpRegister dst, const SwVfpRegister src,
1198             const Condition cond = al);
1199   void vabs(const DwVfpRegister dst,
1200             const DwVfpRegister src,
1201             const Condition cond = al);
1202   void vabs(const SwVfpRegister dst, const SwVfpRegister src,
1203             const Condition cond = al);
1204   void vadd(const DwVfpRegister dst,
1205             const DwVfpRegister src1,
1206             const DwVfpRegister src2,
1207             const Condition cond = al);
1208   void vadd(const SwVfpRegister dst, const SwVfpRegister src1,
1209             const SwVfpRegister src2, const Condition cond = al);
1210   void vsub(const DwVfpRegister dst,
1211             const DwVfpRegister src1,
1212             const DwVfpRegister src2,
1213             const Condition cond = al);
1214   void vsub(const SwVfpRegister dst, const SwVfpRegister src1,
1215             const SwVfpRegister src2, const Condition cond = al);
1216   void vmul(const DwVfpRegister dst,
1217             const DwVfpRegister src1,
1218             const DwVfpRegister src2,
1219             const Condition cond = al);
1220   void vmul(const SwVfpRegister dst, const SwVfpRegister src1,
1221             const SwVfpRegister src2, const Condition cond = al);
1222   void vmla(const DwVfpRegister dst,
1223             const DwVfpRegister src1,
1224             const DwVfpRegister src2,
1225             const Condition cond = al);
1226   void vmla(const SwVfpRegister dst, const SwVfpRegister src1,
1227             const SwVfpRegister src2, const Condition cond = al);
1228   void vmls(const DwVfpRegister dst,
1229             const DwVfpRegister src1,
1230             const DwVfpRegister src2,
1231             const Condition cond = al);
1232   void vmls(const SwVfpRegister dst, const SwVfpRegister src1,
1233             const SwVfpRegister src2, const Condition cond = al);
1234   void vdiv(const DwVfpRegister dst,
1235             const DwVfpRegister src1,
1236             const DwVfpRegister src2,
1237             const Condition cond = al);
1238   void vdiv(const SwVfpRegister dst, const SwVfpRegister src1,
1239             const SwVfpRegister src2, const Condition cond = al);
1240   void vcmp(const DwVfpRegister src1,
1241             const DwVfpRegister src2,
1242             const Condition cond = al);
1243   void vcmp(const SwVfpRegister src1, const SwVfpRegister src2,
1244             const Condition cond = al);
1245   void vcmp(const DwVfpRegister src1,
1246             const double src2,
1247             const Condition cond = al);
1248   void vcmp(const SwVfpRegister src1, const float src2,
1249             const Condition cond = al);
1250   void vsqrt(const DwVfpRegister dst,
1251              const DwVfpRegister src,
1252              const Condition cond = al);
1253   void vsqrt(const SwVfpRegister dst, const SwVfpRegister src,
1254              const Condition cond = al);
1255
1256   // ARMv8 rounding instructions.
1257   void vrinta(const DwVfpRegister dst, const DwVfpRegister src);
1258   void vrintn(const DwVfpRegister dst, const DwVfpRegister src);
1259   void vrintm(const DwVfpRegister dst, const DwVfpRegister src);
1260   void vrintp(const DwVfpRegister dst, const DwVfpRegister src);
1261   void vrintz(const DwVfpRegister dst, const DwVfpRegister src,
1262               const Condition cond = al);
1263
1264   // Support for NEON.
1265   // All these APIs support D0 to D31 and Q0 to Q15.
1266
1267   void vld1(NeonSize size,
1268             const NeonListOperand& dst,
1269             const NeonMemOperand& src);
1270   void vst1(NeonSize size,
1271             const NeonListOperand& src,
1272             const NeonMemOperand& dst);
1273   void vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src);
1274
1275   // Pseudo instructions
1276
1277   // Different nop operations are used by the code generator to detect certain
1278   // states of the generated code.
1279   enum NopMarkerTypes {
1280     NON_MARKING_NOP = 0,
1281     DEBUG_BREAK_NOP,
1282     // IC markers.
1283     PROPERTY_ACCESS_INLINED,
1284     PROPERTY_ACCESS_INLINED_CONTEXT,
1285     PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
1286     // Helper values.
1287     LAST_CODE_MARKER,
1288     FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
1289   };
1290
1291   void nop(int type = 0);   // 0 is the default non-marking type.
1292
1293   void push(Register src, Condition cond = al) {
1294     str(src, MemOperand(sp, 4, NegPreIndex), cond);
1295   }
1296
1297   void pop(Register dst, Condition cond = al) {
1298     ldr(dst, MemOperand(sp, 4, PostIndex), cond);
1299   }
1300
1301   void pop() {
1302     add(sp, sp, Operand(kPointerSize));
1303   }
1304
1305   void vpush(DwVfpRegister src, Condition cond = al) {
1306     vstm(db_w, sp, src, src, cond);
1307   }
1308
1309   void vpop(DwVfpRegister dst, Condition cond = al) {
1310     vldm(ia_w, sp, dst, dst, cond);
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 generator continuation.
1351   void RecordGeneratorContinuation();
1352
1353   // Mark address of a debug break slot.
1354   void RecordDebugBreakSlot(RelocInfo::Mode mode, int argc = 0);
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 a deoptimization reason that can be used by a log or cpu profiler.
1375   // Use --trace-deopt to enable.
1376   void RecordDeoptReason(const int reason, const SourcePosition position);
1377
1378   // Record the emission of a constant pool.
1379   //
1380   // The emission of constant pool depends on the size of the code generated and
1381   // the number of RelocInfo recorded.
1382   // The Debug mechanism needs to map code offsets between two versions of a
1383   // function, compiled with and without debugger support (see for example
1384   // Debug::PrepareForBreakPoints()).
1385   // Compiling functions with debugger support generates additional code
1386   // (DebugCodegen::GenerateSlot()). This may affect the emission of the
1387   // constant pools and cause the version of the code with debugger support to
1388   // have constant pools generated in different places.
1389   // Recording the position and size of emitted constant pools allows to
1390   // correctly compute the offset mappings between the different versions of a
1391   // function in all situations.
1392   //
1393   // The parameter indicates the size of the constant pool (in bytes), including
1394   // the marker and branch over the data.
1395   void RecordConstPool(int size);
1396
1397   // Writes a single byte or word of data in the code stream.  Used
1398   // for inline tables, e.g., jump-tables. CheckConstantPool() should be
1399   // called before any use of db/dd/dq/dp to ensure that constant pools
1400   // are not emitted as part of the tables generated.
1401   void db(uint8_t data);
1402   void dd(uint32_t data);
1403   void dq(uint64_t data);
1404   void dp(uintptr_t data) { dd(data); }
1405
1406   // Emits the address of the code stub's first instruction.
1407   void emit_code_stub_address(Code* stub);
1408
1409   PositionsRecorder* positions_recorder() { return &positions_recorder_; }
1410
1411   // Read/patch instructions
1412   Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
1413   void instr_at_put(int pos, Instr instr) {
1414     *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
1415   }
1416   static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
1417   static void instr_at_put(byte* pc, Instr instr) {
1418     *reinterpret_cast<Instr*>(pc) = instr;
1419   }
1420   static Condition GetCondition(Instr instr);
1421   static bool IsBranch(Instr instr);
1422   static int GetBranchOffset(Instr instr);
1423   static bool IsLdrRegisterImmediate(Instr instr);
1424   static bool IsVldrDRegisterImmediate(Instr instr);
1425   static Instr GetConsantPoolLoadPattern();
1426   static Instr GetConsantPoolLoadMask();
1427   static bool IsLdrPpRegOffset(Instr instr);
1428   static Instr GetLdrPpRegOffsetPattern();
1429   static bool IsLdrPpImmediateOffset(Instr instr);
1430   static bool IsVldrDPpImmediateOffset(Instr instr);
1431   static int GetLdrRegisterImmediateOffset(Instr instr);
1432   static int GetVldrDRegisterImmediateOffset(Instr instr);
1433   static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset);
1434   static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset);
1435   static bool IsStrRegisterImmediate(Instr instr);
1436   static Instr SetStrRegisterImmediateOffset(Instr instr, int offset);
1437   static bool IsAddRegisterImmediate(Instr instr);
1438   static Instr SetAddRegisterImmediateOffset(Instr instr, int offset);
1439   static Register GetRd(Instr instr);
1440   static Register GetRn(Instr instr);
1441   static Register GetRm(Instr instr);
1442   static bool IsPush(Instr instr);
1443   static bool IsPop(Instr instr);
1444   static bool IsStrRegFpOffset(Instr instr);
1445   static bool IsLdrRegFpOffset(Instr instr);
1446   static bool IsStrRegFpNegOffset(Instr instr);
1447   static bool IsLdrRegFpNegOffset(Instr instr);
1448   static bool IsLdrPcImmediateOffset(Instr instr);
1449   static bool IsVldrDPcImmediateOffset(Instr instr);
1450   static bool IsBlxReg(Instr instr);
1451   static bool IsBlxIp(Instr instr);
1452   static bool IsTstImmediate(Instr instr);
1453   static bool IsCmpRegister(Instr instr);
1454   static bool IsCmpImmediate(Instr instr);
1455   static Register GetCmpImmediateRegister(Instr instr);
1456   static int GetCmpImmediateRawImmediate(Instr instr);
1457   static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
1458   static bool IsMovImmed(Instr instr);
1459   static bool IsOrrImmed(Instr instr);
1460   static bool IsMovT(Instr instr);
1461   static Instr GetMovTPattern();
1462   static bool IsMovW(Instr instr);
1463   static Instr GetMovWPattern();
1464   static Instr EncodeMovwImmediate(uint32_t immediate);
1465   static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate);
1466   static int DecodeShiftImm(Instr instr);
1467   static Instr PatchShiftImm(Instr instr, int immed);
1468
1469   // Constants in pools are accessed via pc relative addressing, which can
1470   // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point
1471   // PC-relative loads, thereby defining a maximum distance between the
1472   // instruction and the accessed constant.
1473   static const int kMaxDistToIntPool = 4*KB;
1474   static const int kMaxDistToFPPool = 1*KB;
1475   // All relocations could be integer, it therefore acts as the limit.
1476   static const int kMinNumPendingConstants = 4;
1477   static const int kMaxNumPending32Constants = kMaxDistToIntPool / kInstrSize;
1478   static const int kMaxNumPending64Constants = kMaxDistToFPPool / kInstrSize;
1479
1480   // Postpone the generation of the constant pool for the specified number of
1481   // instructions.
1482   void BlockConstPoolFor(int instructions);
1483
1484   // Check if is time to emit a constant pool.
1485   void CheckConstPool(bool force_emit, bool require_jump);
1486
1487   void MaybeCheckConstPool() {
1488     if (pc_offset() >= next_buffer_check_) {
1489       CheckConstPool(false, true);
1490     }
1491   }
1492
1493   int EmitEmbeddedConstantPool() {
1494     DCHECK(FLAG_enable_embedded_constant_pool);
1495     return constant_pool_builder_.Emit(this);
1496   }
1497
1498   bool ConstantPoolAccessIsInOverflow() const {
1499     return constant_pool_builder_.NextAccess(ConstantPoolEntry::INTPTR) ==
1500            ConstantPoolEntry::OVERFLOWED;
1501   }
1502
1503   void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1504                                           ConstantPoolEntry::Access access,
1505                                           ConstantPoolEntry::Type type);
1506
1507  protected:
1508   // Relocation for a type-recording IC has the AST id added to it.  This
1509   // member variable is a way to pass the information from the call site to
1510   // the relocation info.
1511   TypeFeedbackId recorded_ast_id_;
1512
1513   int buffer_space() const { return reloc_info_writer.pos() - pc_; }
1514
1515   // Decode branch instruction at pos and return branch target pos
1516   int target_at(int pos);
1517
1518   // Patch branch instruction at pos to branch to given branch target pos
1519   void target_at_put(int pos, int target_pos);
1520
1521   // Prevent contant pool emission until EndBlockConstPool is called.
1522   // Call to this function can be nested but must be followed by an equal
1523   // number of call to EndBlockConstpool.
1524   void StartBlockConstPool() {
1525     if (const_pool_blocked_nesting_++ == 0) {
1526       // Prevent constant pool checks happening by setting the next check to
1527       // the biggest possible offset.
1528       next_buffer_check_ = kMaxInt;
1529     }
1530   }
1531
1532   // Resume constant pool emission. Need to be called as many time as
1533   // StartBlockConstPool to have an effect.
1534   void EndBlockConstPool() {
1535     if (--const_pool_blocked_nesting_ == 0) {
1536 #ifdef DEBUG
1537       // Max pool start (if we need a jump and an alignment).
1538       int start = pc_offset() + kInstrSize + 2 * kPointerSize;
1539       // Check the constant pool hasn't been blocked for too long.
1540       DCHECK((num_pending_32_bit_constants_ == 0) ||
1541              (start + num_pending_64_bit_constants_ * kDoubleSize <
1542               (first_const_pool_32_use_ + kMaxDistToIntPool)));
1543       DCHECK((num_pending_64_bit_constants_ == 0) ||
1544              (start < (first_const_pool_64_use_ + kMaxDistToFPPool)));
1545 #endif
1546       // Two cases:
1547       //  * no_const_pool_before_ >= next_buffer_check_ and the emission is
1548       //    still blocked
1549       //  * no_const_pool_before_ < next_buffer_check_ and the next emit will
1550       //    trigger a check.
1551       next_buffer_check_ = no_const_pool_before_;
1552     }
1553   }
1554
1555   bool is_const_pool_blocked() const {
1556     return (const_pool_blocked_nesting_ > 0) ||
1557            (pc_offset() < no_const_pool_before_);
1558   }
1559
1560  private:
1561   int next_buffer_check_;  // pc offset of next buffer check
1562
1563   // Code generation
1564   // The relocation writer's position is at least kGap bytes below the end of
1565   // the generated instructions. This is so that multi-instruction sequences do
1566   // not have to check for overflow. The same is true for writes of large
1567   // relocation info entries.
1568   static const int kGap = 32;
1569
1570   // Constant pool generation
1571   // Pools are emitted in the instruction stream, preferably after unconditional
1572   // jumps or after returns from functions (in dead code locations).
1573   // If a long code sequence does not contain unconditional jumps, it is
1574   // necessary to emit the constant pool before the pool gets too far from the
1575   // location it is accessed from. In this case, we emit a jump over the emitted
1576   // constant pool.
1577   // Constants in the pool may be addresses of functions that gets relocated;
1578   // if so, a relocation info entry is associated to the constant pool entry.
1579
1580   // Repeated checking whether the constant pool should be emitted is rather
1581   // expensive. By default we only check again once a number of instructions
1582   // has been generated. That also means that the sizing of the buffers is not
1583   // an exact science, and that we rely on some slop to not overrun buffers.
1584   static const int kCheckPoolIntervalInst = 32;
1585   static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize;
1586
1587
1588   // Emission of the constant pool may be blocked in some code sequences.
1589   int const_pool_blocked_nesting_;  // Block emission if this is not zero.
1590   int no_const_pool_before_;  // Block emission before this pc offset.
1591
1592   // Keep track of the first instruction requiring a constant pool entry
1593   // since the previous constant pool was emitted.
1594   int first_const_pool_32_use_;
1595   int first_const_pool_64_use_;
1596
1597   // Relocation info generation
1598   // Each relocation is encoded as a variable size value
1599   static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1600   RelocInfoWriter reloc_info_writer;
1601
1602   // ConstantPoolEntry records are used during code generation as temporary
1603   // containers for constants and code target addresses until they are emitted
1604   // to the constant pool. These records are temporarily stored in a separate
1605   // buffer until a constant pool is emitted.
1606   // If every instruction in a long sequence is accessing the pool, we need one
1607   // pending relocation entry per instruction.
1608
1609   // The buffers of pending constant pool entries.
1610   ConstantPoolEntry pending_32_bit_constants_buffer_[kMinNumPendingConstants];
1611   ConstantPoolEntry pending_64_bit_constants_buffer_[kMinNumPendingConstants];
1612   ConstantPoolEntry* pending_32_bit_constants_;
1613   ConstantPoolEntry* pending_64_bit_constants_;
1614   // Number of pending constant pool entries in the 32 bits buffer.
1615   int num_pending_32_bit_constants_;
1616   // Number of pending constant pool entries in the 64 bits buffer.
1617   int num_pending_64_bit_constants_;
1618
1619   ConstantPoolBuilder constant_pool_builder_;
1620
1621   // The bound position, before this we cannot do instruction elimination.
1622   int last_bound_pos_;
1623
1624   // Code emission
1625   inline void CheckBuffer();
1626   void GrowBuffer();
1627   inline void emit(Instr x);
1628
1629   // 32-bit immediate values
1630   void move_32_bit_immediate(Register rd,
1631                              const Operand& x,
1632                              Condition cond = al);
1633
1634   // Instruction generation
1635   void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
1636   void addrmod2(Instr instr, Register rd, const MemOperand& x);
1637   void addrmod3(Instr instr, Register rd, const MemOperand& x);
1638   void addrmod4(Instr instr, Register rn, RegList rl);
1639   void addrmod5(Instr instr, CRegister crd, const MemOperand& x);
1640
1641   // Labels
1642   void print(Label* L);
1643   void bind_to(Label* L, int pos);
1644   void next(Label* L);
1645
1646   // Record reloc info for current pc_
1647   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1648   ConstantPoolEntry::Access ConstantPoolAddEntry(int position,
1649                                                  RelocInfo::Mode rmode,
1650                                                  intptr_t value);
1651   ConstantPoolEntry::Access ConstantPoolAddEntry(int position, double value);
1652
1653   friend class RelocInfo;
1654   friend class CodePatcher;
1655   friend class BlockConstPoolScope;
1656   PositionsRecorder positions_recorder_;
1657   friend class PositionsRecorder;
1658   friend class EnsureSpace;
1659 };
1660
1661
1662 class EnsureSpace BASE_EMBEDDED {
1663  public:
1664   explicit EnsureSpace(Assembler* assembler) {
1665     assembler->CheckBuffer();
1666   }
1667 };
1668
1669
1670 } }  // namespace v8::internal
1671
1672 #endif  // V8_ARM_ASSEMBLER_ARM_H_