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