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