| Index: src/hydrogen-instructions.h
 | 
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
 | 
| index 272c6bdaf044a8906b201348da851e49ac80a815..aa14c4a49784cd25521ba7e2d6c8ae96a4e45e75 100644
 | 
| --- a/src/hydrogen-instructions.h
 | 
| +++ b/src/hydrogen-instructions.h
 | 
| @@ -186,6 +186,11 @@ class LChunkBuilder;
 | 
|    V(Typeof)                                    \
 | 
|    V(TypeofIsAndBranch)                         \
 | 
|    V(UnaryMathOperation)                        \
 | 
| +  V(NullarySIMDOperation)                      \
 | 
| +  V(UnarySIMDOperation)                        \
 | 
| +  V(BinarySIMDOperation)                       \
 | 
| +  V(TernarySIMDOperation)                      \
 | 
| +  V(QuarternarySIMDOperation)                  \
 | 
|    V(UnknownOSRValue)                           \
 | 
|    V(UseConst)                                  \
 | 
|    V(ValueOf)                                   \
 | 
| @@ -316,6 +321,8 @@ class HType V8_FINAL {
 | 
|    static HType TaggedNumber() { return HType(kTaggedNumber); }
 | 
|    static HType Smi() { return HType(kSmi); }
 | 
|    static HType HeapNumber() { return HType(kHeapNumber); }
 | 
| +  static HType Float32x4() { return HType(kFloat32x4); }
 | 
| +  static HType Int32x4() { return HType(kInt32x4); }
 | 
|    static HType String() { return HType(kString); }
 | 
|    static HType Boolean() { return HType(kBoolean); }
 | 
|    static HType NonPrimitive() { return HType(kNonPrimitive); }
 | 
| @@ -351,13 +358,21 @@ class HType V8_FINAL {
 | 
|      return ((type_ & kHeapNumber) == kHeapNumber);
 | 
|    }
 | 
|  
 | 
| +  bool IsFloat32x4() const {
 | 
| +    return ((type_ & kFloat32x4) == kFloat32x4);
 | 
| +  }
 | 
| +
 | 
| +  bool IsInt32x4() const {
 | 
| +    return ((type_ & kInt32x4) == kInt32x4);
 | 
| +  }
 | 
| +
 | 
|    bool IsString() const {
 | 
|      return ((type_ & kString) == kString);
 | 
|    }
 | 
|  
 | 
|    bool IsNonString() const {
 | 
|      return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() ||
 | 
| -        IsBoolean() || IsJSArray();
 | 
| +        IsFloat32x4() || IsInt32x4() || IsBoolean() || IsJSArray();
 | 
|    }
 | 
|  
 | 
|    bool IsBoolean() const {
 | 
| @@ -377,7 +392,8 @@ class HType V8_FINAL {
 | 
|    }
 | 
|  
 | 
|    bool IsHeapObject() const {
 | 
| -    return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive();
 | 
| +    return IsHeapNumber() || IsFloat32x4() || IsInt32x4() || IsString() ||
 | 
| +        IsBoolean() || IsNonPrimitive();
 | 
|    }
 | 
|  
 | 
|    bool ToStringOrToNumberCanBeObserved(Representation representation) {
 | 
| @@ -386,6 +402,8 @@ class HType V8_FINAL {
 | 
|        case kTaggedNumber:     // fallthru
 | 
|        case kSmi:              // fallthru
 | 
|        case kHeapNumber:       // fallthru
 | 
| +      case kFloat32x4:        // fallthru
 | 
| +      case kInt32x4:          // fallthru
 | 
|        case kString:           // fallthru
 | 
|        case kBoolean:
 | 
|          return false;
 | 
| @@ -399,6 +417,7 @@ class HType V8_FINAL {
 | 
|    }
 | 
|  
 | 
|    static HType TypeFromValue(Handle<Object> value);
 | 
| +  static HType TypeFromRepresentation(Representation representation);
 | 
|  
 | 
|    const char* ToString();
 | 
|  
 | 
| @@ -410,11 +429,13 @@ class HType V8_FINAL {
 | 
|      kTaggedNumber = 0xd,     // 0000 0000 0000 1101
 | 
|      kSmi = 0x1d,             // 0000 0000 0001 1101
 | 
|      kHeapNumber = 0x2d,      // 0000 0000 0010 1101
 | 
| -    kString = 0x45,          // 0000 0000 0100 0101
 | 
| -    kBoolean = 0x85,         // 0000 0000 1000 0101
 | 
| -    kNonPrimitive = 0x101,   // 0000 0001 0000 0001
 | 
| -    kJSObject = 0x301,       // 0000 0011 0000 0001
 | 
| -    kJSArray = 0x701         // 0000 0111 0000 0001
 | 
| +    kFloat32x4 = 0x45,       // 0000 0000 0100 0101
 | 
| +    kInt32x4 = 0x85,         // 0000 0000 1000 0101
 | 
| +    kString = 0x105,         // 0000 0001 0000 0101
 | 
| +    kBoolean = 0x205,        // 0000 0010 1000 0101
 | 
| +    kNonPrimitive = 0x401,   // 0000 0100 0000 0001
 | 
| +    kJSObject = 0xc01,       // 0000 1100 0000 0001
 | 
| +    kJSArray = 0x1c01        // 0001 1100 0000 0001
 | 
|    };
 | 
|  
 | 
|    // Make sure type fits in int16.
 | 
| @@ -676,6 +697,8 @@ class HValue : public ZoneObject {
 | 
|        HType t = type();
 | 
|        if (t.IsSmi()) return Representation::Smi();
 | 
|        if (t.IsHeapNumber()) return Representation::Double();
 | 
| +      if (t.IsFloat32x4()) return Representation::Float32x4();
 | 
| +      if (t.IsInt32x4()) return Representation::Int32x4();
 | 
|        if (t.IsHeapObject()) return r;
 | 
|        return Representation::None();
 | 
|      }
 | 
| @@ -1718,7 +1741,13 @@ class HChange V8_FINAL : public HUnaryOperation {
 | 
|      if (value->representation().IsSmi() || value->type().IsSmi()) {
 | 
|        set_type(HType::Smi());
 | 
|      } else {
 | 
| -      set_type(HType::TaggedNumber());
 | 
| +      if (to.IsFloat32x4()) {
 | 
| +        set_type(HType::Float32x4());
 | 
| +      } else if (to.IsInt32x4()) {
 | 
| +        set_type(HType::Int32x4());
 | 
| +      } else {
 | 
| +        set_type(HType::TaggedNumber());
 | 
| +      }
 | 
|        if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
 | 
|      }
 | 
|    }
 | 
| @@ -2744,6 +2773,502 @@ class HLoadRoot V8_FINAL : public HTemplateInstruction<0> {
 | 
|  };
 | 
|  
 | 
|  
 | 
| +class HNullarySIMDOperation V8_FINAL : public HTemplateInstruction<1> {
 | 
| + public:
 | 
| +  static HInstruction* New(Zone* zone,
 | 
| +                           HValue* context,
 | 
| +                           BuiltinFunctionId op);
 | 
| +
 | 
| +  HValue* context() { return OperandAt(0); }
 | 
| +
 | 
| +  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 | 
| +
 | 
| +  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
 | 
| +    return Representation::Tagged();
 | 
| +  }
 | 
| +
 | 
| +  virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
 | 
| +  virtual HValue* Canonicalize() V8_OVERRIDE;
 | 
| +
 | 
| +  BuiltinFunctionId op() const { return op_; }
 | 
| +  const char* OpName() const;
 | 
| +
 | 
| +  DECLARE_CONCRETE_INSTRUCTION(NullarySIMDOperation)
 | 
| +
 | 
| + protected:
 | 
| +  virtual bool DataEquals(HValue* other) V8_OVERRIDE {
 | 
| +    HNullarySIMDOperation* b = HNullarySIMDOperation::cast(other);
 | 
| +    return op_ == b->op();
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  HNullarySIMDOperation(HValue* context, BuiltinFunctionId op)
 | 
| +      : HTemplateInstruction<1>(HType::Float32x4()), op_(op) {
 | 
| +    SetOperandAt(0, context);
 | 
| +    switch (op) {
 | 
| +      case kFloat32x4Zero:
 | 
| +        set_representation(Representation::Float32x4());
 | 
| +        break;
 | 
| +      default:
 | 
| +        UNREACHABLE();
 | 
| +    }
 | 
| +    SetFlag(kUseGVN);
 | 
| +  }
 | 
| +
 | 
| +  virtual bool IsDeletable() const V8_OVERRIDE { return true; }
 | 
| +
 | 
| +  BuiltinFunctionId op_;
 | 
| +};
 | 
| +
 | 
| +
 | 
| +class HUnarySIMDOperation V8_FINAL : public HTemplateInstruction<2> {
 | 
| + public:
 | 
| +  static HInstruction* New(Zone* zone,
 | 
| +                           HValue* context,
 | 
| +                           HValue* value,
 | 
| +                           BuiltinFunctionId op,
 | 
| +                           Representation to = Representation::Float32x4());
 | 
| +
 | 
| +  HValue* context() { return OperandAt(0); }
 | 
| +  HValue* value() { return OperandAt(1); }
 | 
| +
 | 
| +  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 | 
| +
 | 
| +  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
 | 
| +    if (op_ == kFloat32x4OrInt32x4Change) {
 | 
| +      return value()->representation();
 | 
| +    } else if (index == 0) {
 | 
| +      return Representation::Tagged();
 | 
| +    } else {
 | 
| +      switch (op_) {
 | 
| +        case kSIMDAbs:
 | 
| +        case kSIMDNeg:
 | 
| +        case kSIMDReciprocal:
 | 
| +        case kSIMDReciprocalSqrt:
 | 
| +        case kSIMDSqrt:
 | 
| +        case kSIMDBitsToInt32x4:
 | 
| +        case kSIMDToInt32x4:
 | 
| +        case kFloat32x4SignMask:
 | 
| +        case kFloat32x4X:
 | 
| +        case kFloat32x4Y:
 | 
| +        case kFloat32x4Z:
 | 
| +        case kFloat32x4W:
 | 
| +          return Representation::Float32x4();
 | 
| +        case kSIMDBitsToFloat32x4:
 | 
| +        case kSIMDToFloat32x4:
 | 
| +        case kInt32x4SignMask:
 | 
| +        case kInt32x4X:
 | 
| +        case kInt32x4Y:
 | 
| +        case kInt32x4Z:
 | 
| +        case kInt32x4W:
 | 
| +        case kInt32x4FlagX:
 | 
| +        case kInt32x4FlagY:
 | 
| +        case kInt32x4FlagZ:
 | 
| +        case kInt32x4FlagW:
 | 
| +        case kSIMDNegU32:
 | 
| +          return Representation::Int32x4();
 | 
| +        case kFloat32x4Splat:
 | 
| +          return Representation::Double();
 | 
| +        case kInt32x4Splat:
 | 
| +          return Representation::Integer32();
 | 
| +        default:
 | 
| +          UNREACHABLE();
 | 
| +          return Representation::None();
 | 
| +      }
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
 | 
| +
 | 
| +  virtual HValue* Canonicalize() V8_OVERRIDE;
 | 
| +  virtual Representation RepresentationFromInputs() V8_OVERRIDE;
 | 
| +
 | 
| +  BuiltinFunctionId op() const { return op_; }
 | 
| +  const char* OpName() const;
 | 
| +
 | 
| +  DECLARE_CONCRETE_INSTRUCTION(UnarySIMDOperation)
 | 
| +
 | 
| + protected:
 | 
| +  virtual bool DataEquals(HValue* other) V8_OVERRIDE {
 | 
| +    HUnarySIMDOperation* b = HUnarySIMDOperation::cast(other);
 | 
| +    return op_ == b->op();
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  HUnarySIMDOperation(HValue* context, HValue* value, BuiltinFunctionId op,
 | 
| +                      Representation to = Representation::Float32x4())
 | 
| +      : HTemplateInstruction<2>(HType::TypeFromRepresentation(to)), op_(op) {
 | 
| +    SetOperandAt(0, context);
 | 
| +    SetOperandAt(1, value);
 | 
| +    switch (op) {
 | 
| +      case kFloat32x4OrInt32x4Change:
 | 
| +        set_representation(to);
 | 
| +        break;
 | 
| +      case kSIMDAbs:
 | 
| +      case kSIMDNeg:
 | 
| +      case kSIMDReciprocal:
 | 
| +      case kSIMDReciprocalSqrt:
 | 
| +      case kSIMDSqrt:
 | 
| +      case kSIMDBitsToFloat32x4:
 | 
| +      case kSIMDToFloat32x4:
 | 
| +      case kFloat32x4Splat:
 | 
| +        set_representation(Representation::Float32x4());
 | 
| +        break;
 | 
| +      case kSIMDBitsToInt32x4:
 | 
| +      case kSIMDToInt32x4:
 | 
| +      case kInt32x4Splat:
 | 
| +      case kSIMDNegU32:
 | 
| +        set_representation(Representation::Int32x4());
 | 
| +        type_ = HType::Int32x4();
 | 
| +        break;
 | 
| +      case kFloat32x4SignMask:
 | 
| +      case kInt32x4SignMask:
 | 
| +        set_representation(Representation::Integer32());
 | 
| +        break;
 | 
| +      case kFloat32x4X:
 | 
| +      case kFloat32x4Y:
 | 
| +      case kFloat32x4Z:
 | 
| +      case kFloat32x4W:
 | 
| +        set_representation(Representation::Double());
 | 
| +        break;
 | 
| +      case kInt32x4X:
 | 
| +      case kInt32x4Y:
 | 
| +      case kInt32x4Z:
 | 
| +      case kInt32x4W:
 | 
| +        set_representation(Representation::Integer32());
 | 
| +        break;
 | 
| +      case kInt32x4FlagX:
 | 
| +      case kInt32x4FlagY:
 | 
| +      case kInt32x4FlagZ:
 | 
| +      case kInt32x4FlagW:
 | 
| +        set_representation(Representation::Tagged());
 | 
| +        break;
 | 
| +      default:
 | 
| +        UNREACHABLE();
 | 
| +    }
 | 
| +    SetFlag(kUseGVN);
 | 
| +  }
 | 
| +
 | 
| +  virtual bool IsDeletable() const V8_OVERRIDE { return true; }
 | 
| +
 | 
| +  BuiltinFunctionId op_;
 | 
| +};
 | 
| +
 | 
| +
 | 
| +class HBinarySIMDOperation V8_FINAL : public HTemplateInstruction<3> {
 | 
| + public:
 | 
| +  static HInstruction* New(Zone* zone,
 | 
| +                           HValue* context,
 | 
| +                           HValue* left,
 | 
| +                           HValue* right,
 | 
| +                           BuiltinFunctionId op);
 | 
| +
 | 
| +  HValue* context() { return OperandAt(0); }
 | 
| +  HValue* left() { return OperandAt(1); }
 | 
| +  HValue* right() { return OperandAt(2); }
 | 
| +
 | 
| +  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 | 
| +
 | 
| +  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
 | 
| +    if (index == 0) {
 | 
| +      return Representation::Tagged();
 | 
| +    } else {
 | 
| +      switch (op_) {
 | 
| +        case kSIMDAdd:
 | 
| +        case kSIMDSub:
 | 
| +        case kSIMDMul:
 | 
| +        case kSIMDDiv:
 | 
| +        case kSIMDMin:
 | 
| +        case kSIMDMax:
 | 
| +        case kSIMDLessThan:
 | 
| +        case kSIMDLessThanOrEqual:
 | 
| +        case kSIMDEqual:
 | 
| +        case kSIMDNotEqual:
 | 
| +        case kSIMDGreaterThanOrEqual:
 | 
| +        case kSIMDGreaterThan:
 | 
| +          return Representation::Float32x4();
 | 
| +        case kSIMDAnd:
 | 
| +        case kSIMDOr:
 | 
| +        case kSIMDXor:
 | 
| +        case kSIMDAddU32:
 | 
| +        case kSIMDSubU32:
 | 
| +        case kSIMDMulU32:
 | 
| +          return Representation::Int32x4();
 | 
| +        case kSIMDShuffle:
 | 
| +          return index == 1 ? Representation::Float32x4()
 | 
| +                            : Representation::Integer32();
 | 
| +        case kSIMDScale:
 | 
| +        case kSIMDWithX:
 | 
| +        case kSIMDWithY:
 | 
| +        case kSIMDWithZ:
 | 
| +        case kSIMDWithW:
 | 
| +          return index == 1 ? Representation::Float32x4()
 | 
| +                            : Representation::Double();
 | 
| +        case kSIMDWithXu32:
 | 
| +        case kSIMDWithYu32:
 | 
| +        case kSIMDWithZu32:
 | 
| +        case kSIMDWithWu32:
 | 
| +        case kSIMDShuffleU32:
 | 
| +          return index == 1 ? Representation::Int32x4()
 | 
| +                            : Representation::Integer32();
 | 
| +        case kSIMDWithFlagX:
 | 
| +        case kSIMDWithFlagY:
 | 
| +        case kSIMDWithFlagZ:
 | 
| +        case kSIMDWithFlagW:
 | 
| +          return index == 1 ? Representation::Int32x4()
 | 
| +                            : Representation::Tagged();
 | 
| +        default:
 | 
| +          UNREACHABLE();
 | 
| +          return Representation::None();
 | 
| +      }
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
 | 
| +
 | 
| +  virtual HValue* Canonicalize() V8_OVERRIDE;
 | 
| +  virtual Representation RepresentationFromInputs() V8_OVERRIDE;
 | 
| +
 | 
| +  BuiltinFunctionId op() const { return op_; }
 | 
| +  const char* OpName() const;
 | 
| +
 | 
| +  DECLARE_CONCRETE_INSTRUCTION(BinarySIMDOperation)
 | 
| +
 | 
| + protected:
 | 
| +  virtual bool DataEquals(HValue* other) V8_OVERRIDE {
 | 
| +    HBinarySIMDOperation* b = HBinarySIMDOperation::cast(other);
 | 
| +    return op_ == b->op();
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  HBinarySIMDOperation(HValue* context, HValue* left, HValue* right,
 | 
| +                       BuiltinFunctionId op)
 | 
| +      : HTemplateInstruction<3>(HType::Float32x4()), op_(op) {
 | 
| +    SetOperandAt(0, context);
 | 
| +    SetOperandAt(1, left);
 | 
| +    SetOperandAt(2, right);
 | 
| +    switch (op) {
 | 
| +      case kSIMDAdd:
 | 
| +      case kSIMDSub:
 | 
| +      case kSIMDMul:
 | 
| +      case kSIMDDiv:
 | 
| +      case kSIMDMin:
 | 
| +      case kSIMDMax:
 | 
| +      case kSIMDScale:
 | 
| +      case kSIMDShuffle:
 | 
| +      case kSIMDWithX:
 | 
| +      case kSIMDWithY:
 | 
| +      case kSIMDWithZ:
 | 
| +      case kSIMDWithW:
 | 
| +        set_representation(Representation::Float32x4());
 | 
| +        break;
 | 
| +      case kSIMDAnd:
 | 
| +      case kSIMDOr:
 | 
| +      case kSIMDXor:
 | 
| +      case kSIMDAddU32:
 | 
| +      case kSIMDSubU32:
 | 
| +      case kSIMDMulU32:
 | 
| +      case kSIMDLessThan:
 | 
| +      case kSIMDLessThanOrEqual:
 | 
| +      case kSIMDEqual:
 | 
| +      case kSIMDNotEqual:
 | 
| +      case kSIMDGreaterThanOrEqual:
 | 
| +      case kSIMDGreaterThan:
 | 
| +      case kSIMDWithXu32:
 | 
| +      case kSIMDWithYu32:
 | 
| +      case kSIMDWithZu32:
 | 
| +      case kSIMDWithWu32:
 | 
| +      case kSIMDWithFlagX:
 | 
| +      case kSIMDWithFlagY:
 | 
| +      case kSIMDWithFlagZ:
 | 
| +      case kSIMDWithFlagW:
 | 
| +      case kSIMDShuffleU32:
 | 
| +        set_representation(Representation::Int32x4());
 | 
| +        type_ = HType::Int32x4();
 | 
| +        break;
 | 
| +      default:
 | 
| +        UNREACHABLE();
 | 
| +    }
 | 
| +    SetFlag(kUseGVN);
 | 
| +  }
 | 
| +
 | 
| +  virtual bool IsDeletable() const V8_OVERRIDE { return true; }
 | 
| +
 | 
| +  BuiltinFunctionId op_;
 | 
| +};
 | 
| +
 | 
| +
 | 
| +class HTernarySIMDOperation V8_FINAL : public HTemplateInstruction<4> {
 | 
| + public:
 | 
| +  static HInstruction* New(Zone* zone,
 | 
| +                           HValue* context,
 | 
| +                           HValue* first,
 | 
| +                           HValue* second,
 | 
| +                           HValue* third,
 | 
| +                           BuiltinFunctionId op);
 | 
| +
 | 
| +  HValue* context() { return OperandAt(0); }
 | 
| +  HValue* first() { return OperandAt(1); }
 | 
| +  HValue* second() { return OperandAt(2); }
 | 
| +  HValue* third() { return OperandAt(3); }
 | 
| +
 | 
| +  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 | 
| +
 | 
| +  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
 | 
| +    if (index == 0) {
 | 
| +      return Representation::Tagged();
 | 
| +    } else {
 | 
| +      switch (op_) {
 | 
| +        case kSIMDSelect:
 | 
| +          switch (index) {
 | 
| +            case 1: return Representation::Int32x4();
 | 
| +            case 2: return Representation::Float32x4();
 | 
| +            case 3: return Representation::Float32x4();
 | 
| +            default:
 | 
| +              UNREACHABLE();
 | 
| +              return Representation::None();
 | 
| +          }
 | 
| +        case kSIMDShuffleMix:
 | 
| +          switch (index) {
 | 
| +            case 1: return Representation::Float32x4();
 | 
| +            case 2: return Representation::Float32x4();
 | 
| +            case 3: return Representation::Integer32();
 | 
| +            default:
 | 
| +              UNREACHABLE();
 | 
| +              return Representation::None();
 | 
| +          }
 | 
| +        case kSIMDClamp:
 | 
| +          return Representation::Float32x4();
 | 
| +        default:
 | 
| +          UNREACHABLE();
 | 
| +          return Representation::None();
 | 
| +      }
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
 | 
| +
 | 
| +  virtual HValue* Canonicalize() V8_OVERRIDE;
 | 
| +  virtual Representation RepresentationFromInputs() V8_OVERRIDE;
 | 
| +
 | 
| +  BuiltinFunctionId op() const { return op_; }
 | 
| +  const char* OpName() const;
 | 
| +
 | 
| +  DECLARE_CONCRETE_INSTRUCTION(TernarySIMDOperation)
 | 
| +
 | 
| + protected:
 | 
| +  virtual bool DataEquals(HValue* other) V8_OVERRIDE {
 | 
| +    HTernarySIMDOperation* b = HTernarySIMDOperation::cast(other);
 | 
| +    return op_ == b->op();
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  HTernarySIMDOperation(HValue* context, HValue* first, HValue* second,
 | 
| +                        HValue* third, BuiltinFunctionId op)
 | 
| +      : HTemplateInstruction<4>(HType::Float32x4()), op_(op) {
 | 
| +    SetOperandAt(0, context);
 | 
| +    SetOperandAt(1, first);
 | 
| +    SetOperandAt(2, second);
 | 
| +    SetOperandAt(3, third);
 | 
| +    switch (op) {
 | 
| +      case kSIMDSelect:
 | 
| +      case kSIMDShuffleMix:
 | 
| +      case kSIMDClamp:
 | 
| +        set_representation(Representation::Float32x4());
 | 
| +        break;
 | 
| +      default:
 | 
| +        UNREACHABLE();
 | 
| +    }
 | 
| +    SetFlag(kUseGVN);
 | 
| +  }
 | 
| +
 | 
| +  virtual bool IsDeletable() const V8_OVERRIDE { return true; }
 | 
| +
 | 
| +  BuiltinFunctionId op_;
 | 
| +};
 | 
| +
 | 
| +
 | 
| +class HQuarternarySIMDOperation V8_FINAL : public HTemplateInstruction<5> {
 | 
| + public:
 | 
| +  static HInstruction* New(Zone* zone,
 | 
| +                           HValue* context,
 | 
| +                           HValue* x,
 | 
| +                           HValue* y,
 | 
| +                           HValue* z,
 | 
| +                           HValue* w,
 | 
| +                           BuiltinFunctionId op);
 | 
| +
 | 
| +  HValue* context() { return OperandAt(0); }
 | 
| +  HValue* x() { return OperandAt(1); }
 | 
| +  HValue* y() { return OperandAt(2); }
 | 
| +  HValue* z() { return OperandAt(3); }
 | 
| +  HValue* w() { return OperandAt(4); }
 | 
| +
 | 
| +  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 | 
| +
 | 
| +  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
 | 
| +    if (index == 0) {
 | 
| +      return Representation::Tagged();
 | 
| +    } else {
 | 
| +      switch (op_) {
 | 
| +        case kFloat32x4Constructor: return Representation::Double();
 | 
| +        case kInt32x4Constructor:
 | 
| +          return Representation::Integer32();
 | 
| +        case kInt32x4Bool:
 | 
| +          return Representation::Tagged();
 | 
| +        default:
 | 
| +          UNREACHABLE();
 | 
| +          return Representation::None();
 | 
| +      }
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
 | 
| +
 | 
| +  virtual HValue* Canonicalize() V8_OVERRIDE;
 | 
| +  virtual Representation RepresentationFromInputs() V8_OVERRIDE;
 | 
| +
 | 
| +  BuiltinFunctionId op() const { return op_; }
 | 
| +  const char* OpName() const;
 | 
| +
 | 
| +  DECLARE_CONCRETE_INSTRUCTION(QuarternarySIMDOperation)
 | 
| +
 | 
| + protected:
 | 
| +  virtual bool DataEquals(HValue* other) V8_OVERRIDE {
 | 
| +    HQuarternarySIMDOperation* b = HQuarternarySIMDOperation::cast(other);
 | 
| +    return op_ == b->op();
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  HQuarternarySIMDOperation(HValue* context, HValue* x, HValue* y, HValue* z,
 | 
| +                            HValue* w, BuiltinFunctionId op)
 | 
| +      : HTemplateInstruction<5>(HType::Float32x4()), op_(op) {
 | 
| +    SetOperandAt(0, context);
 | 
| +    SetOperandAt(1, x);
 | 
| +    SetOperandAt(2, y);
 | 
| +    SetOperandAt(3, z);
 | 
| +    SetOperandAt(4, w);
 | 
| +    switch (op) {
 | 
| +      case kFloat32x4Constructor:
 | 
| +        set_representation(Representation::Float32x4());
 | 
| +        break;
 | 
| +      case kInt32x4Constructor:
 | 
| +      case kInt32x4Bool:
 | 
| +        set_representation(Representation::Int32x4());
 | 
| +        type_ = HType::Int32x4();
 | 
| +        break;
 | 
| +      default:
 | 
| +        UNREACHABLE();
 | 
| +    }
 | 
| +    SetFlag(kUseGVN);
 | 
| +  }
 | 
| +
 | 
| +  virtual bool IsDeletable() const V8_OVERRIDE { return true; }
 | 
| +
 | 
| +  BuiltinFunctionId op_;
 | 
| +};
 | 
| +
 | 
| +
 | 
|  class HLoadExternalArrayPointer V8_FINAL : public HUnaryOperation {
 | 
|   public:
 | 
|    DECLARE_INSTRUCTION_FACTORY_P1(HLoadExternalArrayPointer, HValue*);
 | 
| @@ -4611,6 +5136,8 @@ class HTypeofIsAndBranch V8_FINAL : public HUnaryControlInstruction {
 | 
|  
 | 
|    Handle<String> type_literal() { return type_literal_; }
 | 
|    bool compares_number_type() { return compares_number_type_; }
 | 
| +  bool compares_float32x4_type() { return compares_float32x4_type_; }
 | 
| +  bool compares_int32x4_type() { return compares_int32x4_type_; }
 | 
|    virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 | 
|  
 | 
|    DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
 | 
| @@ -4627,10 +5154,14 @@ class HTypeofIsAndBranch V8_FINAL : public HUnaryControlInstruction {
 | 
|          type_literal_(type_literal) {
 | 
|      Heap* heap = type_literal->GetHeap();
 | 
|      compares_number_type_ = type_literal->Equals(heap->number_string());
 | 
| +    compares_float32x4_type_ = type_literal->Equals(heap->float32x4_string());
 | 
| +    compares_int32x4_type_ = type_literal->Equals(heap->int32x4_string());
 | 
|    }
 | 
|  
 | 
|    Handle<String> type_literal_;
 | 
|    bool compares_number_type_ : 1;
 | 
| +  bool compares_float32x4_type_ : 1;
 | 
| +  bool compares_int32x4_type_ : 1;
 | 
|  };
 | 
|  
 | 
|  
 | 
| @@ -6030,6 +6561,10 @@ class HObjectAccess V8_FINAL {
 | 
|                           Representation::UInteger8());
 | 
|    }
 | 
|  
 | 
| +  static HObjectAccess ForMapPrototype() {
 | 
| +    return HObjectAccess(kInobject, Map::kPrototypeOffset);
 | 
| +  }
 | 
| +
 | 
|    static HObjectAccess ForPropertyCellValue() {
 | 
|      return HObjectAccess(kInobject, PropertyCell::kValueOffset);
 | 
|    }
 | 
| @@ -6417,6 +6952,12 @@ class HLoadKeyed V8_FINAL
 | 
|        if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
 | 
|            elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
 | 
|          set_representation(Representation::Double());
 | 
| +      } else if (elements_kind == EXTERNAL_FLOAT32x4_ELEMENTS) {
 | 
| +        set_representation(CpuFeatures::IsSupported(SSE2) ?
 | 
| +            Representation::Float32x4() : Representation::Tagged());
 | 
| +      } else if (elements_kind == EXTERNAL_INT32x4_ELEMENTS) {
 | 
| +        set_representation(CpuFeatures::IsSupported(SSE2) ?
 | 
| +            Representation::Int32x4() : Representation::Tagged());
 | 
|        } else {
 | 
|          set_representation(Representation::Integer32());
 | 
|        }
 | 
| @@ -6671,10 +7212,21 @@ class HStoreKeyed V8_FINAL
 | 
|      }
 | 
|  
 | 
|      ASSERT_EQ(index, 2);
 | 
| +
 | 
|      if (IsDoubleOrFloatElementsKind(elements_kind())) {
 | 
|        return Representation::Double();
 | 
|      }
 | 
|  
 | 
| +    if (IsExternalFloat32x4ElementsKind(elements_kind())) {
 | 
| +      return CpuFeatures::IsSupported(SSE2) ?
 | 
| +          Representation::Float32x4() : Representation::Tagged();
 | 
| +    }
 | 
| +
 | 
| +    if (IsExternalInt32x4ElementsKind(elements_kind())) {
 | 
| +      return CpuFeatures::IsSupported(SSE2) ?
 | 
| +          Representation::Int32x4() : Representation::Tagged();
 | 
| +    }
 | 
| +
 | 
|      if (IsFastSmiElementsKind(elements_kind())) {
 | 
|        return Representation::Smi();
 | 
|      }
 | 
| @@ -6698,6 +7250,14 @@ class HStoreKeyed V8_FINAL
 | 
|      if (IsDoubleOrFloatElementsKind(elements_kind())) {
 | 
|        return Representation::Double();
 | 
|      }
 | 
| +    if (IsExternalFloat32x4ElementsKind(elements_kind())) {
 | 
| +      return CpuFeatures::IsSupported(SSE2) ?
 | 
| +          Representation::Float32x4() : Representation::Tagged();
 | 
| +    }
 | 
| +    if (IsExternalInt32x4ElementsKind(elements_kind())) {
 | 
| +      return CpuFeatures::IsSupported(SSE2) ?
 | 
| +          Representation::Int32x4() : Representation::Tagged();
 | 
| +    }
 | 
|      if (is_external()) {
 | 
|        return Representation::Integer32();
 | 
|      }
 | 
| 
 |