Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / src / arm / assembler-arm.cc
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 #include "src/v8.h"
38
39 #if V8_TARGET_ARCH_ARM
40
41 #include "src/arm/assembler-arm-inl.h"
42 #include "src/base/bits.h"
43 #include "src/base/cpu.h"
44 #include "src/macro-assembler.h"
45 #include "src/serialize.h"
46
47 namespace v8 {
48 namespace internal {
49
50 // Get the CPU features enabled by the build. For cross compilation the
51 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS
52 // can be defined to enable ARMv7 and VFPv3 instructions when building the
53 // snapshot.
54 static unsigned CpuFeaturesImpliedByCompiler() {
55   unsigned answer = 0;
56 #ifdef CAN_USE_ARMV7_INSTRUCTIONS
57   if (FLAG_enable_armv7) answer |= 1u << ARMv7;
58 #endif  // CAN_USE_ARMV7_INSTRUCTIONS
59 #ifdef CAN_USE_VFP3_INSTRUCTIONS
60   if (FLAG_enable_vfp3) answer |= 1u << VFP3 | 1u << ARMv7;
61 #endif  // CAN_USE_VFP3_INSTRUCTIONS
62 #ifdef CAN_USE_VFP32DREGS
63   if (FLAG_enable_32dregs) answer |= 1u << VFP32DREGS;
64 #endif  // CAN_USE_VFP32DREGS
65 #ifdef CAN_USE_NEON
66   if (FLAG_enable_neon) answer |= 1u << NEON;
67 #endif  // CAN_USE_VFP32DREGS
68   if ((answer & (1u << ARMv7)) && FLAG_enable_unaligned_accesses) {
69     answer |= 1u << UNALIGNED_ACCESSES;
70   }
71
72   return answer;
73 }
74
75
76 void CpuFeatures::ProbeImpl(bool cross_compile) {
77   supported_ |= CpuFeaturesImpliedByCompiler();
78   cache_line_size_ = 64;
79
80   // Only use statically determined features for cross compile (snapshot).
81   if (cross_compile) return;
82
83 #ifndef __arm__
84   // For the simulator build, use whatever the flags specify.
85   if (FLAG_enable_armv7) {
86     supported_ |= 1u << ARMv7;
87     if (FLAG_enable_vfp3) supported_ |= 1u << VFP3;
88     if (FLAG_enable_neon) supported_ |= 1u << NEON | 1u << VFP32DREGS;
89     if (FLAG_enable_sudiv) supported_ |= 1u << SUDIV;
90     if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
91     if (FLAG_enable_32dregs) supported_ |= 1u << VFP32DREGS;
92   }
93   if (FLAG_enable_mls) supported_ |= 1u << MLS;
94   if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES;
95
96 #else  // __arm__
97   // Probe for additional features at runtime.
98   base::CPU cpu;
99   if (FLAG_enable_vfp3 && cpu.has_vfp3()) {
100     // This implementation also sets the VFP flags if runtime
101     // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI
102     // 0406B, page A1-6.
103     supported_ |= 1u << VFP3 | 1u << ARMv7;
104   }
105
106   if (FLAG_enable_neon && cpu.has_neon()) supported_ |= 1u << NEON;
107   if (FLAG_enable_sudiv && cpu.has_idiva()) supported_ |= 1u << SUDIV;
108   if (FLAG_enable_mls && cpu.has_thumb2()) supported_ |= 1u << MLS;
109
110   if (cpu.architecture() >= 7) {
111     if (FLAG_enable_armv7) supported_ |= 1u << ARMv7;
112     if (FLAG_enable_armv8 && cpu.architecture() >= 8) {
113       supported_ |= 1u << ARMv8;
114     }
115     if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES;
116     // Use movw/movt for QUALCOMM ARMv7 cores.
117     if (FLAG_enable_movw_movt && cpu.implementer() == base::CPU::QUALCOMM) {
118       supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
119     }
120   }
121
122   // ARM Cortex-A9 and Cortex-A5 have 32 byte cachelines.
123   if (cpu.implementer() == base::CPU::ARM &&
124       (cpu.part() == base::CPU::ARM_CORTEX_A5 ||
125        cpu.part() == base::CPU::ARM_CORTEX_A9)) {
126     cache_line_size_ = 32;
127   }
128
129   if (FLAG_enable_32dregs && cpu.has_vfp3_d32()) supported_ |= 1u << VFP32DREGS;
130 #endif
131
132   DCHECK(!IsSupported(VFP3) || IsSupported(ARMv7));
133 }
134
135
136 void CpuFeatures::PrintTarget() {
137   const char* arm_arch = NULL;
138   const char* arm_target_type = "";
139   const char* arm_no_probe = "";
140   const char* arm_fpu = "";
141   const char* arm_thumb = "";
142   const char* arm_float_abi = NULL;
143
144 #if !defined __arm__
145   arm_target_type = " simulator";
146 #endif
147
148 #if defined ARM_TEST_NO_FEATURE_PROBE
149   arm_no_probe = " noprobe";
150 #endif
151
152 #if defined CAN_USE_ARMV7_INSTRUCTIONS
153   arm_arch = "arm v7";
154 #else
155   arm_arch = "arm v6";
156 #endif
157
158 #if defined CAN_USE_NEON
159   arm_fpu = " neon";
160 #elif defined CAN_USE_VFP3_INSTRUCTIONS
161 #  if defined CAN_USE_VFP32DREGS
162   arm_fpu = " vfp3";
163 #  else
164   arm_fpu = " vfp3-d16";
165 #  endif
166 #else
167   arm_fpu = " vfp2";
168 #endif
169
170 #ifdef __arm__
171   arm_float_abi = base::OS::ArmUsingHardFloat() ? "hard" : "softfp";
172 #elif USE_EABI_HARDFLOAT
173   arm_float_abi = "hard";
174 #else
175   arm_float_abi = "softfp";
176 #endif
177
178 #if defined __arm__ && (defined __thumb__) || (defined __thumb2__)
179   arm_thumb = " thumb";
180 #endif
181
182   printf("target%s%s %s%s%s %s\n",
183          arm_target_type, arm_no_probe, arm_arch, arm_fpu, arm_thumb,
184          arm_float_abi);
185 }
186
187
188 void CpuFeatures::PrintFeatures() {
189   printf(
190     "ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d UNALIGNED_ACCESSES=%d "
191     "MOVW_MOVT_IMMEDIATE_LOADS=%d",
192     CpuFeatures::IsSupported(ARMv7),
193     CpuFeatures::IsSupported(VFP3),
194     CpuFeatures::IsSupported(VFP32DREGS),
195     CpuFeatures::IsSupported(NEON),
196     CpuFeatures::IsSupported(SUDIV),
197     CpuFeatures::IsSupported(UNALIGNED_ACCESSES),
198     CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS));
199 #ifdef __arm__
200   bool eabi_hardfloat = base::OS::ArmUsingHardFloat();
201 #elif USE_EABI_HARDFLOAT
202   bool eabi_hardfloat = true;
203 #else
204   bool eabi_hardfloat = false;
205 #endif
206     printf(" USE_EABI_HARDFLOAT=%d\n", eabi_hardfloat);
207 }
208
209
210 // -----------------------------------------------------------------------------
211 // Implementation of DwVfpRegister
212
213 const char* DwVfpRegister::AllocationIndexToString(int index) {
214   DCHECK(index >= 0 && index < NumAllocatableRegisters());
215   DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
216          kNumReservedRegisters - 1);
217   if (index >= kDoubleRegZero.code()) index += kNumReservedRegisters;
218   return VFPRegisters::Name(index, true);
219 }
220
221
222 // -----------------------------------------------------------------------------
223 // Implementation of RelocInfo
224
225 const int RelocInfo::kApplyMask = 0;
226
227
228 bool RelocInfo::IsCodedSpecially() {
229   // The deserializer needs to know whether a pointer is specially coded. Â Being
230   // specially coded on ARM means that it is a movw/movt instruction, or is an
231   // out of line constant pool entry. Â These only occur if
232   // FLAG_enable_ool_constant_pool is true.
233   return FLAG_enable_ool_constant_pool;
234 }
235
236
237 bool RelocInfo::IsInConstantPool() {
238   return Assembler::is_constant_pool_load(pc_);
239 }
240
241
242 void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
243   // Patch the code at the current address with the supplied instructions.
244   Instr* pc = reinterpret_cast<Instr*>(pc_);
245   Instr* instr = reinterpret_cast<Instr*>(instructions);
246   for (int i = 0; i < instruction_count; i++) {
247     *(pc + i) = *(instr + i);
248   }
249
250   // Indicate that code has changed.
251   CpuFeatures::FlushICache(pc_, instruction_count * Assembler::kInstrSize);
252 }
253
254
255 // Patch the code at the current PC with a call to the target address.
256 // Additional guard instructions can be added if required.
257 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
258   // Patch the code at the current address with a call to the target.
259   UNIMPLEMENTED();
260 }
261
262
263 // -----------------------------------------------------------------------------
264 // Implementation of Operand and MemOperand
265 // See assembler-arm-inl.h for inlined constructors
266
267 Operand::Operand(Handle<Object> handle) {
268   AllowDeferredHandleDereference using_raw_address;
269   rm_ = no_reg;
270   // Verify all Objects referred by code are NOT in new space.
271   Object* obj = *handle;
272   if (obj->IsHeapObject()) {
273     DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
274     imm32_ = reinterpret_cast<intptr_t>(handle.location());
275     rmode_ = RelocInfo::EMBEDDED_OBJECT;
276   } else {
277     // no relocation needed
278     imm32_ = reinterpret_cast<intptr_t>(obj);
279     rmode_ = RelocInfo::NONE32;
280   }
281 }
282
283
284 Operand::Operand(Register rm, ShiftOp shift_op, int shift_imm) {
285   DCHECK(is_uint5(shift_imm));
286
287   rm_ = rm;
288   rs_ = no_reg;
289   shift_op_ = shift_op;
290   shift_imm_ = shift_imm & 31;
291
292   if ((shift_op == ROR) && (shift_imm == 0)) {
293     // ROR #0 is functionally equivalent to LSL #0 and this allow us to encode
294     // RRX as ROR #0 (See below).
295     shift_op = LSL;
296   } else if (shift_op == RRX) {
297     // encoded as ROR with shift_imm == 0
298     DCHECK(shift_imm == 0);
299     shift_op_ = ROR;
300     shift_imm_ = 0;
301   }
302 }
303
304
305 Operand::Operand(Register rm, ShiftOp shift_op, Register rs) {
306   DCHECK(shift_op != RRX);
307   rm_ = rm;
308   rs_ = no_reg;
309   shift_op_ = shift_op;
310   rs_ = rs;
311 }
312
313
314 MemOperand::MemOperand(Register rn, int32_t offset, AddrMode am) {
315   rn_ = rn;
316   rm_ = no_reg;
317   offset_ = offset;
318   am_ = am;
319 }
320
321
322 MemOperand::MemOperand(Register rn, Register rm, AddrMode am) {
323   rn_ = rn;
324   rm_ = rm;
325   shift_op_ = LSL;
326   shift_imm_ = 0;
327   am_ = am;
328 }
329
330
331 MemOperand::MemOperand(Register rn, Register rm,
332                        ShiftOp shift_op, int shift_imm, AddrMode am) {
333   DCHECK(is_uint5(shift_imm));
334   rn_ = rn;
335   rm_ = rm;
336   shift_op_ = shift_op;
337   shift_imm_ = shift_imm & 31;
338   am_ = am;
339 }
340
341
342 NeonMemOperand::NeonMemOperand(Register rn, AddrMode am, int align) {
343   DCHECK((am == Offset) || (am == PostIndex));
344   rn_ = rn;
345   rm_ = (am == Offset) ? pc : sp;
346   SetAlignment(align);
347 }
348
349
350 NeonMemOperand::NeonMemOperand(Register rn, Register rm, int align) {
351   rn_ = rn;
352   rm_ = rm;
353   SetAlignment(align);
354 }
355
356
357 void NeonMemOperand::SetAlignment(int align) {
358   switch (align) {
359     case 0:
360       align_ = 0;
361       break;
362     case 64:
363       align_ = 1;
364       break;
365     case 128:
366       align_ = 2;
367       break;
368     case 256:
369       align_ = 3;
370       break;
371     default:
372       UNREACHABLE();
373       align_ = 0;
374       break;
375   }
376 }
377
378
379 NeonListOperand::NeonListOperand(DoubleRegister base, int registers_count) {
380   base_ = base;
381   switch (registers_count) {
382     case 1:
383       type_ = nlt_1;
384       break;
385     case 2:
386       type_ = nlt_2;
387       break;
388     case 3:
389       type_ = nlt_3;
390       break;
391     case 4:
392       type_ = nlt_4;
393       break;
394     default:
395       UNREACHABLE();
396       type_ = nlt_1;
397       break;
398   }
399 }
400
401
402 // -----------------------------------------------------------------------------
403 // Specific instructions, constants, and masks.
404
405 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
406 // register r is not encoded.
407 const Instr kPushRegPattern =
408     al | B26 | 4 | NegPreIndex | kRegister_sp_Code * B16;
409 // ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r))
410 // register r is not encoded.
411 const Instr kPopRegPattern =
412     al | B26 | L | 4 | PostIndex | kRegister_sp_Code * B16;
413 // ldr rd, [pc, #offset]
414 const Instr kLdrPCImmedMask = 15 * B24 | 7 * B20 | 15 * B16;
415 const Instr kLdrPCImmedPattern = 5 * B24 | L | kRegister_pc_Code * B16;
416 // ldr rd, [pp, #offset]
417 const Instr kLdrPpImmedMask = 15 * B24 | 7 * B20 | 15 * B16;
418 const Instr kLdrPpImmedPattern = 5 * B24 | L | kRegister_r8_Code * B16;
419 // ldr rd, [pp, rn]
420 const Instr kLdrPpRegMask = 15 * B24 | 7 * B20 | 15 * B16;
421 const Instr kLdrPpRegPattern = 7 * B24 | L | kRegister_r8_Code * B16;
422 // vldr dd, [pc, #offset]
423 const Instr kVldrDPCMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8;
424 const Instr kVldrDPCPattern = 13 * B24 | L | kRegister_pc_Code * B16 | 11 * B8;
425 // vldr dd, [pp, #offset]
426 const Instr kVldrDPpMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8;
427 const Instr kVldrDPpPattern = 13 * B24 | L | kRegister_r8_Code * B16 | 11 * B8;
428 // blxcc rm
429 const Instr kBlxRegMask =
430     15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4;
431 const Instr kBlxRegPattern =
432     B24 | B21 | 15 * B16 | 15 * B12 | 15 * B8 | BLX;
433 const Instr kBlxIp = al | kBlxRegPattern | ip.code();
434 const Instr kMovMvnMask = 0x6d * B21 | 0xf * B16;
435 const Instr kMovMvnPattern = 0xd * B21;
436 const Instr kMovMvnFlip = B22;
437 const Instr kMovLeaveCCMask = 0xdff * B16;
438 const Instr kMovLeaveCCPattern = 0x1a0 * B16;
439 const Instr kMovwPattern = 0x30 * B20;
440 const Instr kMovtPattern = 0x34 * B20;
441 const Instr kMovwLeaveCCFlip = 0x5 * B21;
442 const Instr kMovImmedMask = 0x7f * B21;
443 const Instr kMovImmedPattern = 0x1d * B21;
444 const Instr kOrrImmedMask = 0x7f * B21;
445 const Instr kOrrImmedPattern = 0x1c * B21;
446 const Instr kCmpCmnMask = 0xdd * B20 | 0xf * B12;
447 const Instr kCmpCmnPattern = 0x15 * B20;
448 const Instr kCmpCmnFlip = B21;
449 const Instr kAddSubFlip = 0x6 * B21;
450 const Instr kAndBicFlip = 0xe * B21;
451
452 // A mask for the Rd register for push, pop, ldr, str instructions.
453 const Instr kLdrRegFpOffsetPattern =
454     al | B26 | L | Offset | kRegister_fp_Code * B16;
455 const Instr kStrRegFpOffsetPattern =
456     al | B26 | Offset | kRegister_fp_Code * B16;
457 const Instr kLdrRegFpNegOffsetPattern =
458     al | B26 | L | NegOffset | kRegister_fp_Code * B16;
459 const Instr kStrRegFpNegOffsetPattern =
460     al | B26 | NegOffset | kRegister_fp_Code * B16;
461 const Instr kLdrStrInstrTypeMask = 0xffff0000;
462
463
464 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
465     : AssemblerBase(isolate, buffer, buffer_size),
466       recorded_ast_id_(TypeFeedbackId::None()),
467       constant_pool_builder_(),
468       positions_recorder_(this) {
469   reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
470   num_pending_32_bit_reloc_info_ = 0;
471   num_pending_64_bit_reloc_info_ = 0;
472   next_buffer_check_ = 0;
473   const_pool_blocked_nesting_ = 0;
474   no_const_pool_before_ = 0;
475   first_const_pool_32_use_ = -1;
476   first_const_pool_64_use_ = -1;
477   last_bound_pos_ = 0;
478   ClearRecordedAstId();
479 }
480
481
482 Assembler::~Assembler() {
483   DCHECK(const_pool_blocked_nesting_ == 0);
484 }
485
486
487 void Assembler::GetCode(CodeDesc* desc) {
488   if (!FLAG_enable_ool_constant_pool) {
489     // Emit constant pool if necessary.
490     CheckConstPool(true, false);
491     DCHECK(num_pending_32_bit_reloc_info_ == 0);
492     DCHECK(num_pending_64_bit_reloc_info_ == 0);
493   }
494   // Set up code descriptor.
495   desc->buffer = buffer_;
496   desc->buffer_size = buffer_size_;
497   desc->instr_size = pc_offset();
498   desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
499   desc->origin = this;
500 }
501
502
503 void Assembler::Align(int m) {
504   DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
505   while ((pc_offset() & (m - 1)) != 0) {
506     nop();
507   }
508 }
509
510
511 void Assembler::CodeTargetAlign() {
512   // Preferred alignment of jump targets on some ARM chips.
513   Align(8);
514 }
515
516
517 Condition Assembler::GetCondition(Instr instr) {
518   return Instruction::ConditionField(instr);
519 }
520
521
522 bool Assembler::IsBranch(Instr instr) {
523   return (instr & (B27 | B25)) == (B27 | B25);
524 }
525
526
527 int Assembler::GetBranchOffset(Instr instr) {
528   DCHECK(IsBranch(instr));
529   // Take the jump offset in the lower 24 bits, sign extend it and multiply it
530   // with 4 to get the offset in bytes.
531   return ((instr & kImm24Mask) << 8) >> 6;
532 }
533
534
535 bool Assembler::IsLdrRegisterImmediate(Instr instr) {
536   return (instr & (B27 | B26 | B25 | B22 | B20)) == (B26 | B20);
537 }
538
539
540 bool Assembler::IsVldrDRegisterImmediate(Instr instr) {
541   return (instr & (15 * B24 | 3 * B20 | 15 * B8)) == (13 * B24 | B20 | 11 * B8);
542 }
543
544
545 int Assembler::GetLdrRegisterImmediateOffset(Instr instr) {
546   DCHECK(IsLdrRegisterImmediate(instr));
547   bool positive = (instr & B23) == B23;
548   int offset = instr & kOff12Mask;  // Zero extended offset.
549   return positive ? offset : -offset;
550 }
551
552
553 int Assembler::GetVldrDRegisterImmediateOffset(Instr instr) {
554   DCHECK(IsVldrDRegisterImmediate(instr));
555   bool positive = (instr & B23) == B23;
556   int offset = instr & kOff8Mask;  // Zero extended offset.
557   offset <<= 2;
558   return positive ? offset : -offset;
559 }
560
561
562 Instr Assembler::SetLdrRegisterImmediateOffset(Instr instr, int offset) {
563   DCHECK(IsLdrRegisterImmediate(instr));
564   bool positive = offset >= 0;
565   if (!positive) offset = -offset;
566   DCHECK(is_uint12(offset));
567   // Set bit indicating whether the offset should be added.
568   instr = (instr & ~B23) | (positive ? B23 : 0);
569   // Set the actual offset.
570   return (instr & ~kOff12Mask) | offset;
571 }
572
573
574 Instr Assembler::SetVldrDRegisterImmediateOffset(Instr instr, int offset) {
575   DCHECK(IsVldrDRegisterImmediate(instr));
576   DCHECK((offset & ~3) == offset);  // Must be 64-bit aligned.
577   bool positive = offset >= 0;
578   if (!positive) offset = -offset;
579   DCHECK(is_uint10(offset));
580   // Set bit indicating whether the offset should be added.
581   instr = (instr & ~B23) | (positive ? B23 : 0);
582   // Set the actual offset. Its bottom 2 bits are zero.
583   return (instr & ~kOff8Mask) | (offset >> 2);
584 }
585
586
587 bool Assembler::IsStrRegisterImmediate(Instr instr) {
588   return (instr & (B27 | B26 | B25 | B22 | B20)) == B26;
589 }
590
591
592 Instr Assembler::SetStrRegisterImmediateOffset(Instr instr, int offset) {
593   DCHECK(IsStrRegisterImmediate(instr));
594   bool positive = offset >= 0;
595   if (!positive) offset = -offset;
596   DCHECK(is_uint12(offset));
597   // Set bit indicating whether the offset should be added.
598   instr = (instr & ~B23) | (positive ? B23 : 0);
599   // Set the actual offset.
600   return (instr & ~kOff12Mask) | offset;
601 }
602
603
604 bool Assembler::IsAddRegisterImmediate(Instr instr) {
605   return (instr & (B27 | B26 | B25 | B24 | B23 | B22 | B21)) == (B25 | B23);
606 }
607
608
609 Instr Assembler::SetAddRegisterImmediateOffset(Instr instr, int offset) {
610   DCHECK(IsAddRegisterImmediate(instr));
611   DCHECK(offset >= 0);
612   DCHECK(is_uint12(offset));
613   // Set the offset.
614   return (instr & ~kOff12Mask) | offset;
615 }
616
617
618 Register Assembler::GetRd(Instr instr) {
619   Register reg;
620   reg.code_ = Instruction::RdValue(instr);
621   return reg;
622 }
623
624
625 Register Assembler::GetRn(Instr instr) {
626   Register reg;
627   reg.code_ = Instruction::RnValue(instr);
628   return reg;
629 }
630
631
632 Register Assembler::GetRm(Instr instr) {
633   Register reg;
634   reg.code_ = Instruction::RmValue(instr);
635   return reg;
636 }
637
638
639 Instr Assembler::GetConsantPoolLoadPattern() {
640   if (FLAG_enable_ool_constant_pool) {
641     return kLdrPpImmedPattern;
642   } else {
643     return kLdrPCImmedPattern;
644   }
645 }
646
647
648 Instr Assembler::GetConsantPoolLoadMask() {
649   if (FLAG_enable_ool_constant_pool) {
650     return kLdrPpImmedMask;
651   } else {
652     return kLdrPCImmedMask;
653   }
654 }
655
656
657 bool Assembler::IsPush(Instr instr) {
658   return ((instr & ~kRdMask) == kPushRegPattern);
659 }
660
661
662 bool Assembler::IsPop(Instr instr) {
663   return ((instr & ~kRdMask) == kPopRegPattern);
664 }
665
666
667 bool Assembler::IsStrRegFpOffset(Instr instr) {
668   return ((instr & kLdrStrInstrTypeMask) == kStrRegFpOffsetPattern);
669 }
670
671
672 bool Assembler::IsLdrRegFpOffset(Instr instr) {
673   return ((instr & kLdrStrInstrTypeMask) == kLdrRegFpOffsetPattern);
674 }
675
676
677 bool Assembler::IsStrRegFpNegOffset(Instr instr) {
678   return ((instr & kLdrStrInstrTypeMask) == kStrRegFpNegOffsetPattern);
679 }
680
681
682 bool Assembler::IsLdrRegFpNegOffset(Instr instr) {
683   return ((instr & kLdrStrInstrTypeMask) == kLdrRegFpNegOffsetPattern);
684 }
685
686
687 bool Assembler::IsLdrPcImmediateOffset(Instr instr) {
688   // Check the instruction is indeed a
689   // ldr<cond> <Rd>, [pc +/- offset_12].
690   return (instr & kLdrPCImmedMask) == kLdrPCImmedPattern;
691 }
692
693
694 bool Assembler::IsLdrPpImmediateOffset(Instr instr) {
695   // Check the instruction is indeed a
696   // ldr<cond> <Rd>, [pp +/- offset_12].
697   return (instr & kLdrPpImmedMask) == kLdrPpImmedPattern;
698 }
699
700
701 bool Assembler::IsLdrPpRegOffset(Instr instr) {
702   // Check the instruction is indeed a
703   // ldr<cond> <Rd>, [pp, +/- <Rm>].
704   return (instr & kLdrPpRegMask) == kLdrPpRegPattern;
705 }
706
707
708 Instr Assembler::GetLdrPpRegOffsetPattern() { return kLdrPpRegPattern; }
709
710
711 bool Assembler::IsVldrDPcImmediateOffset(Instr instr) {
712   // Check the instruction is indeed a
713   // vldr<cond> <Dd>, [pc +/- offset_10].
714   return (instr & kVldrDPCMask) == kVldrDPCPattern;
715 }
716
717
718 bool Assembler::IsVldrDPpImmediateOffset(Instr instr) {
719   // Check the instruction is indeed a
720   // vldr<cond> <Dd>, [pp +/- offset_10].
721   return (instr & kVldrDPpMask) == kVldrDPpPattern;
722 }
723
724
725 bool Assembler::IsBlxReg(Instr instr) {
726   // Check the instruction is indeed a
727   // blxcc <Rm>
728   return (instr & kBlxRegMask) == kBlxRegPattern;
729 }
730
731
732 bool Assembler::IsBlxIp(Instr instr) {
733   // Check the instruction is indeed a
734   // blx ip
735   return instr == kBlxIp;
736 }
737
738
739 bool Assembler::IsTstImmediate(Instr instr) {
740   return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask)) ==
741       (I | TST | S);
742 }
743
744
745 bool Assembler::IsCmpRegister(Instr instr) {
746   return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask | B4)) ==
747       (CMP | S);
748 }
749
750
751 bool Assembler::IsCmpImmediate(Instr instr) {
752   return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask)) ==
753       (I | CMP | S);
754 }
755
756
757 Register Assembler::GetCmpImmediateRegister(Instr instr) {
758   DCHECK(IsCmpImmediate(instr));
759   return GetRn(instr);
760 }
761
762
763 int Assembler::GetCmpImmediateRawImmediate(Instr instr) {
764   DCHECK(IsCmpImmediate(instr));
765   return instr & kOff12Mask;
766 }
767
768
769 // Labels refer to positions in the (to be) generated code.
770 // There are bound, linked, and unused labels.
771 //
772 // Bound labels refer to known positions in the already
773 // generated code. pos() is the position the label refers to.
774 //
775 // Linked labels refer to unknown positions in the code
776 // to be generated; pos() is the position of the last
777 // instruction using the label.
778 //
779 // The linked labels form a link chain by making the branch offset
780 // in the instruction steam to point to the previous branch
781 // instruction using the same label.
782 //
783 // The link chain is terminated by a branch offset pointing to the
784 // same position.
785
786
787 int Assembler::target_at(int pos) {
788   Instr instr = instr_at(pos);
789   if (is_uint24(instr)) {
790     // Emitted link to a label, not part of a branch.
791     return instr;
792   }
793   DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
794   int imm26 = ((instr & kImm24Mask) << 8) >> 6;
795   if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
796       ((instr & B24) != 0)) {
797     // blx uses bit 24 to encode bit 2 of imm26
798     imm26 += 2;
799   }
800   return pos + kPcLoadDelta + imm26;
801 }
802
803
804 void Assembler::target_at_put(int pos, int target_pos) {
805   Instr instr = instr_at(pos);
806   if (is_uint24(instr)) {
807     DCHECK(target_pos == pos || target_pos >= 0);
808     // Emitted link to a label, not part of a branch.
809     // Load the position of the label relative to the generated code object
810     // pointer in a register.
811
812     // Here are the instructions we need to emit:
813     //   For ARMv7: target24 => target16_1:target16_0
814     //      movw dst, #target16_0
815     //      movt dst, #target16_1
816     //   For ARMv6: target24 => target8_2:target8_1:target8_0
817     //      mov dst, #target8_0
818     //      orr dst, dst, #target8_1 << 8
819     //      orr dst, dst, #target8_2 << 16
820
821     // We extract the destination register from the emitted nop instruction.
822     Register dst = Register::from_code(
823         Instruction::RmValue(instr_at(pos + kInstrSize)));
824     DCHECK(IsNop(instr_at(pos + kInstrSize), dst.code()));
825     uint32_t target24 = target_pos + (Code::kHeaderSize - kHeapObjectTag);
826     DCHECK(is_uint24(target24));
827     if (is_uint8(target24)) {
828       // If the target fits in a byte then only patch with a mov
829       // instruction.
830       CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
831                           1,
832                           CodePatcher::DONT_FLUSH);
833       patcher.masm()->mov(dst, Operand(target24));
834     } else {
835       uint16_t target16_0 = target24 & kImm16Mask;
836       uint16_t target16_1 = target24 >> 16;
837       if (CpuFeatures::IsSupported(ARMv7)) {
838         // Patch with movw/movt.
839         if (target16_1 == 0) {
840           CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
841                               1,
842                               CodePatcher::DONT_FLUSH);
843           patcher.masm()->movw(dst, target16_0);
844         } else {
845           CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
846                               2,
847                               CodePatcher::DONT_FLUSH);
848           patcher.masm()->movw(dst, target16_0);
849           patcher.masm()->movt(dst, target16_1);
850         }
851       } else {
852         // Patch with a sequence of mov/orr/orr instructions.
853         uint8_t target8_0 = target16_0 & kImm8Mask;
854         uint8_t target8_1 = target16_0 >> 8;
855         uint8_t target8_2 = target16_1 & kImm8Mask;
856         if (target8_2 == 0) {
857           CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
858                               2,
859                               CodePatcher::DONT_FLUSH);
860           patcher.masm()->mov(dst, Operand(target8_0));
861           patcher.masm()->orr(dst, dst, Operand(target8_1 << 8));
862         } else {
863           CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
864                               3,
865                               CodePatcher::DONT_FLUSH);
866           patcher.masm()->mov(dst, Operand(target8_0));
867           patcher.masm()->orr(dst, dst, Operand(target8_1 << 8));
868           patcher.masm()->orr(dst, dst, Operand(target8_2 << 16));
869         }
870       }
871     }
872     return;
873   }
874   int imm26 = target_pos - (pos + kPcLoadDelta);
875   DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
876   if (Instruction::ConditionField(instr) == kSpecialCondition) {
877     // blx uses bit 24 to encode bit 2 of imm26
878     DCHECK((imm26 & 1) == 0);
879     instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24;
880   } else {
881     DCHECK((imm26 & 3) == 0);
882     instr &= ~kImm24Mask;
883   }
884   int imm24 = imm26 >> 2;
885   DCHECK(is_int24(imm24));
886   instr_at_put(pos, instr | (imm24 & kImm24Mask));
887 }
888
889
890 void Assembler::print(Label* L) {
891   if (L->is_unused()) {
892     PrintF("unused label\n");
893   } else if (L->is_bound()) {
894     PrintF("bound label to %d\n", L->pos());
895   } else if (L->is_linked()) {
896     Label l = *L;
897     PrintF("unbound label");
898     while (l.is_linked()) {
899       PrintF("@ %d ", l.pos());
900       Instr instr = instr_at(l.pos());
901       if ((instr & ~kImm24Mask) == 0) {
902         PrintF("value\n");
903       } else {
904         DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx
905         Condition cond = Instruction::ConditionField(instr);
906         const char* b;
907         const char* c;
908         if (cond == kSpecialCondition) {
909           b = "blx";
910           c = "";
911         } else {
912           if ((instr & B24) != 0)
913             b = "bl";
914           else
915             b = "b";
916
917           switch (cond) {
918             case eq: c = "eq"; break;
919             case ne: c = "ne"; break;
920             case hs: c = "hs"; break;
921             case lo: c = "lo"; break;
922             case mi: c = "mi"; break;
923             case pl: c = "pl"; break;
924             case vs: c = "vs"; break;
925             case vc: c = "vc"; break;
926             case hi: c = "hi"; break;
927             case ls: c = "ls"; break;
928             case ge: c = "ge"; break;
929             case lt: c = "lt"; break;
930             case gt: c = "gt"; break;
931             case le: c = "le"; break;
932             case al: c = ""; break;
933             default:
934               c = "";
935               UNREACHABLE();
936           }
937         }
938         PrintF("%s%s\n", b, c);
939       }
940       next(&l);
941     }
942   } else {
943     PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
944   }
945 }
946
947
948 void Assembler::bind_to(Label* L, int pos) {
949   DCHECK(0 <= pos && pos <= pc_offset());  // must have a valid binding position
950   while (L->is_linked()) {
951     int fixup_pos = L->pos();
952     next(L);  // call next before overwriting link with target at fixup_pos
953     target_at_put(fixup_pos, pos);
954   }
955   L->bind_to(pos);
956
957   // Keep track of the last bound label so we don't eliminate any instructions
958   // before a bound label.
959   if (pos > last_bound_pos_)
960     last_bound_pos_ = pos;
961 }
962
963
964 void Assembler::bind(Label* L) {
965   DCHECK(!L->is_bound());  // label can only be bound once
966   bind_to(L, pc_offset());
967 }
968
969
970 void Assembler::next(Label* L) {
971   DCHECK(L->is_linked());
972   int link = target_at(L->pos());
973   if (link == L->pos()) {
974     // Branch target points to the same instuction. This is the end of the link
975     // chain.
976     L->Unuse();
977   } else {
978     DCHECK(link >= 0);
979     L->link_to(link);
980   }
981 }
982
983
984 // Low-level code emission routines depending on the addressing mode.
985 // If this returns true then you have to use the rotate_imm and immed_8
986 // that it returns, because it may have already changed the instruction
987 // to match them!
988 static bool fits_shifter(uint32_t imm32,
989                          uint32_t* rotate_imm,
990                          uint32_t* immed_8,
991                          Instr* instr) {
992   // imm32 must be unsigned.
993   for (int rot = 0; rot < 16; rot++) {
994     uint32_t imm8 = (imm32 << 2*rot) | (imm32 >> (32 - 2*rot));
995     if ((imm8 <= 0xff)) {
996       *rotate_imm = rot;
997       *immed_8 = imm8;
998       return true;
999     }
1000   }
1001   // If the opcode is one with a complementary version and the complementary
1002   // immediate fits, change the opcode.
1003   if (instr != NULL) {
1004     if ((*instr & kMovMvnMask) == kMovMvnPattern) {
1005       if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) {
1006         *instr ^= kMovMvnFlip;
1007         return true;
1008       } else if ((*instr & kMovLeaveCCMask) == kMovLeaveCCPattern) {
1009         if (CpuFeatures::IsSupported(ARMv7)) {
1010           if (imm32 < 0x10000) {
1011             *instr ^= kMovwLeaveCCFlip;
1012             *instr |= Assembler::EncodeMovwImmediate(imm32);
1013             *rotate_imm = *immed_8 = 0;  // Not used for movw.
1014             return true;
1015           }
1016         }
1017       }
1018     } else if ((*instr & kCmpCmnMask) == kCmpCmnPattern) {
1019       if (fits_shifter(-static_cast<int>(imm32), rotate_imm, immed_8, NULL)) {
1020         *instr ^= kCmpCmnFlip;
1021         return true;
1022       }
1023     } else {
1024       Instr alu_insn = (*instr & kALUMask);
1025       if (alu_insn == ADD ||
1026           alu_insn == SUB) {
1027         if (fits_shifter(-static_cast<int>(imm32), rotate_imm, immed_8, NULL)) {
1028           *instr ^= kAddSubFlip;
1029           return true;
1030         }
1031       } else if (alu_insn == AND ||
1032                  alu_insn == BIC) {
1033         if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) {
1034           *instr ^= kAndBicFlip;
1035           return true;
1036         }
1037       }
1038     }
1039   }
1040   return false;
1041 }
1042
1043
1044 // We have to use the temporary register for things that can be relocated even
1045 // if they can be encoded in the ARM's 12 bits of immediate-offset instruction
1046 // space.  There is no guarantee that the relocated location can be similarly
1047 // encoded.
1048 bool Operand::must_output_reloc_info(const Assembler* assembler) const {
1049   if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
1050     if (assembler != NULL && assembler->predictable_code_size()) return true;
1051     return assembler->serializer_enabled();
1052   } else if (RelocInfo::IsNone(rmode_)) {
1053     return false;
1054   }
1055   return true;
1056 }
1057
1058
1059 static bool use_mov_immediate_load(const Operand& x,
1060                                    const Assembler* assembler) {
1061   if (FLAG_enable_ool_constant_pool && assembler != NULL &&
1062       !assembler->is_ool_constant_pool_available()) {
1063     return true;
1064   } else if (CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
1065              (assembler == NULL || !assembler->predictable_code_size())) {
1066     // Prefer movw / movt to constant pool if it is more efficient on the CPU.
1067     return true;
1068   } else if (x.must_output_reloc_info(assembler)) {
1069     // Prefer constant pool if data is likely to be patched.
1070     return false;
1071   } else {
1072     // Otherwise, use immediate load if movw / movt is available.
1073     return CpuFeatures::IsSupported(ARMv7);
1074   }
1075 }
1076
1077
1078 int Operand::instructions_required(const Assembler* assembler,
1079                                    Instr instr) const {
1080   if (rm_.is_valid()) return 1;
1081   uint32_t dummy1, dummy2;
1082   if (must_output_reloc_info(assembler) ||
1083       !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
1084     // The immediate operand cannot be encoded as a shifter operand, or use of
1085     // constant pool is required.  First account for the instructions required
1086     // for the constant pool or immediate load
1087     int instructions;
1088     if (use_mov_immediate_load(*this, assembler)) {
1089       // A movw / movt or mov / orr immediate load.
1090       instructions = CpuFeatures::IsSupported(ARMv7) ? 2 : 4;
1091     } else if (assembler != NULL && assembler->use_extended_constant_pool()) {
1092       // An extended constant pool load.
1093       instructions = CpuFeatures::IsSupported(ARMv7) ? 3 : 5;
1094     } else {
1095       // A small constant pool load.
1096       instructions = 1;
1097     }
1098
1099     if ((instr & ~kCondMask) != 13 * B21) {  // mov, S not set
1100       // For a mov or mvn instruction which doesn't set the condition
1101       // code, the constant pool or immediate load is enough, otherwise we need
1102       // to account for the actual instruction being requested.
1103       instructions += 1;
1104     }
1105     return instructions;
1106   } else {
1107     // No use of constant pool and the immediate operand can be encoded as a
1108     // shifter operand.
1109     return 1;
1110   }
1111 }
1112
1113
1114 void Assembler::move_32_bit_immediate(Register rd,
1115                                       const Operand& x,
1116                                       Condition cond) {
1117   RelocInfo rinfo(pc_, x.rmode_, x.imm32_, NULL);
1118   uint32_t imm32 = static_cast<uint32_t>(x.imm32_);
1119   if (x.must_output_reloc_info(this)) {
1120     RecordRelocInfo(rinfo);
1121   }
1122
1123   if (use_mov_immediate_load(x, this)) {
1124     Register target = rd.code() == pc.code() ? ip : rd;
1125     if (CpuFeatures::IsSupported(ARMv7)) {
1126       if (!FLAG_enable_ool_constant_pool && x.must_output_reloc_info(this)) {
1127         // Make sure the movw/movt doesn't get separated.
1128         BlockConstPoolFor(2);
1129       }
1130       movw(target, imm32 & 0xffff, cond);
1131       movt(target, imm32 >> 16, cond);
1132     } else {
1133       DCHECK(FLAG_enable_ool_constant_pool);
1134       mov(target, Operand(imm32 & kImm8Mask), LeaveCC, cond);
1135       orr(target, target, Operand(imm32 & (kImm8Mask << 8)), LeaveCC, cond);
1136       orr(target, target, Operand(imm32 & (kImm8Mask << 16)), LeaveCC, cond);
1137       orr(target, target, Operand(imm32 & (kImm8Mask << 24)), LeaveCC, cond);
1138     }
1139     if (target.code() != rd.code()) {
1140       mov(rd, target, LeaveCC, cond);
1141     }
1142   } else {
1143     DCHECK(!FLAG_enable_ool_constant_pool || is_ool_constant_pool_available());
1144     ConstantPoolArray::LayoutSection section = ConstantPoolAddEntry(rinfo);
1145     if (section == ConstantPoolArray::EXTENDED_SECTION) {
1146       DCHECK(FLAG_enable_ool_constant_pool);
1147       Register target = rd.code() == pc.code() ? ip : rd;
1148       // Emit instructions to load constant pool offset.
1149       if (CpuFeatures::IsSupported(ARMv7)) {
1150         movw(target, 0, cond);
1151         movt(target, 0, cond);
1152       } else {
1153         mov(target, Operand(0), LeaveCC, cond);
1154         orr(target, target, Operand(0), LeaveCC, cond);
1155         orr(target, target, Operand(0), LeaveCC, cond);
1156         orr(target, target, Operand(0), LeaveCC, cond);
1157       }
1158       // Load from constant pool at offset.
1159       ldr(rd, MemOperand(pp, target), cond);
1160     } else {
1161       DCHECK(section == ConstantPoolArray::SMALL_SECTION);
1162       ldr(rd, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0), cond);
1163     }
1164   }
1165 }
1166
1167
1168 void Assembler::addrmod1(Instr instr,
1169                          Register rn,
1170                          Register rd,
1171                          const Operand& x) {
1172   CheckBuffer();
1173   DCHECK((instr & ~(kCondMask | kOpCodeMask | S)) == 0);
1174   if (!x.rm_.is_valid()) {
1175     // Immediate.
1176     uint32_t rotate_imm;
1177     uint32_t immed_8;
1178     if (x.must_output_reloc_info(this) ||
1179         !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) {
1180       // The immediate operand cannot be encoded as a shifter operand, so load
1181       // it first to register ip and change the original instruction to use ip.
1182       // However, if the original instruction is a 'mov rd, x' (not setting the
1183       // condition code), then replace it with a 'ldr rd, [pc]'.
1184       CHECK(!rn.is(ip));  // rn should never be ip, or will be trashed
1185       Condition cond = Instruction::ConditionField(instr);
1186       if ((instr & ~kCondMask) == 13*B21) {  // mov, S not set
1187         move_32_bit_immediate(rd, x, cond);
1188       } else {
1189         mov(ip, x, LeaveCC, cond);
1190         addrmod1(instr, rn, rd, Operand(ip));
1191       }
1192       return;
1193     }
1194     instr |= I | rotate_imm*B8 | immed_8;
1195   } else if (!x.rs_.is_valid()) {
1196     // Immediate shift.
1197     instr |= x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
1198   } else {
1199     // Register shift.
1200     DCHECK(!rn.is(pc) && !rd.is(pc) && !x.rm_.is(pc) && !x.rs_.is(pc));
1201     instr |= x.rs_.code()*B8 | x.shift_op_ | B4 | x.rm_.code();
1202   }
1203   emit(instr | rn.code()*B16 | rd.code()*B12);
1204   if (rn.is(pc) || x.rm_.is(pc)) {
1205     // Block constant pool emission for one instruction after reading pc.
1206     BlockConstPoolFor(1);
1207   }
1208 }
1209
1210
1211 void Assembler::addrmod2(Instr instr, Register rd, const MemOperand& x) {
1212   DCHECK((instr & ~(kCondMask | B | L)) == B26);
1213   int am = x.am_;
1214   if (!x.rm_.is_valid()) {
1215     // Immediate offset.
1216     int offset_12 = x.offset_;
1217     if (offset_12 < 0) {
1218       offset_12 = -offset_12;
1219       am ^= U;
1220     }
1221     if (!is_uint12(offset_12)) {
1222       // Immediate offset cannot be encoded, load it first to register ip
1223       // rn (and rd in a load) should never be ip, or will be trashed.
1224       DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
1225       mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
1226       addrmod2(instr, rd, MemOperand(x.rn_, ip, x.am_));
1227       return;
1228     }
1229     DCHECK(offset_12 >= 0);  // no masking needed
1230     instr |= offset_12;
1231   } else {
1232     // Register offset (shift_imm_ and shift_op_ are 0) or scaled
1233     // register offset the constructors make sure than both shift_imm_
1234     // and shift_op_ are initialized.
1235     DCHECK(!x.rm_.is(pc));
1236     instr |= B25 | x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
1237   }
1238   DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
1239   emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
1240 }
1241
1242
1243 void Assembler::addrmod3(Instr instr, Register rd, const MemOperand& x) {
1244   DCHECK((instr & ~(kCondMask | L | S6 | H)) == (B4 | B7));
1245   DCHECK(x.rn_.is_valid());
1246   int am = x.am_;
1247   if (!x.rm_.is_valid()) {
1248     // Immediate offset.
1249     int offset_8 = x.offset_;
1250     if (offset_8 < 0) {
1251       offset_8 = -offset_8;
1252       am ^= U;
1253     }
1254     if (!is_uint8(offset_8)) {
1255       // Immediate offset cannot be encoded, load it first to register ip
1256       // rn (and rd in a load) should never be ip, or will be trashed.
1257       DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
1258       mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
1259       addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
1260       return;
1261     }
1262     DCHECK(offset_8 >= 0);  // no masking needed
1263     instr |= B | (offset_8 >> 4)*B8 | (offset_8 & 0xf);
1264   } else if (x.shift_imm_ != 0) {
1265     // Scaled register offset not supported, load index first
1266     // rn (and rd in a load) should never be ip, or will be trashed.
1267     DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
1268     mov(ip, Operand(x.rm_, x.shift_op_, x.shift_imm_), LeaveCC,
1269         Instruction::ConditionField(instr));
1270     addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
1271     return;
1272   } else {
1273     // Register offset.
1274     DCHECK((am & (P|W)) == P || !x.rm_.is(pc));  // no pc index with writeback
1275     instr |= x.rm_.code();
1276   }
1277   DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
1278   emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
1279 }
1280
1281
1282 void Assembler::addrmod4(Instr instr, Register rn, RegList rl) {
1283   DCHECK((instr & ~(kCondMask | P | U | W | L)) == B27);
1284   DCHECK(rl != 0);
1285   DCHECK(!rn.is(pc));
1286   emit(instr | rn.code()*B16 | rl);
1287 }
1288
1289
1290 void Assembler::addrmod5(Instr instr, CRegister crd, const MemOperand& x) {
1291   // Unindexed addressing is not encoded by this function.
1292   DCHECK_EQ((B27 | B26),
1293             (instr & ~(kCondMask | kCoprocessorMask | P | U | N | W | L)));
1294   DCHECK(x.rn_.is_valid() && !x.rm_.is_valid());
1295   int am = x.am_;
1296   int offset_8 = x.offset_;
1297   DCHECK((offset_8 & 3) == 0);  // offset must be an aligned word offset
1298   offset_8 >>= 2;
1299   if (offset_8 < 0) {
1300     offset_8 = -offset_8;
1301     am ^= U;
1302   }
1303   DCHECK(is_uint8(offset_8));  // unsigned word offset must fit in a byte
1304   DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
1305
1306   // Post-indexed addressing requires W == 1; different than in addrmod2/3.
1307   if ((am & P) == 0)
1308     am |= W;
1309
1310   DCHECK(offset_8 >= 0);  // no masking needed
1311   emit(instr | am | x.rn_.code()*B16 | crd.code()*B12 | offset_8);
1312 }
1313
1314
1315 int Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
1316   int target_pos;
1317   if (L->is_bound()) {
1318     target_pos = L->pos();
1319   } else {
1320     if (L->is_linked()) {
1321       // Point to previous instruction that uses the link.
1322       target_pos = L->pos();
1323     } else {
1324       // First entry of the link chain points to itself.
1325       target_pos = pc_offset();
1326     }
1327     L->link_to(pc_offset());
1328   }
1329
1330   // Block the emission of the constant pool, since the branch instruction must
1331   // be emitted at the pc offset recorded by the label.
1332   BlockConstPoolFor(1);
1333   return target_pos - (pc_offset() + kPcLoadDelta);
1334 }
1335
1336
1337 // Branch instructions.
1338 void Assembler::b(int branch_offset, Condition cond) {
1339   DCHECK((branch_offset & 3) == 0);
1340   int imm24 = branch_offset >> 2;
1341   DCHECK(is_int24(imm24));
1342   emit(cond | B27 | B25 | (imm24 & kImm24Mask));
1343
1344   if (cond == al) {
1345     // Dead code is a good location to emit the constant pool.
1346     CheckConstPool(false, false);
1347   }
1348 }
1349
1350
1351 void Assembler::bl(int branch_offset, Condition cond) {
1352   positions_recorder()->WriteRecordedPositions();
1353   DCHECK((branch_offset & 3) == 0);
1354   int imm24 = branch_offset >> 2;
1355   DCHECK(is_int24(imm24));
1356   emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask));
1357 }
1358
1359
1360 void Assembler::blx(int branch_offset) {  // v5 and above
1361   positions_recorder()->WriteRecordedPositions();
1362   DCHECK((branch_offset & 1) == 0);
1363   int h = ((branch_offset & 2) >> 1)*B24;
1364   int imm24 = branch_offset >> 2;
1365   DCHECK(is_int24(imm24));
1366   emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask));
1367 }
1368
1369
1370 void Assembler::blx(Register target, Condition cond) {  // v5 and above
1371   positions_recorder()->WriteRecordedPositions();
1372   DCHECK(!target.is(pc));
1373   emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | target.code());
1374 }
1375
1376
1377 void Assembler::bx(Register target, Condition cond) {  // v5 and above, plus v4t
1378   positions_recorder()->WriteRecordedPositions();
1379   DCHECK(!target.is(pc));  // use of pc is actually allowed, but discouraged
1380   emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BX | target.code());
1381 }
1382
1383
1384 // Data-processing instructions.
1385
1386 void Assembler::and_(Register dst, Register src1, const Operand& src2,
1387                      SBit s, Condition cond) {
1388   addrmod1(cond | AND | s, src1, dst, src2);
1389 }
1390
1391
1392 void Assembler::eor(Register dst, Register src1, const Operand& src2,
1393                     SBit s, Condition cond) {
1394   addrmod1(cond | EOR | s, src1, dst, src2);
1395 }
1396
1397
1398 void Assembler::sub(Register dst, Register src1, const Operand& src2,
1399                     SBit s, Condition cond) {
1400   addrmod1(cond | SUB | s, src1, dst, src2);
1401 }
1402
1403
1404 void Assembler::rsb(Register dst, Register src1, const Operand& src2,
1405                     SBit s, Condition cond) {
1406   addrmod1(cond | RSB | s, src1, dst, src2);
1407 }
1408
1409
1410 void Assembler::add(Register dst, Register src1, const Operand& src2,
1411                     SBit s, Condition cond) {
1412   addrmod1(cond | ADD | s, src1, dst, src2);
1413 }
1414
1415
1416 void Assembler::adc(Register dst, Register src1, const Operand& src2,
1417                     SBit s, Condition cond) {
1418   addrmod1(cond | ADC | s, src1, dst, src2);
1419 }
1420
1421
1422 void Assembler::sbc(Register dst, Register src1, const Operand& src2,
1423                     SBit s, Condition cond) {
1424   addrmod1(cond | SBC | s, src1, dst, src2);
1425 }
1426
1427
1428 void Assembler::rsc(Register dst, Register src1, const Operand& src2,
1429                     SBit s, Condition cond) {
1430   addrmod1(cond | RSC | s, src1, dst, src2);
1431 }
1432
1433
1434 void Assembler::tst(Register src1, const Operand& src2, Condition cond) {
1435   addrmod1(cond | TST | S, src1, r0, src2);
1436 }
1437
1438
1439 void Assembler::teq(Register src1, const Operand& src2, Condition cond) {
1440   addrmod1(cond | TEQ | S, src1, r0, src2);
1441 }
1442
1443
1444 void Assembler::cmp(Register src1, const Operand& src2, Condition cond) {
1445   addrmod1(cond | CMP | S, src1, r0, src2);
1446 }
1447
1448
1449 void Assembler::cmp_raw_immediate(
1450     Register src, int raw_immediate, Condition cond) {
1451   DCHECK(is_uint12(raw_immediate));
1452   emit(cond | I | CMP | S | src.code() << 16 | raw_immediate);
1453 }
1454
1455
1456 void Assembler::cmn(Register src1, const Operand& src2, Condition cond) {
1457   addrmod1(cond | CMN | S, src1, r0, src2);
1458 }
1459
1460
1461 void Assembler::orr(Register dst, Register src1, const Operand& src2,
1462                     SBit s, Condition cond) {
1463   addrmod1(cond | ORR | s, src1, dst, src2);
1464 }
1465
1466
1467 void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
1468   if (dst.is(pc)) {
1469     positions_recorder()->WriteRecordedPositions();
1470   }
1471   // Don't allow nop instructions in the form mov rn, rn to be generated using
1472   // the mov instruction. They must be generated using nop(int/NopMarkerTypes)
1473   // or MarkCode(int/NopMarkerTypes) pseudo instructions.
1474   DCHECK(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
1475   addrmod1(cond | MOV | s, r0, dst, src);
1476 }
1477
1478
1479 void Assembler::mov_label_offset(Register dst, Label* label) {
1480   if (label->is_bound()) {
1481     mov(dst, Operand(label->pos() + (Code::kHeaderSize - kHeapObjectTag)));
1482   } else {
1483     // Emit the link to the label in the code stream followed by extra nop
1484     // instructions.
1485     // If the label is not linked, then start a new link chain by linking it to
1486     // itself, emitting pc_offset().
1487     int link = label->is_linked() ? label->pos() : pc_offset();
1488     label->link_to(pc_offset());
1489
1490     // When the label is bound, these instructions will be patched with a
1491     // sequence of movw/movt or mov/orr/orr instructions. They will load the
1492     // destination register with the position of the label from the beginning
1493     // of the code.
1494     //
1495     // The link will be extracted from the first instruction and the destination
1496     // register from the second.
1497     //   For ARMv7:
1498     //      link
1499     //      mov dst, dst
1500     //   For ARMv6:
1501     //      link
1502     //      mov dst, dst
1503     //      mov dst, dst
1504     //
1505     // When the label gets bound: target_at extracts the link and target_at_put
1506     // patches the instructions.
1507     DCHECK(is_uint24(link));
1508     BlockConstPoolScope block_const_pool(this);
1509     emit(link);
1510     nop(dst.code());
1511     if (!CpuFeatures::IsSupported(ARMv7)) {
1512       nop(dst.code());
1513     }
1514   }
1515 }
1516
1517
1518 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) {
1519   DCHECK(CpuFeatures::IsSupported(ARMv7));
1520   emit(cond | 0x30*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate));
1521 }
1522
1523
1524 void Assembler::movt(Register reg, uint32_t immediate, Condition cond) {
1525   DCHECK(CpuFeatures::IsSupported(ARMv7));
1526   emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate));
1527 }
1528
1529
1530 void Assembler::bic(Register dst, Register src1, const Operand& src2,
1531                     SBit s, Condition cond) {
1532   addrmod1(cond | BIC | s, src1, dst, src2);
1533 }
1534
1535
1536 void Assembler::mvn(Register dst, const Operand& src, SBit s, Condition cond) {
1537   addrmod1(cond | MVN | s, r0, dst, src);
1538 }
1539
1540
1541 // Multiply instructions.
1542 void Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
1543                     SBit s, Condition cond) {
1544   DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
1545   emit(cond | A | s | dst.code()*B16 | srcA.code()*B12 |
1546        src2.code()*B8 | B7 | B4 | src1.code());
1547 }
1548
1549
1550 void Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
1551                     Condition cond) {
1552   DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
1553   DCHECK(IsEnabled(MLS));
1554   emit(cond | B22 | B21 | dst.code()*B16 | srcA.code()*B12 |
1555        src2.code()*B8 | B7 | B4 | src1.code());
1556 }
1557
1558
1559 void Assembler::sdiv(Register dst, Register src1, Register src2,
1560                      Condition cond) {
1561   DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
1562   DCHECK(IsEnabled(SUDIV));
1563   emit(cond | B26 | B25| B24 | B20 | dst.code()*B16 | 0xf * B12 |
1564        src2.code()*B8 | B4 | src1.code());
1565 }
1566
1567
1568 void Assembler::udiv(Register dst, Register src1, Register src2,
1569                      Condition cond) {
1570   DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
1571   DCHECK(IsEnabled(SUDIV));
1572   emit(cond | B26 | B25 | B24 | B21 | B20 | dst.code() * B16 | 0xf * B12 |
1573        src2.code() * B8 | B4 | src1.code());
1574 }
1575
1576
1577 void Assembler::mul(Register dst, Register src1, Register src2, SBit s,
1578                     Condition cond) {
1579   DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
1580   // dst goes in bits 16-19 for this instruction!
1581   emit(cond | s | dst.code() * B16 | src2.code() * B8 | B7 | B4 | src1.code());
1582 }
1583
1584
1585 void Assembler::smmla(Register dst, Register src1, Register src2, Register srcA,
1586                       Condition cond) {
1587   DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
1588   emit(cond | B26 | B25 | B24 | B22 | B20 | dst.code() * B16 |
1589        srcA.code() * B12 | src2.code() * B8 | B4 | src1.code());
1590 }
1591
1592
1593 void Assembler::smmul(Register dst, Register src1, Register src2,
1594                       Condition cond) {
1595   DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
1596   emit(cond | B26 | B25 | B24 | B22 | B20 | dst.code() * B16 | 0xf * B12 |
1597        src2.code() * B8 | B4 | src1.code());
1598 }
1599
1600
1601 void Assembler::smlal(Register dstL,
1602                       Register dstH,
1603                       Register src1,
1604                       Register src2,
1605                       SBit s,
1606                       Condition cond) {
1607   DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1608   DCHECK(!dstL.is(dstH));
1609   emit(cond | B23 | B22 | A | s | dstH.code()*B16 | dstL.code()*B12 |
1610        src2.code()*B8 | B7 | B4 | src1.code());
1611 }
1612
1613
1614 void Assembler::smull(Register dstL,
1615                       Register dstH,
1616                       Register src1,
1617                       Register src2,
1618                       SBit s,
1619                       Condition cond) {
1620   DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1621   DCHECK(!dstL.is(dstH));
1622   emit(cond | B23 | B22 | s | dstH.code()*B16 | dstL.code()*B12 |
1623        src2.code()*B8 | B7 | B4 | src1.code());
1624 }
1625
1626
1627 void Assembler::umlal(Register dstL,
1628                       Register dstH,
1629                       Register src1,
1630                       Register src2,
1631                       SBit s,
1632                       Condition cond) {
1633   DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1634   DCHECK(!dstL.is(dstH));
1635   emit(cond | B23 | A | s | dstH.code()*B16 | dstL.code()*B12 |
1636        src2.code()*B8 | B7 | B4 | src1.code());
1637 }
1638
1639
1640 void Assembler::umull(Register dstL,
1641                       Register dstH,
1642                       Register src1,
1643                       Register src2,
1644                       SBit s,
1645                       Condition cond) {
1646   DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1647   DCHECK(!dstL.is(dstH));
1648   emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 |
1649        src2.code()*B8 | B7 | B4 | src1.code());
1650 }
1651
1652
1653 // Miscellaneous arithmetic instructions.
1654 void Assembler::clz(Register dst, Register src, Condition cond) {
1655   // v5 and above.
1656   DCHECK(!dst.is(pc) && !src.is(pc));
1657   emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 |
1658        15*B8 | CLZ | src.code());
1659 }
1660
1661
1662 // Saturating instructions.
1663
1664 // Unsigned saturate.
1665 void Assembler::usat(Register dst,
1666                      int satpos,
1667                      const Operand& src,
1668                      Condition cond) {
1669   // v6 and above.
1670   DCHECK(CpuFeatures::IsSupported(ARMv7));
1671   DCHECK(!dst.is(pc) && !src.rm_.is(pc));
1672   DCHECK((satpos >= 0) && (satpos <= 31));
1673   DCHECK((src.shift_op_ == ASR) || (src.shift_op_ == LSL));
1674   DCHECK(src.rs_.is(no_reg));
1675
1676   int sh = 0;
1677   if (src.shift_op_ == ASR) {
1678       sh = 1;
1679   }
1680
1681   emit(cond | 0x6*B24 | 0xe*B20 | satpos*B16 | dst.code()*B12 |
1682        src.shift_imm_*B7 | sh*B6 | 0x1*B4 | src.rm_.code());
1683 }
1684
1685
1686 // Bitfield manipulation instructions.
1687
1688 // Unsigned bit field extract.
1689 // Extracts #width adjacent bits from position #lsb in a register, and
1690 // writes them to the low bits of a destination register.
1691 //   ubfx dst, src, #lsb, #width
1692 void Assembler::ubfx(Register dst,
1693                      Register src,
1694                      int lsb,
1695                      int width,
1696                      Condition cond) {
1697   // v7 and above.
1698   DCHECK(CpuFeatures::IsSupported(ARMv7));
1699   DCHECK(!dst.is(pc) && !src.is(pc));
1700   DCHECK((lsb >= 0) && (lsb <= 31));
1701   DCHECK((width >= 1) && (width <= (32 - lsb)));
1702   emit(cond | 0xf*B23 | B22 | B21 | (width - 1)*B16 | dst.code()*B12 |
1703        lsb*B7 | B6 | B4 | src.code());
1704 }
1705
1706
1707 // Signed bit field extract.
1708 // Extracts #width adjacent bits from position #lsb in a register, and
1709 // writes them to the low bits of a destination register. The extracted
1710 // value is sign extended to fill the destination register.
1711 //   sbfx dst, src, #lsb, #width
1712 void Assembler::sbfx(Register dst,
1713                      Register src,
1714                      int lsb,
1715                      int width,
1716                      Condition cond) {
1717   // v7 and above.
1718   DCHECK(CpuFeatures::IsSupported(ARMv7));
1719   DCHECK(!dst.is(pc) && !src.is(pc));
1720   DCHECK((lsb >= 0) && (lsb <= 31));
1721   DCHECK((width >= 1) && (width <= (32 - lsb)));
1722   emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 |
1723        lsb*B7 | B6 | B4 | src.code());
1724 }
1725
1726
1727 // Bit field clear.
1728 // Sets #width adjacent bits at position #lsb in the destination register
1729 // to zero, preserving the value of the other bits.
1730 //   bfc dst, #lsb, #width
1731 void Assembler::bfc(Register dst, int lsb, int width, Condition cond) {
1732   // v7 and above.
1733   DCHECK(CpuFeatures::IsSupported(ARMv7));
1734   DCHECK(!dst.is(pc));
1735   DCHECK((lsb >= 0) && (lsb <= 31));
1736   DCHECK((width >= 1) && (width <= (32 - lsb)));
1737   int msb = lsb + width - 1;
1738   emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 0xf);
1739 }
1740
1741
1742 // Bit field insert.
1743 // Inserts #width adjacent bits from the low bits of the source register
1744 // into position #lsb of the destination register.
1745 //   bfi dst, src, #lsb, #width
1746 void Assembler::bfi(Register dst,
1747                     Register src,
1748                     int lsb,
1749                     int width,
1750                     Condition cond) {
1751   // v7 and above.
1752   DCHECK(CpuFeatures::IsSupported(ARMv7));
1753   DCHECK(!dst.is(pc) && !src.is(pc));
1754   DCHECK((lsb >= 0) && (lsb <= 31));
1755   DCHECK((width >= 1) && (width <= (32 - lsb)));
1756   int msb = lsb + width - 1;
1757   emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 |
1758        src.code());
1759 }
1760
1761
1762 void Assembler::pkhbt(Register dst,
1763                       Register src1,
1764                       const Operand& src2,
1765                       Condition cond ) {
1766   // Instruction details available in ARM DDI 0406C.b, A8.8.125.
1767   // cond(31-28) | 01101000(27-20) | Rn(19-16) |
1768   // Rd(15-12) | imm5(11-7) | 0(6) | 01(5-4) | Rm(3-0)
1769   DCHECK(!dst.is(pc));
1770   DCHECK(!src1.is(pc));
1771   DCHECK(!src2.rm().is(pc));
1772   DCHECK(!src2.rm().is(no_reg));
1773   DCHECK(src2.rs().is(no_reg));
1774   DCHECK((src2.shift_imm_ >= 0) && (src2.shift_imm_ <= 31));
1775   DCHECK(src2.shift_op() == LSL);
1776   emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
1777        src2.shift_imm_*B7 | B4 | src2.rm().code());
1778 }
1779
1780
1781 void Assembler::pkhtb(Register dst,
1782                       Register src1,
1783                       const Operand& src2,
1784                       Condition cond) {
1785   // Instruction details available in ARM DDI 0406C.b, A8.8.125.
1786   // cond(31-28) | 01101000(27-20) | Rn(19-16) |
1787   // Rd(15-12) | imm5(11-7) | 1(6) | 01(5-4) | Rm(3-0)
1788   DCHECK(!dst.is(pc));
1789   DCHECK(!src1.is(pc));
1790   DCHECK(!src2.rm().is(pc));
1791   DCHECK(!src2.rm().is(no_reg));
1792   DCHECK(src2.rs().is(no_reg));
1793   DCHECK((src2.shift_imm_ >= 1) && (src2.shift_imm_ <= 32));
1794   DCHECK(src2.shift_op() == ASR);
1795   int asr = (src2.shift_imm_ == 32) ? 0 : src2.shift_imm_;
1796   emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
1797        asr*B7 | B6 | B4 | src2.rm().code());
1798 }
1799
1800
1801 void Assembler::uxtb(Register dst,
1802                      const Operand& src,
1803                      Condition cond) {
1804   // Instruction details available in ARM DDI 0406C.b, A8.8.274.
1805   // cond(31-28) | 01101110(27-20) | 1111(19-16) |
1806   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1807   DCHECK(!dst.is(pc));
1808   DCHECK(!src.rm().is(pc));
1809   DCHECK(!src.rm().is(no_reg));
1810   DCHECK(src.rs().is(no_reg));
1811   DCHECK((src.shift_imm_ == 0) ||
1812          (src.shift_imm_ == 8) ||
1813          (src.shift_imm_ == 16) ||
1814          (src.shift_imm_ == 24));
1815   // Operand maps ROR #0 to LSL #0.
1816   DCHECK((src.shift_op() == ROR) ||
1817          ((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
1818   emit(cond | 0x6E*B20 | 0xF*B16 | dst.code()*B12 |
1819        ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
1820 }
1821
1822
1823 void Assembler::uxtab(Register dst,
1824                       Register src1,
1825                       const Operand& src2,
1826                       Condition cond) {
1827   // Instruction details available in ARM DDI 0406C.b, A8.8.271.
1828   // cond(31-28) | 01101110(27-20) | Rn(19-16) |
1829   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1830   DCHECK(!dst.is(pc));
1831   DCHECK(!src1.is(pc));
1832   DCHECK(!src2.rm().is(pc));
1833   DCHECK(!src2.rm().is(no_reg));
1834   DCHECK(src2.rs().is(no_reg));
1835   DCHECK((src2.shift_imm_ == 0) ||
1836          (src2.shift_imm_ == 8) ||
1837          (src2.shift_imm_ == 16) ||
1838          (src2.shift_imm_ == 24));
1839   // Operand maps ROR #0 to LSL #0.
1840   DCHECK((src2.shift_op() == ROR) ||
1841          ((src2.shift_op() == LSL) && (src2.shift_imm_ == 0)));
1842   emit(cond | 0x6E*B20 | src1.code()*B16 | dst.code()*B12 |
1843        ((src2.shift_imm_ >> 1) &0xC)*B8 | 7*B4 | src2.rm().code());
1844 }
1845
1846
1847 void Assembler::uxtb16(Register dst,
1848                        const Operand& src,
1849                        Condition cond) {
1850   // Instruction details available in ARM DDI 0406C.b, A8.8.275.
1851   // cond(31-28) | 01101100(27-20) | 1111(19-16) |
1852   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1853   DCHECK(!dst.is(pc));
1854   DCHECK(!src.rm().is(pc));
1855   DCHECK(!src.rm().is(no_reg));
1856   DCHECK(src.rs().is(no_reg));
1857   DCHECK((src.shift_imm_ == 0) ||
1858          (src.shift_imm_ == 8) ||
1859          (src.shift_imm_ == 16) ||
1860          (src.shift_imm_ == 24));
1861   // Operand maps ROR #0 to LSL #0.
1862   DCHECK((src.shift_op() == ROR) ||
1863          ((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
1864   emit(cond | 0x6C*B20 | 0xF*B16 | dst.code()*B12 |
1865        ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
1866 }
1867
1868
1869 // Status register access instructions.
1870 void Assembler::mrs(Register dst, SRegister s, Condition cond) {
1871   DCHECK(!dst.is(pc));
1872   emit(cond | B24 | s | 15*B16 | dst.code()*B12);
1873 }
1874
1875
1876 void Assembler::msr(SRegisterFieldMask fields, const Operand& src,
1877                     Condition cond) {
1878   DCHECK(fields >= B16 && fields < B20);  // at least one field set
1879   Instr instr;
1880   if (!src.rm_.is_valid()) {
1881     // Immediate.
1882     uint32_t rotate_imm;
1883     uint32_t immed_8;
1884     if (src.must_output_reloc_info(this) ||
1885         !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) {
1886       // Immediate operand cannot be encoded, load it first to register ip.
1887       move_32_bit_immediate(ip, src);
1888       msr(fields, Operand(ip), cond);
1889       return;
1890     }
1891     instr = I | rotate_imm*B8 | immed_8;
1892   } else {
1893     DCHECK(!src.rs_.is_valid() && src.shift_imm_ == 0);  // only rm allowed
1894     instr = src.rm_.code();
1895   }
1896   emit(cond | instr | B24 | B21 | fields | 15*B12);
1897 }
1898
1899
1900 // Load/Store instructions.
1901 void Assembler::ldr(Register dst, const MemOperand& src, Condition cond) {
1902   if (dst.is(pc)) {
1903     positions_recorder()->WriteRecordedPositions();
1904   }
1905   addrmod2(cond | B26 | L, dst, src);
1906 }
1907
1908
1909 void Assembler::str(Register src, const MemOperand& dst, Condition cond) {
1910   addrmod2(cond | B26, src, dst);
1911 }
1912
1913
1914 void Assembler::ldrb(Register dst, const MemOperand& src, Condition cond) {
1915   addrmod2(cond | B26 | B | L, dst, src);
1916 }
1917
1918
1919 void Assembler::strb(Register src, const MemOperand& dst, Condition cond) {
1920   addrmod2(cond | B26 | B, src, dst);
1921 }
1922
1923
1924 void Assembler::ldrh(Register dst, const MemOperand& src, Condition cond) {
1925   addrmod3(cond | L | B7 | H | B4, dst, src);
1926 }
1927
1928
1929 void Assembler::strh(Register src, const MemOperand& dst, Condition cond) {
1930   addrmod3(cond | B7 | H | B4, src, dst);
1931 }
1932
1933
1934 void Assembler::ldrsb(Register dst, const MemOperand& src, Condition cond) {
1935   addrmod3(cond | L | B7 | S6 | B4, dst, src);
1936 }
1937
1938
1939 void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) {
1940   addrmod3(cond | L | B7 | S6 | H | B4, dst, src);
1941 }
1942
1943
1944 void Assembler::ldrd(Register dst1, Register dst2,
1945                      const MemOperand& src, Condition cond) {
1946   DCHECK(IsEnabled(ARMv7));
1947   DCHECK(src.rm().is(no_reg));
1948   DCHECK(!dst1.is(lr));  // r14.
1949   DCHECK_EQ(0, dst1.code() % 2);
1950   DCHECK_EQ(dst1.code() + 1, dst2.code());
1951   addrmod3(cond | B7 | B6 | B4, dst1, src);
1952 }
1953
1954
1955 void Assembler::strd(Register src1, Register src2,
1956                      const MemOperand& dst, Condition cond) {
1957   DCHECK(dst.rm().is(no_reg));
1958   DCHECK(!src1.is(lr));  // r14.
1959   DCHECK_EQ(0, src1.code() % 2);
1960   DCHECK_EQ(src1.code() + 1, src2.code());
1961   DCHECK(IsEnabled(ARMv7));
1962   addrmod3(cond | B7 | B6 | B5 | B4, src1, dst);
1963 }
1964
1965
1966 // Preload instructions.
1967 void Assembler::pld(const MemOperand& address) {
1968   // Instruction details available in ARM DDI 0406C.b, A8.8.128.
1969   // 1111(31-28) | 0111(27-24) | U(23) | R(22) | 01(21-20) | Rn(19-16) |
1970   // 1111(15-12) | imm5(11-07) | type(6-5) | 0(4)| Rm(3-0) |
1971   DCHECK(address.rm().is(no_reg));
1972   DCHECK(address.am() == Offset);
1973   int U = B23;
1974   int offset = address.offset();
1975   if (offset < 0) {
1976     offset = -offset;
1977     U = 0;
1978   }
1979   DCHECK(offset < 4096);
1980   emit(kSpecialCondition | B26 | B24 | U | B22 | B20 | address.rn().code()*B16 |
1981        0xf*B12 | offset);
1982 }
1983
1984
1985 // Load/Store multiple instructions.
1986 void Assembler::ldm(BlockAddrMode am,
1987                     Register base,
1988                     RegList dst,
1989                     Condition cond) {
1990   // ABI stack constraint: ldmxx base, {..sp..}  base != sp  is not restartable.
1991   DCHECK(base.is(sp) || (dst & sp.bit()) == 0);
1992
1993   addrmod4(cond | B27 | am | L, base, dst);
1994
1995   // Emit the constant pool after a function return implemented by ldm ..{..pc}.
1996   if (cond == al && (dst & pc.bit()) != 0) {
1997     // There is a slight chance that the ldm instruction was actually a call,
1998     // in which case it would be wrong to return into the constant pool; we
1999     // recognize this case by checking if the emission of the pool was blocked
2000     // at the pc of the ldm instruction by a mov lr, pc instruction; if this is
2001     // the case, we emit a jump over the pool.
2002     CheckConstPool(true, no_const_pool_before_ == pc_offset() - kInstrSize);
2003   }
2004 }
2005
2006
2007 void Assembler::stm(BlockAddrMode am,
2008                     Register base,
2009                     RegList src,
2010                     Condition cond) {
2011   addrmod4(cond | B27 | am, base, src);
2012 }
2013
2014
2015 // Exception-generating instructions and debugging support.
2016 // Stops with a non-negative code less than kNumOfWatchedStops support
2017 // enabling/disabling and a counter feature. See simulator-arm.h .
2018 void Assembler::stop(const char* msg, Condition cond, int32_t code) {
2019 #ifndef __arm__
2020   DCHECK(code >= kDefaultStopCode);
2021   {
2022     // The Simulator will handle the stop instruction and get the message
2023     // address. It expects to find the address just after the svc instruction.
2024     BlockConstPoolScope block_const_pool(this);
2025     if (code >= 0) {
2026       svc(kStopCode + code, cond);
2027     } else {
2028       svc(kStopCode + kMaxStopCode, cond);
2029     }
2030     emit(reinterpret_cast<Instr>(msg));
2031   }
2032 #else  // def __arm__
2033   if (cond != al) {
2034     Label skip;
2035     b(&skip, NegateCondition(cond));
2036     bkpt(0);
2037     bind(&skip);
2038   } else {
2039     bkpt(0);
2040   }
2041 #endif  // def __arm__
2042 }
2043
2044
2045 void Assembler::bkpt(uint32_t imm16) {  // v5 and above
2046   DCHECK(is_uint16(imm16));
2047   emit(al | B24 | B21 | (imm16 >> 4)*B8 | BKPT | (imm16 & 0xf));
2048 }
2049
2050
2051 void Assembler::svc(uint32_t imm24, Condition cond) {
2052   DCHECK(is_uint24(imm24));
2053   emit(cond | 15*B24 | imm24);
2054 }
2055
2056
2057 // Coprocessor instructions.
2058 void Assembler::cdp(Coprocessor coproc,
2059                     int opcode_1,
2060                     CRegister crd,
2061                     CRegister crn,
2062                     CRegister crm,
2063                     int opcode_2,
2064                     Condition cond) {
2065   DCHECK(is_uint4(opcode_1) && is_uint3(opcode_2));
2066   emit(cond | B27 | B26 | B25 | (opcode_1 & 15)*B20 | crn.code()*B16 |
2067        crd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | crm.code());
2068 }
2069
2070
2071 void Assembler::cdp2(Coprocessor coproc,
2072                      int opcode_1,
2073                      CRegister crd,
2074                      CRegister crn,
2075                      CRegister crm,
2076                      int opcode_2) {  // v5 and above
2077   cdp(coproc, opcode_1, crd, crn, crm, opcode_2, kSpecialCondition);
2078 }
2079
2080
2081 void Assembler::mcr(Coprocessor coproc,
2082                     int opcode_1,
2083                     Register rd,
2084                     CRegister crn,
2085                     CRegister crm,
2086                     int opcode_2,
2087                     Condition cond) {
2088   DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2));
2089   emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | crn.code()*B16 |
2090        rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
2091 }
2092
2093
2094 void Assembler::mcr2(Coprocessor coproc,
2095                      int opcode_1,
2096                      Register rd,
2097                      CRegister crn,
2098                      CRegister crm,
2099                      int opcode_2) {  // v5 and above
2100   mcr(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition);
2101 }
2102
2103
2104 void Assembler::mrc(Coprocessor coproc,
2105                     int opcode_1,
2106                     Register rd,
2107                     CRegister crn,
2108                     CRegister crm,
2109                     int opcode_2,
2110                     Condition cond) {
2111   DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2));
2112   emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | L | crn.code()*B16 |
2113        rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
2114 }
2115
2116
2117 void Assembler::mrc2(Coprocessor coproc,
2118                      int opcode_1,
2119                      Register rd,
2120                      CRegister crn,
2121                      CRegister crm,
2122                      int opcode_2) {  // v5 and above
2123   mrc(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition);
2124 }
2125
2126
2127 void Assembler::ldc(Coprocessor coproc,
2128                     CRegister crd,
2129                     const MemOperand& src,
2130                     LFlag l,
2131                     Condition cond) {
2132   addrmod5(cond | B27 | B26 | l | L | coproc*B8, crd, src);
2133 }
2134
2135
2136 void Assembler::ldc(Coprocessor coproc,
2137                     CRegister crd,
2138                     Register rn,
2139                     int option,
2140                     LFlag l,
2141                     Condition cond) {
2142   // Unindexed addressing.
2143   DCHECK(is_uint8(option));
2144   emit(cond | B27 | B26 | U | l | L | rn.code()*B16 | crd.code()*B12 |
2145        coproc*B8 | (option & 255));
2146 }
2147
2148
2149 void Assembler::ldc2(Coprocessor coproc,
2150                      CRegister crd,
2151                      const MemOperand& src,
2152                      LFlag l) {  // v5 and above
2153   ldc(coproc, crd, src, l, kSpecialCondition);
2154 }
2155
2156
2157 void Assembler::ldc2(Coprocessor coproc,
2158                      CRegister crd,
2159                      Register rn,
2160                      int option,
2161                      LFlag l) {  // v5 and above
2162   ldc(coproc, crd, rn, option, l, kSpecialCondition);
2163 }
2164
2165
2166 // Support for VFP.
2167
2168 void Assembler::vldr(const DwVfpRegister dst,
2169                      const Register base,
2170                      int offset,
2171                      const Condition cond) {
2172   // Ddst = MEM(Rbase + offset).
2173   // Instruction details available in ARM DDI 0406C.b, A8-924.
2174   // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) |
2175   // Vd(15-12) | 1011(11-8) | offset
2176   int u = 1;
2177   if (offset < 0) {
2178     offset = -offset;
2179     u = 0;
2180   }
2181   int vd, d;
2182   dst.split_code(&vd, &d);
2183
2184   DCHECK(offset >= 0);
2185   if ((offset % 4) == 0 && (offset / 4) < 256) {
2186     emit(cond | 0xD*B24 | u*B23 | d*B22 | B20 | base.code()*B16 | vd*B12 |
2187          0xB*B8 | ((offset / 4) & 255));
2188   } else {
2189     // Larger offsets must be handled by computing the correct address
2190     // in the ip register.
2191     DCHECK(!base.is(ip));
2192     if (u == 1) {
2193       add(ip, base, Operand(offset));
2194     } else {
2195       sub(ip, base, Operand(offset));
2196     }
2197     emit(cond | 0xD*B24 | d*B22 | B20 | ip.code()*B16 | vd*B12 | 0xB*B8);
2198   }
2199 }
2200
2201
2202 void Assembler::vldr(const DwVfpRegister dst,
2203                      const MemOperand& operand,
2204                      const Condition cond) {
2205   DCHECK(operand.am_ == Offset);
2206   if (operand.rm().is_valid()) {
2207     add(ip, operand.rn(),
2208         Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
2209     vldr(dst, ip, 0, cond);
2210   } else {
2211     vldr(dst, operand.rn(), operand.offset(), cond);
2212   }
2213 }
2214
2215
2216 void Assembler::vldr(const SwVfpRegister dst,
2217                      const Register base,
2218                      int offset,
2219                      const Condition cond) {
2220   // Sdst = MEM(Rbase + offset).
2221   // Instruction details available in ARM DDI 0406A, A8-628.
2222   // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) |
2223   // Vdst(15-12) | 1010(11-8) | offset
2224   int u = 1;
2225   if (offset < 0) {
2226     offset = -offset;
2227     u = 0;
2228   }
2229   int sd, d;
2230   dst.split_code(&sd, &d);
2231   DCHECK(offset >= 0);
2232
2233   if ((offset % 4) == 0 && (offset / 4) < 256) {
2234   emit(cond | u*B23 | d*B22 | 0xD1*B20 | base.code()*B16 | sd*B12 |
2235        0xA*B8 | ((offset / 4) & 255));
2236   } else {
2237     // Larger offsets must be handled by computing the correct address
2238     // in the ip register.
2239     DCHECK(!base.is(ip));
2240     if (u == 1) {
2241       add(ip, base, Operand(offset));
2242     } else {
2243       sub(ip, base, Operand(offset));
2244     }
2245     emit(cond | d*B22 | 0xD1*B20 | ip.code()*B16 | sd*B12 | 0xA*B8);
2246   }
2247 }
2248
2249
2250 void Assembler::vldr(const SwVfpRegister dst,
2251                      const MemOperand& operand,
2252                      const Condition cond) {
2253   DCHECK(operand.am_ == Offset);
2254   if (operand.rm().is_valid()) {
2255     add(ip, operand.rn(),
2256         Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
2257     vldr(dst, ip, 0, cond);
2258   } else {
2259     vldr(dst, operand.rn(), operand.offset(), cond);
2260   }
2261 }
2262
2263
2264 void Assembler::vstr(const DwVfpRegister src,
2265                      const Register base,
2266                      int offset,
2267                      const Condition cond) {
2268   // MEM(Rbase + offset) = Dsrc.
2269   // Instruction details available in ARM DDI 0406C.b, A8-1082.
2270   // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) |
2271   // Vd(15-12) | 1011(11-8) | (offset/4)
2272   int u = 1;
2273   if (offset < 0) {
2274     offset = -offset;
2275     u = 0;
2276   }
2277   DCHECK(offset >= 0);
2278   int vd, d;
2279   src.split_code(&vd, &d);
2280
2281   if ((offset % 4) == 0 && (offset / 4) < 256) {
2282     emit(cond | 0xD*B24 | u*B23 | d*B22 | base.code()*B16 | vd*B12 | 0xB*B8 |
2283          ((offset / 4) & 255));
2284   } else {
2285     // Larger offsets must be handled by computing the correct address
2286     // in the ip register.
2287     DCHECK(!base.is(ip));
2288     if (u == 1) {
2289       add(ip, base, Operand(offset));
2290     } else {
2291       sub(ip, base, Operand(offset));
2292     }
2293     emit(cond | 0xD*B24 | d*B22 | ip.code()*B16 | vd*B12 | 0xB*B8);
2294   }
2295 }
2296
2297
2298 void Assembler::vstr(const DwVfpRegister src,
2299                      const MemOperand& operand,
2300                      const Condition cond) {
2301   DCHECK(operand.am_ == Offset);
2302   if (operand.rm().is_valid()) {
2303     add(ip, operand.rn(),
2304         Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
2305     vstr(src, ip, 0, cond);
2306   } else {
2307     vstr(src, operand.rn(), operand.offset(), cond);
2308   }
2309 }
2310
2311
2312 void Assembler::vstr(const SwVfpRegister src,
2313                      const Register base,
2314                      int offset,
2315                      const Condition cond) {
2316   // MEM(Rbase + offset) = SSrc.
2317   // Instruction details available in ARM DDI 0406A, A8-786.
2318   // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) |
2319   // Vdst(15-12) | 1010(11-8) | (offset/4)
2320   int u = 1;
2321   if (offset < 0) {
2322     offset = -offset;
2323     u = 0;
2324   }
2325   int sd, d;
2326   src.split_code(&sd, &d);
2327   DCHECK(offset >= 0);
2328   if ((offset % 4) == 0 && (offset / 4) < 256) {
2329     emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 |
2330          0xA*B8 | ((offset / 4) & 255));
2331   } else {
2332     // Larger offsets must be handled by computing the correct address
2333     // in the ip register.
2334     DCHECK(!base.is(ip));
2335     if (u == 1) {
2336       add(ip, base, Operand(offset));
2337     } else {
2338       sub(ip, base, Operand(offset));
2339     }
2340     emit(cond | d*B22 | 0xD0*B20 | ip.code()*B16 | sd*B12 | 0xA*B8);
2341   }
2342 }
2343
2344
2345 void Assembler::vstr(const SwVfpRegister src,
2346                      const MemOperand& operand,
2347                      const Condition cond) {
2348   DCHECK(operand.am_ == Offset);
2349   if (operand.rm().is_valid()) {
2350     add(ip, operand.rn(),
2351         Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
2352     vstr(src, ip, 0, cond);
2353   } else {
2354     vstr(src, operand.rn(), operand.offset(), cond);
2355   }
2356 }
2357
2358
2359 void  Assembler::vldm(BlockAddrMode am,
2360                       Register base,
2361                       DwVfpRegister first,
2362                       DwVfpRegister last,
2363                       Condition cond) {
2364   // Instruction details available in ARM DDI 0406C.b, A8-922.
2365   // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) |
2366   // first(15-12) | 1011(11-8) | (count * 2)
2367   DCHECK_LE(first.code(), last.code());
2368   DCHECK(am == ia || am == ia_w || am == db_w);
2369   DCHECK(!base.is(pc));
2370
2371   int sd, d;
2372   first.split_code(&sd, &d);
2373   int count = last.code() - first.code() + 1;
2374   DCHECK(count <= 16);
2375   emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 |
2376        0xB*B8 | count*2);
2377 }
2378
2379
2380 void  Assembler::vstm(BlockAddrMode am,
2381                       Register base,
2382                       DwVfpRegister first,
2383                       DwVfpRegister last,
2384                       Condition cond) {
2385   // Instruction details available in ARM DDI 0406C.b, A8-1080.
2386   // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) |
2387   // first(15-12) | 1011(11-8) | (count * 2)
2388   DCHECK_LE(first.code(), last.code());
2389   DCHECK(am == ia || am == ia_w || am == db_w);
2390   DCHECK(!base.is(pc));
2391
2392   int sd, d;
2393   first.split_code(&sd, &d);
2394   int count = last.code() - first.code() + 1;
2395   DCHECK(count <= 16);
2396   emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 |
2397        0xB*B8 | count*2);
2398 }
2399
2400 void  Assembler::vldm(BlockAddrMode am,
2401                       Register base,
2402                       SwVfpRegister first,
2403                       SwVfpRegister last,
2404                       Condition cond) {
2405   // Instruction details available in ARM DDI 0406A, A8-626.
2406   // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) |
2407   // first(15-12) | 1010(11-8) | (count/2)
2408   DCHECK_LE(first.code(), last.code());
2409   DCHECK(am == ia || am == ia_w || am == db_w);
2410   DCHECK(!base.is(pc));
2411
2412   int sd, d;
2413   first.split_code(&sd, &d);
2414   int count = last.code() - first.code() + 1;
2415   emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 |
2416        0xA*B8 | count);
2417 }
2418
2419
2420 void  Assembler::vstm(BlockAddrMode am,
2421                       Register base,
2422                       SwVfpRegister first,
2423                       SwVfpRegister last,
2424                       Condition cond) {
2425   // Instruction details available in ARM DDI 0406A, A8-784.
2426   // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) |
2427   // first(15-12) | 1011(11-8) | (count/2)
2428   DCHECK_LE(first.code(), last.code());
2429   DCHECK(am == ia || am == ia_w || am == db_w);
2430   DCHECK(!base.is(pc));
2431
2432   int sd, d;
2433   first.split_code(&sd, &d);
2434   int count = last.code() - first.code() + 1;
2435   emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 |
2436        0xA*B8 | count);
2437 }
2438
2439
2440 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
2441   uint64_t i;
2442   memcpy(&i, &d, 8);
2443
2444   *lo = i & 0xffffffff;
2445   *hi = i >> 32;
2446 }
2447
2448
2449 // Only works for little endian floating point formats.
2450 // We don't support VFP on the mixed endian floating point platform.
2451 static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) {
2452   DCHECK(CpuFeatures::IsSupported(VFP3));
2453
2454   // VMOV can accept an immediate of the form:
2455   //
2456   //  +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7
2457   //
2458   // The immediate is encoded using an 8-bit quantity, comprised of two
2459   // 4-bit fields. For an 8-bit immediate of the form:
2460   //
2461   //  [abcdefgh]
2462   //
2463   // where a is the MSB and h is the LSB, an immediate 64-bit double can be
2464   // created of the form:
2465   //
2466   //  [aBbbbbbb,bbcdefgh,00000000,00000000,
2467   //      00000000,00000000,00000000,00000000]
2468   //
2469   // where B = ~b.
2470   //
2471
2472   uint32_t lo, hi;
2473   DoubleAsTwoUInt32(d, &lo, &hi);
2474
2475   // The most obvious constraint is the long block of zeroes.
2476   if ((lo != 0) || ((hi & 0xffff) != 0)) {
2477     return false;
2478   }
2479
2480   // Bits 62:55 must be all clear or all set.
2481   if (((hi & 0x3fc00000) != 0) && ((hi & 0x3fc00000) != 0x3fc00000)) {
2482     return false;
2483   }
2484
2485   // Bit 63 must be NOT bit 62.
2486   if (((hi ^ (hi << 1)) & (0x40000000)) == 0) {
2487     return false;
2488   }
2489
2490   // Create the encoded immediate in the form:
2491   //  [00000000,0000abcd,00000000,0000efgh]
2492   *encoding  = (hi >> 16) & 0xf;      // Low nybble.
2493   *encoding |= (hi >> 4) & 0x70000;   // Low three bits of the high nybble.
2494   *encoding |= (hi >> 12) & 0x80000;  // Top bit of the high nybble.
2495
2496   return true;
2497 }
2498
2499
2500 void Assembler::vmov(const DwVfpRegister dst,
2501                      double imm,
2502                      const Register scratch) {
2503   uint32_t enc;
2504   if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) {
2505     // The double can be encoded in the instruction.
2506     //
2507     // Dd = immediate
2508     // Instruction details available in ARM DDI 0406C.b, A8-936.
2509     // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) |
2510     // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0)
2511     int vd, d;
2512     dst.split_code(&vd, &d);
2513     emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc);
2514   } else if (FLAG_enable_vldr_imm && is_ool_constant_pool_available()) {
2515     // TODO(jfb) Temporarily turned off until we have constant blinding or
2516     //           some equivalent mitigation: an attacker can otherwise control
2517     //           generated data which also happens to be executable, a Very Bad
2518     //           Thing indeed.
2519     //           Blinding gets tricky because we don't have xor, we probably
2520     //           need to add/subtract without losing precision, which requires a
2521     //           cookie value that Lithium is probably better positioned to
2522     //           choose.
2523     //           We could also add a few peepholes here like detecting 0.0 and
2524     //           -0.0 and doing a vmov from the sequestered d14, forcing denorms
2525     //           to zero (we set flush-to-zero), and normalizing NaN values.
2526     //           We could also detect redundant values.
2527     //           The code could also randomize the order of values, though
2528     //           that's tricky because vldr has a limited reach. Furthermore
2529     //           it breaks load locality.
2530     RelocInfo rinfo(pc_, imm);
2531     ConstantPoolArray::LayoutSection section = ConstantPoolAddEntry(rinfo);
2532     if (section == ConstantPoolArray::EXTENDED_SECTION) {
2533       DCHECK(FLAG_enable_ool_constant_pool);
2534       // Emit instructions to load constant pool offset.
2535       movw(ip, 0);
2536       movt(ip, 0);
2537       // Load from constant pool at offset.
2538       vldr(dst, MemOperand(pp, ip));
2539     } else {
2540       DCHECK(section == ConstantPoolArray::SMALL_SECTION);
2541       vldr(dst, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0));
2542     }
2543   } else {
2544     // Synthesise the double from ARM immediates.
2545     uint32_t lo, hi;
2546     DoubleAsTwoUInt32(imm, &lo, &hi);
2547
2548     if (scratch.is(no_reg)) {
2549       if (dst.code() < 16) {
2550         const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code());
2551         // Move the low part of the double into the lower of the corresponsing S
2552         // registers of D register dst.
2553         mov(ip, Operand(lo));
2554         vmov(loc.low(), ip);
2555
2556         // Move the high part of the double into the higher of the
2557         // corresponsing S registers of D register dst.
2558         mov(ip, Operand(hi));
2559         vmov(loc.high(), ip);
2560       } else {
2561         // D16-D31 does not have S registers, so move the low and high parts
2562         // directly to the D register using vmov.32.
2563         // Note: This may be slower, so we only do this when we have to.
2564         mov(ip, Operand(lo));
2565         vmov(dst, VmovIndexLo, ip);
2566         mov(ip, Operand(hi));
2567         vmov(dst, VmovIndexHi, ip);
2568       }
2569     } else {
2570       // Move the low and high parts of the double to a D register in one
2571       // instruction.
2572       mov(ip, Operand(lo));
2573       mov(scratch, Operand(hi));
2574       vmov(dst, ip, scratch);
2575     }
2576   }
2577 }
2578
2579
2580 void Assembler::vmov(const SwVfpRegister dst,
2581                      const SwVfpRegister src,
2582                      const Condition cond) {
2583   // Sd = Sm
2584   // Instruction details available in ARM DDI 0406B, A8-642.
2585   int sd, d, sm, m;
2586   dst.split_code(&sd, &d);
2587   src.split_code(&sm, &m);
2588   emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm);
2589 }
2590
2591
2592 void Assembler::vmov(const DwVfpRegister dst,
2593                      const DwVfpRegister src,
2594                      const Condition cond) {
2595   // Dd = Dm
2596   // Instruction details available in ARM DDI 0406C.b, A8-938.
2597   // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) |
2598   // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2599   int vd, d;
2600   dst.split_code(&vd, &d);
2601   int vm, m;
2602   src.split_code(&vm, &m);
2603   emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 |
2604        vm);
2605 }
2606
2607
2608 void Assembler::vmov(const DwVfpRegister dst,
2609                      const VmovIndex index,
2610                      const Register src,
2611                      const Condition cond) {
2612   // Dd[index] = Rt
2613   // Instruction details available in ARM DDI 0406C.b, A8-940.
2614   // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) |
2615   // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0)
2616   DCHECK(index.index == 0 || index.index == 1);
2617   int vd, d;
2618   dst.split_code(&vd, &d);
2619   emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 |
2620        d*B7 | B4);
2621 }
2622
2623
2624 void Assembler::vmov(const Register dst,
2625                      const VmovIndex index,
2626                      const DwVfpRegister src,
2627                      const Condition cond) {
2628   // Dd[index] = Rt
2629   // Instruction details available in ARM DDI 0406C.b, A8.8.342.
2630   // cond(31-28) | 1110(27-24) | U=0(23) | opc1=0index(22-21) | 1(20) |
2631   // Vn(19-16) | Rt(15-12) | 1011(11-8) | N(7) | opc2=00(6-5) | 1(4) | 0000(3-0)
2632   DCHECK(index.index == 0 || index.index == 1);
2633   int vn, n;
2634   src.split_code(&vn, &n);
2635   emit(cond | 0xE*B24 | index.index*B21 | B20 | vn*B16 | dst.code()*B12 |
2636        0xB*B8 | n*B7 | B4);
2637 }
2638
2639
2640 void Assembler::vmov(const DwVfpRegister dst,
2641                      const Register src1,
2642                      const Register src2,
2643                      const Condition cond) {
2644   // Dm = <Rt,Rt2>.
2645   // Instruction details available in ARM DDI 0406C.b, A8-948.
2646   // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) |
2647   // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
2648   DCHECK(!src1.is(pc) && !src2.is(pc));
2649   int vm, m;
2650   dst.split_code(&vm, &m);
2651   emit(cond | 0xC*B24 | B22 | src2.code()*B16 |
2652        src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm);
2653 }
2654
2655
2656 void Assembler::vmov(const Register dst1,
2657                      const Register dst2,
2658                      const DwVfpRegister src,
2659                      const Condition cond) {
2660   // <Rt,Rt2> = Dm.
2661   // Instruction details available in ARM DDI 0406C.b, A8-948.
2662   // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) |
2663   // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
2664   DCHECK(!dst1.is(pc) && !dst2.is(pc));
2665   int vm, m;
2666   src.split_code(&vm, &m);
2667   emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 |
2668        dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm);
2669 }
2670
2671
2672 void Assembler::vmov(const SwVfpRegister dst,
2673                      const Register src,
2674                      const Condition cond) {
2675   // Sn = Rt.
2676   // Instruction details available in ARM DDI 0406A, A8-642.
2677   // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) |
2678   // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
2679   DCHECK(!src.is(pc));
2680   int sn, n;
2681   dst.split_code(&sn, &n);
2682   emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4);
2683 }
2684
2685
2686 void Assembler::vmov(const Register dst,
2687                      const SwVfpRegister src,
2688                      const Condition cond) {
2689   // Rt = Sn.
2690   // Instruction details available in ARM DDI 0406A, A8-642.
2691   // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) |
2692   // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
2693   DCHECK(!dst.is(pc));
2694   int sn, n;
2695   src.split_code(&sn, &n);
2696   emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4);
2697 }
2698
2699
2700 // Type of data to read from or write to VFP register.
2701 // Used as specifier in generic vcvt instruction.
2702 enum VFPType { S32, U32, F32, F64 };
2703
2704
2705 static bool IsSignedVFPType(VFPType type) {
2706   switch (type) {
2707     case S32:
2708       return true;
2709     case U32:
2710       return false;
2711     default:
2712       UNREACHABLE();
2713       return false;
2714   }
2715 }
2716
2717
2718 static bool IsIntegerVFPType(VFPType type) {
2719   switch (type) {
2720     case S32:
2721     case U32:
2722       return true;
2723     case F32:
2724     case F64:
2725       return false;
2726     default:
2727       UNREACHABLE();
2728       return false;
2729   }
2730 }
2731
2732
2733 static bool IsDoubleVFPType(VFPType type) {
2734   switch (type) {
2735     case F32:
2736       return false;
2737     case F64:
2738       return true;
2739     default:
2740       UNREACHABLE();
2741       return false;
2742   }
2743 }
2744
2745
2746 // Split five bit reg_code based on size of reg_type.
2747 //  32-bit register codes are Vm:M
2748 //  64-bit register codes are M:Vm
2749 // where Vm is four bits, and M is a single bit.
2750 static void SplitRegCode(VFPType reg_type,
2751                          int reg_code,
2752                          int* vm,
2753                          int* m) {
2754   DCHECK((reg_code >= 0) && (reg_code <= 31));
2755   if (IsIntegerVFPType(reg_type) || !IsDoubleVFPType(reg_type)) {
2756     // 32 bit type.
2757     *m  = reg_code & 0x1;
2758     *vm = reg_code >> 1;
2759   } else {
2760     // 64 bit type.
2761     *m  = (reg_code & 0x10) >> 4;
2762     *vm = reg_code & 0x0F;
2763   }
2764 }
2765
2766
2767 // Encode vcvt.src_type.dst_type instruction.
2768 static Instr EncodeVCVT(const VFPType dst_type,
2769                         const int dst_code,
2770                         const VFPType src_type,
2771                         const int src_code,
2772                         VFPConversionMode mode,
2773                         const Condition cond) {
2774   DCHECK(src_type != dst_type);
2775   int D, Vd, M, Vm;
2776   SplitRegCode(src_type, src_code, &Vm, &M);
2777   SplitRegCode(dst_type, dst_code, &Vd, &D);
2778
2779   if (IsIntegerVFPType(dst_type) || IsIntegerVFPType(src_type)) {
2780     // Conversion between IEEE floating point and 32-bit integer.
2781     // Instruction details available in ARM DDI 0406B, A8.6.295.
2782     // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 1(19) | opc2(18-16) |
2783     // Vd(15-12) | 101(11-9) | sz(8) | op(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2784     DCHECK(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type));
2785
2786     int sz, opc2, op;
2787
2788     if (IsIntegerVFPType(dst_type)) {
2789       opc2 = IsSignedVFPType(dst_type) ? 0x5 : 0x4;
2790       sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
2791       op = mode;
2792     } else {
2793       DCHECK(IsIntegerVFPType(src_type));
2794       opc2 = 0x0;
2795       sz = IsDoubleVFPType(dst_type) ? 0x1 : 0x0;
2796       op = IsSignedVFPType(src_type) ? 0x1 : 0x0;
2797     }
2798
2799     return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | B19 | opc2*B16 |
2800             Vd*B12 | 0x5*B9 | sz*B8 | op*B7 | B6 | M*B5 | Vm);
2801   } else {
2802     // Conversion between IEEE double and single precision.
2803     // Instruction details available in ARM DDI 0406B, A8.6.298.
2804     // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0111(19-16) |
2805     // Vd(15-12) | 101(11-9) | sz(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2806     int sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
2807     return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 |
2808             Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm);
2809   }
2810 }
2811
2812
2813 void Assembler::vcvt_f64_s32(const DwVfpRegister dst,
2814                              const SwVfpRegister src,
2815                              VFPConversionMode mode,
2816                              const Condition cond) {
2817   emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond));
2818 }
2819
2820
2821 void Assembler::vcvt_f32_s32(const SwVfpRegister dst,
2822                              const SwVfpRegister src,
2823                              VFPConversionMode mode,
2824                              const Condition cond) {
2825   emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond));
2826 }
2827
2828
2829 void Assembler::vcvt_f64_u32(const DwVfpRegister dst,
2830                              const SwVfpRegister src,
2831                              VFPConversionMode mode,
2832                              const Condition cond) {
2833   emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond));
2834 }
2835
2836
2837 void Assembler::vcvt_s32_f64(const SwVfpRegister dst,
2838                              const DwVfpRegister src,
2839                              VFPConversionMode mode,
2840                              const Condition cond) {
2841   emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond));
2842 }
2843
2844
2845 void Assembler::vcvt_u32_f64(const SwVfpRegister dst,
2846                              const DwVfpRegister src,
2847                              VFPConversionMode mode,
2848                              const Condition cond) {
2849   emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond));
2850 }
2851
2852
2853 void Assembler::vcvt_f64_f32(const DwVfpRegister dst,
2854                              const SwVfpRegister src,
2855                              VFPConversionMode mode,
2856                              const Condition cond) {
2857   emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond));
2858 }
2859
2860
2861 void Assembler::vcvt_f32_f64(const SwVfpRegister dst,
2862                              const DwVfpRegister src,
2863                              VFPConversionMode mode,
2864                              const Condition cond) {
2865   emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond));
2866 }
2867
2868
2869 void Assembler::vcvt_f64_s32(const DwVfpRegister dst,
2870                              int fraction_bits,
2871                              const Condition cond) {
2872   // Instruction details available in ARM DDI 0406C.b, A8-874.
2873   // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 1010(19-16) | Vd(15-12) |
2874   // 101(11-9) | sf=1(8) | sx=1(7) | 1(6) | i(5) | 0(4) | imm4(3-0)
2875   DCHECK(fraction_bits > 0 && fraction_bits <= 32);
2876   DCHECK(CpuFeatures::IsSupported(VFP3));
2877   int vd, d;
2878   dst.split_code(&vd, &d);
2879   int imm5 = 32 - fraction_bits;
2880   int i = imm5 & 1;
2881   int imm4 = (imm5 >> 1) & 0xf;
2882   emit(cond | 0xE*B24 | B23 | d*B22 | 0x3*B20 | B19 | 0x2*B16 |
2883        vd*B12 | 0x5*B9 | B8 | B7 | B6 | i*B5 | imm4);
2884 }
2885
2886
2887 void Assembler::vneg(const DwVfpRegister dst,
2888                      const DwVfpRegister src,
2889                      const Condition cond) {
2890   // Instruction details available in ARM DDI 0406C.b, A8-968.
2891   // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) |
2892   // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2893   int vd, d;
2894   dst.split_code(&vd, &d);
2895   int vm, m;
2896   src.split_code(&vm, &m);
2897
2898   emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 |
2899        m*B5 | vm);
2900 }
2901
2902
2903 void Assembler::vabs(const DwVfpRegister dst,
2904                      const DwVfpRegister src,
2905                      const Condition cond) {
2906   // Instruction details available in ARM DDI 0406C.b, A8-524.
2907   // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) |
2908   // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2909   int vd, d;
2910   dst.split_code(&vd, &d);
2911   int vm, m;
2912   src.split_code(&vm, &m);
2913   emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 |
2914        m*B5 | vm);
2915 }
2916
2917
2918 void Assembler::vadd(const DwVfpRegister dst,
2919                      const DwVfpRegister src1,
2920                      const DwVfpRegister src2,
2921                      const Condition cond) {
2922   // Dd = vadd(Dn, Dm) double precision floating point addition.
2923   // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2924   // Instruction details available in ARM DDI 0406C.b, A8-830.
2925   // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) |
2926   // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
2927   int vd, d;
2928   dst.split_code(&vd, &d);
2929   int vn, n;
2930   src1.split_code(&vn, &n);
2931   int vm, m;
2932   src2.split_code(&vm, &m);
2933   emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2934        n*B7 | m*B5 | vm);
2935 }
2936
2937
2938 void Assembler::vsub(const DwVfpRegister dst,
2939                      const DwVfpRegister src1,
2940                      const DwVfpRegister src2,
2941                      const Condition cond) {
2942   // Dd = vsub(Dn, Dm) double precision floating point subtraction.
2943   // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2944   // Instruction details available in ARM DDI 0406C.b, A8-1086.
2945   // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) |
2946   // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2947   int vd, d;
2948   dst.split_code(&vd, &d);
2949   int vn, n;
2950   src1.split_code(&vn, &n);
2951   int vm, m;
2952   src2.split_code(&vm, &m);
2953   emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2954        n*B7 | B6 | m*B5 | vm);
2955 }
2956
2957
2958 void Assembler::vmul(const DwVfpRegister dst,
2959                      const DwVfpRegister src1,
2960                      const DwVfpRegister src2,
2961                      const Condition cond) {
2962   // Dd = vmul(Dn, Dm) double precision floating point multiplication.
2963   // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2964   // Instruction details available in ARM DDI 0406C.b, A8-960.
2965   // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) |
2966   // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
2967   int vd, d;
2968   dst.split_code(&vd, &d);
2969   int vn, n;
2970   src1.split_code(&vn, &n);
2971   int vm, m;
2972   src2.split_code(&vm, &m);
2973   emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2974        n*B7 | m*B5 | vm);
2975 }
2976
2977
2978 void Assembler::vmla(const DwVfpRegister dst,
2979                      const DwVfpRegister src1,
2980                      const DwVfpRegister src2,
2981                      const Condition cond) {
2982   // Instruction details available in ARM DDI 0406C.b, A8-932.
2983   // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) |
2984   // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=0(6) | M(5) | 0(4) | Vm(3-0)
2985   int vd, d;
2986   dst.split_code(&vd, &d);
2987   int vn, n;
2988   src1.split_code(&vn, &n);
2989   int vm, m;
2990   src2.split_code(&vm, &m);
2991   emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 |
2992        vm);
2993 }
2994
2995
2996 void Assembler::vmls(const DwVfpRegister dst,
2997                      const DwVfpRegister src1,
2998                      const DwVfpRegister src2,
2999                      const Condition cond) {
3000   // Instruction details available in ARM DDI 0406C.b, A8-932.
3001   // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) |
3002   // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=1(6) | M(5) | 0(4) | Vm(3-0)
3003   int vd, d;
3004   dst.split_code(&vd, &d);
3005   int vn, n;
3006   src1.split_code(&vn, &n);
3007   int vm, m;
3008   src2.split_code(&vm, &m);
3009   emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | B6 |
3010        m*B5 | vm);
3011 }
3012
3013
3014 void Assembler::vdiv(const DwVfpRegister dst,
3015                      const DwVfpRegister src1,
3016                      const DwVfpRegister src2,
3017                      const Condition cond) {
3018   // Dd = vdiv(Dn, Dm) double precision floating point division.
3019   // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
3020   // Instruction details available in ARM DDI 0406C.b, A8-882.
3021   // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) |
3022   // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
3023   int vd, d;
3024   dst.split_code(&vd, &d);
3025   int vn, n;
3026   src1.split_code(&vn, &n);
3027   int vm, m;
3028   src2.split_code(&vm, &m);
3029   emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 |
3030        vm);
3031 }
3032
3033
3034 void Assembler::vcmp(const DwVfpRegister src1,
3035                      const DwVfpRegister src2,
3036                      const Condition cond) {
3037   // vcmp(Dd, Dm) double precision floating point comparison.
3038   // Instruction details available in ARM DDI 0406C.b, A8-864.
3039   // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) |
3040   // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
3041   int vd, d;
3042   src1.split_code(&vd, &d);
3043   int vm, m;
3044   src2.split_code(&vm, &m);
3045   emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 |
3046        m*B5 | vm);
3047 }
3048
3049
3050 void Assembler::vcmp(const DwVfpRegister src1,
3051                      const double src2,
3052                      const Condition cond) {
3053   // vcmp(Dd, #0.0) double precision floating point comparison.
3054   // Instruction details available in ARM DDI 0406C.b, A8-864.
3055   // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) |
3056   // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0)
3057   DCHECK(src2 == 0.0);
3058   int vd, d;
3059   src1.split_code(&vd, &d);
3060   emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6);
3061 }
3062
3063
3064 void Assembler::vmsr(Register dst, Condition cond) {
3065   // Instruction details available in ARM DDI 0406A, A8-652.
3066   // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) |
3067   // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0)
3068   emit(cond | 0xE*B24 | 0xE*B20 |  B16 |
3069        dst.code()*B12 | 0xA*B8 | B4);
3070 }
3071
3072
3073 void Assembler::vmrs(Register dst, Condition cond) {
3074   // Instruction details available in ARM DDI 0406A, A8-652.
3075   // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) |
3076   // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0)
3077   emit(cond | 0xE*B24 | 0xF*B20 |  B16 |
3078        dst.code()*B12 | 0xA*B8 | B4);
3079 }
3080
3081
3082 void Assembler::vsqrt(const DwVfpRegister dst,
3083                       const DwVfpRegister src,
3084                       const Condition cond) {
3085   // Instruction details available in ARM DDI 0406C.b, A8-1058.
3086   // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) |
3087   // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0)
3088   int vd, d;
3089   dst.split_code(&vd, &d);
3090   int vm, m;
3091   src.split_code(&vm, &m);
3092   emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 |
3093        m*B5 | vm);
3094 }
3095
3096
3097 void Assembler::vrinta(const DwVfpRegister dst, const DwVfpRegister src) {
3098   // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) |
3099   // 10(19-18) | RM=00(17-16) |  Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) |
3100   // M(5) | 0(4) | Vm(3-0)
3101   DCHECK(CpuFeatures::IsSupported(ARMv8));
3102   int vd, d;
3103   dst.split_code(&vd, &d);
3104   int vm, m;
3105   src.split_code(&vm, &m);
3106   emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | vd * B12 |
3107        0x5 * B9 | B8 | B6 | m * B5 | vm);
3108 }
3109
3110
3111 void Assembler::vrintn(const DwVfpRegister dst, const DwVfpRegister src) {
3112   // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) |
3113   // 10(19-18) | RM=01(17-16) |  Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) |
3114   // M(5) | 0(4) | Vm(3-0)
3115   DCHECK(CpuFeatures::IsSupported(ARMv8));
3116   int vd, d;
3117   dst.split_code(&vd, &d);
3118   int vm, m;
3119   src.split_code(&vm, &m);
3120   emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x1 * B16 |
3121        vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm);
3122 }
3123
3124
3125 void Assembler::vrintp(const DwVfpRegister dst, const DwVfpRegister src) {
3126   // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) |
3127   // 10(19-18) | RM=10(17-16) |  Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) |
3128   // M(5) | 0(4) | Vm(3-0)
3129   DCHECK(CpuFeatures::IsSupported(ARMv8));
3130   int vd, d;
3131   dst.split_code(&vd, &d);
3132   int vm, m;
3133   src.split_code(&vm, &m);
3134   emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x2 * B16 |
3135        vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm);
3136 }
3137
3138
3139 void Assembler::vrintm(const DwVfpRegister dst, const DwVfpRegister src) {
3140   // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) |
3141   // 10(19-18) | RM=11(17-16) |  Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) |
3142   // M(5) | 0(4) | Vm(3-0)
3143   DCHECK(CpuFeatures::IsSupported(ARMv8));
3144   int vd, d;
3145   dst.split_code(&vd, &d);
3146   int vm, m;
3147   src.split_code(&vm, &m);
3148   emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x3 * B16 |
3149        vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm);
3150 }
3151
3152
3153 void Assembler::vrintz(const DwVfpRegister dst, const DwVfpRegister src,
3154                        const Condition cond) {
3155   // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 011(19-17) | 0(16) |
3156   // Vd(15-12) | 101(11-9) | sz=1(8) | op=1(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
3157   DCHECK(CpuFeatures::IsSupported(ARMv8));
3158   int vd, d;
3159   dst.split_code(&vd, &d);
3160   int vm, m;
3161   src.split_code(&vm, &m);
3162   emit(cond | 0x1D * B23 | d * B22 | 0x3 * B20 | 0x3 * B17 | vd * B12 |
3163        0x5 * B9 | B8 | B7 | B6 | m * B5 | vm);
3164 }
3165
3166
3167 // Support for NEON.
3168
3169 void Assembler::vld1(NeonSize size,
3170                      const NeonListOperand& dst,
3171                      const NeonMemOperand& src) {
3172   // Instruction details available in ARM DDI 0406C.b, A8.8.320.
3173   // 1111(31-28) | 01000(27-23) | D(22) | 10(21-20) | Rn(19-16) |
3174   // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
3175   DCHECK(CpuFeatures::IsSupported(NEON));
3176   int vd, d;
3177   dst.base().split_code(&vd, &d);
3178   emit(0xFU*B28 | 4*B24 | d*B22 | 2*B20 | src.rn().code()*B16 | vd*B12 |
3179        dst.type()*B8 | size*B6 | src.align()*B4 | src.rm().code());
3180 }
3181
3182
3183 void Assembler::vst1(NeonSize size,
3184                      const NeonListOperand& src,
3185                      const NeonMemOperand& dst) {
3186   // Instruction details available in ARM DDI 0406C.b, A8.8.404.
3187   // 1111(31-28) | 01000(27-23) | D(22) | 00(21-20) | Rn(19-16) |
3188   // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
3189   DCHECK(CpuFeatures::IsSupported(NEON));
3190   int vd, d;
3191   src.base().split_code(&vd, &d);
3192   emit(0xFU*B28 | 4*B24 | d*B22 | dst.rn().code()*B16 | vd*B12 | src.type()*B8 |
3193        size*B6 | dst.align()*B4 | dst.rm().code());
3194 }
3195
3196
3197 void Assembler::vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src) {
3198   // Instruction details available in ARM DDI 0406C.b, A8.8.346.
3199   // 1111(31-28) | 001(27-25) | U(24) | 1(23) | D(22) | imm3(21-19) |
3200   // 000(18-16) | Vd(15-12) | 101000(11-6) | M(5) | 1(4) | Vm(3-0)
3201   DCHECK(CpuFeatures::IsSupported(NEON));
3202   int vd, d;
3203   dst.split_code(&vd, &d);
3204   int vm, m;
3205   src.split_code(&vm, &m);
3206   emit(0xFU*B28 | B25 | (dt & NeonDataTypeUMask) | B23 | d*B22 |
3207         (dt & NeonDataTypeSizeMask)*B19 | vd*B12 | 0xA*B8 | m*B5 | B4 | vm);
3208 }
3209
3210
3211 // Pseudo instructions.
3212 void Assembler::nop(int type) {
3213   // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes
3214   // some of the CPU's pipeline and has to issue. Older ARM chips simply used
3215   // MOV Rx, Rx as NOP and it performs better even in newer CPUs.
3216   // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode
3217   // a type.
3218   DCHECK(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
3219   emit(al | 13*B21 | type*B12 | type);
3220 }
3221
3222
3223 bool Assembler::IsMovT(Instr instr) {
3224   instr &= ~(((kNumberOfConditions - 1) << 28) |  // Mask off conditions
3225              ((kNumRegisters-1)*B12) |            // mask out register
3226              EncodeMovwImmediate(0xFFFF));        // mask out immediate value
3227   return instr == kMovtPattern;
3228 }
3229
3230
3231 bool Assembler::IsMovW(Instr instr) {
3232   instr &= ~(((kNumberOfConditions - 1) << 28) |  // Mask off conditions
3233              ((kNumRegisters-1)*B12) |            // mask out destination
3234              EncodeMovwImmediate(0xFFFF));        // mask out immediate value
3235   return instr == kMovwPattern;
3236 }
3237
3238
3239 Instr Assembler::GetMovTPattern() { return kMovtPattern; }
3240
3241
3242 Instr Assembler::GetMovWPattern() { return kMovwPattern; }
3243
3244
3245 Instr Assembler::EncodeMovwImmediate(uint32_t immediate) {
3246   DCHECK(immediate < 0x10000);
3247   return ((immediate & 0xf000) << 4) | (immediate & 0xfff);
3248 }
3249
3250
3251 Instr Assembler::PatchMovwImmediate(Instr instruction, uint32_t immediate) {
3252   instruction &= ~EncodeMovwImmediate(0xffff);
3253   return instruction | EncodeMovwImmediate(immediate);
3254 }
3255
3256
3257 int Assembler::DecodeShiftImm(Instr instr) {
3258   int rotate = Instruction::RotateValue(instr) * 2;
3259   int immed8 = Instruction::Immed8Value(instr);
3260   return (immed8 >> rotate) | (immed8 << (32 - rotate));
3261 }
3262
3263
3264 Instr Assembler::PatchShiftImm(Instr instr, int immed) {
3265   uint32_t rotate_imm = 0;
3266   uint32_t immed_8 = 0;
3267   bool immed_fits = fits_shifter(immed, &rotate_imm, &immed_8, NULL);
3268   DCHECK(immed_fits);
3269   USE(immed_fits);
3270   return (instr & ~kOff12Mask) | (rotate_imm << 8) | immed_8;
3271 }
3272
3273
3274 bool Assembler::IsNop(Instr instr, int type) {
3275   DCHECK(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
3276   // Check for mov rx, rx where x = type.
3277   return instr == (al | 13*B21 | type*B12 | type);
3278 }
3279
3280
3281 bool Assembler::IsMovImmed(Instr instr) {
3282   return (instr & kMovImmedMask) == kMovImmedPattern;
3283 }
3284
3285
3286 bool Assembler::IsOrrImmed(Instr instr) {
3287   return (instr & kOrrImmedMask) == kOrrImmedPattern;
3288 }
3289
3290
3291 // static
3292 bool Assembler::ImmediateFitsAddrMode1Instruction(int32_t imm32) {
3293   uint32_t dummy1;
3294   uint32_t dummy2;
3295   return fits_shifter(imm32, &dummy1, &dummy2, NULL);
3296 }
3297
3298
3299 bool Assembler::ImmediateFitsAddrMode2Instruction(int32_t imm32) {
3300   return is_uint12(abs(imm32));
3301 }
3302
3303
3304 // Debugging.
3305 void Assembler::RecordJSReturn() {
3306   positions_recorder()->WriteRecordedPositions();
3307   CheckBuffer();
3308   RecordRelocInfo(RelocInfo::JS_RETURN);
3309 }
3310
3311
3312 void Assembler::RecordDebugBreakSlot() {
3313   positions_recorder()->WriteRecordedPositions();
3314   CheckBuffer();
3315   RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
3316 }
3317
3318
3319 void Assembler::RecordComment(const char* msg) {
3320   if (FLAG_code_comments) {
3321     CheckBuffer();
3322     RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
3323   }
3324 }
3325
3326
3327 void Assembler::RecordConstPool(int size) {
3328   // We only need this for debugger support, to correctly compute offsets in the
3329   // code.
3330   RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size));
3331 }
3332
3333
3334 void Assembler::GrowBuffer() {
3335   if (!own_buffer_) FATAL("external code buffer is too small");
3336
3337   // Compute new buffer size.
3338   CodeDesc desc;  // the new buffer
3339   if (buffer_size_ < 1 * MB) {
3340     desc.buffer_size = 2*buffer_size_;
3341   } else {
3342     desc.buffer_size = buffer_size_ + 1*MB;
3343   }
3344   CHECK_GT(desc.buffer_size, 0);  // no overflow
3345
3346   // Set up new buffer.
3347   desc.buffer = NewArray<byte>(desc.buffer_size);
3348
3349   desc.instr_size = pc_offset();
3350   desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
3351
3352   // Copy the data.
3353   int pc_delta = desc.buffer - buffer_;
3354   int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
3355   MemMove(desc.buffer, buffer_, desc.instr_size);
3356   MemMove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(),
3357           desc.reloc_size);
3358
3359   // Switch buffers.
3360   DeleteArray(buffer_);
3361   buffer_ = desc.buffer;
3362   buffer_size_ = desc.buffer_size;
3363   pc_ += pc_delta;
3364   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
3365                                reloc_info_writer.last_pc() + pc_delta);
3366
3367   // None of our relocation types are pc relative pointing outside the code
3368   // buffer nor pc absolute pointing inside the code buffer, so there is no need
3369   // to relocate any emitted relocation entries.
3370
3371   // Relocate pending relocation entries.
3372   for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
3373     RelocInfo& rinfo = pending_32_bit_reloc_info_[i];
3374     DCHECK(rinfo.rmode() != RelocInfo::COMMENT &&
3375            rinfo.rmode() != RelocInfo::POSITION);
3376     if (rinfo.rmode() != RelocInfo::JS_RETURN) {
3377       rinfo.set_pc(rinfo.pc() + pc_delta);
3378     }
3379   }
3380   for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) {
3381     RelocInfo& rinfo = pending_64_bit_reloc_info_[i];
3382     DCHECK(rinfo.rmode() == RelocInfo::NONE64);
3383     rinfo.set_pc(rinfo.pc() + pc_delta);
3384   }
3385   constant_pool_builder_.Relocate(pc_delta);
3386 }
3387
3388
3389 void Assembler::db(uint8_t data) {
3390   // No relocation info should be pending while using db. db is used
3391   // to write pure data with no pointers and the constant pool should
3392   // be emitted before using db.
3393   DCHECK(num_pending_32_bit_reloc_info_ == 0);
3394   DCHECK(num_pending_64_bit_reloc_info_ == 0);
3395   CheckBuffer();
3396   *reinterpret_cast<uint8_t*>(pc_) = data;
3397   pc_ += sizeof(uint8_t);
3398 }
3399
3400
3401 void Assembler::dd(uint32_t data) {
3402   // No relocation info should be pending while using dd. dd is used
3403   // to write pure data with no pointers and the constant pool should
3404   // be emitted before using dd.
3405   DCHECK(num_pending_32_bit_reloc_info_ == 0);
3406   DCHECK(num_pending_64_bit_reloc_info_ == 0);
3407   CheckBuffer();
3408   *reinterpret_cast<uint32_t*>(pc_) = data;
3409   pc_ += sizeof(uint32_t);
3410 }
3411
3412
3413 void Assembler::emit_code_stub_address(Code* stub) {
3414   CheckBuffer();
3415   *reinterpret_cast<uint32_t*>(pc_) =
3416       reinterpret_cast<uint32_t>(stub->instruction_start());
3417   pc_ += sizeof(uint32_t);
3418 }
3419
3420
3421 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3422   RelocInfo rinfo(pc_, rmode, data, NULL);
3423   RecordRelocInfo(rinfo);
3424 }
3425
3426
3427 void Assembler::RecordRelocInfo(const RelocInfo& rinfo) {
3428   if (!RelocInfo::IsNone(rinfo.rmode())) {
3429     // Don't record external references unless the heap will be serialized.
3430     if (rinfo.rmode() == RelocInfo::EXTERNAL_REFERENCE &&
3431         !serializer_enabled() && !emit_debug_code()) {
3432       return;
3433     }
3434     DCHECK(buffer_space() >= kMaxRelocSize);  // too late to grow buffer here
3435     if (rinfo.rmode() == RelocInfo::CODE_TARGET_WITH_ID) {
3436       RelocInfo reloc_info_with_ast_id(rinfo.pc(),
3437                                        rinfo.rmode(),
3438                                        RecordedAstId().ToInt(),
3439                                        NULL);
3440       ClearRecordedAstId();
3441       reloc_info_writer.Write(&reloc_info_with_ast_id);
3442     } else {
3443       reloc_info_writer.Write(&rinfo);
3444     }
3445   }
3446 }
3447
3448
3449 ConstantPoolArray::LayoutSection Assembler::ConstantPoolAddEntry(
3450     const RelocInfo& rinfo) {
3451   if (FLAG_enable_ool_constant_pool) {
3452     return constant_pool_builder_.AddEntry(this, rinfo);
3453   } else {
3454     if (rinfo.rmode() == RelocInfo::NONE64) {
3455       DCHECK(num_pending_64_bit_reloc_info_ < kMaxNumPending64RelocInfo);
3456       if (num_pending_64_bit_reloc_info_ == 0) {
3457         first_const_pool_64_use_ = pc_offset();
3458       }
3459       pending_64_bit_reloc_info_[num_pending_64_bit_reloc_info_++] = rinfo;
3460     } else {
3461       DCHECK(num_pending_32_bit_reloc_info_ < kMaxNumPending32RelocInfo);
3462       if (num_pending_32_bit_reloc_info_ == 0) {
3463         first_const_pool_32_use_ = pc_offset();
3464       }
3465       pending_32_bit_reloc_info_[num_pending_32_bit_reloc_info_++] = rinfo;
3466     }
3467     // Make sure the constant pool is not emitted in place of the next
3468     // instruction for which we just recorded relocation info.
3469     BlockConstPoolFor(1);
3470     return ConstantPoolArray::SMALL_SECTION;
3471   }
3472 }
3473
3474
3475 void Assembler::BlockConstPoolFor(int instructions) {
3476   if (FLAG_enable_ool_constant_pool) {
3477     // Should be a no-op if using an out-of-line constant pool.
3478     DCHECK(num_pending_32_bit_reloc_info_ == 0);
3479     DCHECK(num_pending_64_bit_reloc_info_ == 0);
3480     return;
3481   }
3482
3483   int pc_limit = pc_offset() + instructions * kInstrSize;
3484   if (no_const_pool_before_ < pc_limit) {
3485     // Max pool start (if we need a jump and an alignment).
3486 #ifdef DEBUG
3487     int start = pc_limit + kInstrSize + 2 * kPointerSize;
3488     DCHECK((num_pending_32_bit_reloc_info_ == 0) ||
3489            (start - first_const_pool_32_use_ +
3490             num_pending_64_bit_reloc_info_ * kDoubleSize < kMaxDistToIntPool));
3491     DCHECK((num_pending_64_bit_reloc_info_ == 0) ||
3492            (start - first_const_pool_64_use_ < kMaxDistToFPPool));
3493 #endif
3494     no_const_pool_before_ = pc_limit;
3495   }
3496
3497   if (next_buffer_check_ < no_const_pool_before_) {
3498     next_buffer_check_ = no_const_pool_before_;
3499   }
3500 }
3501
3502
3503 void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
3504   if (FLAG_enable_ool_constant_pool) {
3505     // Should be a no-op if using an out-of-line constant pool.
3506     DCHECK(num_pending_32_bit_reloc_info_ == 0);
3507     DCHECK(num_pending_64_bit_reloc_info_ == 0);
3508     return;
3509   }
3510
3511   // Some short sequence of instruction mustn't be broken up by constant pool
3512   // emission, such sequences are protected by calls to BlockConstPoolFor and
3513   // BlockConstPoolScope.
3514   if (is_const_pool_blocked()) {
3515     // Something is wrong if emission is forced and blocked at the same time.
3516     DCHECK(!force_emit);
3517     return;
3518   }
3519
3520   // There is nothing to do if there are no pending constant pool entries.
3521   if ((num_pending_32_bit_reloc_info_ == 0) &&
3522       (num_pending_64_bit_reloc_info_ == 0)) {
3523     // Calculate the offset of the next check.
3524     next_buffer_check_ = pc_offset() + kCheckPoolInterval;
3525     return;
3526   }
3527
3528   // Check that the code buffer is large enough before emitting the constant
3529   // pool (include the jump over the pool and the constant pool marker and
3530   // the gap to the relocation information).
3531   int jump_instr = require_jump ? kInstrSize : 0;
3532   int size_up_to_marker = jump_instr + kInstrSize;
3533   int size_after_marker = num_pending_32_bit_reloc_info_ * kPointerSize;
3534   bool has_fp_values = (num_pending_64_bit_reloc_info_ > 0);
3535   bool require_64_bit_align = false;
3536   if (has_fp_values) {
3537     require_64_bit_align = (((uintptr_t)pc_ + size_up_to_marker) & 0x7);
3538     if (require_64_bit_align) {
3539       size_after_marker += kInstrSize;
3540     }
3541     size_after_marker += num_pending_64_bit_reloc_info_ * kDoubleSize;
3542   }
3543
3544   int size = size_up_to_marker + size_after_marker;
3545
3546   // We emit a constant pool when:
3547   //  * requested to do so by parameter force_emit (e.g. after each function).
3548   //  * the distance from the first instruction accessing the constant pool to
3549   //    any of the constant pool entries will exceed its limit the next
3550   //    time the pool is checked. This is overly restrictive, but we don't emit
3551   //    constant pool entries in-order so it's conservatively correct.
3552   //  * the instruction doesn't require a jump after itself to jump over the
3553   //    constant pool, and we're getting close to running out of range.
3554   if (!force_emit) {
3555     DCHECK((first_const_pool_32_use_ >= 0) || (first_const_pool_64_use_ >= 0));
3556     bool need_emit = false;
3557     if (has_fp_values) {
3558       int dist64 = pc_offset() +
3559                    size -
3560                    num_pending_32_bit_reloc_info_ * kPointerSize -
3561                    first_const_pool_64_use_;
3562       if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) ||
3563           (!require_jump && (dist64 >= kMaxDistToFPPool / 2))) {
3564         need_emit = true;
3565       }
3566     }
3567     int dist32 =
3568       pc_offset() + size - first_const_pool_32_use_;
3569     if ((dist32 >= kMaxDistToIntPool - kCheckPoolInterval) ||
3570         (!require_jump && (dist32 >= kMaxDistToIntPool / 2))) {
3571       need_emit = true;
3572     }
3573     if (!need_emit) return;
3574   }
3575
3576   int needed_space = size + kGap;
3577   while (buffer_space() <= needed_space) GrowBuffer();
3578
3579   {
3580     // Block recursive calls to CheckConstPool.
3581     BlockConstPoolScope block_const_pool(this);
3582     RecordComment("[ Constant Pool");
3583     RecordConstPool(size);
3584
3585     // Emit jump over constant pool if necessary.
3586     Label after_pool;
3587     if (require_jump) {
3588       b(&after_pool);
3589     }
3590
3591     // Put down constant pool marker "Undefined instruction".
3592     // The data size helps disassembly know what to print.
3593     emit(kConstantPoolMarker |
3594          EncodeConstantPoolLength(size_after_marker / kPointerSize));
3595
3596     if (require_64_bit_align) {
3597       emit(kConstantPoolMarker);
3598     }
3599
3600     // Emit 64-bit constant pool entries first: their range is smaller than
3601     // 32-bit entries.
3602     for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) {
3603       RelocInfo& rinfo = pending_64_bit_reloc_info_[i];
3604
3605       DCHECK(!((uintptr_t)pc_ & 0x7));  // Check 64-bit alignment.
3606
3607       Instr instr = instr_at(rinfo.pc());
3608       // Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0.
3609       DCHECK((IsVldrDPcImmediateOffset(instr) &&
3610               GetVldrDRegisterImmediateOffset(instr) == 0));
3611
3612       int delta = pc_ - rinfo.pc() - kPcLoadDelta;
3613       DCHECK(is_uint10(delta));
3614
3615       bool found = false;
3616       uint64_t value = rinfo.raw_data64();
3617       for (int j = 0; j < i; j++) {
3618         RelocInfo& rinfo2 = pending_64_bit_reloc_info_[j];
3619         if (value == rinfo2.raw_data64()) {
3620           found = true;
3621           DCHECK(rinfo2.rmode() == RelocInfo::NONE64);
3622           Instr instr2 = instr_at(rinfo2.pc());
3623           DCHECK(IsVldrDPcImmediateOffset(instr2));
3624           delta = GetVldrDRegisterImmediateOffset(instr2);
3625           delta += rinfo2.pc() - rinfo.pc();
3626           break;
3627         }
3628       }
3629
3630       instr_at_put(rinfo.pc(), SetVldrDRegisterImmediateOffset(instr, delta));
3631
3632       if (!found) {
3633         uint64_t uint_data = rinfo.raw_data64();
3634         emit(uint_data & 0xFFFFFFFF);
3635         emit(uint_data >> 32);
3636       }
3637     }
3638
3639     // Emit 32-bit constant pool entries.
3640     for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
3641       RelocInfo& rinfo = pending_32_bit_reloc_info_[i];
3642       DCHECK(rinfo.rmode() != RelocInfo::COMMENT &&
3643              rinfo.rmode() != RelocInfo::POSITION &&
3644              rinfo.rmode() != RelocInfo::STATEMENT_POSITION &&
3645              rinfo.rmode() != RelocInfo::CONST_POOL &&
3646              rinfo.rmode() != RelocInfo::NONE64);
3647
3648       Instr instr = instr_at(rinfo.pc());
3649
3650       // 64-bit loads shouldn't get here.
3651       DCHECK(!IsVldrDPcImmediateOffset(instr));
3652
3653       if (IsLdrPcImmediateOffset(instr) &&
3654           GetLdrRegisterImmediateOffset(instr) == 0) {
3655         int delta = pc_ - rinfo.pc() - kPcLoadDelta;
3656         DCHECK(is_uint12(delta));
3657         // 0 is the smallest delta:
3658         //   ldr rd, [pc, #0]
3659         //   constant pool marker
3660         //   data
3661
3662         bool found = false;
3663         if (!serializer_enabled() && rinfo.rmode() >= RelocInfo::CELL) {
3664           for (int j = 0; j < i; j++) {
3665             RelocInfo& rinfo2 = pending_32_bit_reloc_info_[j];
3666
3667             if ((rinfo2.data() == rinfo.data()) &&
3668                 (rinfo2.rmode() == rinfo.rmode())) {
3669               Instr instr2 = instr_at(rinfo2.pc());
3670               if (IsLdrPcImmediateOffset(instr2)) {
3671                 delta = GetLdrRegisterImmediateOffset(instr2);
3672                 delta += rinfo2.pc() - rinfo.pc();
3673                 found = true;
3674                 break;
3675               }
3676             }
3677           }
3678         }
3679
3680         instr_at_put(rinfo.pc(), SetLdrRegisterImmediateOffset(instr, delta));
3681
3682         if (!found) {
3683           emit(rinfo.data());
3684         }
3685       } else {
3686         DCHECK(IsMovW(instr));
3687       }
3688     }
3689
3690     num_pending_32_bit_reloc_info_ = 0;
3691     num_pending_64_bit_reloc_info_ = 0;
3692     first_const_pool_32_use_ = -1;
3693     first_const_pool_64_use_ = -1;
3694
3695     RecordComment("]");
3696
3697     if (after_pool.is_linked()) {
3698       bind(&after_pool);
3699     }
3700   }
3701
3702   // Since a constant pool was just emitted, move the check offset forward by
3703   // the standard interval.
3704   next_buffer_check_ = pc_offset() + kCheckPoolInterval;
3705 }
3706
3707
3708 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
3709   if (!FLAG_enable_ool_constant_pool) {
3710     return isolate->factory()->empty_constant_pool_array();
3711   }
3712   return constant_pool_builder_.New(isolate);
3713 }
3714
3715
3716 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
3717   constant_pool_builder_.Populate(this, constant_pool);
3718 }
3719
3720
3721 ConstantPoolBuilder::ConstantPoolBuilder()
3722     : entries_(), current_section_(ConstantPoolArray::SMALL_SECTION) {}
3723
3724
3725 bool ConstantPoolBuilder::IsEmpty() {
3726   return entries_.size() == 0;
3727 }
3728
3729
3730 ConstantPoolArray::Type ConstantPoolBuilder::GetConstantPoolType(
3731     RelocInfo::Mode rmode) {
3732   if (rmode == RelocInfo::NONE64) {
3733     return ConstantPoolArray::INT64;
3734   } else if (!RelocInfo::IsGCRelocMode(rmode)) {
3735     return ConstantPoolArray::INT32;
3736   } else if (RelocInfo::IsCodeTarget(rmode)) {
3737     return ConstantPoolArray::CODE_PTR;
3738   } else {
3739     DCHECK(RelocInfo::IsGCRelocMode(rmode) && !RelocInfo::IsCodeTarget(rmode));
3740     return ConstantPoolArray::HEAP_PTR;
3741   }
3742 }
3743
3744
3745 ConstantPoolArray::LayoutSection ConstantPoolBuilder::AddEntry(
3746     Assembler* assm, const RelocInfo& rinfo) {
3747   RelocInfo::Mode rmode = rinfo.rmode();
3748   DCHECK(rmode != RelocInfo::COMMENT &&
3749          rmode != RelocInfo::POSITION &&
3750          rmode != RelocInfo::STATEMENT_POSITION &&
3751          rmode != RelocInfo::CONST_POOL);
3752
3753   // Try to merge entries which won't be patched.
3754   int merged_index = -1;
3755   ConstantPoolArray::LayoutSection entry_section = current_section_;
3756   if (RelocInfo::IsNone(rmode) ||
3757       (!assm->serializer_enabled() && (rmode >= RelocInfo::CELL))) {
3758     size_t i;
3759     std::vector<ConstantPoolEntry>::const_iterator it;
3760     for (it = entries_.begin(), i = 0; it != entries_.end(); it++, i++) {
3761       if (RelocInfo::IsEqual(rinfo, it->rinfo_)) {
3762         // Merge with found entry.
3763         merged_index = i;
3764         entry_section = entries_[i].section_;
3765         break;
3766       }
3767     }
3768   }
3769   DCHECK(entry_section <= current_section_);
3770   entries_.push_back(ConstantPoolEntry(rinfo, entry_section, merged_index));
3771
3772   if (merged_index == -1) {
3773     // Not merged, so update the appropriate count.
3774     number_of_entries_[entry_section].increment(GetConstantPoolType(rmode));
3775   }
3776
3777   // Check if we still have room for another entry in the small section
3778   // given Arm's ldr and vldr immediate offset range.
3779   if (current_section_ == ConstantPoolArray::SMALL_SECTION &&
3780       !(is_uint12(ConstantPoolArray::SizeFor(*small_entries())) &&
3781         is_uint10(ConstantPoolArray::MaxInt64Offset(
3782             small_entries()->count_of(ConstantPoolArray::INT64))))) {
3783     current_section_ = ConstantPoolArray::EXTENDED_SECTION;
3784   }
3785   return entry_section;
3786 }
3787
3788
3789 void ConstantPoolBuilder::Relocate(int pc_delta) {
3790   for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
3791        entry != entries_.end(); entry++) {
3792     DCHECK(entry->rinfo_.rmode() != RelocInfo::JS_RETURN);
3793     entry->rinfo_.set_pc(entry->rinfo_.pc() + pc_delta);
3794   }
3795 }
3796
3797
3798 Handle<ConstantPoolArray> ConstantPoolBuilder::New(Isolate* isolate) {
3799   if (IsEmpty()) {
3800     return isolate->factory()->empty_constant_pool_array();
3801   } else if (extended_entries()->is_empty()) {
3802     return isolate->factory()->NewConstantPoolArray(*small_entries());
3803   } else {
3804     DCHECK(current_section_ == ConstantPoolArray::EXTENDED_SECTION);
3805     return isolate->factory()->NewExtendedConstantPoolArray(
3806         *small_entries(), *extended_entries());
3807   }
3808 }
3809
3810
3811 void ConstantPoolBuilder::Populate(Assembler* assm,
3812                                    ConstantPoolArray* constant_pool) {
3813   DCHECK_EQ(extended_entries()->is_empty(),
3814             !constant_pool->is_extended_layout());
3815   DCHECK(small_entries()->equals(ConstantPoolArray::NumberOfEntries(
3816       constant_pool, ConstantPoolArray::SMALL_SECTION)));
3817   if (constant_pool->is_extended_layout()) {
3818     DCHECK(extended_entries()->equals(ConstantPoolArray::NumberOfEntries(
3819         constant_pool, ConstantPoolArray::EXTENDED_SECTION)));
3820   }
3821
3822   // Set up initial offsets.
3823   int offsets[ConstantPoolArray::NUMBER_OF_LAYOUT_SECTIONS]
3824              [ConstantPoolArray::NUMBER_OF_TYPES];
3825   for (int section = 0; section <= constant_pool->final_section(); section++) {
3826     int section_start = (section == ConstantPoolArray::EXTENDED_SECTION)
3827                             ? small_entries()->total_count()
3828                             : 0;
3829     for (int i = 0; i < ConstantPoolArray::NUMBER_OF_TYPES; i++) {
3830       ConstantPoolArray::Type type = static_cast<ConstantPoolArray::Type>(i);
3831       if (number_of_entries_[section].count_of(type) != 0) {
3832         offsets[section][type] = constant_pool->OffsetOfElementAt(
3833             number_of_entries_[section].base_of(type) + section_start);
3834       }
3835     }
3836   }
3837
3838   for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
3839        entry != entries_.end(); entry++) {
3840     RelocInfo rinfo = entry->rinfo_;
3841     RelocInfo::Mode rmode = entry->rinfo_.rmode();
3842     ConstantPoolArray::Type type = GetConstantPoolType(rmode);
3843
3844     // Update constant pool if necessary and get the entry's offset.
3845     int offset;
3846     if (entry->merged_index_ == -1) {
3847       offset = offsets[entry->section_][type];
3848       offsets[entry->section_][type] += ConstantPoolArray::entry_size(type);
3849       if (type == ConstantPoolArray::INT64) {
3850         constant_pool->set_at_offset(offset, rinfo.data64());
3851       } else if (type == ConstantPoolArray::INT32) {
3852         constant_pool->set_at_offset(offset,
3853                                      static_cast<int32_t>(rinfo.data()));
3854       } else if (type == ConstantPoolArray::CODE_PTR) {
3855         constant_pool->set_at_offset(offset,
3856                                      reinterpret_cast<Address>(rinfo.data()));
3857       } else {
3858         DCHECK(type == ConstantPoolArray::HEAP_PTR);
3859         constant_pool->set_at_offset(offset,
3860                                      reinterpret_cast<Object*>(rinfo.data()));
3861       }
3862       offset -= kHeapObjectTag;
3863       entry->merged_index_ = offset;  // Stash offset for merged entries.
3864     } else {
3865       DCHECK(entry->merged_index_ < (entry - entries_.begin()));
3866       offset = entries_[entry->merged_index_].merged_index_;
3867     }
3868
3869     // Patch vldr/ldr instruction with correct offset.
3870     Instr instr = assm->instr_at(rinfo.pc());
3871     if (entry->section_ == ConstantPoolArray::EXTENDED_SECTION) {
3872       if (CpuFeatures::IsSupported(ARMv7)) {
3873         // Instructions to patch must be 'movw rd, [#0]' and 'movt rd, [#0].
3874         Instr next_instr = assm->instr_at(rinfo.pc() + Assembler::kInstrSize);
3875         DCHECK((Assembler::IsMovW(instr) &&
3876                 Instruction::ImmedMovwMovtValue(instr) == 0));
3877         DCHECK((Assembler::IsMovT(next_instr) &&
3878                 Instruction::ImmedMovwMovtValue(next_instr) == 0));
3879         assm->instr_at_put(
3880             rinfo.pc(), Assembler::PatchMovwImmediate(instr, offset & 0xffff));
3881         assm->instr_at_put(
3882             rinfo.pc() + Assembler::kInstrSize,
3883             Assembler::PatchMovwImmediate(next_instr, offset >> 16));
3884       } else {
3885         // Instructions to patch must be 'mov rd, [#0]' and 'orr rd, rd, [#0].
3886         Instr instr_2 = assm->instr_at(rinfo.pc() + Assembler::kInstrSize);
3887         Instr instr_3 = assm->instr_at(rinfo.pc() + 2 * Assembler::kInstrSize);
3888         Instr instr_4 = assm->instr_at(rinfo.pc() + 3 * Assembler::kInstrSize);
3889         DCHECK((Assembler::IsMovImmed(instr) &&
3890                 Instruction::Immed8Value(instr) == 0));
3891         DCHECK((Assembler::IsOrrImmed(instr_2) &&
3892                 Instruction::Immed8Value(instr_2) == 0) &&
3893                Assembler::GetRn(instr_2).is(Assembler::GetRd(instr_2)));
3894         DCHECK((Assembler::IsOrrImmed(instr_3) &&
3895                 Instruction::Immed8Value(instr_3) == 0) &&
3896                Assembler::GetRn(instr_3).is(Assembler::GetRd(instr_3)));
3897         DCHECK((Assembler::IsOrrImmed(instr_4) &&
3898                 Instruction::Immed8Value(instr_4) == 0) &&
3899                Assembler::GetRn(instr_4).is(Assembler::GetRd(instr_4)));
3900         assm->instr_at_put(
3901             rinfo.pc(), Assembler::PatchShiftImm(instr, (offset & kImm8Mask)));
3902         assm->instr_at_put(
3903             rinfo.pc() + Assembler::kInstrSize,
3904             Assembler::PatchShiftImm(instr_2, (offset & (kImm8Mask << 8))));
3905         assm->instr_at_put(
3906             rinfo.pc() + 2 * Assembler::kInstrSize,
3907             Assembler::PatchShiftImm(instr_3, (offset & (kImm8Mask << 16))));
3908         assm->instr_at_put(
3909             rinfo.pc() + 3 * Assembler::kInstrSize,
3910             Assembler::PatchShiftImm(instr_4, (offset & (kImm8Mask << 24))));
3911       }
3912     } else if (type == ConstantPoolArray::INT64) {
3913       // Instruction to patch must be 'vldr rd, [pp, #0]'.
3914       DCHECK((Assembler::IsVldrDPpImmediateOffset(instr) &&
3915               Assembler::GetVldrDRegisterImmediateOffset(instr) == 0));
3916       DCHECK(is_uint10(offset));
3917       assm->instr_at_put(rinfo.pc(), Assembler::SetVldrDRegisterImmediateOffset(
3918                                          instr, offset));
3919     } else {
3920       // Instruction to patch must be 'ldr rd, [pp, #0]'.
3921       DCHECK((Assembler::IsLdrPpImmediateOffset(instr) &&
3922               Assembler::GetLdrRegisterImmediateOffset(instr) == 0));
3923       DCHECK(is_uint12(offset));
3924       assm->instr_at_put(
3925           rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset));
3926     }
3927   }
3928 }
3929
3930
3931 } }  // namespace v8::internal
3932
3933 #endif  // V8_TARGET_ARCH_ARM