Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / v8 / src / ia32 / lithium-ia32.cc
index e02b65e..bd8ba42 100644 (file)
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <sstream>
+
 #include "src/v8.h"
 
 #if V8_TARGET_ARCH_IA32
@@ -342,32 +344,50 @@ void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
 
 
 int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) {
-  // Skip a slot if for a double-width slot.
-  if (kind == DOUBLE_REGISTERS) {
-    spill_slot_count_++;
-    spill_slot_count_ |= 1;
-    num_double_slots_++;
+  switch (kind) {
+    case GENERAL_REGISTERS: return spill_slot_count_++;
+    case DOUBLE_REGISTERS: {
+      // Skip a slot if for a double-width slot.
+      spill_slot_count_++;
+      spill_slot_count_ |= 1;
+      num_double_slots_++;
+      return spill_slot_count_++;
+    }
+    case FLOAT32x4_REGISTERS:
+    case FLOAT64x2_REGISTERS:
+    case INT32x4_REGISTERS: {
+      // Skip three slots if for a quad-width slot.
+      spill_slot_count_ += 3;
+      num_double_slots_ += 2;  // for dynamic frame alignment
+      return spill_slot_count_++;
+    }
+    default:
+      UNREACHABLE();
+      return -1;
   }
-  return spill_slot_count_++;
 }
 
 
 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) {
   int index = GetNextSpillIndex(kind);
-  if (kind == DOUBLE_REGISTERS) {
-    return LDoubleStackSlot::Create(index, zone());
-  } else {
-    DCHECK(kind == GENERAL_REGISTERS);
-    return LStackSlot::Create(index, zone());
+  switch (kind) {
+    case GENERAL_REGISTERS: return LStackSlot::Create(index, zone());
+    case DOUBLE_REGISTERS: return LDoubleStackSlot::Create(index, zone());
+    case FLOAT32x4_REGISTERS: return LFloat32x4StackSlot::Create(index, zone());
+    case FLOAT64x2_REGISTERS: return LFloat64x2StackSlot::Create(index, zone());
+    case INT32x4_REGISTERS: return LInt32x4StackSlot::Create(index, zone());
+    default:
+      UNREACHABLE();
+      return NULL;
   }
 }
 
 
 void LStoreNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
-  OStringStream os;
+  std::ostringstream os;
   os << hydrogen()->access() << " <- ";
-  stream->Add(os.c_str());
+  stream->Add(os.str().c_str());
   value()->PrintTo(stream);
 }
 
@@ -461,12 +481,6 @@ LPlatformChunk* LChunkBuilder::Build() {
 }
 
 
-void LChunkBuilder::Abort(BailoutReason reason) {
-  info()->set_bailout_reason(reason);
-  status_ = ABORTED;
-}
-
-
 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
   return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
                                   Register::ToAllocationIndex(reg));
@@ -627,9 +641,8 @@ LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
   HEnvironment* hydrogen_env = current_block_->last_environment();
   int argument_index_accumulator = 0;
   ZoneList<HValue*> objects_to_materialize(0, zone());
-  instr->set_environment(CreateEnvironment(hydrogen_env,
-                                           &argument_index_accumulator,
-                                           &objects_to_materialize));
+  instr->set_environment(CreateEnvironment(
+      hydrogen_env, &argument_index_accumulator, &objects_to_materialize));
   return instr;
 }
 
@@ -744,11 +757,7 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
     // Shift operations can only deoptimize if we do a logical shift by 0 and
     // the result cannot be truncated to int32.
     if (op == Token::SHR && constant_value == 0) {
-      if (FLAG_opt_safe_uint32_operations) {
-        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-      } else {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-      }
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
     }
 
     LInstruction* result =
@@ -983,6 +992,7 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
 
   bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() ||
       type.IsJSArray() || type.IsHeapNumber() || type.IsString();
+
   LOperand* temp = !easy_case && expected.NeedsMap() ? TempRegister() : NULL;
   LInstruction* branch = new(zone()) LBranch(UseRegister(value), temp);
   if (!easy_case &&
@@ -1124,13 +1134,13 @@ LInstruction* LChunkBuilder::DoCallJSFunction(
 
 LInstruction* LChunkBuilder::DoCallWithDescriptor(
     HCallWithDescriptor* instr) {
-  const InterfaceDescriptor* descriptor = instr->descriptor();
+  CallInterfaceDescriptor descriptor = instr->descriptor();
   LOperand* target = UseRegisterOrConstantAtStart(instr->target());
   ZoneList<LOperand*> ops(instr->OperandCount(), zone());
   ops.Add(target, zone());
   for (int i = 1; i < instr->OperandCount(); i++) {
-    LOperand* op = UseFixed(instr->OperandAt(i),
-        descriptor->GetParameterRegister(i - 1));
+    LOperand* op =
+        UseFixed(instr->OperandAt(i), descriptor.GetParameterRegister(i - 1));
     ops.Add(op, zone());
   }
 
@@ -1140,6 +1150,19 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
 }
 
 
+LInstruction* LChunkBuilder::DoTailCallThroughMegamorphicCache(
+    HTailCallThroughMegamorphicCache* instr) {
+  LOperand* context = UseFixed(instr->context(), esi);
+  LOperand* receiver_register =
+      UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
+  LOperand* name_register =
+      UseFixed(instr->name(), LoadDescriptor::NameRegister());
+  // Not marked as call. It can't deoptimize, and it never returns.
+  return new (zone()) LTailCallThroughMegamorphicCache(
+      context, receiver_register, name_register);
+}
+
+
 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
   LOperand* context = UseFixed(instr->context(), esi);
   LOperand* function = UseFixed(instr->function(), edi);
@@ -1640,9 +1663,10 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
   Representation exponent_type = instr->right()->representation();
   DCHECK(instr->left()->representation().IsDouble());
   LOperand* left = UseFixedDouble(instr->left(), xmm2);
-  LOperand* right = exponent_type.IsDouble() ?
-      UseFixedDouble(instr->right(), xmm1) :
-      UseFixed(instr->right(), eax);
+  LOperand* right =
+      exponent_type.IsDouble()
+          ? UseFixedDouble(instr->right(), xmm1)
+          : UseFixed(instr->right(), MathPowTaggedDescriptor::exponent());
   LPower* result = new(zone()) LPower(left, right);
   return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
                     CAN_DEOPTIMIZE_EAGERLY);
@@ -1851,7 +1875,9 @@ LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
   LOperand* length = !index->IsConstantOperand()
       ? UseOrConstantAtStart(instr->length())
       : UseAtStart(instr->length());
-  LInstruction* result = new(zone()) LBoundsCheck(index, length);
+  LOperand* temp0 = TempRegister();
+  LOperand* temp1 = TempRegister();
+  LInstruction* result = new(zone()) LBoundsCheck(index, length, temp0, temp1);
   if (!FLAG_debug_code || !instr->skip_check()) {
     result = AssignEnvironment(result);
   }
@@ -1905,6 +1931,11 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
           DefineAsRegister(new(zone()) LNumberUntagD(value, temp));
       if (!val->representation().IsSmi()) result = AssignEnvironment(result);
       return result;
+    } else if (to.IsSIMD128()) {
+      LOperand* value = UseRegister(instr->value());
+      LOperand* temp = TempRegister();
+      LTaggedToSIMD128* res = new(zone()) LTaggedToSIMD128(value, temp, to);
+      return AssignEnvironment(DefineAsRegister(res));
     } else if (to.IsSmi()) {
       LOperand* value = UseRegister(val);
       if (val->type().IsSmi()) {
@@ -1979,6 +2010,17 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
         return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val)));
       }
     }
+  } else if (from.IsSIMD128()) {
+    DCHECK(to.IsTagged());
+    info()->MarkAsDeferredCalling();
+    LOperand* value = UseRegister(instr->value());
+    LOperand* temp = TempRegister();
+    LOperand* temp2 = TempRegister();
+
+    // Make sure that temp and result_temp are different registers.
+    LUnallocated* result_temp = TempRegister();
+    LSIMD128ToTagged* result = new(zone()) LSIMD128ToTagged(value, temp, temp2);
+    return AssignPointerMap(Define(result, result_temp));
   }
   UNREACHABLE();
   return NULL;
@@ -2083,7 +2125,7 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
     return DefineAsRegister(new(zone()) LConstantI);
   } else if (r.IsDouble()) {
     double value = instr->DoubleValue();
-    bool value_is_zero = BitCast<uint64_t, double>(value) == 0;
+    bool value_is_zero = bit_cast<uint64_t, double>(value) == 0;
     LOperand* temp = value_is_zero ? NULL : TempRegister();
     return DefineAsRegister(new(zone()) LConstantD(temp));
   } else if (r.IsExternal()) {
@@ -2107,11 +2149,11 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
 
 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
   LOperand* context = UseFixed(instr->context(), esi);
-  LOperand* global_object = UseFixed(instr->global_object(),
-                                     LoadIC::ReceiverRegister());
+  LOperand* global_object =
+      UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
   if (FLAG_vector_ics) {
-    vector = FixedTemp(LoadIC::VectorRegister());
+    vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
   LLoadGlobalGeneric* result =
@@ -2168,10 +2210,11 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
 
 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
   LOperand* context = UseFixed(instr->context(), esi);
-  LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister());
+  LOperand* object =
+      UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
   if (FLAG_vector_ics) {
-    vector = FixedTemp(LoadIC::VectorRegister());
+    vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
   LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(
       context, object, vector);
@@ -2210,7 +2253,19 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
         (instr->representation().IsInteger32() &&
          !(IsDoubleOrFloatElementsKind(instr->elements_kind()))) ||
         (instr->representation().IsDouble() &&
-         (IsDoubleOrFloatElementsKind(instr->elements_kind()))));
+         (IsDoubleOrFloatElementsKind(instr->elements_kind()))) ||
+        (CpuFeatures::SupportsSIMD128InCrankshaft()
+            ? instr->representation().IsFloat32x4()
+            : instr->representation().IsTagged() &&
+         (IsFloat32x4ElementsKind(instr->elements_kind()))) ||
+        (CpuFeatures::SupportsSIMD128InCrankshaft()
+            ? instr->representation().IsFloat64x2()
+            : instr->representation().IsTagged() &&
+         (IsFloat64x2ElementsKind(instr->elements_kind()))) ||
+        (CpuFeatures::SupportsSIMD128InCrankshaft()
+            ? instr->representation().IsInt32x4()
+            : instr->representation().IsTagged() &&
+         (IsInt32x4ElementsKind(instr->elements_kind()))));
     LOperand* backing_store = UseRegister(instr->elements());
     result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key));
   }
@@ -2231,11 +2286,12 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
 
 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
   LOperand* context = UseFixed(instr->context(), esi);
-  LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister());
-  LOperand* key = UseFixed(instr->key(), LoadIC::NameRegister());
+  LOperand* object =
+      UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
+  LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
   LOperand* vector = NULL;
   if (FLAG_vector_ics) {
-    vector = FixedTemp(LoadIC::VectorRegister());
+    vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
   LLoadKeyedGeneric* result =
       new(zone()) LLoadKeyedGeneric(context, object, key, vector);
@@ -2245,15 +2301,26 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
 
 LOperand* LChunkBuilder::GetStoreKeyedValueOperand(HStoreKeyed* instr) {
   ElementsKind elements_kind = instr->elements_kind();
+  BuiltinFunctionId op = instr->op();
 
   // Determine if we need a byte register in this case for the value.
   bool val_is_fixed_register =
-      elements_kind == EXTERNAL_INT8_ELEMENTS ||
+      (elements_kind == EXTERNAL_INT8_ELEMENTS ||
       elements_kind == EXTERNAL_UINT8_ELEMENTS ||
       elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS ||
       elements_kind == UINT8_ELEMENTS ||
       elements_kind == INT8_ELEMENTS ||
-      elements_kind == UINT8_CLAMPED_ELEMENTS;
+      elements_kind == UINT8_CLAMPED_ELEMENTS) &&
+      (op != kInt8ArraySetFloat32x4XYZW &&
+      op != kInt8ArraySetFloat32x4X &&
+      op != kInt8ArraySetFloat32x4XY &&
+      op != kInt8ArraySetFloat32x4XYZ &&
+      op != kInt8ArraySetInt32x4XYZW &&
+      op != kInt8ArraySetInt32x4X &&
+      op != kInt8ArraySetInt32x4XY &&
+      op != kInt8ArraySetInt32x4XYZ &&
+      op != kInt8ArraySetFloat64x2XY &&
+      op != kInt8ArraySetFloat64x2X);
   if (val_is_fixed_register) {
     return UseFixed(instr->value(), eax);
   }
@@ -2297,7 +2364,19 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
       (instr->value()->representation().IsInteger32() &&
        !IsDoubleOrFloatElementsKind(elements_kind)) ||
       (instr->value()->representation().IsDouble() &&
-       IsDoubleOrFloatElementsKind(elements_kind)));
+       IsDoubleOrFloatElementsKind(elements_kind)) ||
+      (CpuFeatures::SupportsSIMD128InCrankshaft()
+          ? instr->value()->representation().IsFloat32x4()
+          : instr->value()->representation().IsTagged() &&
+       IsFloat32x4ElementsKind(elements_kind)) ||
+      (CpuFeatures::SupportsSIMD128InCrankshaft()
+          ? instr->value()->representation().IsFloat64x2()
+          : instr->value()->representation().IsTagged() &&
+       IsFloat64x2ElementsKind(elements_kind)) ||
+      (CpuFeatures::SupportsSIMD128InCrankshaft()
+          ? instr->value()->representation().IsInt32x4()
+          : instr->value()->representation().IsTagged() &&
+       IsInt32x4ElementsKind(elements_kind)));
   DCHECK((instr->is_fixed_typed_array() &&
           instr->elements()->representation().IsTagged()) ||
          (instr->is_external() &&
@@ -2316,10 +2395,10 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
 
 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
   LOperand* context = UseFixed(instr->context(), esi);
-  LOperand* object = UseFixed(instr->object(),
-                              KeyedStoreIC::ReceiverRegister());
-  LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister());
-  LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister());
+  LOperand* object =
+      UseFixed(instr->object(), StoreDescriptor::ReceiverRegister());
+  LOperand* key = UseFixed(instr->key(), StoreDescriptor::NameRegister());
+  LOperand* value = UseFixed(instr->value(), StoreDescriptor::ValueRegister());
 
   DCHECK(instr->object()->representation().IsTagged());
   DCHECK(instr->key()->representation().IsTagged());
@@ -2399,8 +2478,6 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
     val = UseTempRegister(instr->value());
   } else if (can_be_constant) {
     val = UseRegisterOrConstant(instr->value());
-  } else if (instr->field_representation().IsSmi()) {
-    val = UseTempRegister(instr->value());
   } else if (instr->field_representation().IsDouble()) {
     val = UseRegisterAtStart(instr->value());
   } else {
@@ -2421,8 +2498,9 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
 
 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
   LOperand* context = UseFixed(instr->context(), esi);
-  LOperand* object = UseFixed(instr->object(), StoreIC::ReceiverRegister());
-  LOperand* value = UseFixed(instr->value(), StoreIC::ValueRegister());
+  LOperand* object =
+      UseFixed(instr->object(), StoreDescriptor::ReceiverRegister());
+  LOperand* value = UseFixed(instr->value(), StoreDescriptor::ValueRegister());
 
   LStoreNamedGeneric* result =
       new(zone()) LStoreNamedGeneric(context, object, value);
@@ -2499,10 +2577,10 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
     return DefineAsSpilled(result, spill_index);
   } else {
     DCHECK(info()->IsStub());
-    CodeStubInterfaceDescriptor* descriptor =
-        info()->code_stub()->GetInterfaceDescriptor();
+    CallInterfaceDescriptor descriptor =
+        info()->code_stub()->GetCallInterfaceDescriptor();
     int index = static_cast<int>(instr->index());
-    Register reg = descriptor->GetEnvironmentParameterRegister(index);
+    Register reg = descriptor.GetEnvironmentParameterRegister(index);
     return DefineFixed(result, reg);
   }
 }
@@ -2518,7 +2596,7 @@ LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
   } else {
     spill_index = env_index - instr->environment()->first_local_index();
     if (spill_index > LUnallocated::kMaxFixedSlotIndex) {
-      Abort(kNotEnoughSpillSlotsForOsr);
+      Retry(kNotEnoughSpillSlotsForOsr);
       spill_index = 0;
     }
     if (spill_index == 0) {
@@ -2630,6 +2708,7 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
   if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
     inner->Bind(instr->arguments_var(), instr->arguments_object());
   }
+  inner->BindContext(instr->closure_context());
   inner->set_entry(instr);
   current_block_->UpdateEnvironment(inner);
   chunk_->AddInlinedClosure(instr->closure());
@@ -2702,6 +2781,283 @@ LInstruction* LChunkBuilder::DoAllocateBlockContext(
 }
 
 
+const char* LNullarySIMDOperation::Mnemonic() const {
+  switch (op()) {
+#define SIMD_NULLARY_OPERATION_CASE_ITEM(module, function, name, p4)           \
+    case k##name:                                                              \
+      return #module "-" #function;
+SIMD_NULLARY_OPERATIONS(SIMD_NULLARY_OPERATION_CASE_ITEM)
+#undef SIMD_NULLARY_OPERATION_CASE_ITEM
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoNullarySIMDOperation(
+    HNullarySIMDOperation* instr) {
+  LNullarySIMDOperation* result =
+      new(zone()) LNullarySIMDOperation(instr->op());
+  switch (instr->op()) {
+#define SIMD_NULLARY_OPERATION_CASE_ITEM(module, function, name, p4)           \
+    case k##name:
+SIMD_NULLARY_OPERATIONS(SIMD_NULLARY_OPERATION_CASE_ITEM)
+#undef SIMD_NULLARY_OPERATION_CASE_ITEM
+      return DefineAsRegister(result);
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+const char* LUnarySIMDOperation::Mnemonic() const {
+  switch (op()) {
+    case kSIMD128Change: return "SIMD128-change";
+#define SIMD_UNARY_OPERATION_CASE_ITEM(module, function, name, p4, p5)         \
+    case k##name:                                                              \
+      return #module "-" #function;
+SIMD_UNARY_OPERATIONS(SIMD_UNARY_OPERATION_CASE_ITEM)
+SIMD_UNARY_OPERATIONS_FOR_PROPERTY_ACCESS(SIMD_UNARY_OPERATION_CASE_ITEM)
+#undef SIMD_UNARY_OPERATION_CASE_ITEM
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoUnarySIMDOperation(HUnarySIMDOperation* instr) {
+  LOperand* input = UseRegisterAtStart(instr->value());
+  LUnarySIMDOperation* result =
+      new(zone()) LUnarySIMDOperation(input, instr->op());
+  switch (instr->op()) {
+    case kSIMD128Change:
+      return AssignEnvironment(DefineAsRegister(result));
+    case kFloat32x4Abs:
+    case kFloat32x4Neg:
+    case kFloat32x4Reciprocal:
+    case kFloat32x4ReciprocalSqrt:
+    case kFloat32x4Sqrt:
+    case kFloat64x2Abs:
+    case kFloat64x2Neg:
+    case kFloat64x2Sqrt:
+    case kInt32x4Neg:
+    case kInt32x4Not:
+      return DefineSameAsFirst(result);
+    case kFloat32x4Coercion:
+    case kFloat64x2Coercion:
+    case kInt32x4Coercion:
+    case kFloat32x4BitsToInt32x4:
+    case kFloat32x4ToInt32x4:
+    case kInt32x4BitsToFloat32x4:
+    case kInt32x4ToFloat32x4:
+    case kFloat32x4Splat:
+    case kInt32x4Splat:
+    case kFloat32x4GetSignMask:
+    case kFloat32x4GetX:
+    case kFloat32x4GetY:
+    case kFloat32x4GetZ:
+    case kFloat32x4GetW:
+    case kFloat64x2GetSignMask:
+    case kFloat64x2GetX:
+    case kFloat64x2GetY:
+    case kInt32x4GetSignMask:
+    case kInt32x4GetX:
+    case kInt32x4GetY:
+    case kInt32x4GetZ:
+    case kInt32x4GetW:
+    case kInt32x4GetFlagX:
+    case kInt32x4GetFlagY:
+    case kInt32x4GetFlagZ:
+    case kInt32x4GetFlagW:
+      return DefineAsRegister(result);
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+const char* LBinarySIMDOperation::Mnemonic() const {
+  switch (op()) {
+#define SIMD_BINARY_OPERATION_CASE_ITEM(module, function, name, p4, p5, p6)    \
+    case k##name:                                                              \
+      return #module "-" #function;
+SIMD_BINARY_OPERATIONS(SIMD_BINARY_OPERATION_CASE_ITEM)
+#undef SIMD_BINARY_OPERATION_CASE_ITEM
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoBinarySIMDOperation(
+    HBinarySIMDOperation* instr) {
+  switch (instr->op()) {
+    case kFloat32x4Add:
+    case kFloat32x4Div:
+    case kFloat32x4Max:
+    case kFloat32x4Min:
+    case kFloat32x4Mul:
+    case kFloat32x4Sub:
+    case kFloat32x4Scale:
+    case kFloat32x4WithX:
+    case kFloat32x4WithY:
+    case kFloat32x4WithZ:
+    case kFloat32x4WithW:
+    case kFloat64x2Add:
+    case kFloat64x2Div:
+    case kFloat64x2Max:
+    case kFloat64x2Min:
+    case kFloat64x2Mul:
+    case kFloat64x2Sub:
+    case kFloat64x2Scale:
+    case kFloat64x2WithX:
+    case kFloat64x2WithY:
+    case kInt32x4Add:
+    case kInt32x4And:
+    case kInt32x4Mul:
+    case kInt32x4Or:
+    case kInt32x4Sub:
+    case kInt32x4Xor:
+    case kInt32x4WithX:
+    case kInt32x4WithY:
+    case kInt32x4WithZ:
+    case kInt32x4WithW:
+    case kInt32x4WithFlagX:
+    case kInt32x4WithFlagY:
+    case kInt32x4WithFlagZ:
+    case kInt32x4WithFlagW:
+    case kInt32x4GreaterThan:
+    case kInt32x4Equal:
+    case kInt32x4LessThan: {
+      LOperand* left = UseRegisterAtStart(instr->left());
+      LOperand* right = UseRegisterAtStart(instr->right());
+      LBinarySIMDOperation* result =
+          new(zone()) LBinarySIMDOperation(left, right, instr->op());
+      if (instr->op() == kInt32x4WithFlagX ||
+          instr->op() == kInt32x4WithFlagY ||
+          instr->op() == kInt32x4WithFlagZ ||
+          instr->op() == kInt32x4WithFlagW) {
+        return AssignEnvironment(DefineSameAsFirst(result));
+      } else {
+        return DefineSameAsFirst(result);
+      }
+    }
+    case kFloat64x2Constructor: {
+      LOperand* left = UseRegisterAtStart(instr->left());
+      LOperand* right = UseRegisterAtStart(instr->right());
+      LBinarySIMDOperation* result =
+          new(zone()) LBinarySIMDOperation(left, right, instr->op());
+      return DefineAsRegister(result);
+    }
+    case kFloat32x4Shuffle:
+    case kInt32x4Shuffle:
+    case kInt32x4ShiftLeft:
+    case kInt32x4ShiftRight:
+    case kInt32x4ShiftRightArithmetic: {
+      LOperand* left = UseRegisterAtStart(instr->left());
+      LOperand* right = UseOrConstant(instr->right());
+      LBinarySIMDOperation* result =
+          new(zone()) LBinarySIMDOperation(left, right, instr->op());
+      return AssignEnvironment(DefineSameAsFirst(result));
+    }
+    case kFloat32x4LessThan:
+    case kFloat32x4LessThanOrEqual:
+    case kFloat32x4Equal:
+    case kFloat32x4NotEqual:
+    case kFloat32x4GreaterThanOrEqual:
+    case kFloat32x4GreaterThan: {
+      LOperand* left = UseRegisterAtStart(instr->left());
+      LOperand* right = UseRegisterAtStart(instr->right());
+      LBinarySIMDOperation* result =
+          new(zone()) LBinarySIMDOperation(left, right, instr->op());
+      return DefineAsRegister(result);
+    }
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+const char* LTernarySIMDOperation::Mnemonic() const {
+  switch (op()) {
+#define SIMD_TERNARY_OPERATION_CASE_ITEM(module, function, name, p4, p5, p6,   \
+                                         p7)                                   \
+    case k##name:                                                              \
+      return #module "-" #function;
+SIMD_TERNARY_OPERATIONS(SIMD_TERNARY_OPERATION_CASE_ITEM)
+#undef SIMD_TERNARY_OPERATION_CASE_ITEM
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoTernarySIMDOperation(
+    HTernarySIMDOperation* instr) {
+  LOperand* first = UseRegisterAtStart(instr->first());
+  LOperand* second = UseRegisterAtStart(instr->second());
+  LOperand* third = instr->op() == kFloat32x4ShuffleMix
+                    ? UseOrConstant(instr->third())
+                    : UseRegisterAtStart(instr->third());
+  LTernarySIMDOperation* result =
+      new(zone()) LTernarySIMDOperation(first, second, third, instr->op());
+  switch (instr->op()) {
+    case kInt32x4Select:
+    case kFloat32x4Select: {
+      return DefineAsRegister(result);
+    }
+    case kFloat32x4ShuffleMix: {
+      return AssignEnvironment(DefineSameAsFirst(result));
+    }
+    case kFloat32x4Clamp:
+    case kFloat64x2Clamp: {
+      return DefineSameAsFirst(result);
+    }
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+const char* LQuarternarySIMDOperation::Mnemonic() const {
+  switch (op()) {
+#define SIMD_QUARTERNARY_OPERATION_CASE_ITEM(module, function, name, p4, p5,   \
+                                             p6, p7, p8)                       \
+    case k##name:                                                              \
+      return #module "-" #function;
+SIMD_QUARTERNARY_OPERATIONS(SIMD_QUARTERNARY_OPERATION_CASE_ITEM)
+#undef SIMD_QUARTERNARY_OPERATION_CASE_ITEM
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoQuarternarySIMDOperation(
+    HQuarternarySIMDOperation* instr) {
+  LOperand* x = UseRegisterAtStart(instr->x());
+  LOperand* y = UseRegisterAtStart(instr->y());
+  LOperand* z = UseRegisterAtStart(instr->z());
+  LOperand* w = UseRegisterAtStart(instr->w());
+  LQuarternarySIMDOperation* result =
+      new(zone()) LQuarternarySIMDOperation(x, y, z, w, instr->op());
+  if (instr->op() == kInt32x4Bool) {
+    return AssignEnvironment(DefineAsRegister(result));
+  } else {
+    return DefineAsRegister(result);
+  }
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_IA32