Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / v8 / src / arm / assembler-arm.cc
index 68738a7..1a2f5d6 100644 (file)
@@ -39,6 +39,7 @@
 #if V8_TARGET_ARCH_ARM
 
 #include "src/arm/assembler-arm-inl.h"
+#include "src/base/cpu.h"
 #include "src/macro-assembler.h"
 #include "src/serialize.h"
 
@@ -93,7 +94,7 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
 
 #else  // __arm__
   // Probe for additional features at runtime.
-  CPU cpu;
+  base::CPU cpu;
   if (FLAG_enable_vfp3 && cpu.has_vfp3()) {
     // This implementation also sets the VFP flags if runtime
     // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI
@@ -109,76 +110,74 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
     if (FLAG_enable_armv7) supported_ |= 1u << ARMv7;
     if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES;
     // Use movw/movt for QUALCOMM ARMv7 cores.
-    if (FLAG_enable_movw_movt && cpu.implementer() == CPU::QUALCOMM) {
+    if (FLAG_enable_movw_movt && cpu.implementer() == base::CPU::QUALCOMM) {
       supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
     }
   }
 
   // ARM Cortex-A9 and Cortex-A5 have 32 byte cachelines.
-  if (cpu.implementer() == CPU::ARM && (cpu.part() == CPU::ARM_CORTEX_A5 ||
-                                        cpu.part() == CPU::ARM_CORTEX_A9)) {
+  if (cpu.implementer() == base::CPU::ARM &&
+      (cpu.part() == base::CPU::ARM_CORTEX_A5 ||
+       cpu.part() == base::CPU::ARM_CORTEX_A9)) {
     cache_line_size_ = 32;
   }
 
   if (FLAG_enable_32dregs && cpu.has_vfp3_d32()) supported_ |= 1u << VFP32DREGS;
 #endif
 
-  ASSERT(!IsSupported(VFP3) || IsSupported(ARMv7));
+  DCHECK(!IsSupported(VFP3) || IsSupported(ARMv7));
 }
 
 
 void CpuFeatures::PrintTarget() {
   const char* arm_arch = NULL;
-  const char* arm_test = "";
+  const char* arm_target_type = "";
+  const char* arm_no_probe = "";
   const char* arm_fpu = "";
   const char* arm_thumb = "";
   const char* arm_float_abi = NULL;
 
+#if !defined __arm__
+  arm_target_type = " simulator";
+#endif
+
+#if defined ARM_TEST_NO_FEATURE_PROBE
+  arm_no_probe = " noprobe";
+#endif
+
 #if defined CAN_USE_ARMV7_INSTRUCTIONS
   arm_arch = "arm v7";
 #else
   arm_arch = "arm v6";
 #endif
 
-#ifdef __arm__
-
-# ifdef ARM_TEST
-  arm_test = " test";
-# endif
-# if defined __ARM_NEON__
+#if defined CAN_USE_NEON
   arm_fpu = " neon";
-# elif defined CAN_USE_VFP3_INSTRUCTIONS
-  arm_fpu = " vfp3";
-# else
-  arm_fpu = " vfp2";
-# endif
-# if (defined __thumb__) || (defined __thumb2__)
-  arm_thumb = " thumb";
-# endif
-  arm_float_abi = OS::ArmUsingHardFloat() ? "hard" : "softfp";
-
-#else  // __arm__
-
-  arm_test = " simulator";
-# if defined CAN_USE_VFP3_INSTRUCTIONS
+#elif defined CAN_USE_VFP3_INSTRUCTIONS
 #  if defined CAN_USE_VFP32DREGS
   arm_fpu = " vfp3";
 #  else
   arm_fpu = " vfp3-d16";
 #  endif
-# else
+#else
   arm_fpu = " vfp2";
-# endif
-# if USE_EABI_HARDFLOAT == 1
+#endif
+
+#ifdef __arm__
+  arm_float_abi = base::OS::ArmUsingHardFloat() ? "hard" : "softfp";
+#elif USE_EABI_HARDFLOAT
   arm_float_abi = "hard";
-# else
+#else
   arm_float_abi = "softfp";
-# endif
+#endif
 
-#endif  // __arm__
+#if defined __arm__ && (defined __thumb__) || (defined __thumb2__)
+  arm_thumb = " thumb";
+#endif
 
-  printf("target%s %s%s%s %s\n",
-         arm_test, arm_arch, arm_fpu, arm_thumb, arm_float_abi);
+  printf("target%s%s %s%s%s %s\n",
+         arm_target_type, arm_no_probe, arm_arch, arm_fpu, arm_thumb,
+         arm_float_abi);
 }
 
 
@@ -194,7 +193,7 @@ void CpuFeatures::PrintFeatures() {
     CpuFeatures::IsSupported(UNALIGNED_ACCESSES),
     CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS));
 #ifdef __arm__
-  bool eabi_hardfloat = OS::ArmUsingHardFloat();
+  bool eabi_hardfloat = base::OS::ArmUsingHardFloat();
 #elif USE_EABI_HARDFLOAT
   bool eabi_hardfloat = true;
 #else
@@ -208,8 +207,8 @@ void CpuFeatures::PrintFeatures() {
 // Implementation of DwVfpRegister
 
 const char* DwVfpRegister::AllocationIndexToString(int index) {
-  ASSERT(index >= 0 && index < NumAllocatableRegisters());
-  ASSERT(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
+  DCHECK(index >= 0 && index < NumAllocatableRegisters());
+  DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
          kNumReservedRegisters - 1);
   if (index >= kDoubleRegZero.code()) index += kNumReservedRegisters;
   return VFPRegisters::Name(index, true);
@@ -232,11 +231,7 @@ bool RelocInfo::IsCodedSpecially() {
 
 
 bool RelocInfo::IsInConstantPool() {
-  if (FLAG_enable_ool_constant_pool) {
-    return Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc_));
-  } else {
-    return Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_));
-  }
+  return Assembler::is_constant_pool_load(pc_);
 }
 
 
@@ -249,7 +244,7 @@ void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
   }
 
   // Indicate that code has changed.
-  CPU::FlushICache(pc_, instruction_count * Assembler::kInstrSize);
+  CpuFeatures::FlushICache(pc_, instruction_count * Assembler::kInstrSize);
 }
 
 
@@ -271,7 +266,7 @@ Operand::Operand(Handle<Object> handle) {
   // Verify all Objects referred by code are NOT in new space.
   Object* obj = *handle;
   if (obj->IsHeapObject()) {
-    ASSERT(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
+    DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
     imm32_ = reinterpret_cast<intptr_t>(handle.location());
     rmode_ = RelocInfo::EMBEDDED_OBJECT;
   } else {
@@ -283,7 +278,7 @@ Operand::Operand(Handle<Object> handle) {
 
 
 Operand::Operand(Register rm, ShiftOp shift_op, int shift_imm) {
-  ASSERT(is_uint5(shift_imm));
+  DCHECK(is_uint5(shift_imm));
 
   rm_ = rm;
   rs_ = no_reg;
@@ -296,7 +291,7 @@ Operand::Operand(Register rm, ShiftOp shift_op, int shift_imm) {
     shift_op = LSL;
   } else if (shift_op == RRX) {
     // encoded as ROR with shift_imm == 0
-    ASSERT(shift_imm == 0);
+    DCHECK(shift_imm == 0);
     shift_op_ = ROR;
     shift_imm_ = 0;
   }
@@ -304,7 +299,7 @@ Operand::Operand(Register rm, ShiftOp shift_op, int shift_imm) {
 
 
 Operand::Operand(Register rm, ShiftOp shift_op, Register rs) {
-  ASSERT(shift_op != RRX);
+  DCHECK(shift_op != RRX);
   rm_ = rm;
   rs_ = no_reg;
   shift_op_ = shift_op;
@@ -331,7 +326,7 @@ MemOperand::MemOperand(Register rn, Register rm, AddrMode am) {
 
 MemOperand::MemOperand(Register rn, Register rm,
                        ShiftOp shift_op, int shift_imm, AddrMode am) {
-  ASSERT(is_uint5(shift_imm));
+  DCHECK(is_uint5(shift_imm));
   rn_ = rn;
   rm_ = rm;
   shift_op_ = shift_op;
@@ -341,7 +336,7 @@ MemOperand::MemOperand(Register rn, Register rm,
 
 
 NeonMemOperand::NeonMemOperand(Register rn, AddrMode am, int align) {
-  ASSERT((am == Offset) || (am == PostIndex));
+  DCHECK((am == Offset) || (am == PostIndex));
   rn_ = rn;
   rm_ = (am == Offset) ? pc : sp;
   SetAlignment(align);
@@ -403,10 +398,6 @@ NeonListOperand::NeonListOperand(DoubleRegister base, int registers_count) {
 // -----------------------------------------------------------------------------
 // Specific instructions, constants, and masks.
 
-// add(sp, sp, 4) instruction (aka Pop())
-const Instr kPopInstruction =
-    al | PostIndex | 4 | LeaveCC | I | kRegister_sp_Code * B16 |
-        kRegister_sp_Code * B12;
 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
 // register r is not encoded.
 const Instr kPushRegPattern =
@@ -415,14 +406,15 @@ const Instr kPushRegPattern =
 // register r is not encoded.
 const Instr kPopRegPattern =
     al | B26 | L | 4 | PostIndex | kRegister_sp_Code * B16;
-// mov lr, pc
-const Instr kMovLrPc = al | MOV | kRegister_pc_Code | kRegister_lr_Code * B12;
 // ldr rd, [pc, #offset]
-const Instr kLdrPCMask = 15 * B24 | 7 * B20 | 15 * B16;
-const Instr kLdrPCPattern = 5 * B24 | L | kRegister_pc_Code * B16;
+const Instr kLdrPCImmedMask = 15 * B24 | 7 * B20 | 15 * B16;
+const Instr kLdrPCImmedPattern = 5 * B24 | L | kRegister_pc_Code * B16;
 // ldr rd, [pp, #offset]
-const Instr kLdrPpMask = 15 * B24 | 7 * B20 | 15 * B16;
-const Instr kLdrPpPattern = 5 * B24 | L | kRegister_r8_Code * B16;
+const Instr kLdrPpImmedMask = 15 * B24 | 7 * B20 | 15 * B16;
+const Instr kLdrPpImmedPattern = 5 * B24 | L | kRegister_r8_Code * B16;
+// ldr rd, [pp, rn]
+const Instr kLdrPpRegMask = 15 * B24 | 7 * B20 | 15 * B16;
+const Instr kLdrPpRegPattern = 7 * B24 | L | kRegister_r8_Code * B16;
 // vldr dd, [pc, #offset]
 const Instr kVldrDPCMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8;
 const Instr kVldrDPCPattern = 13 * B24 | L | kRegister_pc_Code * B16 | 11 * B8;
@@ -440,8 +432,8 @@ const Instr kMovMvnPattern = 0xd * B21;
 const Instr kMovMvnFlip = B22;
 const Instr kMovLeaveCCMask = 0xdff * B16;
 const Instr kMovLeaveCCPattern = 0x1a0 * B16;
-const Instr kMovwMask = 0xff * B20;
 const Instr kMovwPattern = 0x30 * B20;
+const Instr kMovtPattern = 0x34 * B20;
 const Instr kMovwLeaveCCFlip = 0x5 * B21;
 const Instr kCmpCmnMask = 0xdd * B20 | 0xf * B12;
 const Instr kCmpCmnPattern = 0x15 * B20;
@@ -459,8 +451,6 @@ const Instr kLdrRegFpNegOffsetPattern =
 const Instr kStrRegFpNegOffsetPattern =
     al | B26 | NegOffset | kRegister_fp_Code * B16;
 const Instr kLdrStrInstrTypeMask = 0xffff0000;
-const Instr kLdrStrInstrArgumentMask = 0x0000ffff;
-const Instr kLdrStrOffsetMask = 0x00000fff;
 
 
 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
@@ -478,13 +468,12 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
   first_const_pool_64_use_ = -1;
   last_bound_pos_ = 0;
   constant_pool_available_ = !FLAG_enable_ool_constant_pool;
-  constant_pool_full_ = false;
   ClearRecordedAstId();
 }
 
 
 Assembler::~Assembler() {
-  ASSERT(const_pool_blocked_nesting_ == 0);
+  DCHECK(const_pool_blocked_nesting_ == 0);
 }
 
 
@@ -492,8 +481,8 @@ void Assembler::GetCode(CodeDesc* desc) {
   if (!FLAG_enable_ool_constant_pool) {
     // Emit constant pool if necessary.
     CheckConstPool(true, false);
-    ASSERT(num_pending_32_bit_reloc_info_ == 0);
-    ASSERT(num_pending_64_bit_reloc_info_ == 0);
+    DCHECK(num_pending_32_bit_reloc_info_ == 0);
+    DCHECK(num_pending_64_bit_reloc_info_ == 0);
   }
   // Set up code descriptor.
   desc->buffer = buffer_;
@@ -505,7 +494,7 @@ void Assembler::GetCode(CodeDesc* desc) {
 
 
 void Assembler::Align(int m) {
-  ASSERT(m >= 4 && IsPowerOf2(m));
+  DCHECK(m >= 4 && IsPowerOf2(m));
   while ((pc_offset() & (m - 1)) != 0) {
     nop();
   }
@@ -529,7 +518,7 @@ bool Assembler::IsBranch(Instr instr) {
 
 
 int Assembler::GetBranchOffset(Instr instr) {
-  ASSERT(IsBranch(instr));
+  DCHECK(IsBranch(instr));
   // Take the jump offset in the lower 24 bits, sign extend it and multiply it
   // with 4 to get the offset in bytes.
   return ((instr & kImm24Mask) << 8) >> 6;
@@ -547,7 +536,7 @@ bool Assembler::IsVldrDRegisterImmediate(Instr instr) {
 
 
 int Assembler::GetLdrRegisterImmediateOffset(Instr instr) {
-  ASSERT(IsLdrRegisterImmediate(instr));
+  DCHECK(IsLdrRegisterImmediate(instr));
   bool positive = (instr & B23) == B23;
   int offset = instr & kOff12Mask;  // Zero extended offset.
   return positive ? offset : -offset;
@@ -555,7 +544,7 @@ int Assembler::GetLdrRegisterImmediateOffset(Instr instr) {
 
 
 int Assembler::GetVldrDRegisterImmediateOffset(Instr instr) {
-  ASSERT(IsVldrDRegisterImmediate(instr));
+  DCHECK(IsVldrDRegisterImmediate(instr));
   bool positive = (instr & B23) == B23;
   int offset = instr & kOff8Mask;  // Zero extended offset.
   offset <<= 2;
@@ -564,10 +553,10 @@ int Assembler::GetVldrDRegisterImmediateOffset(Instr instr) {
 
 
 Instr Assembler::SetLdrRegisterImmediateOffset(Instr instr, int offset) {
-  ASSERT(IsLdrRegisterImmediate(instr));
+  DCHECK(IsLdrRegisterImmediate(instr));
   bool positive = offset >= 0;
   if (!positive) offset = -offset;
-  ASSERT(is_uint12(offset));
+  DCHECK(is_uint12(offset));
   // Set bit indicating whether the offset should be added.
   instr = (instr & ~B23) | (positive ? B23 : 0);
   // Set the actual offset.
@@ -576,11 +565,11 @@ Instr Assembler::SetLdrRegisterImmediateOffset(Instr instr, int offset) {
 
 
 Instr Assembler::SetVldrDRegisterImmediateOffset(Instr instr, int offset) {
-  ASSERT(IsVldrDRegisterImmediate(instr));
-  ASSERT((offset & ~3) == offset);  // Must be 64-bit aligned.
+  DCHECK(IsVldrDRegisterImmediate(instr));
+  DCHECK((offset & ~3) == offset);  // Must be 64-bit aligned.
   bool positive = offset >= 0;
   if (!positive) offset = -offset;
-  ASSERT(is_uint10(offset));
+  DCHECK(is_uint10(offset));
   // Set bit indicating whether the offset should be added.
   instr = (instr & ~B23) | (positive ? B23 : 0);
   // Set the actual offset. Its bottom 2 bits are zero.
@@ -594,10 +583,10 @@ bool Assembler::IsStrRegisterImmediate(Instr instr) {
 
 
 Instr Assembler::SetStrRegisterImmediateOffset(Instr instr, int offset) {
-  ASSERT(IsStrRegisterImmediate(instr));
+  DCHECK(IsStrRegisterImmediate(instr));
   bool positive = offset >= 0;
   if (!positive) offset = -offset;
-  ASSERT(is_uint12(offset));
+  DCHECK(is_uint12(offset));
   // Set bit indicating whether the offset should be added.
   instr = (instr & ~B23) | (positive ? B23 : 0);
   // Set the actual offset.
@@ -611,9 +600,9 @@ bool Assembler::IsAddRegisterImmediate(Instr instr) {
 
 
 Instr Assembler::SetAddRegisterImmediateOffset(Instr instr, int offset) {
-  ASSERT(IsAddRegisterImmediate(instr));
-  ASSERT(offset >= 0);
-  ASSERT(is_uint12(offset));
+  DCHECK(IsAddRegisterImmediate(instr));
+  DCHECK(offset >= 0);
+  DCHECK(is_uint12(offset));
   // Set the offset.
   return (instr & ~kOff12Mask) | offset;
 }
@@ -640,6 +629,24 @@ Register Assembler::GetRm(Instr instr) {
 }
 
 
+Instr Assembler::GetConsantPoolLoadPattern() {
+  if (FLAG_enable_ool_constant_pool) {
+    return kLdrPpImmedPattern;
+  } else {
+    return kLdrPCImmedPattern;
+  }
+}
+
+
+Instr Assembler::GetConsantPoolLoadMask() {
+  if (FLAG_enable_ool_constant_pool) {
+    return kLdrPpImmedMask;
+  } else {
+    return kLdrPCImmedMask;
+  }
+}
+
+
 bool Assembler::IsPush(Instr instr) {
   return ((instr & ~kRdMask) == kPushRegPattern);
 }
@@ -673,17 +680,27 @@ bool Assembler::IsLdrRegFpNegOffset(Instr instr) {
 bool Assembler::IsLdrPcImmediateOffset(Instr instr) {
   // Check the instruction is indeed a
   // ldr<cond> <Rd>, [pc +/- offset_12].
-  return (instr & kLdrPCMask) == kLdrPCPattern;
+  return (instr & kLdrPCImmedMask) == kLdrPCImmedPattern;
 }
 
 
 bool Assembler::IsLdrPpImmediateOffset(Instr instr) {
   // Check the instruction is indeed a
   // ldr<cond> <Rd>, [pp +/- offset_12].
-  return (instr & kLdrPpMask) == kLdrPpPattern;
+  return (instr & kLdrPpImmedMask) == kLdrPpImmedPattern;
 }
 
 
+bool Assembler::IsLdrPpRegOffset(Instr instr) {
+  // Check the instruction is indeed a
+  // ldr<cond> <Rd>, [pp, +/- <Rm>].
+  return (instr & kLdrPpRegMask) == kLdrPpRegPattern;
+}
+
+
+Instr Assembler::GetLdrPpRegOffsetPattern() { return kLdrPpRegPattern; }
+
+
 bool Assembler::IsVldrDPcImmediateOffset(Instr instr) {
   // Check the instruction is indeed a
   // vldr<cond> <Dd>, [pc +/- offset_10].
@@ -698,6 +715,20 @@ bool Assembler::IsVldrDPpImmediateOffset(Instr instr) {
 }
 
 
+bool Assembler::IsBlxReg(Instr instr) {
+  // Check the instruction is indeed a
+  // blxcc <Rm>
+  return (instr & kBlxRegMask) == kBlxRegPattern;
+}
+
+
+bool Assembler::IsBlxIp(Instr instr) {
+  // Check the instruction is indeed a
+  // blx ip
+  return instr == kBlxIp;
+}
+
+
 bool Assembler::IsTstImmediate(Instr instr) {
   return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask)) ==
       (I | TST | S);
@@ -717,13 +748,13 @@ bool Assembler::IsCmpImmediate(Instr instr) {
 
 
 Register Assembler::GetCmpImmediateRegister(Instr instr) {
-  ASSERT(IsCmpImmediate(instr));
+  DCHECK(IsCmpImmediate(instr));
   return GetRn(instr);
 }
 
 
 int Assembler::GetCmpImmediateRawImmediate(Instr instr) {
-  ASSERT(IsCmpImmediate(instr));
+  DCHECK(IsCmpImmediate(instr));
   return instr & kOff12Mask;
 }
 
@@ -752,7 +783,7 @@ int Assembler::target_at(int pos) {
     // Emitted link to a label, not part of a branch.
     return instr;
   }
-  ASSERT((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
+  DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
   int imm26 = ((instr & kImm24Mask) << 8) >> 6;
   if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
       ((instr & B24) != 0)) {
@@ -766,7 +797,7 @@ int Assembler::target_at(int pos) {
 void Assembler::target_at_put(int pos, int target_pos) {
   Instr instr = instr_at(pos);
   if (is_uint24(instr)) {
-    ASSERT(target_pos == pos || target_pos >= 0);
+    DCHECK(target_pos == pos || target_pos >= 0);
     // Emitted link to a label, not part of a branch.
     // Load the position of the label relative to the generated code object
     // pointer in a register.
@@ -783,9 +814,9 @@ void Assembler::target_at_put(int pos, int target_pos) {
     // We extract the destination register from the emitted nop instruction.
     Register dst = Register::from_code(
         Instruction::RmValue(instr_at(pos + kInstrSize)));
-    ASSERT(IsNop(instr_at(pos + kInstrSize), dst.code()));
+    DCHECK(IsNop(instr_at(pos + kInstrSize), dst.code()));
     uint32_t target24 = target_pos + (Code::kHeaderSize - kHeapObjectTag);
-    ASSERT(is_uint24(target24));
+    DCHECK(is_uint24(target24));
     if (is_uint8(target24)) {
       // If the target fits in a byte then only patch with a mov
       // instruction.
@@ -834,17 +865,17 @@ void Assembler::target_at_put(int pos, int target_pos) {
     return;
   }
   int imm26 = target_pos - (pos + kPcLoadDelta);
-  ASSERT((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
+  DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
   if (Instruction::ConditionField(instr) == kSpecialCondition) {
     // blx uses bit 24 to encode bit 2 of imm26
-    ASSERT((imm26 & 1) == 0);
+    DCHECK((imm26 & 1) == 0);
     instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24;
   } else {
-    ASSERT((imm26 & 3) == 0);
+    DCHECK((imm26 & 3) == 0);
     instr &= ~kImm24Mask;
   }
   int imm24 = imm26 >> 2;
-  ASSERT(is_int24(imm24));
+  DCHECK(is_int24(imm24));
   instr_at_put(pos, instr | (imm24 & kImm24Mask));
 }
 
@@ -863,7 +894,7 @@ void Assembler::print(Label* L) {
       if ((instr & ~kImm24Mask) == 0) {
         PrintF("value\n");
       } else {
-        ASSERT((instr & 7*B25) == 5*B25);  // b, bl, or blx
+        DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx
         Condition cond = Instruction::ConditionField(instr);
         const char* b;
         const char* c;
@@ -908,7 +939,7 @@ void Assembler::print(Label* L) {
 
 
 void Assembler::bind_to(Label* L, int pos) {
-  ASSERT(0 <= pos && pos <= pc_offset());  // must have a valid binding position
+  DCHECK(0 <= pos && pos <= pc_offset());  // must have a valid binding position
   while (L->is_linked()) {
     int fixup_pos = L->pos();
     next(L);  // call next before overwriting link with target at fixup_pos
@@ -924,20 +955,20 @@ void Assembler::bind_to(Label* L, int pos) {
 
 
 void Assembler::bind(Label* L) {
-  ASSERT(!L->is_bound());  // label can only be bound once
+  DCHECK(!L->is_bound());  // label can only be bound once
   bind_to(L, pc_offset());
 }
 
 
 void Assembler::next(Label* L) {
-  ASSERT(L->is_linked());
+  DCHECK(L->is_linked());
   int link = target_at(L->pos());
   if (link == L->pos()) {
     // Branch target points to the same instuction. This is the end of the link
     // chain.
     L->Unuse();
   } else {
-    ASSERT(link >= 0);
+    DCHECK(link >= 0);
     L->link_to(link);
   }
 }
@@ -971,7 +1002,7 @@ static bool fits_shifter(uint32_t imm32,
         if (CpuFeatures::IsSupported(ARMv7)) {
           if (imm32 < 0x10000) {
             *instr ^= kMovwLeaveCCFlip;
-            *instr |= EncodeMovwImmediate(imm32);
+            *instr |= Assembler::EncodeMovwImmediate(imm32);
             *rotate_imm = *immed_8 = 0;  // Not used for movw.
             return true;
           }
@@ -1020,10 +1051,10 @@ bool Operand::must_output_reloc_info(const Assembler* assembler) const {
 
 static bool use_mov_immediate_load(const Operand& x,
                                    const Assembler* assembler) {
-  if (assembler != NULL && !assembler->can_use_constant_pool()) {
+  if (assembler != NULL && !assembler->is_constant_pool_available()) {
     // If there is no constant pool available, we must use an mov immediate.
     // TODO(rmcilroy): enable ARMv6 support.
-    ASSERT(CpuFeatures::IsSupported(ARMv7));
+    DCHECK(CpuFeatures::IsSupported(ARMv7));
     return true;
   } else if (CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
              (assembler == NULL || !assembler->predictable_code_size())) {
@@ -1039,28 +1070,35 @@ static bool use_mov_immediate_load(const Operand& x,
 }
 
 
-bool Operand::is_single_instruction(const Assembler* assembler,
-                                    Instr instr) const {
-  if (rm_.is_valid()) return true;
+int Operand::instructions_required(const Assembler* assembler,
+                                   Instr instr) const {
+  if (rm_.is_valid()) return 1;
   uint32_t dummy1, dummy2;
   if (must_output_reloc_info(assembler) ||
       !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
     // The immediate operand cannot be encoded as a shifter operand, or use of
-    // constant pool is required. For a mov instruction not setting the
-    // condition code additional instruction conventions can be used.
-    if ((instr & ~kCondMask) == 13*B21) {  // mov, S not set
-      return !use_mov_immediate_load(*this, assembler);
+    // constant pool is required.  First account for the instructions required
+    // for the constant pool or immediate load
+    int instructions;
+    if (use_mov_immediate_load(*this, assembler)) {
+      instructions = 2;  // A movw, movt immediate load.
+    } else if (assembler != NULL && assembler->use_extended_constant_pool()) {
+      instructions = 3;  // An extended constant pool load.
     } else {
-      // If this is not a mov or mvn instruction there will always an additional
-      // instructions - either mov or ldr. The mov might actually be two
-      // instructions mov or movw followed by movt so including the actual
-      // instruction two or three instructions will be generated.
-      return false;
+      instructions = 1;  // A small constant pool load.
+    }
+
+    if ((instr & ~kCondMask) != 13 * B21) {  // mov, S not set
+      // For a mov or mvn instruction which doesn't set the condition
+      // code, the constant pool or immediate load is enough, otherwise we need
+      // to account for the actual instruction being requested.
+      instructions += 1;
     }
+    return instructions;
   } else {
     // No use of constant pool and the immediate operand can be encoded as a
     // shifter operand.
-    return true;
+    return 1;
   }
 }
 
@@ -1076,22 +1114,32 @@ void Assembler::move_32_bit_immediate(Register rd,
   if (use_mov_immediate_load(x, this)) {
     Register target = rd.code() == pc.code() ? ip : rd;
     // TODO(rmcilroy): add ARMv6 support for immediate loads.
-    ASSERT(CpuFeatures::IsSupported(ARMv7));
+    DCHECK(CpuFeatures::IsSupported(ARMv7));
     if (!FLAG_enable_ool_constant_pool &&
         x.must_output_reloc_info(this)) {
       // Make sure the movw/movt doesn't get separated.
       BlockConstPoolFor(2);
     }
-    emit(cond | 0x30*B20 | target.code()*B12 |
-         EncodeMovwImmediate(x.imm32_ & 0xffff));
+    movw(target, static_cast<uint32_t>(x.imm32_ & 0xffff), cond);
     movt(target, static_cast<uint32_t>(x.imm32_) >> 16, cond);
     if (target.code() != rd.code()) {
       mov(rd, target, LeaveCC, cond);
     }
   } else {
-    ASSERT(can_use_constant_pool());
-    ConstantPoolAddEntry(rinfo);
-    ldr(rd, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0), cond);
+    DCHECK(is_constant_pool_available());
+    ConstantPoolArray::LayoutSection section = ConstantPoolAddEntry(rinfo);
+    if (section == ConstantPoolArray::EXTENDED_SECTION) {
+      DCHECK(FLAG_enable_ool_constant_pool);
+      Register target = rd.code() == pc.code() ? ip : rd;
+      // Emit instructions to load constant pool offset.
+      movw(target, 0, cond);
+      movt(target, 0, cond);
+      // Load from constant pool at offset.
+      ldr(rd, MemOperand(pp, target), cond);
+    } else {
+      DCHECK(section == ConstantPoolArray::SMALL_SECTION);
+      ldr(rd, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0), cond);
+    }
   }
 }
 
@@ -1101,7 +1149,7 @@ void Assembler::addrmod1(Instr instr,
                          Register rd,
                          const Operand& x) {
   CheckBuffer();
-  ASSERT((instr & ~(kCondMask | kOpCodeMask | S)) == 0);
+  DCHECK((instr & ~(kCondMask | kOpCodeMask | S)) == 0);
   if (!x.rm_.is_valid()) {
     // Immediate.
     uint32_t rotate_imm;
@@ -1128,7 +1176,7 @@ void Assembler::addrmod1(Instr instr,
     instr |= x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
   } else {
     // Register shift.
-    ASSERT(!rn.is(pc) && !rd.is(pc) && !x.rm_.is(pc) && !x.rs_.is(pc));
+    DCHECK(!rn.is(pc) && !rd.is(pc) && !x.rm_.is(pc) && !x.rs_.is(pc));
     instr |= x.rs_.code()*B8 | x.shift_op_ | B4 | x.rm_.code();
   }
   emit(instr | rn.code()*B16 | rd.code()*B12);
@@ -1140,7 +1188,7 @@ void Assembler::addrmod1(Instr instr,
 
 
 void Assembler::addrmod2(Instr instr, Register rd, const MemOperand& x) {
-  ASSERT((instr & ~(kCondMask | B | L)) == B26);
+  DCHECK((instr & ~(kCondMask | B | L)) == B26);
   int am = x.am_;
   if (!x.rm_.is_valid()) {
     // Immediate offset.
@@ -1152,28 +1200,28 @@ void Assembler::addrmod2(Instr instr, Register rd, const MemOperand& x) {
     if (!is_uint12(offset_12)) {
       // Immediate offset cannot be encoded, load it first to register ip
       // rn (and rd in a load) should never be ip, or will be trashed.
-      ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
+      DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
       mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
       addrmod2(instr, rd, MemOperand(x.rn_, ip, x.am_));
       return;
     }
-    ASSERT(offset_12 >= 0);  // no masking needed
+    DCHECK(offset_12 >= 0);  // no masking needed
     instr |= offset_12;
   } else {
     // Register offset (shift_imm_ and shift_op_ are 0) or scaled
     // register offset the constructors make sure than both shift_imm_
     // and shift_op_ are initialized.
-    ASSERT(!x.rm_.is(pc));
+    DCHECK(!x.rm_.is(pc));
     instr |= B25 | x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
   }
-  ASSERT((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
+  DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
   emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
 }
 
 
 void Assembler::addrmod3(Instr instr, Register rd, const MemOperand& x) {
-  ASSERT((instr & ~(kCondMask | L | S6 | H)) == (B4 | B7));
-  ASSERT(x.rn_.is_valid());
+  DCHECK((instr & ~(kCondMask | L | S6 | H)) == (B4 | B7));
+  DCHECK(x.rn_.is_valid());
   int am = x.am_;
   if (!x.rm_.is_valid()) {
     // Immediate offset.
@@ -1185,60 +1233,60 @@ void Assembler::addrmod3(Instr instr, Register rd, const MemOperand& x) {
     if (!is_uint8(offset_8)) {
       // Immediate offset cannot be encoded, load it first to register ip
       // rn (and rd in a load) should never be ip, or will be trashed.
-      ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
+      DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
       mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
       addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
       return;
     }
-    ASSERT(offset_8 >= 0);  // no masking needed
+    DCHECK(offset_8 >= 0);  // no masking needed
     instr |= B | (offset_8 >> 4)*B8 | (offset_8 & 0xf);
   } else if (x.shift_imm_ != 0) {
     // Scaled register offset not supported, load index first
     // rn (and rd in a load) should never be ip, or will be trashed.
-    ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
+    DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
     mov(ip, Operand(x.rm_, x.shift_op_, x.shift_imm_), LeaveCC,
         Instruction::ConditionField(instr));
     addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
     return;
   } else {
     // Register offset.
-    ASSERT((am & (P|W)) == P || !x.rm_.is(pc));  // no pc index with writeback
+    DCHECK((am & (P|W)) == P || !x.rm_.is(pc));  // no pc index with writeback
     instr |= x.rm_.code();
   }
-  ASSERT((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
+  DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
   emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
 }
 
 
 void Assembler::addrmod4(Instr instr, Register rn, RegList rl) {
-  ASSERT((instr & ~(kCondMask | P | U | W | L)) == B27);
-  ASSERT(rl != 0);
-  ASSERT(!rn.is(pc));
+  DCHECK((instr & ~(kCondMask | P | U | W | L)) == B27);
+  DCHECK(rl != 0);
+  DCHECK(!rn.is(pc));
   emit(instr | rn.code()*B16 | rl);
 }
 
 
 void Assembler::addrmod5(Instr instr, CRegister crd, const MemOperand& x) {
   // Unindexed addressing is not encoded by this function.
-  ASSERT_EQ((B27 | B26),
+  DCHECK_EQ((B27 | B26),
             (instr & ~(kCondMask | kCoprocessorMask | P | U | N | W | L)));
-  ASSERT(x.rn_.is_valid() && !x.rm_.is_valid());
+  DCHECK(x.rn_.is_valid() && !x.rm_.is_valid());
   int am = x.am_;
   int offset_8 = x.offset_;
-  ASSERT((offset_8 & 3) == 0);  // offset must be an aligned word offset
+  DCHECK((offset_8 & 3) == 0);  // offset must be an aligned word offset
   offset_8 >>= 2;
   if (offset_8 < 0) {
     offset_8 = -offset_8;
     am ^= U;
   }
-  ASSERT(is_uint8(offset_8));  // unsigned word offset must fit in a byte
-  ASSERT((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
+  DCHECK(is_uint8(offset_8));  // unsigned word offset must fit in a byte
+  DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
 
   // Post-indexed addressing requires W == 1; different than in addrmod2/3.
   if ((am & P) == 0)
     am |= W;
 
-  ASSERT(offset_8 >= 0);  // no masking needed
+  DCHECK(offset_8 >= 0);  // no masking needed
   emit(instr | am | x.rn_.code()*B16 | crd.code()*B12 | offset_8);
 }
 
@@ -1267,9 +1315,9 @@ int Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
 
 // Branch instructions.
 void Assembler::b(int branch_offset, Condition cond) {
-  ASSERT((branch_offset & 3) == 0);
+  DCHECK((branch_offset & 3) == 0);
   int imm24 = branch_offset >> 2;
-  ASSERT(is_int24(imm24));
+  DCHECK(is_int24(imm24));
   emit(cond | B27 | B25 | (imm24 & kImm24Mask));
 
   if (cond == al) {
@@ -1281,33 +1329,33 @@ void Assembler::b(int branch_offset, Condition cond) {
 
 void Assembler::bl(int branch_offset, Condition cond) {
   positions_recorder()->WriteRecordedPositions();
-  ASSERT((branch_offset & 3) == 0);
+  DCHECK((branch_offset & 3) == 0);
   int imm24 = branch_offset >> 2;
-  ASSERT(is_int24(imm24));
+  DCHECK(is_int24(imm24));
   emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask));
 }
 
 
 void Assembler::blx(int branch_offset) {  // v5 and above
   positions_recorder()->WriteRecordedPositions();
-  ASSERT((branch_offset & 1) == 0);
+  DCHECK((branch_offset & 1) == 0);
   int h = ((branch_offset & 2) >> 1)*B24;
   int imm24 = branch_offset >> 2;
-  ASSERT(is_int24(imm24));
+  DCHECK(is_int24(imm24));
   emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask));
 }
 
 
 void Assembler::blx(Register target, Condition cond) {  // v5 and above
   positions_recorder()->WriteRecordedPositions();
-  ASSERT(!target.is(pc));
+  DCHECK(!target.is(pc));
   emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | target.code());
 }
 
 
 void Assembler::bx(Register target, Condition cond) {  // v5 and above, plus v4t
   positions_recorder()->WriteRecordedPositions();
-  ASSERT(!target.is(pc));  // use of pc is actually allowed, but discouraged
+  DCHECK(!target.is(pc));  // use of pc is actually allowed, but discouraged
   emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BX | target.code());
 }
 
@@ -1379,7 +1427,7 @@ void Assembler::cmp(Register src1, const Operand& src2, Condition cond) {
 
 void Assembler::cmp_raw_immediate(
     Register src, int raw_immediate, Condition cond) {
-  ASSERT(is_uint12(raw_immediate));
+  DCHECK(is_uint12(raw_immediate));
   emit(cond | I | CMP | S | src.code() << 16 | raw_immediate);
 }
 
@@ -1402,7 +1450,7 @@ void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
   // Don't allow nop instructions in the form mov rn, rn to be generated using
   // the mov instruction. They must be generated using nop(int/NopMarkerTypes)
   // or MarkCode(int/NopMarkerTypes) pseudo instructions.
-  ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
+  DCHECK(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
   addrmod1(cond | MOV | s, r0, dst, src);
 }
 
@@ -1435,7 +1483,7 @@ void Assembler::mov_label_offset(Register dst, Label* label) {
     //
     // When the label gets bound: target_at extracts the link and target_at_put
     // patches the instructions.
-    ASSERT(is_uint24(link));
+    DCHECK(is_uint24(link));
     BlockConstPoolScope block_const_pool(this);
     emit(link);
     nop(dst.code());
@@ -1447,15 +1495,13 @@ void Assembler::mov_label_offset(Register dst, Label* label) {
 
 
 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) {
-  ASSERT(immediate < 0x10000);
-  // May use movw if supported, but on unsupported platforms will try to use
-  // equivalent rotated immed_8 value and other tricks before falling back to a
-  // constant pool load.
-  mov(reg, Operand(immediate), LeaveCC, cond);
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  emit(cond | 0x30*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate));
 }
 
 
 void Assembler::movt(Register reg, uint32_t immediate, Condition cond) {
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
   emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate));
 }
 
@@ -1474,7 +1520,7 @@ void Assembler::mvn(Register dst, const Operand& src, SBit s, Condition cond) {
 // Multiply instructions.
 void Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
                     SBit s, Condition cond) {
-  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
   emit(cond | A | s | dst.code()*B16 | srcA.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1482,8 +1528,8 @@ void Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
 
 void Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
                     Condition cond) {
-  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
-  ASSERT(IsEnabled(MLS));
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
+  DCHECK(IsEnabled(MLS));
   emit(cond | B22 | B21 | dst.code()*B16 | srcA.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1491,16 +1537,25 @@ void Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
 
 void Assembler::sdiv(Register dst, Register src1, Register src2,
                      Condition cond) {
-  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(IsEnabled(SUDIV));
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(IsEnabled(SUDIV));
   emit(cond | B26 | B25| B24 | B20 | dst.code()*B16 | 0xf * B12 |
        src2.code()*B8 | B4 | src1.code());
 }
 
 
+void Assembler::udiv(Register dst, Register src1, Register src2,
+                     Condition cond) {
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(IsEnabled(SUDIV));
+  emit(cond | B26 | B25 | B24 | B21 | B20 | dst.code() * B16 | 0xf * B12 |
+       src2.code() * B8 | B4 | src1.code());
+}
+
+
 void Assembler::mul(Register dst, Register src1, Register src2,
                     SBit s, Condition cond) {
-  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
   // dst goes in bits 16-19 for this instruction!
   emit(cond | s | dst.code()*B16 | src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1512,8 +1567,8 @@ void Assembler::smlal(Register dstL,
                       Register src2,
                       SBit s,
                       Condition cond) {
-  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH));
+  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(!dstL.is(dstH));
   emit(cond | B23 | B22 | A | s | dstH.code()*B16 | dstL.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1525,8 +1580,8 @@ void Assembler::smull(Register dstL,
                       Register src2,
                       SBit s,
                       Condition cond) {
-  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH));
+  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(!dstL.is(dstH));
   emit(cond | B23 | B22 | s | dstH.code()*B16 | dstL.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1538,8 +1593,8 @@ void Assembler::umlal(Register dstL,
                       Register src2,
                       SBit s,
                       Condition cond) {
-  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH));
+  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(!dstL.is(dstH));
   emit(cond | B23 | A | s | dstH.code()*B16 | dstL.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1551,8 +1606,8 @@ void Assembler::umull(Register dstL,
                       Register src2,
                       SBit s,
                       Condition cond) {
-  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH));
+  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(!dstL.is(dstH));
   emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1561,7 +1616,7 @@ void Assembler::umull(Register dstL,
 // Miscellaneous arithmetic instructions.
 void Assembler::clz(Register dst, Register src, Condition cond) {
   // v5 and above.
-  ASSERT(!dst.is(pc) && !src.is(pc));
+  DCHECK(!dst.is(pc) && !src.is(pc));
   emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 |
        15*B8 | CLZ | src.code());
 }
@@ -1575,11 +1630,11 @@ void Assembler::usat(Register dst,
                      const Operand& src,
                      Condition cond) {
   // v6 and above.
-  ASSERT(CpuFeatures::IsSupported(ARMv7));
-  ASSERT(!dst.is(pc) && !src.rm_.is(pc));
-  ASSERT((satpos >= 0) && (satpos <= 31));
-  ASSERT((src.shift_op_ == ASR) || (src.shift_op_ == LSL));
-  ASSERT(src.rs_.is(no_reg));
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  DCHECK(!dst.is(pc) && !src.rm_.is(pc));
+  DCHECK((satpos >= 0) && (satpos <= 31));
+  DCHECK((src.shift_op_ == ASR) || (src.shift_op_ == LSL));
+  DCHECK(src.rs_.is(no_reg));
 
   int sh = 0;
   if (src.shift_op_ == ASR) {
@@ -1603,10 +1658,10 @@ void Assembler::ubfx(Register dst,
                      int width,
                      Condition cond) {
   // v7 and above.
-  ASSERT(CpuFeatures::IsSupported(ARMv7));
-  ASSERT(!dst.is(pc) && !src.is(pc));
-  ASSERT((lsb >= 0) && (lsb <= 31));
-  ASSERT((width >= 1) && (width <= (32 - lsb)));
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  DCHECK(!dst.is(pc) && !src.is(pc));
+  DCHECK((lsb >= 0) && (lsb <= 31));
+  DCHECK((width >= 1) && (width <= (32 - lsb)));
   emit(cond | 0xf*B23 | B22 | B21 | (width - 1)*B16 | dst.code()*B12 |
        lsb*B7 | B6 | B4 | src.code());
 }
@@ -1623,10 +1678,10 @@ void Assembler::sbfx(Register dst,
                      int width,
                      Condition cond) {
   // v7 and above.
-  ASSERT(CpuFeatures::IsSupported(ARMv7));
-  ASSERT(!dst.is(pc) && !src.is(pc));
-  ASSERT((lsb >= 0) && (lsb <= 31));
-  ASSERT((width >= 1) && (width <= (32 - lsb)));
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  DCHECK(!dst.is(pc) && !src.is(pc));
+  DCHECK((lsb >= 0) && (lsb <= 31));
+  DCHECK((width >= 1) && (width <= (32 - lsb)));
   emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 |
        lsb*B7 | B6 | B4 | src.code());
 }
@@ -1638,10 +1693,10 @@ void Assembler::sbfx(Register dst,
 //   bfc dst, #lsb, #width
 void Assembler::bfc(Register dst, int lsb, int width, Condition cond) {
   // v7 and above.
-  ASSERT(CpuFeatures::IsSupported(ARMv7));
-  ASSERT(!dst.is(pc));
-  ASSERT((lsb >= 0) && (lsb <= 31));
-  ASSERT((width >= 1) && (width <= (32 - lsb)));
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  DCHECK(!dst.is(pc));
+  DCHECK((lsb >= 0) && (lsb <= 31));
+  DCHECK((width >= 1) && (width <= (32 - lsb)));
   int msb = lsb + width - 1;
   emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 0xf);
 }
@@ -1657,10 +1712,10 @@ void Assembler::bfi(Register dst,
                     int width,
                     Condition cond) {
   // v7 and above.
-  ASSERT(CpuFeatures::IsSupported(ARMv7));
-  ASSERT(!dst.is(pc) && !src.is(pc));
-  ASSERT((lsb >= 0) && (lsb <= 31));
-  ASSERT((width >= 1) && (width <= (32 - lsb)));
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  DCHECK(!dst.is(pc) && !src.is(pc));
+  DCHECK((lsb >= 0) && (lsb <= 31));
+  DCHECK((width >= 1) && (width <= (32 - lsb)));
   int msb = lsb + width - 1;
   emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 |
        src.code());
@@ -1674,13 +1729,13 @@ void Assembler::pkhbt(Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.125.
   // cond(31-28) | 01101000(27-20) | Rn(19-16) |
   // Rd(15-12) | imm5(11-7) | 0(6) | 01(5-4) | Rm(3-0)
-  ASSERT(!dst.is(pc));
-  ASSERT(!src1.is(pc));
-  ASSERT(!src2.rm().is(pc));
-  ASSERT(!src2.rm().is(no_reg));
-  ASSERT(src2.rs().is(no_reg));
-  ASSERT((src2.shift_imm_ >= 0) && (src2.shift_imm_ <= 31));
-  ASSERT(src2.shift_op() == LSL);
+  DCHECK(!dst.is(pc));
+  DCHECK(!src1.is(pc));
+  DCHECK(!src2.rm().is(pc));
+  DCHECK(!src2.rm().is(no_reg));
+  DCHECK(src2.rs().is(no_reg));
+  DCHECK((src2.shift_imm_ >= 0) && (src2.shift_imm_ <= 31));
+  DCHECK(src2.shift_op() == LSL);
   emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
        src2.shift_imm_*B7 | B4 | src2.rm().code());
 }
@@ -1693,13 +1748,13 @@ void Assembler::pkhtb(Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.125.
   // cond(31-28) | 01101000(27-20) | Rn(19-16) |
   // Rd(15-12) | imm5(11-7) | 1(6) | 01(5-4) | Rm(3-0)
-  ASSERT(!dst.is(pc));
-  ASSERT(!src1.is(pc));
-  ASSERT(!src2.rm().is(pc));
-  ASSERT(!src2.rm().is(no_reg));
-  ASSERT(src2.rs().is(no_reg));
-  ASSERT((src2.shift_imm_ >= 1) && (src2.shift_imm_ <= 32));
-  ASSERT(src2.shift_op() == ASR);
+  DCHECK(!dst.is(pc));
+  DCHECK(!src1.is(pc));
+  DCHECK(!src2.rm().is(pc));
+  DCHECK(!src2.rm().is(no_reg));
+  DCHECK(src2.rs().is(no_reg));
+  DCHECK((src2.shift_imm_ >= 1) && (src2.shift_imm_ <= 32));
+  DCHECK(src2.shift_op() == ASR);
   int asr = (src2.shift_imm_ == 32) ? 0 : src2.shift_imm_;
   emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
        asr*B7 | B6 | B4 | src2.rm().code());
@@ -1712,16 +1767,16 @@ void Assembler::uxtb(Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.274.
   // cond(31-28) | 01101110(27-20) | 1111(19-16) |
   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
-  ASSERT(!dst.is(pc));
-  ASSERT(!src.rm().is(pc));
-  ASSERT(!src.rm().is(no_reg));
-  ASSERT(src.rs().is(no_reg));
-  ASSERT((src.shift_imm_ == 0) ||
+  DCHECK(!dst.is(pc));
+  DCHECK(!src.rm().is(pc));
+  DCHECK(!src.rm().is(no_reg));
+  DCHECK(src.rs().is(no_reg));
+  DCHECK((src.shift_imm_ == 0) ||
          (src.shift_imm_ == 8) ||
          (src.shift_imm_ == 16) ||
          (src.shift_imm_ == 24));
   // Operand maps ROR #0 to LSL #0.
-  ASSERT((src.shift_op() == ROR) ||
+  DCHECK((src.shift_op() == ROR) ||
          ((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
   emit(cond | 0x6E*B20 | 0xF*B16 | dst.code()*B12 |
        ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
@@ -1735,17 +1790,17 @@ void Assembler::uxtab(Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.271.
   // cond(31-28) | 01101110(27-20) | Rn(19-16) |
   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
-  ASSERT(!dst.is(pc));
-  ASSERT(!src1.is(pc));
-  ASSERT(!src2.rm().is(pc));
-  ASSERT(!src2.rm().is(no_reg));
-  ASSERT(src2.rs().is(no_reg));
-  ASSERT((src2.shift_imm_ == 0) ||
+  DCHECK(!dst.is(pc));
+  DCHECK(!src1.is(pc));
+  DCHECK(!src2.rm().is(pc));
+  DCHECK(!src2.rm().is(no_reg));
+  DCHECK(src2.rs().is(no_reg));
+  DCHECK((src2.shift_imm_ == 0) ||
          (src2.shift_imm_ == 8) ||
          (src2.shift_imm_ == 16) ||
          (src2.shift_imm_ == 24));
   // Operand maps ROR #0 to LSL #0.
-  ASSERT((src2.shift_op() == ROR) ||
+  DCHECK((src2.shift_op() == ROR) ||
          ((src2.shift_op() == LSL) && (src2.shift_imm_ == 0)));
   emit(cond | 0x6E*B20 | src1.code()*B16 | dst.code()*B12 |
        ((src2.shift_imm_ >> 1) &0xC)*B8 | 7*B4 | src2.rm().code());
@@ -1758,16 +1813,16 @@ void Assembler::uxtb16(Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.275.
   // cond(31-28) | 01101100(27-20) | 1111(19-16) |
   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
-  ASSERT(!dst.is(pc));
-  ASSERT(!src.rm().is(pc));
-  ASSERT(!src.rm().is(no_reg));
-  ASSERT(src.rs().is(no_reg));
-  ASSERT((src.shift_imm_ == 0) ||
+  DCHECK(!dst.is(pc));
+  DCHECK(!src.rm().is(pc));
+  DCHECK(!src.rm().is(no_reg));
+  DCHECK(src.rs().is(no_reg));
+  DCHECK((src.shift_imm_ == 0) ||
          (src.shift_imm_ == 8) ||
          (src.shift_imm_ == 16) ||
          (src.shift_imm_ == 24));
   // Operand maps ROR #0 to LSL #0.
-  ASSERT((src.shift_op() == ROR) ||
+  DCHECK((src.shift_op() == ROR) ||
          ((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
   emit(cond | 0x6C*B20 | 0xF*B16 | dst.code()*B12 |
        ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
@@ -1776,14 +1831,14 @@ void Assembler::uxtb16(Register dst,
 
 // Status register access instructions.
 void Assembler::mrs(Register dst, SRegister s, Condition cond) {
-  ASSERT(!dst.is(pc));
+  DCHECK(!dst.is(pc));
   emit(cond | B24 | s | 15*B16 | dst.code()*B12);
 }
 
 
 void Assembler::msr(SRegisterFieldMask fields, const Operand& src,
                     Condition cond) {
-  ASSERT(fields >= B16 && fields < B20);  // at least one field set
+  DCHECK(fields >= B16 && fields < B20);  // at least one field set
   Instr instr;
   if (!src.rm_.is_valid()) {
     // Immediate.
@@ -1798,7 +1853,7 @@ void Assembler::msr(SRegisterFieldMask fields, const Operand& src,
     }
     instr = I | rotate_imm*B8 | immed_8;
   } else {
-    ASSERT(!src.rs_.is_valid() && src.shift_imm_ == 0);  // only rm allowed
+    DCHECK(!src.rs_.is_valid() && src.shift_imm_ == 0);  // only rm allowed
     instr = src.rm_.code();
   }
   emit(cond | instr | B24 | B21 | fields | 15*B12);
@@ -1851,22 +1906,22 @@ void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) {
 
 void Assembler::ldrd(Register dst1, Register dst2,
                      const MemOperand& src, Condition cond) {
-  ASSERT(IsEnabled(ARMv7));
-  ASSERT(src.rm().is(no_reg));
-  ASSERT(!dst1.is(lr));  // r14.
-  ASSERT_EQ(0, dst1.code() % 2);
-  ASSERT_EQ(dst1.code() + 1, dst2.code());
+  DCHECK(IsEnabled(ARMv7));
+  DCHECK(src.rm().is(no_reg));
+  DCHECK(!dst1.is(lr));  // r14.
+  DCHECK_EQ(0, dst1.code() % 2);
+  DCHECK_EQ(dst1.code() + 1, dst2.code());
   addrmod3(cond | B7 | B6 | B4, dst1, src);
 }
 
 
 void Assembler::strd(Register src1, Register src2,
                      const MemOperand& dst, Condition cond) {
-  ASSERT(dst.rm().is(no_reg));
-  ASSERT(!src1.is(lr));  // r14.
-  ASSERT_EQ(0, src1.code() % 2);
-  ASSERT_EQ(src1.code() + 1, src2.code());
-  ASSERT(IsEnabled(ARMv7));
+  DCHECK(dst.rm().is(no_reg));
+  DCHECK(!src1.is(lr));  // r14.
+  DCHECK_EQ(0, src1.code() % 2);
+  DCHECK_EQ(src1.code() + 1, src2.code());
+  DCHECK(IsEnabled(ARMv7));
   addrmod3(cond | B7 | B6 | B5 | B4, src1, dst);
 }
 
@@ -1876,15 +1931,15 @@ void Assembler::pld(const MemOperand& address) {
   // Instruction details available in ARM DDI 0406C.b, A8.8.128.
   // 1111(31-28) | 0111(27-24) | U(23) | R(22) | 01(21-20) | Rn(19-16) |
   // 1111(15-12) | imm5(11-07) | type(6-5) | 0(4)| Rm(3-0) |
-  ASSERT(address.rm().is(no_reg));
-  ASSERT(address.am() == Offset);
+  DCHECK(address.rm().is(no_reg));
+  DCHECK(address.am() == Offset);
   int U = B23;
   int offset = address.offset();
   if (offset < 0) {
     offset = -offset;
     U = 0;
   }
-  ASSERT(offset < 4096);
+  DCHECK(offset < 4096);
   emit(kSpecialCondition | B26 | B24 | U | B22 | B20 | address.rn().code()*B16 |
        0xf*B12 | offset);
 }
@@ -1896,7 +1951,7 @@ void Assembler::ldm(BlockAddrMode am,
                     RegList dst,
                     Condition cond) {
   // ABI stack constraint: ldmxx base, {..sp..}  base != sp  is not restartable.
-  ASSERT(base.is(sp) || (dst & sp.bit()) == 0);
+  DCHECK(base.is(sp) || (dst & sp.bit()) == 0);
 
   addrmod4(cond | B27 | am | L, base, dst);
 
@@ -1925,7 +1980,7 @@ void Assembler::stm(BlockAddrMode am,
 // enabling/disabling and a counter feature. See simulator-arm.h .
 void Assembler::stop(const char* msg, Condition cond, int32_t code) {
 #ifndef __arm__
-  ASSERT(code >= kDefaultStopCode);
+  DCHECK(code >= kDefaultStopCode);
   {
     // The Simulator will handle the stop instruction and get the message
     // address. It expects to find the address just after the svc instruction.
@@ -1951,13 +2006,13 @@ void Assembler::stop(const char* msg, Condition cond, int32_t code) {
 
 
 void Assembler::bkpt(uint32_t imm16) {  // v5 and above
-  ASSERT(is_uint16(imm16));
+  DCHECK(is_uint16(imm16));
   emit(al | B24 | B21 | (imm16 >> 4)*B8 | BKPT | (imm16 & 0xf));
 }
 
 
 void Assembler::svc(uint32_t imm24, Condition cond) {
-  ASSERT(is_uint24(imm24));
+  DCHECK(is_uint24(imm24));
   emit(cond | 15*B24 | imm24);
 }
 
@@ -1970,7 +2025,7 @@ void Assembler::cdp(Coprocessor coproc,
                     CRegister crm,
                     int opcode_2,
                     Condition cond) {
-  ASSERT(is_uint4(opcode_1) && is_uint3(opcode_2));
+  DCHECK(is_uint4(opcode_1) && is_uint3(opcode_2));
   emit(cond | B27 | B26 | B25 | (opcode_1 & 15)*B20 | crn.code()*B16 |
        crd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | crm.code());
 }
@@ -1993,7 +2048,7 @@ void Assembler::mcr(Coprocessor coproc,
                     CRegister crm,
                     int opcode_2,
                     Condition cond) {
-  ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2));
+  DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2));
   emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | crn.code()*B16 |
        rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
 }
@@ -2016,7 +2071,7 @@ void Assembler::mrc(Coprocessor coproc,
                     CRegister crm,
                     int opcode_2,
                     Condition cond) {
-  ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2));
+  DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2));
   emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | L | crn.code()*B16 |
        rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
 }
@@ -2048,7 +2103,7 @@ void Assembler::ldc(Coprocessor coproc,
                     LFlag l,
                     Condition cond) {
   // Unindexed addressing.
-  ASSERT(is_uint8(option));
+  DCHECK(is_uint8(option));
   emit(cond | B27 | B26 | U | l | L | rn.code()*B16 | crd.code()*B12 |
        coproc*B8 | (option & 255));
 }
@@ -2089,14 +2144,14 @@ void Assembler::vldr(const DwVfpRegister dst,
   int vd, d;
   dst.split_code(&vd, &d);
 
-  ASSERT(offset >= 0);
+  DCHECK(offset >= 0);
   if ((offset % 4) == 0 && (offset / 4) < 256) {
     emit(cond | 0xD*B24 | u*B23 | d*B22 | B20 | base.code()*B16 | vd*B12 |
          0xB*B8 | ((offset / 4) & 255));
   } else {
     // Larger offsets must be handled by computing the correct address
     // in the ip register.
-    ASSERT(!base.is(ip));
+    DCHECK(!base.is(ip));
     if (u == 1) {
       add(ip, base, Operand(offset));
     } else {
@@ -2110,9 +2165,14 @@ void Assembler::vldr(const DwVfpRegister dst,
 void Assembler::vldr(const DwVfpRegister dst,
                      const MemOperand& operand,
                      const Condition cond) {
-  ASSERT(!operand.rm().is_valid());
-  ASSERT(operand.am_ == Offset);
-  vldr(dst, operand.rn(), operand.offset(), cond);
+  DCHECK(operand.am_ == Offset);
+  if (operand.rm().is_valid()) {
+    add(ip, operand.rn(),
+        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
+    vldr(dst, ip, 0, cond);
+  } else {
+    vldr(dst, operand.rn(), operand.offset(), cond);
+  }
 }
 
 
@@ -2131,7 +2191,7 @@ void Assembler::vldr(const SwVfpRegister dst,
   }
   int sd, d;
   dst.split_code(&sd, &d);
-  ASSERT(offset >= 0);
+  DCHECK(offset >= 0);
 
   if ((offset % 4) == 0 && (offset / 4) < 256) {
   emit(cond | u*B23 | d*B22 | 0xD1*B20 | base.code()*B16 | sd*B12 |
@@ -2139,7 +2199,7 @@ void Assembler::vldr(const SwVfpRegister dst,
   } else {
     // Larger offsets must be handled by computing the correct address
     // in the ip register.
-    ASSERT(!base.is(ip));
+    DCHECK(!base.is(ip));
     if (u == 1) {
       add(ip, base, Operand(offset));
     } else {
@@ -2153,9 +2213,14 @@ void Assembler::vldr(const SwVfpRegister dst,
 void Assembler::vldr(const SwVfpRegister dst,
                      const MemOperand& operand,
                      const Condition cond) {
-  ASSERT(!operand.rm().is_valid());
-  ASSERT(operand.am_ == Offset);
-  vldr(dst, operand.rn(), operand.offset(), cond);
+  DCHECK(operand.am_ == Offset);
+  if (operand.rm().is_valid()) {
+    add(ip, operand.rn(),
+        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
+    vldr(dst, ip, 0, cond);
+  } else {
+    vldr(dst, operand.rn(), operand.offset(), cond);
+  }
 }
 
 
@@ -2172,7 +2237,7 @@ void Assembler::vstr(const DwVfpRegister src,
     offset = -offset;
     u = 0;
   }
-  ASSERT(offset >= 0);
+  DCHECK(offset >= 0);
   int vd, d;
   src.split_code(&vd, &d);
 
@@ -2182,7 +2247,7 @@ void Assembler::vstr(const DwVfpRegister src,
   } else {
     // Larger offsets must be handled by computing the correct address
     // in the ip register.
-    ASSERT(!base.is(ip));
+    DCHECK(!base.is(ip));
     if (u == 1) {
       add(ip, base, Operand(offset));
     } else {
@@ -2196,9 +2261,14 @@ void Assembler::vstr(const DwVfpRegister src,
 void Assembler::vstr(const DwVfpRegister src,
                      const MemOperand& operand,
                      const Condition cond) {
-  ASSERT(!operand.rm().is_valid());
-  ASSERT(operand.am_ == Offset);
-  vstr(src, operand.rn(), operand.offset(), cond);
+  DCHECK(operand.am_ == Offset);
+  if (operand.rm().is_valid()) {
+    add(ip, operand.rn(),
+        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
+    vstr(src, ip, 0, cond);
+  } else {
+    vstr(src, operand.rn(), operand.offset(), cond);
+  }
 }
 
 
@@ -2217,14 +2287,14 @@ void Assembler::vstr(const SwVfpRegister src,
   }
   int sd, d;
   src.split_code(&sd, &d);
-  ASSERT(offset >= 0);
+  DCHECK(offset >= 0);
   if ((offset % 4) == 0 && (offset / 4) < 256) {
     emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 |
          0xA*B8 | ((offset / 4) & 255));
   } else {
     // Larger offsets must be handled by computing the correct address
     // in the ip register.
-    ASSERT(!base.is(ip));
+    DCHECK(!base.is(ip));
     if (u == 1) {
       add(ip, base, Operand(offset));
     } else {
@@ -2238,9 +2308,14 @@ void Assembler::vstr(const SwVfpRegister src,
 void Assembler::vstr(const SwVfpRegister src,
                      const MemOperand& operand,
                      const Condition cond) {
-  ASSERT(!operand.rm().is_valid());
-  ASSERT(operand.am_ == Offset);
-  vstr(src, operand.rn(), operand.offset(), cond);
+  DCHECK(operand.am_ == Offset);
+  if (operand.rm().is_valid()) {
+    add(ip, operand.rn(),
+        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
+    vstr(src, ip, 0, cond);
+  } else {
+    vstr(src, operand.rn(), operand.offset(), cond);
+  }
 }
 
 
@@ -2252,14 +2327,14 @@ void  Assembler::vldm(BlockAddrMode am,
   // Instruction details available in ARM DDI 0406C.b, A8-922.
   // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) |
   // first(15-12) | 1011(11-8) | (count * 2)
-  ASSERT_LE(first.code(), last.code());
-  ASSERT(am == ia || am == ia_w || am == db_w);
-  ASSERT(!base.is(pc));
+  DCHECK_LE(first.code(), last.code());
+  DCHECK(am == ia || am == ia_w || am == db_w);
+  DCHECK(!base.is(pc));
 
   int sd, d;
   first.split_code(&sd, &d);
   int count = last.code() - first.code() + 1;
-  ASSERT(count <= 16);
+  DCHECK(count <= 16);
   emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 |
        0xB*B8 | count*2);
 }
@@ -2273,14 +2348,14 @@ void  Assembler::vstm(BlockAddrMode am,
   // Instruction details available in ARM DDI 0406C.b, A8-1080.
   // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) |
   // first(15-12) | 1011(11-8) | (count * 2)
-  ASSERT_LE(first.code(), last.code());
-  ASSERT(am == ia || am == ia_w || am == db_w);
-  ASSERT(!base.is(pc));
+  DCHECK_LE(first.code(), last.code());
+  DCHECK(am == ia || am == ia_w || am == db_w);
+  DCHECK(!base.is(pc));
 
   int sd, d;
   first.split_code(&sd, &d);
   int count = last.code() - first.code() + 1;
-  ASSERT(count <= 16);
+  DCHECK(count <= 16);
   emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 |
        0xB*B8 | count*2);
 }
@@ -2293,9 +2368,9 @@ void  Assembler::vldm(BlockAddrMode am,
   // Instruction details available in ARM DDI 0406A, A8-626.
   // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) |
   // first(15-12) | 1010(11-8) | (count/2)
-  ASSERT_LE(first.code(), last.code());
-  ASSERT(am == ia || am == ia_w || am == db_w);
-  ASSERT(!base.is(pc));
+  DCHECK_LE(first.code(), last.code());
+  DCHECK(am == ia || am == ia_w || am == db_w);
+  DCHECK(!base.is(pc));
 
   int sd, d;
   first.split_code(&sd, &d);
@@ -2313,9 +2388,9 @@ void  Assembler::vstm(BlockAddrMode am,
   // Instruction details available in ARM DDI 0406A, A8-784.
   // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) |
   // first(15-12) | 1011(11-8) | (count/2)
-  ASSERT_LE(first.code(), last.code());
-  ASSERT(am == ia || am == ia_w || am == db_w);
-  ASSERT(!base.is(pc));
+  DCHECK_LE(first.code(), last.code());
+  DCHECK(am == ia || am == ia_w || am == db_w);
+  DCHECK(!base.is(pc));
 
   int sd, d;
   first.split_code(&sd, &d);
@@ -2337,7 +2412,7 @@ static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
 // Only works for little endian floating point formats.
 // We don't support VFP on the mixed endian floating point platform.
 static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) {
-  ASSERT(CpuFeatures::IsSupported(VFP3));
+  DCHECK(CpuFeatures::IsSupported(VFP3));
 
   // VMOV can accept an immediate of the form:
   //
@@ -2399,7 +2474,7 @@ void Assembler::vmov(const DwVfpRegister dst,
     int vd, d;
     dst.split_code(&vd, &d);
     emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc);
-  } else if (FLAG_enable_vldr_imm && can_use_constant_pool()) {
+  } else if (FLAG_enable_vldr_imm && is_constant_pool_available()) {
     // TODO(jfb) Temporarily turned off until we have constant blinding or
     //           some equivalent mitigation: an attacker can otherwise control
     //           generated data which also happens to be executable, a Very Bad
@@ -2416,8 +2491,18 @@ void Assembler::vmov(const DwVfpRegister dst,
     //           that's tricky because vldr has a limited reach. Furthermore
     //           it breaks load locality.
     RelocInfo rinfo(pc_, imm);
-    ConstantPoolAddEntry(rinfo);
-    vldr(dst, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0));
+    ConstantPoolArray::LayoutSection section = ConstantPoolAddEntry(rinfo);
+    if (section == ConstantPoolArray::EXTENDED_SECTION) {
+      DCHECK(FLAG_enable_ool_constant_pool);
+      // Emit instructions to load constant pool offset.
+      movw(ip, 0);
+      movt(ip, 0);
+      // Load from constant pool at offset.
+      vldr(dst, MemOperand(pp, ip));
+    } else {
+      DCHECK(section == ConstantPoolArray::SMALL_SECTION);
+      vldr(dst, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0));
+    }
   } else {
     // Synthesise the double from ARM immediates.
     uint32_t lo, hi;
@@ -2491,7 +2576,7 @@ void Assembler::vmov(const DwVfpRegister dst,
   // Instruction details available in ARM DDI 0406C.b, A8-940.
   // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) |
   // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0)
-  ASSERT(index.index == 0 || index.index == 1);
+  DCHECK(index.index == 0 || index.index == 1);
   int vd, d;
   dst.split_code(&vd, &d);
   emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 |
@@ -2507,7 +2592,7 @@ void Assembler::vmov(const Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.342.
   // cond(31-28) | 1110(27-24) | U=0(23) | opc1=0index(22-21) | 1(20) |
   // Vn(19-16) | Rt(15-12) | 1011(11-8) | N(7) | opc2=00(6-5) | 1(4) | 0000(3-0)
-  ASSERT(index.index == 0 || index.index == 1);
+  DCHECK(index.index == 0 || index.index == 1);
   int vn, n;
   src.split_code(&vn, &n);
   emit(cond | 0xE*B24 | index.index*B21 | B20 | vn*B16 | dst.code()*B12 |
@@ -2523,7 +2608,7 @@ void Assembler::vmov(const DwVfpRegister dst,
   // Instruction details available in ARM DDI 0406C.b, A8-948.
   // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) |
   // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
-  ASSERT(!src1.is(pc) && !src2.is(pc));
+  DCHECK(!src1.is(pc) && !src2.is(pc));
   int vm, m;
   dst.split_code(&vm, &m);
   emit(cond | 0xC*B24 | B22 | src2.code()*B16 |
@@ -2539,7 +2624,7 @@ void Assembler::vmov(const Register dst1,
   // Instruction details available in ARM DDI 0406C.b, A8-948.
   // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) |
   // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
-  ASSERT(!dst1.is(pc) && !dst2.is(pc));
+  DCHECK(!dst1.is(pc) && !dst2.is(pc));
   int vm, m;
   src.split_code(&vm, &m);
   emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 |
@@ -2554,7 +2639,7 @@ void Assembler::vmov(const SwVfpRegister dst,
   // Instruction details available in ARM DDI 0406A, A8-642.
   // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) |
   // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
-  ASSERT(!src.is(pc));
+  DCHECK(!src.is(pc));
   int sn, n;
   dst.split_code(&sn, &n);
   emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4);
@@ -2568,7 +2653,7 @@ void Assembler::vmov(const Register dst,
   // Instruction details available in ARM DDI 0406A, A8-642.
   // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) |
   // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
-  ASSERT(!dst.is(pc));
+  DCHECK(!dst.is(pc));
   int sn, n;
   src.split_code(&sn, &n);
   emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4);
@@ -2629,7 +2714,7 @@ static void SplitRegCode(VFPType reg_type,
                          int reg_code,
                          int* vm,
                          int* m) {
-  ASSERT((reg_code >= 0) && (reg_code <= 31));
+  DCHECK((reg_code >= 0) && (reg_code <= 31));
   if (IsIntegerVFPType(reg_type) || !IsDoubleVFPType(reg_type)) {
     // 32 bit type.
     *m  = reg_code & 0x1;
@@ -2649,7 +2734,7 @@ static Instr EncodeVCVT(const VFPType dst_type,
                         const int src_code,
                         VFPConversionMode mode,
                         const Condition cond) {
-  ASSERT(src_type != dst_type);
+  DCHECK(src_type != dst_type);
   int D, Vd, M, Vm;
   SplitRegCode(src_type, src_code, &Vm, &M);
   SplitRegCode(dst_type, dst_code, &Vd, &D);
@@ -2659,7 +2744,7 @@ static Instr EncodeVCVT(const VFPType dst_type,
     // Instruction details available in ARM DDI 0406B, A8.6.295.
     // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 1(19) | opc2(18-16) |
     // Vd(15-12) | 101(11-9) | sz(8) | op(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
-    ASSERT(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type));
+    DCHECK(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type));
 
     int sz, opc2, op;
 
@@ -2668,7 +2753,7 @@ static Instr EncodeVCVT(const VFPType dst_type,
       sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
       op = mode;
     } else {
-      ASSERT(IsIntegerVFPType(src_type));
+      DCHECK(IsIntegerVFPType(src_type));
       opc2 = 0x0;
       sz = IsDoubleVFPType(dst_type) ? 0x1 : 0x0;
       op = IsSignedVFPType(src_type) ? 0x1 : 0x0;
@@ -2750,8 +2835,8 @@ void Assembler::vcvt_f64_s32(const DwVfpRegister dst,
   // Instruction details available in ARM DDI 0406C.b, A8-874.
   // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 1010(19-16) | Vd(15-12) |
   // 101(11-9) | sf=1(8) | sx=1(7) | 1(6) | i(5) | 0(4) | imm4(3-0)
-  ASSERT(fraction_bits > 0 && fraction_bits <= 32);
-  ASSERT(CpuFeatures::IsSupported(VFP3));
+  DCHECK(fraction_bits > 0 && fraction_bits <= 32);
+  DCHECK(CpuFeatures::IsSupported(VFP3));
   int vd, d;
   dst.split_code(&vd, &d);
   int imm5 = 32 - fraction_bits;
@@ -2932,7 +3017,7 @@ void Assembler::vcmp(const DwVfpRegister src1,
   // Instruction details available in ARM DDI 0406C.b, A8-864.
   // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) |
   // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0)
-  ASSERT(src2 == 0.0);
+  DCHECK(src2 == 0.0);
   int vd, d;
   src1.split_code(&vd, &d);
   emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6);
@@ -2980,7 +3065,7 @@ void Assembler::vld1(NeonSize size,
   // Instruction details available in ARM DDI 0406C.b, A8.8.320.
   // 1111(31-28) | 01000(27-23) | D(22) | 10(21-20) | Rn(19-16) |
   // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
-  ASSERT(CpuFeatures::IsSupported(NEON));
+  DCHECK(CpuFeatures::IsSupported(NEON));
   int vd, d;
   dst.base().split_code(&vd, &d);
   emit(0xFU*B28 | 4*B24 | d*B22 | 2*B20 | src.rn().code()*B16 | vd*B12 |
@@ -2994,7 +3079,7 @@ void Assembler::vst1(NeonSize size,
   // Instruction details available in ARM DDI 0406C.b, A8.8.404.
   // 1111(31-28) | 01000(27-23) | D(22) | 00(21-20) | Rn(19-16) |
   // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
-  ASSERT(CpuFeatures::IsSupported(NEON));
+  DCHECK(CpuFeatures::IsSupported(NEON));
   int vd, d;
   src.base().split_code(&vd, &d);
   emit(0xFU*B28 | 4*B24 | d*B22 | dst.rn().code()*B16 | vd*B12 | src.type()*B8 |
@@ -3006,7 +3091,7 @@ void Assembler::vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src) {
   // Instruction details available in ARM DDI 0406C.b, A8.8.346.
   // 1111(31-28) | 001(27-25) | U(24) | 1(23) | D(22) | imm3(21-19) |
   // 000(18-16) | Vd(15-12) | 101000(11-6) | M(5) | 1(4) | Vm(3-0)
-  ASSERT(CpuFeatures::IsSupported(NEON));
+  DCHECK(CpuFeatures::IsSupported(NEON));
   int vd, d;
   dst.split_code(&vd, &d);
   int vm, m;
@@ -3023,7 +3108,7 @@ void Assembler::nop(int type) {
   // MOV Rx, Rx as NOP and it performs better even in newer CPUs.
   // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode
   // a type.
-  ASSERT(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
+  DCHECK(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
   emit(al | 13*B21 | type*B12 | type);
 }
 
@@ -3032,7 +3117,7 @@ bool Assembler::IsMovT(Instr instr) {
   instr &= ~(((kNumberOfConditions - 1) << 28) |  // Mask off conditions
              ((kNumRegisters-1)*B12) |            // mask out register
              EncodeMovwImmediate(0xFFFF));        // mask out immediate value
-  return instr == 0x34*B20;
+  return instr == kMovtPattern;
 }
 
 
@@ -3040,17 +3125,36 @@ bool Assembler::IsMovW(Instr instr) {
   instr &= ~(((kNumberOfConditions - 1) << 28) |  // Mask off conditions
              ((kNumRegisters-1)*B12) |            // mask out destination
              EncodeMovwImmediate(0xFFFF));        // mask out immediate value
-  return instr == 0x30*B20;
+  return instr == kMovwPattern;
+}
+
+
+Instr Assembler::GetMovTPattern() { return kMovtPattern; }
+
+
+Instr Assembler::GetMovWPattern() { return kMovwPattern; }
+
+
+Instr Assembler::EncodeMovwImmediate(uint32_t immediate) {
+  DCHECK(immediate < 0x10000);
+  return ((immediate & 0xf000) << 4) | (immediate & 0xfff);
+}
+
+
+Instr Assembler::PatchMovwImmediate(Instr instruction, uint32_t immediate) {
+  instruction &= ~EncodeMovwImmediate(0xffff);
+  return instruction | EncodeMovwImmediate(immediate);
 }
 
 
 bool Assembler::IsNop(Instr instr, int type) {
-  ASSERT(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
+  DCHECK(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
   // Check for mov rx, rx where x = type.
   return instr == (al | 13*B21 | type*B12 | type);
 }
 
 
+// static
 bool Assembler::ImmediateFitsAddrMode1Instruction(int32_t imm32) {
   uint32_t dummy1;
   uint32_t dummy2;
@@ -3098,9 +3202,7 @@ void Assembler::GrowBuffer() {
 
   // Compute new buffer size.
   CodeDesc desc;  // the new buffer
-  if (buffer_size_ < 4*KB) {
-    desc.buffer_size = 4*KB;
-  } else if (buffer_size_ < 1*MB) {
+  if (buffer_size_ < 1 * MB) {
     desc.buffer_size = 2*buffer_size_;
   } else {
     desc.buffer_size = buffer_size_ + 1*MB;
@@ -3135,7 +3237,7 @@ void Assembler::GrowBuffer() {
   // Relocate pending relocation entries.
   for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
     RelocInfo& rinfo = pending_32_bit_reloc_info_[i];
-    ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
+    DCHECK(rinfo.rmode() != RelocInfo::COMMENT &&
            rinfo.rmode() != RelocInfo::POSITION);
     if (rinfo.rmode() != RelocInfo::JS_RETURN) {
       rinfo.set_pc(rinfo.pc() + pc_delta);
@@ -3143,7 +3245,7 @@ void Assembler::GrowBuffer() {
   }
   for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) {
     RelocInfo& rinfo = pending_64_bit_reloc_info_[i];
-    ASSERT(rinfo.rmode() == RelocInfo::NONE64);
+    DCHECK(rinfo.rmode() == RelocInfo::NONE64);
     rinfo.set_pc(rinfo.pc() + pc_delta);
   }
   constant_pool_builder_.Relocate(pc_delta);
@@ -3154,8 +3256,8 @@ void Assembler::db(uint8_t data) {
   // No relocation info should be pending while using db. db is used
   // to write pure data with no pointers and the constant pool should
   // be emitted before using db.
-  ASSERT(num_pending_32_bit_reloc_info_ == 0);
-  ASSERT(num_pending_64_bit_reloc_info_ == 0);
+  DCHECK(num_pending_32_bit_reloc_info_ == 0);
+  DCHECK(num_pending_64_bit_reloc_info_ == 0);
   CheckBuffer();
   *reinterpret_cast<uint8_t*>(pc_) = data;
   pc_ += sizeof(uint8_t);
@@ -3166,8 +3268,8 @@ void Assembler::dd(uint32_t data) {
   // No relocation info should be pending while using dd. dd is used
   // to write pure data with no pointers and the constant pool should
   // be emitted before using dd.
-  ASSERT(num_pending_32_bit_reloc_info_ == 0);
-  ASSERT(num_pending_64_bit_reloc_info_ == 0);
+  DCHECK(num_pending_32_bit_reloc_info_ == 0);
+  DCHECK(num_pending_64_bit_reloc_info_ == 0);
   CheckBuffer();
   *reinterpret_cast<uint32_t*>(pc_) = data;
   pc_ += sizeof(uint32_t);
@@ -3195,7 +3297,7 @@ void Assembler::RecordRelocInfo(const RelocInfo& rinfo) {
         !serializer_enabled() && !emit_debug_code()) {
       return;
     }
-    ASSERT(buffer_space() >= kMaxRelocSize);  // too late to grow buffer here
+    DCHECK(buffer_space() >= kMaxRelocSize);  // too late to grow buffer here
     if (rinfo.rmode() == RelocInfo::CODE_TARGET_WITH_ID) {
       RelocInfo reloc_info_with_ast_id(rinfo.pc(),
                                        rinfo.rmode(),
@@ -3210,18 +3312,19 @@ void Assembler::RecordRelocInfo(const RelocInfo& rinfo) {
 }
 
 
-void Assembler::ConstantPoolAddEntry(const RelocInfo& rinfo) {
+ConstantPoolArray::LayoutSection Assembler::ConstantPoolAddEntry(
+    const RelocInfo& rinfo) {
   if (FLAG_enable_ool_constant_pool) {
-    constant_pool_builder_.AddEntry(this, rinfo);
+    return constant_pool_builder_.AddEntry(this, rinfo);
   } else {
     if (rinfo.rmode() == RelocInfo::NONE64) {
-      ASSERT(num_pending_64_bit_reloc_info_ < kMaxNumPending64RelocInfo);
+      DCHECK(num_pending_64_bit_reloc_info_ < kMaxNumPending64RelocInfo);
       if (num_pending_64_bit_reloc_info_ == 0) {
         first_const_pool_64_use_ = pc_offset();
       }
       pending_64_bit_reloc_info_[num_pending_64_bit_reloc_info_++] = rinfo;
     } else {
-      ASSERT(num_pending_32_bit_reloc_info_ < kMaxNumPending32RelocInfo);
+      DCHECK(num_pending_32_bit_reloc_info_ < kMaxNumPending32RelocInfo);
       if (num_pending_32_bit_reloc_info_ == 0) {
         first_const_pool_32_use_ = pc_offset();
       }
@@ -3230,6 +3333,7 @@ void Assembler::ConstantPoolAddEntry(const RelocInfo& rinfo) {
     // Make sure the constant pool is not emitted in place of the next
     // instruction for which we just recorded relocation info.
     BlockConstPoolFor(1);
+    return ConstantPoolArray::SMALL_SECTION;
   }
 }
 
@@ -3237,8 +3341,8 @@ void Assembler::ConstantPoolAddEntry(const RelocInfo& rinfo) {
 void Assembler::BlockConstPoolFor(int instructions) {
   if (FLAG_enable_ool_constant_pool) {
     // Should be a no-op if using an out-of-line constant pool.
-    ASSERT(num_pending_32_bit_reloc_info_ == 0);
-    ASSERT(num_pending_64_bit_reloc_info_ == 0);
+    DCHECK(num_pending_32_bit_reloc_info_ == 0);
+    DCHECK(num_pending_64_bit_reloc_info_ == 0);
     return;
   }
 
@@ -3247,10 +3351,10 @@ void Assembler::BlockConstPoolFor(int instructions) {
     // Max pool start (if we need a jump and an alignment).
 #ifdef DEBUG
     int start = pc_limit + kInstrSize + 2 * kPointerSize;
-    ASSERT((num_pending_32_bit_reloc_info_ == 0) ||
+    DCHECK((num_pending_32_bit_reloc_info_ == 0) ||
            (start - first_const_pool_32_use_ +
             num_pending_64_bit_reloc_info_ * kDoubleSize < kMaxDistToIntPool));
-    ASSERT((num_pending_64_bit_reloc_info_ == 0) ||
+    DCHECK((num_pending_64_bit_reloc_info_ == 0) ||
            (start - first_const_pool_64_use_ < kMaxDistToFPPool));
 #endif
     no_const_pool_before_ = pc_limit;
@@ -3265,8 +3369,8 @@ void Assembler::BlockConstPoolFor(int instructions) {
 void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
   if (FLAG_enable_ool_constant_pool) {
     // Should be a no-op if using an out-of-line constant pool.
-    ASSERT(num_pending_32_bit_reloc_info_ == 0);
-    ASSERT(num_pending_64_bit_reloc_info_ == 0);
+    DCHECK(num_pending_32_bit_reloc_info_ == 0);
+    DCHECK(num_pending_64_bit_reloc_info_ == 0);
     return;
   }
 
@@ -3275,7 +3379,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
   // BlockConstPoolScope.
   if (is_const_pool_blocked()) {
     // Something is wrong if emission is forced and blocked at the same time.
-    ASSERT(!force_emit);
+    DCHECK(!force_emit);
     return;
   }
 
@@ -3314,7 +3418,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
   //  * the instruction doesn't require a jump after itself to jump over the
   //    constant pool, and we're getting close to running out of range.
   if (!force_emit) {
-    ASSERT((first_const_pool_32_use_ >= 0) || (first_const_pool_64_use_ >= 0));
+    DCHECK((first_const_pool_32_use_ >= 0) || (first_const_pool_64_use_ >= 0));
     bool need_emit = false;
     if (has_fp_values) {
       int dist64 = pc_offset() +
@@ -3364,15 +3468,15 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
     for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) {
       RelocInfo& rinfo = pending_64_bit_reloc_info_[i];
 
-      ASSERT(!((uintptr_t)pc_ & 0x7));  // Check 64-bit alignment.
+      DCHECK(!((uintptr_t)pc_ & 0x7));  // Check 64-bit alignment.
 
       Instr instr = instr_at(rinfo.pc());
       // Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0.
-      ASSERT((IsVldrDPcImmediateOffset(instr) &&
+      DCHECK((IsVldrDPcImmediateOffset(instr) &&
               GetVldrDRegisterImmediateOffset(instr) == 0));
 
       int delta = pc_ - rinfo.pc() - kPcLoadDelta;
-      ASSERT(is_uint10(delta));
+      DCHECK(is_uint10(delta));
 
       bool found = false;
       uint64_t value = rinfo.raw_data64();
@@ -3380,9 +3484,9 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
         RelocInfo& rinfo2 = pending_64_bit_reloc_info_[j];
         if (value == rinfo2.raw_data64()) {
           found = true;
-          ASSERT(rinfo2.rmode() == RelocInfo::NONE64);
+          DCHECK(rinfo2.rmode() == RelocInfo::NONE64);
           Instr instr2 = instr_at(rinfo2.pc());
-          ASSERT(IsVldrDPcImmediateOffset(instr2));
+          DCHECK(IsVldrDPcImmediateOffset(instr2));
           delta = GetVldrDRegisterImmediateOffset(instr2);
           delta += rinfo2.pc() - rinfo.pc();
           break;
@@ -3401,7 +3505,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
     // Emit 32-bit constant pool entries.
     for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
       RelocInfo& rinfo = pending_32_bit_reloc_info_[i];
-      ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
+      DCHECK(rinfo.rmode() != RelocInfo::COMMENT &&
              rinfo.rmode() != RelocInfo::POSITION &&
              rinfo.rmode() != RelocInfo::STATEMENT_POSITION &&
              rinfo.rmode() != RelocInfo::CONST_POOL &&
@@ -3410,12 +3514,12 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
       Instr instr = instr_at(rinfo.pc());
 
       // 64-bit loads shouldn't get here.
-      ASSERT(!IsVldrDPcImmediateOffset(instr));
+      DCHECK(!IsVldrDPcImmediateOffset(instr));
 
       if (IsLdrPcImmediateOffset(instr) &&
           GetLdrRegisterImmediateOffset(instr) == 0) {
         int delta = pc_ - rinfo.pc() - kPcLoadDelta;
-        ASSERT(is_uint12(delta));
+        DCHECK(is_uint12(delta));
         // 0 is the smallest delta:
         //   ldr rd, [pc, #0]
         //   constant pool marker
@@ -3445,7 +3549,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
           emit(rinfo.data());
         }
       } else {
-        ASSERT(IsMovW(instr));
+        DCHECK(IsMovW(instr));
       }
     }
 
@@ -3481,12 +3585,7 @@ void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
 
 
 ConstantPoolBuilder::ConstantPoolBuilder()
-    : entries_(),
-      merged_indexes_(),
-      count_of_64bit_(0),
-      count_of_code_ptr_(0),
-      count_of_heap_ptr_(0),
-      count_of_32bit_(0) { }
+    : entries_(), current_section_(ConstantPoolArray::SMALL_SECTION) {}
 
 
 bool ConstantPoolBuilder::IsEmpty() {
@@ -3494,87 +3593,70 @@ bool ConstantPoolBuilder::IsEmpty() {
 }
 
 
-bool ConstantPoolBuilder::Is64BitEntry(RelocInfo::Mode rmode) {
-  return rmode == RelocInfo::NONE64;
-}
-
-
-bool ConstantPoolBuilder::Is32BitEntry(RelocInfo::Mode rmode) {
-  return !RelocInfo::IsGCRelocMode(rmode) && rmode != RelocInfo::NONE64;
-}
-
-
-bool ConstantPoolBuilder::IsCodePtrEntry(RelocInfo::Mode rmode) {
-  return RelocInfo::IsCodeTarget(rmode);
-}
-
-
-bool ConstantPoolBuilder::IsHeapPtrEntry(RelocInfo::Mode rmode) {
-  return RelocInfo::IsGCRelocMode(rmode) && !RelocInfo::IsCodeTarget(rmode);
+ConstantPoolArray::Type ConstantPoolBuilder::GetConstantPoolType(
+    RelocInfo::Mode rmode) {
+  if (rmode == RelocInfo::NONE64) {
+    return ConstantPoolArray::INT64;
+  } else if (!RelocInfo::IsGCRelocMode(rmode)) {
+    return ConstantPoolArray::INT32;
+  } else if (RelocInfo::IsCodeTarget(rmode)) {
+    return ConstantPoolArray::CODE_PTR;
+  } else {
+    DCHECK(RelocInfo::IsGCRelocMode(rmode) && !RelocInfo::IsCodeTarget(rmode));
+    return ConstantPoolArray::HEAP_PTR;
+  }
 }
 
 
-void ConstantPoolBuilder::AddEntry(Assembler* assm,
-                                   const RelocInfo& rinfo) {
+ConstantPoolArray::LayoutSection ConstantPoolBuilder::AddEntry(
+    Assembler* assm, const RelocInfo& rinfo) {
   RelocInfo::Mode rmode = rinfo.rmode();
-  ASSERT(rmode != RelocInfo::COMMENT &&
+  DCHECK(rmode != RelocInfo::COMMENT &&
          rmode != RelocInfo::POSITION &&
          rmode != RelocInfo::STATEMENT_POSITION &&
          rmode != RelocInfo::CONST_POOL);
 
-
   // Try to merge entries which won't be patched.
   int merged_index = -1;
+  ConstantPoolArray::LayoutSection entry_section = current_section_;
   if (RelocInfo::IsNone(rmode) ||
       (!assm->serializer_enabled() && (rmode >= RelocInfo::CELL))) {
     size_t i;
-    std::vector<RelocInfo>::const_iterator it;
+    std::vector<ConstantPoolEntry>::const_iterator it;
     for (it = entries_.begin(), i = 0; it != entries_.end(); it++, i++) {
-      if (RelocInfo::IsEqual(rinfo, *it)) {
+      if (RelocInfo::IsEqual(rinfo, it->rinfo_)) {
+        // Merge with found entry.
         merged_index = i;
+        entry_section = entries_[i].section_;
         break;
       }
     }
   }
-
-  entries_.push_back(rinfo);
-  merged_indexes_.push_back(merged_index);
+  DCHECK(entry_section <= current_section_);
+  entries_.push_back(ConstantPoolEntry(rinfo, entry_section, merged_index));
 
   if (merged_index == -1) {
     // Not merged, so update the appropriate count.
-    if (Is64BitEntry(rmode)) {
-      count_of_64bit_++;
-    } else if (Is32BitEntry(rmode)) {
-      count_of_32bit_++;
-    } else if (IsCodePtrEntry(rmode)) {
-      count_of_code_ptr_++;
-    } else {
-      ASSERT(IsHeapPtrEntry(rmode));
-      count_of_heap_ptr_++;
-    }
+    number_of_entries_[entry_section].increment(GetConstantPoolType(rmode));
   }
 
-  // Check if we still have room for another entry given Arm's ldr and vldr
-  // immediate offset range.
-  // TODO(rmcilroy): Avoid creating a new object here when we support
-  //                 extended constant pools.
-  ConstantPoolArray::NumberOfEntries total(count_of_64bit_,
-                                           count_of_code_ptr_,
-                                           count_of_heap_ptr_,
-                                           count_of_32bit_);
-  ConstantPoolArray::NumberOfEntries int64_counts(count_of_64bit_, 0, 0, 0);
-  if (!(is_uint12(ConstantPoolArray::SizeFor(total)) &&
-        is_uint10(ConstantPoolArray::SizeFor(int64_counts)))) {
-    assm->set_constant_pool_full();
+  // Check if we still have room for another entry in the small section
+  // given Arm's ldr and vldr immediate offset range.
+  if (current_section_ == ConstantPoolArray::SMALL_SECTION &&
+      !(is_uint12(ConstantPoolArray::SizeFor(*small_entries())) &&
+        is_uint10(ConstantPoolArray::MaxInt64Offset(
+            small_entries()->count_of(ConstantPoolArray::INT64))))) {
+    current_section_ = ConstantPoolArray::EXTENDED_SECTION;
   }
+  return entry_section;
 }
 
 
 void ConstantPoolBuilder::Relocate(int pc_delta) {
-  for (std::vector<RelocInfo>::iterator rinfo = entries_.begin();
-       rinfo != entries_.end(); rinfo++) {
-    ASSERT(rinfo->rmode() != RelocInfo::JS_RETURN);
-    rinfo->set_pc(rinfo->pc() + pc_delta);
+  for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
+       entry != entries_.end(); entry++) {
+    DCHECK(entry->rinfo_.rmode() != RelocInfo::JS_RETURN);
+    entry->rinfo_.set_pc(entry->rinfo_.pc() + pc_delta);
   }
 }
 
@@ -3582,89 +3664,104 @@ void ConstantPoolBuilder::Relocate(int pc_delta) {
 Handle<ConstantPoolArray> ConstantPoolBuilder::New(Isolate* isolate) {
   if (IsEmpty()) {
     return isolate->factory()->empty_constant_pool_array();
+  } else if (extended_entries()->is_empty()) {
+    return isolate->factory()->NewConstantPoolArray(*small_entries());
   } else {
-    ConstantPoolArray::NumberOfEntries small(count_of_64bit_,
-                                             count_of_code_ptr_,
-                                             count_of_heap_ptr_,
-                                             count_of_32bit_);
-    return isolate->factory()->NewConstantPoolArray(small);
+    DCHECK(current_section_ == ConstantPoolArray::EXTENDED_SECTION);
+    return isolate->factory()->NewExtendedConstantPoolArray(
+        *small_entries(), *extended_entries());
   }
 }
 
 
 void ConstantPoolBuilder::Populate(Assembler* assm,
                                    ConstantPoolArray* constant_pool) {
-  ASSERT(count_of_64bit_ == constant_pool->number_of_entries(
-             ConstantPoolArray::INT64, ConstantPoolArray::SMALL_SECTION));
-  ASSERT(count_of_code_ptr_ == constant_pool->number_of_entries(
-             ConstantPoolArray::CODE_PTR, ConstantPoolArray::SMALL_SECTION));
-  ASSERT(count_of_heap_ptr_ == constant_pool->number_of_entries(
-             ConstantPoolArray::HEAP_PTR, ConstantPoolArray::SMALL_SECTION));
-  ASSERT(count_of_32bit_ == constant_pool->number_of_entries(
-             ConstantPoolArray::INT32, ConstantPoolArray::SMALL_SECTION));
-  ASSERT(entries_.size() == merged_indexes_.size());
-
-  int index_64bit = 0;
-  int index_code_ptr = count_of_64bit_;
-  int index_heap_ptr = count_of_64bit_ + count_of_code_ptr_;
-  int index_32bit = count_of_64bit_ + count_of_code_ptr_ + count_of_heap_ptr_;
-
-  size_t i;
-  std::vector<RelocInfo>::const_iterator rinfo;
-  for (rinfo = entries_.begin(), i = 0; rinfo != entries_.end(); rinfo++, i++) {
-    RelocInfo::Mode rmode = rinfo->rmode();
+  DCHECK_EQ(extended_entries()->is_empty(),
+            !constant_pool->is_extended_layout());
+  DCHECK(small_entries()->equals(ConstantPoolArray::NumberOfEntries(
+      constant_pool, ConstantPoolArray::SMALL_SECTION)));
+  if (constant_pool->is_extended_layout()) {
+    DCHECK(extended_entries()->equals(ConstantPoolArray::NumberOfEntries(
+        constant_pool, ConstantPoolArray::EXTENDED_SECTION)));
+  }
+
+  // Set up initial offsets.
+  int offsets[ConstantPoolArray::NUMBER_OF_LAYOUT_SECTIONS]
+             [ConstantPoolArray::NUMBER_OF_TYPES];
+  for (int section = 0; section <= constant_pool->final_section(); section++) {
+    int section_start = (section == ConstantPoolArray::EXTENDED_SECTION)
+                            ? small_entries()->total_count()
+                            : 0;
+    for (int i = 0; i < ConstantPoolArray::NUMBER_OF_TYPES; i++) {
+      ConstantPoolArray::Type type = static_cast<ConstantPoolArray::Type>(i);
+      if (number_of_entries_[section].count_of(type) != 0) {
+        offsets[section][type] = constant_pool->OffsetOfElementAt(
+            number_of_entries_[section].base_of(type) + section_start);
+      }
+    }
+  }
+
+  for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
+       entry != entries_.end(); entry++) {
+    RelocInfo rinfo = entry->rinfo_;
+    RelocInfo::Mode rmode = entry->rinfo_.rmode();
+    ConstantPoolArray::Type type = GetConstantPoolType(rmode);
 
     // Update constant pool if necessary and get the entry's offset.
     int offset;
-    if (merged_indexes_[i] == -1) {
-      if (Is64BitEntry(rmode)) {
-        offset = constant_pool->OffsetOfElementAt(index_64bit) - kHeapObjectTag;
-        constant_pool->set(index_64bit++, rinfo->data64());
-      } else if (Is32BitEntry(rmode)) {
-        offset = constant_pool->OffsetOfElementAt(index_32bit) - kHeapObjectTag;
-        constant_pool->set(index_32bit++, static_cast<int32_t>(rinfo->data()));
-      } else if (IsCodePtrEntry(rmode)) {
-        offset = constant_pool->OffsetOfElementAt(index_code_ptr) -
-            kHeapObjectTag;
-        constant_pool->set(index_code_ptr++,
-                           reinterpret_cast<Address>(rinfo->data()));
+    if (entry->merged_index_ == -1) {
+      offset = offsets[entry->section_][type];
+      offsets[entry->section_][type] += ConstantPoolArray::entry_size(type);
+      if (type == ConstantPoolArray::INT64) {
+        constant_pool->set_at_offset(offset, rinfo.data64());
+      } else if (type == ConstantPoolArray::INT32) {
+        constant_pool->set_at_offset(offset,
+                                     static_cast<int32_t>(rinfo.data()));
+      } else if (type == ConstantPoolArray::CODE_PTR) {
+        constant_pool->set_at_offset(offset,
+                                     reinterpret_cast<Address>(rinfo.data()));
       } else {
-        ASSERT(IsHeapPtrEntry(rmode));
-        offset = constant_pool->OffsetOfElementAt(index_heap_ptr) -
-            kHeapObjectTag;
-        constant_pool->set(index_heap_ptr++,
-                           reinterpret_cast<Object *>(rinfo->data()));
+        DCHECK(type == ConstantPoolArray::HEAP_PTR);
+        constant_pool->set_at_offset(offset,
+                                     reinterpret_cast<Object*>(rinfo.data()));
       }
-      merged_indexes_[i] = offset;  // Stash offset for merged entries.
+      offset -= kHeapObjectTag;
+      entry->merged_index_ = offset;  // Stash offset for merged entries.
     } else {
-      size_t merged_index = static_cast<size_t>(merged_indexes_[i]);
-      ASSERT(merged_index < merged_indexes_.size() && merged_index < i);
-      offset = merged_indexes_[merged_index];
+      DCHECK(entry->merged_index_ < (entry - entries_.begin()));
+      offset = entries_[entry->merged_index_].merged_index_;
     }
 
     // Patch vldr/ldr instruction with correct offset.
-    Instr instr = assm->instr_at(rinfo->pc());
-    if (Is64BitEntry(rmode)) {
+    Instr instr = assm->instr_at(rinfo.pc());
+    if (entry->section_ == ConstantPoolArray::EXTENDED_SECTION) {
+      // Instructions to patch must be 'movw rd, [#0]' and 'movt rd, [#0].
+      Instr next_instr = assm->instr_at(rinfo.pc() + Assembler::kInstrSize);
+      DCHECK((Assembler::IsMovW(instr) &&
+              Instruction::ImmedMovwMovtValue(instr) == 0));
+      DCHECK((Assembler::IsMovT(next_instr) &&
+              Instruction::ImmedMovwMovtValue(next_instr) == 0));
+      assm->instr_at_put(rinfo.pc(),
+                         Assembler::PatchMovwImmediate(instr, offset & 0xffff));
+      assm->instr_at_put(
+          rinfo.pc() + Assembler::kInstrSize,
+          Assembler::PatchMovwImmediate(next_instr, offset >> 16));
+    } else if (type == ConstantPoolArray::INT64) {
       // Instruction to patch must be 'vldr rd, [pp, #0]'.
-      ASSERT((Assembler::IsVldrDPpImmediateOffset(instr) &&
+      DCHECK((Assembler::IsVldrDPpImmediateOffset(instr) &&
               Assembler::GetVldrDRegisterImmediateOffset(instr) == 0));
-      ASSERT(is_uint10(offset));
-      assm->instr_at_put(rinfo->pc(),
-          Assembler::SetVldrDRegisterImmediateOffset(instr, offset));
+      DCHECK(is_uint10(offset));
+      assm->instr_at_put(rinfo.pc(), Assembler::SetVldrDRegisterImmediateOffset(
+                                         instr, offset));
     } else {
       // Instruction to patch must be 'ldr rd, [pp, #0]'.
-      ASSERT((Assembler::IsLdrPpImmediateOffset(instr) &&
+      DCHECK((Assembler::IsLdrPpImmediateOffset(instr) &&
               Assembler::GetLdrRegisterImmediateOffset(instr) == 0));
-      ASSERT(is_uint12(offset));
-      assm->instr_at_put(rinfo->pc(),
-          Assembler::SetLdrRegisterImmediateOffset(instr, offset));
+      DCHECK(is_uint12(offset));
+      assm->instr_at_put(
+          rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset));
     }
   }
-
-  ASSERT((index_64bit == count_of_64bit_) &&
-         (index_code_ptr == (index_64bit + count_of_code_ptr_)) &&
-         (index_heap_ptr == (index_code_ptr + count_of_heap_ptr_)) &&
-         (index_32bit == (index_heap_ptr + count_of_32bit_)));
 }