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