diff --git a/src/compiler/arm/code-generator-arm.cc b/src/compiler/arm/code-generator-arm.cc
new file mode 100644
index 0000000..1ec174d
--- /dev/null
+++ b/src/compiler/arm/code-generator-arm.cc
@@ -0,0 +1,876 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/code-generator.h"
+
+#include "src/arm/macro-assembler-arm.h"
+#include "src/compiler/code-generator-impl.h"
+#include "src/compiler/gap-resolver.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/scopes.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+#define __ masm()->
+
+
+#define kScratchReg r9
+
+
+// Adds Arm-specific methods to convert InstructionOperands.
+class ArmOperandConverter : public InstructionOperandConverter {
+ public:
+  ArmOperandConverter(CodeGenerator* gen, Instruction* instr)
+      : InstructionOperandConverter(gen, instr) {}
+
+  SBit OutputSBit() const {
+    switch (instr_->flags_mode()) {
+      case kFlags_branch:
+      case kFlags_set:
+        return SetCC;
+      case kFlags_none:
+        return LeaveCC;
+    }
+    UNREACHABLE();
+    return LeaveCC;
+  }
+
+  Operand InputImmediate(int index) {
+    Constant constant = ToConstant(instr_->InputAt(index));
+    switch (constant.type()) {
+      case Constant::kInt32:
+        return Operand(constant.ToInt32());
+      case Constant::kFloat64:
+        return Operand(
+            isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
+      case Constant::kInt64:
+      case Constant::kExternalReference:
+      case Constant::kHeapObject:
+        break;
+    }
+    UNREACHABLE();
+    return Operand::Zero();
+  }
+
+  Operand InputOperand2(int first_index) {
+    const int index = first_index;
+    switch (AddressingModeField::decode(instr_->opcode())) {
+      case kMode_None:
+      case kMode_Offset_RI:
+      case kMode_Offset_RR:
+        break;
+      case kMode_Operand2_I:
+        return InputImmediate(index + 0);
+      case kMode_Operand2_R:
+        return Operand(InputRegister(index + 0));
+      case kMode_Operand2_R_ASR_I:
+        return Operand(InputRegister(index + 0), ASR, InputInt5(index + 1));
+      case kMode_Operand2_R_ASR_R:
+        return Operand(InputRegister(index + 0), ASR, InputRegister(index + 1));
+      case kMode_Operand2_R_LSL_I:
+        return Operand(InputRegister(index + 0), LSL, InputInt5(index + 1));
+      case kMode_Operand2_R_LSL_R:
+        return Operand(InputRegister(index + 0), LSL, InputRegister(index + 1));
+      case kMode_Operand2_R_LSR_I:
+        return Operand(InputRegister(index + 0), LSR, InputInt5(index + 1));
+      case kMode_Operand2_R_LSR_R:
+        return Operand(InputRegister(index + 0), LSR, InputRegister(index + 1));
+      case kMode_Operand2_R_ROR_I:
+        return Operand(InputRegister(index + 0), ROR, InputInt5(index + 1));
+      case kMode_Operand2_R_ROR_R:
+        return Operand(InputRegister(index + 0), ROR, InputRegister(index + 1));
+    }
+    UNREACHABLE();
+    return Operand::Zero();
+  }
+
+  MemOperand InputOffset(int* first_index) {
+    const int index = *first_index;
+    switch (AddressingModeField::decode(instr_->opcode())) {
+      case kMode_None:
+      case kMode_Operand2_I:
+      case kMode_Operand2_R:
+      case kMode_Operand2_R_ASR_I:
+      case kMode_Operand2_R_ASR_R:
+      case kMode_Operand2_R_LSL_I:
+      case kMode_Operand2_R_LSL_R:
+      case kMode_Operand2_R_LSR_I:
+      case kMode_Operand2_R_LSR_R:
+      case kMode_Operand2_R_ROR_I:
+      case kMode_Operand2_R_ROR_R:
+        break;
+      case kMode_Offset_RI:
+        *first_index += 2;
+        return MemOperand(InputRegister(index + 0), InputInt32(index + 1));
+      case kMode_Offset_RR:
+        *first_index += 2;
+        return MemOperand(InputRegister(index + 0), InputRegister(index + 1));
+    }
+    UNREACHABLE();
+    return MemOperand(r0);
+  }
+
+  MemOperand InputOffset() {
+    int index = 0;
+    return InputOffset(&index);
+  }
+
+  MemOperand ToMemOperand(InstructionOperand* op) const {
+    DCHECK(op != NULL);
+    DCHECK(!op->IsRegister());
+    DCHECK(!op->IsDoubleRegister());
+    DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
+    // The linkage computes where all spill slots are located.
+    FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0);
+    return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
+  }
+};
+
+
+// Assembles an instruction after register allocation, producing machine code.
+void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
+  ArmOperandConverter i(this, instr);
+
+  switch (ArchOpcodeField::decode(instr->opcode())) {
+    case kArchCallCodeObject: {
+      EnsureSpaceForLazyDeopt();
+      if (instr->InputAt(0)->IsImmediate()) {
+        __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
+                RelocInfo::CODE_TARGET);
+      } else {
+        __ add(ip, i.InputRegister(0),
+               Operand(Code::kHeaderSize - kHeapObjectTag));
+        __ Call(ip);
+      }
+      AddSafepointAndDeopt(instr);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArchCallJSFunction: {
+      EnsureSpaceForLazyDeopt();
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ ldr(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
+        __ cmp(cp, kScratchReg);
+        __ Assert(eq, kWrongFunctionContext);
+      }
+      __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
+      __ Call(ip);
+      AddSafepointAndDeopt(instr);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArchJmp:
+      __ b(code_->GetLabel(i.InputBlock(0)));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArchNop:
+      // don't emit code for nops.
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArchRet:
+      AssembleReturn();
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArchTruncateDoubleToI:
+      __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmAdd:
+      __ add(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1),
+             i.OutputSBit());
+      break;
+    case kArmAnd:
+      __ and_(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1),
+              i.OutputSBit());
+      break;
+    case kArmBic:
+      __ bic(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1),
+             i.OutputSBit());
+      break;
+    case kArmMul:
+      __ mul(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+             i.OutputSBit());
+      break;
+    case kArmMla:
+      __ mla(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+             i.InputRegister(2), i.OutputSBit());
+      break;
+    case kArmMls: {
+      CpuFeatureScope scope(masm(), MLS);
+      __ mls(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+             i.InputRegister(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmSdiv: {
+      CpuFeatureScope scope(masm(), SUDIV);
+      __ sdiv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmUdiv: {
+      CpuFeatureScope scope(masm(), SUDIV);
+      __ udiv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmMov:
+      __ Move(i.OutputRegister(), i.InputOperand2(0), i.OutputSBit());
+      break;
+    case kArmMvn:
+      __ mvn(i.OutputRegister(), i.InputOperand2(0), i.OutputSBit());
+      break;
+    case kArmOrr:
+      __ orr(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1),
+             i.OutputSBit());
+      break;
+    case kArmEor:
+      __ eor(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1),
+             i.OutputSBit());
+      break;
+    case kArmSub:
+      __ sub(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1),
+             i.OutputSBit());
+      break;
+    case kArmRsb:
+      __ rsb(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1),
+             i.OutputSBit());
+      break;
+    case kArmBfc: {
+      CpuFeatureScope scope(masm(), ARMv7);
+      __ bfc(i.OutputRegister(), i.InputInt8(1), i.InputInt8(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmUbfx: {
+      CpuFeatureScope scope(masm(), ARMv7);
+      __ ubfx(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+              i.InputInt8(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmCmp:
+      __ cmp(i.InputRegister(0), i.InputOperand2(1));
+      DCHECK_EQ(SetCC, i.OutputSBit());
+      break;
+    case kArmCmn:
+      __ cmn(i.InputRegister(0), i.InputOperand2(1));
+      DCHECK_EQ(SetCC, i.OutputSBit());
+      break;
+    case kArmTst:
+      __ tst(i.InputRegister(0), i.InputOperand2(1));
+      DCHECK_EQ(SetCC, i.OutputSBit());
+      break;
+    case kArmTeq:
+      __ teq(i.InputRegister(0), i.InputOperand2(1));
+      DCHECK_EQ(SetCC, i.OutputSBit());
+      break;
+    case kArmVcmpF64:
+      __ VFPCompareAndSetFlags(i.InputDoubleRegister(0),
+                               i.InputDoubleRegister(1));
+      DCHECK_EQ(SetCC, i.OutputSBit());
+      break;
+    case kArmVaddF64:
+      __ vadd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+              i.InputDoubleRegister(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVsubF64:
+      __ vsub(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+              i.InputDoubleRegister(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVmulF64:
+      __ vmul(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+              i.InputDoubleRegister(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVmlaF64:
+      __ vmla(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+              i.InputDoubleRegister(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVmlsF64:
+      __ vmls(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+              i.InputDoubleRegister(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVdivF64:
+      __ vdiv(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+              i.InputDoubleRegister(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVmodF64: {
+      // TODO(bmeurer): We should really get rid of this special instruction,
+      // and generate a CallAddress instruction instead.
+      FrameScope scope(masm(), StackFrame::MANUAL);
+      __ PrepareCallCFunction(0, 2, kScratchReg);
+      __ MovToFloatParameters(i.InputDoubleRegister(0),
+                              i.InputDoubleRegister(1));
+      __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
+                       0, 2);
+      // Move the result in the double result register.
+      __ MovFromFloatResult(i.OutputDoubleRegister());
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmVnegF64:
+      __ vneg(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    case kArmVsqrtF64:
+      __ vsqrt(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    case kArmVcvtF64S32: {
+      SwVfpRegister scratch = kScratchDoubleReg.low();
+      __ vmov(scratch, i.InputRegister(0));
+      __ vcvt_f64_s32(i.OutputDoubleRegister(), scratch);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmVcvtF64U32: {
+      SwVfpRegister scratch = kScratchDoubleReg.low();
+      __ vmov(scratch, i.InputRegister(0));
+      __ vcvt_f64_u32(i.OutputDoubleRegister(), scratch);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmVcvtS32F64: {
+      SwVfpRegister scratch = kScratchDoubleReg.low();
+      __ vcvt_s32_f64(scratch, i.InputDoubleRegister(0));
+      __ vmov(i.OutputRegister(), scratch);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmVcvtU32F64: {
+      SwVfpRegister scratch = kScratchDoubleReg.low();
+      __ vcvt_u32_f64(scratch, i.InputDoubleRegister(0));
+      __ vmov(i.OutputRegister(), scratch);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmLdrb:
+      __ ldrb(i.OutputRegister(), i.InputOffset());
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmLdrsb:
+      __ ldrsb(i.OutputRegister(), i.InputOffset());
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmStrb: {
+      int index = 0;
+      MemOperand operand = i.InputOffset(&index);
+      __ strb(i.InputRegister(index), operand);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmLdrh:
+      __ ldrh(i.OutputRegister(), i.InputOffset());
+      break;
+    case kArmLdrsh:
+      __ ldrsh(i.OutputRegister(), i.InputOffset());
+      break;
+    case kArmStrh: {
+      int index = 0;
+      MemOperand operand = i.InputOffset(&index);
+      __ strh(i.InputRegister(index), operand);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmLdr:
+      __ ldr(i.OutputRegister(), i.InputOffset());
+      break;
+    case kArmStr: {
+      int index = 0;
+      MemOperand operand = i.InputOffset(&index);
+      __ str(i.InputRegister(index), operand);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmVldr32: {
+      SwVfpRegister scratch = kScratchDoubleReg.low();
+      __ vldr(scratch, i.InputOffset());
+      __ vcvt_f64_f32(i.OutputDoubleRegister(), scratch);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmVstr32: {
+      int index = 0;
+      SwVfpRegister scratch = kScratchDoubleReg.low();
+      MemOperand operand = i.InputOffset(&index);
+      __ vcvt_f32_f64(scratch, i.InputDoubleRegister(index));
+      __ vstr(scratch, operand);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmVldr64:
+      __ vldr(i.OutputDoubleRegister(), i.InputOffset());
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVstr64: {
+      int index = 0;
+      MemOperand operand = i.InputOffset(&index);
+      __ vstr(i.InputDoubleRegister(index), operand);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmPush:
+      __ Push(i.InputRegister(0));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmStoreWriteBarrier: {
+      Register object = i.InputRegister(0);
+      Register index = i.InputRegister(1);
+      Register value = i.InputRegister(2);
+      __ add(index, object, index);
+      __ str(value, MemOperand(index));
+      SaveFPRegsMode mode =
+          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
+      LinkRegisterStatus lr_status = kLRHasNotBeenSaved;
+      __ RecordWrite(object, index, value, lr_status, mode);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+  }
+}
+
+
+// Assembles branches after an instruction.
+void CodeGenerator::AssembleArchBranch(Instruction* instr,
+                                       FlagsCondition condition) {
+  ArmOperandConverter i(this, instr);
+  Label done;
+
+  // Emit a branch. The true and false targets are always the last two inputs
+  // to the instruction.
+  BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2);
+  BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1);
+  bool fallthru = IsNextInAssemblyOrder(fblock);
+  Label* tlabel = code()->GetLabel(tblock);
+  Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
+  switch (condition) {
+    case kUnorderedEqual:
+      __ b(vs, flabel);
+    // Fall through.
+    case kEqual:
+      __ b(eq, tlabel);
+      break;
+    case kUnorderedNotEqual:
+      __ b(vs, tlabel);
+    // Fall through.
+    case kNotEqual:
+      __ b(ne, tlabel);
+      break;
+    case kSignedLessThan:
+      __ b(lt, tlabel);
+      break;
+    case kSignedGreaterThanOrEqual:
+      __ b(ge, tlabel);
+      break;
+    case kSignedLessThanOrEqual:
+      __ b(le, tlabel);
+      break;
+    case kSignedGreaterThan:
+      __ b(gt, tlabel);
+      break;
+    case kUnorderedLessThan:
+      __ b(vs, flabel);
+    // Fall through.
+    case kUnsignedLessThan:
+      __ b(lo, tlabel);
+      break;
+    case kUnorderedGreaterThanOrEqual:
+      __ b(vs, tlabel);
+    // Fall through.
+    case kUnsignedGreaterThanOrEqual:
+      __ b(hs, tlabel);
+      break;
+    case kUnorderedLessThanOrEqual:
+      __ b(vs, flabel);
+    // Fall through.
+    case kUnsignedLessThanOrEqual:
+      __ b(ls, tlabel);
+      break;
+    case kUnorderedGreaterThan:
+      __ b(vs, tlabel);
+    // Fall through.
+    case kUnsignedGreaterThan:
+      __ b(hi, tlabel);
+      break;
+    case kOverflow:
+      __ b(vs, tlabel);
+      break;
+    case kNotOverflow:
+      __ b(vc, tlabel);
+      break;
+  }
+  if (!fallthru) __ b(flabel);  // no fallthru to flabel.
+  __ bind(&done);
+}
+
+
+// Assembles boolean materializations after an instruction.
+void CodeGenerator::AssembleArchBoolean(Instruction* instr,
+                                        FlagsCondition condition) {
+  ArmOperandConverter i(this, instr);
+  Label done;
+
+  // Materialize a full 32-bit 1 or 0 value. The result register is always the
+  // last output of the instruction.
+  Label check;
+  DCHECK_NE(0, instr->OutputCount());
+  Register reg = i.OutputRegister(instr->OutputCount() - 1);
+  Condition cc = kNoCondition;
+  switch (condition) {
+    case kUnorderedEqual:
+      __ b(vc, &check);
+      __ mov(reg, Operand(0));
+      __ b(&done);
+    // Fall through.
+    case kEqual:
+      cc = eq;
+      break;
+    case kUnorderedNotEqual:
+      __ b(vc, &check);
+      __ mov(reg, Operand(1));
+      __ b(&done);
+    // Fall through.
+    case kNotEqual:
+      cc = ne;
+      break;
+    case kSignedLessThan:
+      cc = lt;
+      break;
+    case kSignedGreaterThanOrEqual:
+      cc = ge;
+      break;
+    case kSignedLessThanOrEqual:
+      cc = le;
+      break;
+    case kSignedGreaterThan:
+      cc = gt;
+      break;
+    case kUnorderedLessThan:
+      __ b(vc, &check);
+      __ mov(reg, Operand(0));
+      __ b(&done);
+    // Fall through.
+    case kUnsignedLessThan:
+      cc = lo;
+      break;
+    case kUnorderedGreaterThanOrEqual:
+      __ b(vc, &check);
+      __ mov(reg, Operand(1));
+      __ b(&done);
+    // Fall through.
+    case kUnsignedGreaterThanOrEqual:
+      cc = hs;
+      break;
+    case kUnorderedLessThanOrEqual:
+      __ b(vc, &check);
+      __ mov(reg, Operand(0));
+      __ b(&done);
+    // Fall through.
+    case kUnsignedLessThanOrEqual:
+      cc = ls;
+      break;
+    case kUnorderedGreaterThan:
+      __ b(vc, &check);
+      __ mov(reg, Operand(1));
+      __ b(&done);
+    // Fall through.
+    case kUnsignedGreaterThan:
+      cc = hi;
+      break;
+    case kOverflow:
+      cc = vs;
+      break;
+    case kNotOverflow:
+      cc = vc;
+      break;
+  }
+  __ bind(&check);
+  __ mov(reg, Operand(0));
+  __ mov(reg, Operand(1), LeaveCC, cc);
+  __ bind(&done);
+}
+
+
+void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
+  Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
+      isolate(), deoptimization_id, Deoptimizer::LAZY);
+  __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
+}
+
+
+void CodeGenerator::AssemblePrologue() {
+  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+    bool saved_pp;
+    if (FLAG_enable_ool_constant_pool) {
+      __ Push(lr, fp, pp);
+      // Adjust FP to point to saved FP.
+      __ sub(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset));
+      saved_pp = true;
+    } else {
+      __ Push(lr, fp);
+      __ mov(fp, sp);
+      saved_pp = false;
+    }
+    const RegList saves = descriptor->CalleeSavedRegisters();
+    if (saves != 0 || saved_pp) {
+      // Save callee-saved registers.
+      int register_save_area_size = saved_pp ? kPointerSize : 0;
+      for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
+        if (!((1 << i) & saves)) continue;
+        register_save_area_size += kPointerSize;
+      }
+      frame()->SetRegisterSaveAreaSize(register_save_area_size);
+      __ stm(db_w, sp, saves);
+    }
+  } else if (descriptor->IsJSFunctionCall()) {
+    CompilationInfo* info = linkage()->info();
+    __ Prologue(info->IsCodePreAgingActive());
+    frame()->SetRegisterSaveAreaSize(
+        StandardFrameConstants::kFixedFrameSizeFromFp);
+
+    // Sloppy mode functions and builtins need to replace the receiver with the
+    // global proxy when called as functions (without an explicit receiver
+    // object).
+    // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
+    if (info->strict_mode() == SLOPPY && !info->is_native()) {
+      Label ok;
+      // +2 for return address and saved frame pointer.
+      int receiver_slot = info->scope()->num_parameters() + 2;
+      __ ldr(r2, MemOperand(fp, receiver_slot * kPointerSize));
+      __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
+      __ b(ne, &ok);
+      __ ldr(r2, GlobalObjectOperand());
+      __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalProxyOffset));
+      __ str(r2, MemOperand(fp, receiver_slot * kPointerSize));
+      __ bind(&ok);
+    }
+
+  } else {
+    __ StubPrologue();
+    frame()->SetRegisterSaveAreaSize(
+        StandardFrameConstants::kFixedFrameSizeFromFp);
+  }
+  int stack_slots = frame()->GetSpillSlotCount();
+  if (stack_slots > 0) {
+    __ sub(sp, sp, Operand(stack_slots * kPointerSize));
+  }
+}
+
+
+void CodeGenerator::AssembleReturn() {
+  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+    if (frame()->GetRegisterSaveAreaSize() > 0) {
+      // Remove this frame's spill slots first.
+      int stack_slots = frame()->GetSpillSlotCount();
+      if (stack_slots > 0) {
+        __ add(sp, sp, Operand(stack_slots * kPointerSize));
+      }
+      // Restore registers.
+      const RegList saves = descriptor->CalleeSavedRegisters();
+      if (saves != 0) {
+        __ ldm(ia_w, sp, saves);
+      }
+    }
+    __ LeaveFrame(StackFrame::MANUAL);
+    __ Ret();
+  } else {
+    __ LeaveFrame(StackFrame::MANUAL);
+    int pop_count = descriptor->IsJSFunctionCall()
+                        ? static_cast<int>(descriptor->JSParameterCount())
+                        : 0;
+    __ Drop(pop_count);
+    __ Ret();
+  }
+}
+
+
+void CodeGenerator::AssembleMove(InstructionOperand* source,
+                                 InstructionOperand* destination) {
+  ArmOperandConverter g(this, NULL);
+  // Dispatch on the source and destination operand kinds.  Not all
+  // combinations are possible.
+  if (source->IsRegister()) {
+    DCHECK(destination->IsRegister() || destination->IsStackSlot());
+    Register src = g.ToRegister(source);
+    if (destination->IsRegister()) {
+      __ mov(g.ToRegister(destination), src);
+    } else {
+      __ str(src, g.ToMemOperand(destination));
+    }
+  } else if (source->IsStackSlot()) {
+    DCHECK(destination->IsRegister() || destination->IsStackSlot());
+    MemOperand src = g.ToMemOperand(source);
+    if (destination->IsRegister()) {
+      __ ldr(g.ToRegister(destination), src);
+    } else {
+      Register temp = kScratchReg;
+      __ ldr(temp, src);
+      __ str(temp, g.ToMemOperand(destination));
+    }
+  } else if (source->IsConstant()) {
+    if (destination->IsRegister() || destination->IsStackSlot()) {
+      Register dst =
+          destination->IsRegister() ? g.ToRegister(destination) : kScratchReg;
+      Constant src = g.ToConstant(source);
+      switch (src.type()) {
+        case Constant::kInt32:
+          __ mov(dst, Operand(src.ToInt32()));
+          break;
+        case Constant::kInt64:
+          UNREACHABLE();
+          break;
+        case Constant::kFloat64:
+          __ Move(dst,
+                  isolate()->factory()->NewNumber(src.ToFloat64(), TENURED));
+          break;
+        case Constant::kExternalReference:
+          __ mov(dst, Operand(src.ToExternalReference()));
+          break;
+        case Constant::kHeapObject:
+          __ Move(dst, src.ToHeapObject());
+          break;
+      }
+      if (destination->IsStackSlot()) __ str(dst, g.ToMemOperand(destination));
+    } else if (destination->IsDoubleRegister()) {
+      DwVfpRegister result = g.ToDoubleRegister(destination);
+      __ vmov(result, g.ToDouble(source));
+    } else {
+      DCHECK(destination->IsDoubleStackSlot());
+      DwVfpRegister temp = kScratchDoubleReg;
+      __ vmov(temp, g.ToDouble(source));
+      __ vstr(temp, g.ToMemOperand(destination));
+    }
+  } else if (source->IsDoubleRegister()) {
+    DwVfpRegister src = g.ToDoubleRegister(source);
+    if (destination->IsDoubleRegister()) {
+      DwVfpRegister dst = g.ToDoubleRegister(destination);
+      __ Move(dst, src);
+    } else {
+      DCHECK(destination->IsDoubleStackSlot());
+      __ vstr(src, g.ToMemOperand(destination));
+    }
+  } else if (source->IsDoubleStackSlot()) {
+    DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot());
+    MemOperand src = g.ToMemOperand(source);
+    if (destination->IsDoubleRegister()) {
+      __ vldr(g.ToDoubleRegister(destination), src);
+    } else {
+      DwVfpRegister temp = kScratchDoubleReg;
+      __ vldr(temp, src);
+      __ vstr(temp, g.ToMemOperand(destination));
+    }
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
+void CodeGenerator::AssembleSwap(InstructionOperand* source,
+                                 InstructionOperand* destination) {
+  ArmOperandConverter g(this, NULL);
+  // Dispatch on the source and destination operand kinds.  Not all
+  // combinations are possible.
+  if (source->IsRegister()) {
+    // Register-register.
+    Register temp = kScratchReg;
+    Register src = g.ToRegister(source);
+    if (destination->IsRegister()) {
+      Register dst = g.ToRegister(destination);
+      __ Move(temp, src);
+      __ Move(src, dst);
+      __ Move(dst, temp);
+    } else {
+      DCHECK(destination->IsStackSlot());
+      MemOperand dst = g.ToMemOperand(destination);
+      __ mov(temp, src);
+      __ ldr(src, dst);
+      __ str(temp, dst);
+    }
+  } else if (source->IsStackSlot()) {
+    DCHECK(destination->IsStackSlot());
+    Register temp_0 = kScratchReg;
+    SwVfpRegister temp_1 = kScratchDoubleReg.low();
+    MemOperand src = g.ToMemOperand(source);
+    MemOperand dst = g.ToMemOperand(destination);
+    __ ldr(temp_0, src);
+    __ vldr(temp_1, dst);
+    __ str(temp_0, dst);
+    __ vstr(temp_1, src);
+  } else if (source->IsDoubleRegister()) {
+    DwVfpRegister temp = kScratchDoubleReg;
+    DwVfpRegister src = g.ToDoubleRegister(source);
+    if (destination->IsDoubleRegister()) {
+      DwVfpRegister dst = g.ToDoubleRegister(destination);
+      __ Move(temp, src);
+      __ Move(src, dst);
+      __ Move(dst, temp);
+    } else {
+      DCHECK(destination->IsDoubleStackSlot());
+      MemOperand dst = g.ToMemOperand(destination);
+      __ Move(temp, src);
+      __ vldr(src, dst);
+      __ vstr(temp, dst);
+    }
+  } else if (source->IsDoubleStackSlot()) {
+    DCHECK(destination->IsDoubleStackSlot());
+    Register temp_0 = kScratchReg;
+    DwVfpRegister temp_1 = kScratchDoubleReg;
+    MemOperand src0 = g.ToMemOperand(source);
+    MemOperand src1(src0.rn(), src0.offset() + kPointerSize);
+    MemOperand dst0 = g.ToMemOperand(destination);
+    MemOperand dst1(dst0.rn(), dst0.offset() + kPointerSize);
+    __ vldr(temp_1, dst0);  // Save destination in temp_1.
+    __ ldr(temp_0, src0);   // Then use temp_0 to copy source to destination.
+    __ str(temp_0, dst0);
+    __ ldr(temp_0, src1);
+    __ str(temp_0, dst1);
+    __ vstr(temp_1, src0);
+  } else {
+    // No other combinations are possible.
+    UNREACHABLE();
+  }
+}
+
+
+void CodeGenerator::AddNopForSmiCodeInlining() {
+  // On 32-bit ARM we do not insert nops for inlined Smi code.
+}
+
+
+void CodeGenerator::EnsureSpaceForLazyDeopt() {
+  int space_needed = Deoptimizer::patch_size();
+  if (!linkage()->info()->IsStub()) {
+    // Ensure that we have enough space after the previous lazy-bailout
+    // instruction for patching the code here.
+    int current_pc = masm()->pc_offset();
+    if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+      // Block literal pool emission for duration of padding.
+      v8::internal::Assembler::BlockConstPoolScope block_const_pool(masm());
+      int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+      DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
+      while (padding_size > 0) {
+        __ nop();
+        padding_size -= v8::internal::Assembler::kInstrSize;
+      }
+    }
+  }
+  MarkLazyDeoptSite();
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
