V(BitI) \
V(BoundsCheck) \
V(Branch) \
- V(CallConstantFunction) \
+ V(CallJSFunction) \
+ V(CallWithDescriptor) \
V(CallFunction) \
- V(CallGlobal) \
- V(CallKeyed) \
- V(CallKnownGlobal) \
- V(CallNamed) \
V(CallNew) \
V(CallNewArray) \
V(CallRuntime) \
V(ClampTToUint8NoSSE2) \
V(ClassOfTestAndBranch) \
V(ClobberDoubles) \
+ V(CompareMinusZeroAndBranch) \
V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \
V(CmpHoleAndBranch) \
V(DoubleToI) \
V(DoubleToSmi) \
V(Drop) \
+ V(Dummy) \
V(DummyUse) \
- V(ElementsKind) \
V(ForInCacheArray) \
V(ForInPrepareMap) \
V(FunctionLiteral) \
V(GetCachedArrayIndex) \
- V(GlobalObject) \
- V(GlobalReceiver) \
V(Goto) \
V(HasCachedArrayIndexAndBranch) \
V(HasInstanceTypeAndBranch) \
V(Label) \
V(LazyBailout) \
V(LoadContextSlot) \
- V(LoadExternalArrayPointer) \
V(LoadFieldByIndex) \
V(LoadFunctionPrototype) \
V(LoadGlobalCell) \
V(LoadRoot) \
V(MapEnumLength) \
V(MathAbs) \
- V(MathCos) \
V(MathExp) \
V(MathFloor) \
V(MathFloorOfDiv) \
V(MathMinMax) \
V(MathPowHalf) \
V(MathRound) \
- V(MathSin) \
V(MathSqrt) \
- V(MathTan) \
+ V(NullarySIMDOperation) \
+ V(UnarySIMDOperation) \
+ V(BinarySIMDOperation) \
+ V(TernarySIMDOperation) \
+ V(QuarternarySIMDOperation) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
V(NumberTagI) \
V(NumberTagU) \
V(NumberUntagD) \
+ V(SIMD128ToTagged) \
+ V(TaggedToSIMD128) \
V(OsrEntry) \
- V(OuterContext) \
V(Parameter) \
V(Power) \
- V(Random) \
V(PushArgument) \
V(RegExpLiteral) \
V(Return) \
+ V(SeqStringGetChar) \
V(SeqStringSetChar) \
V(ShiftI) \
V(SmiTag) \
V(StoreCodeEntry) \
V(StoreContextSlot) \
V(StoreGlobalCell) \
- V(StoreGlobalGeneric) \
V(StoreKeyed) \
V(StoreKeyedGeneric) \
V(StoreNamedField) \
V(SubI) \
V(TaggedToI) \
V(ThisFunction) \
- V(Throw) \
V(ToFastProperties) \
V(TransitionElementsKind) \
V(TrapAllocationMemento) \
V(Uint32ToDouble) \
V(Uint32ToSmi) \
V(UnknownOSRValue) \
- V(ValueOf) \
V(WrapReceiver)
// R = number of result operands (0 or 1).
-// I = number of input operands.
-// T = number of temporary operands.
-template<int R, int I, int T>
-class LTemplateInstruction : public LInstruction {
+template<int R>
+class LTemplateResultInstruction : public LInstruction {
public:
// Allow 0 or 1 output operands.
STATIC_ASSERT(R == 0 || R == 1);
protected:
EmbeddedContainer<LOperand*, R> results_;
+};
+
+
+// R = number of result operands (0 or 1).
+// I = number of input operands.
+// T = number of temporary operands.
+template<int R, int I, int T>
+class LTemplateInstruction : public LTemplateResultInstruction<R> {
+ protected:
EmbeddedContainer<LOperand*, I> inputs_;
EmbeddedContainer<LOperand*, T> temps_;
};
+class LDummy V8_FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+ explicit LDummy() { }
+ DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
+};
+
+
class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public:
explicit LDummyUse(LOperand* value) {
DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
DECLARE_HYDROGEN_ACCESSOR(CallStub)
-
- TranscendentalCache::Type transcendental_type() {
- return hydrogen()->transcendental_type();
- }
};
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
+ DECLARE_HYDROGEN_ACCESSOR(WrapReceiver)
};
};
-class LMathRound V8_FINAL : public LTemplateInstruction<1, 2, 1> {
+class LMathRound V8_FINAL : public LTemplateInstruction<1, 1, 1> {
public:
- LMathRound(LOperand* context, LOperand* value, LOperand* temp) {
- inputs_[1] = context;
+ LMathRound(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
- LOperand* context() { return inputs_[1]; }
LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; }
};
-class LMathSin V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LMathExp V8_FINAL : public LTemplateInstruction<1, 1, 2> {
public:
- explicit LMathSin(LOperand* value) {
+ LMathExp(LOperand* value,
+ LOperand* temp1,
+ LOperand* temp2) {
inputs_[0] = value;
+ temps_[0] = temp1;
+ temps_[1] = temp2;
+ ExternalReference::InitializeMathExpData();
}
LOperand* value() { return inputs_[0]; }
+ LOperand* temp1() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
- DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin")
+ DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
};
-class LMathCos V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LMathSqrt V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public:
- explicit LMathCos(LOperand* value) {
+ explicit LMathSqrt(LOperand* value) {
inputs_[0] = value;
}
LOperand* value() { return inputs_[0]; }
- DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos")
+ DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
};
-class LMathTan V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LMathPowHalf V8_FINAL : public LTemplateInstruction<1, 1, 1> {
public:
- explicit LMathTan(LOperand* value) {
+ LMathPowHalf(LOperand* value, LOperand* temp) {
inputs_[0] = value;
+ temps_[0] = temp;
}
LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
- DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan")
+ DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
};
-class LMathExp V8_FINAL : public LTemplateInstruction<1, 1, 2> {
+class LNullarySIMDOperation V8_FINAL : public LTemplateInstruction<1, 0, 0> {
public:
- LMathExp(LOperand* value,
- LOperand* temp1,
- LOperand* temp2) {
- inputs_[0] = value;
- temps_[0] = temp1;
- temps_[1] = temp2;
- ExternalReference::InitializeMathExpData();
+ explicit LNullarySIMDOperation(BuiltinFunctionId op)
+ : op_(op) {
}
- LOperand* value() { return inputs_[0]; }
- LOperand* temp1() { return temps_[0]; }
- LOperand* temp2() { return temps_[1]; }
+ BuiltinFunctionId op() const { return op_; }
- DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
+ virtual Opcode opcode() const V8_OVERRIDE {
+ return LInstruction::kNullarySIMDOperation;
+ }
+ virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
+ virtual const char* Mnemonic() const V8_OVERRIDE;
+ static LNullarySIMDOperation* cast(LInstruction* instr) {
+ ASSERT(instr->IsNullarySIMDOperation());
+ return reinterpret_cast<LNullarySIMDOperation*>(instr);
+ }
+
+ DECLARE_HYDROGEN_ACCESSOR(NullarySIMDOperation)
+
+ private:
+ BuiltinFunctionId op_;
};
-class LMathSqrt V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LUnarySIMDOperation V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public:
- explicit LMathSqrt(LOperand* value) {
+ LUnarySIMDOperation(LOperand* value, BuiltinFunctionId op)
+ : op_(op) {
inputs_[0] = value;
}
LOperand* value() { return inputs_[0]; }
+ BuiltinFunctionId op() const { return op_; }
- DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
+ virtual Opcode opcode() const V8_OVERRIDE {
+ return LInstruction::kUnarySIMDOperation;
+ }
+ virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
+ virtual const char* Mnemonic() const V8_OVERRIDE;
+ static LUnarySIMDOperation* cast(LInstruction* instr) {
+ ASSERT(instr->IsUnarySIMDOperation());
+ return reinterpret_cast<LUnarySIMDOperation*>(instr);
+ }
+
+ DECLARE_HYDROGEN_ACCESSOR(UnarySIMDOperation)
+
+ private:
+ BuiltinFunctionId op_;
};
-class LMathPowHalf V8_FINAL : public LTemplateInstruction<1, 2, 1> {
+class LBinarySIMDOperation V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
- LMathPowHalf(LOperand* context, LOperand* value, LOperand* temp) {
- inputs_[1] = context;
- inputs_[0] = value;
- temps_[0] = temp;
+ LBinarySIMDOperation(LOperand* left, LOperand* right, BuiltinFunctionId op)
+ : op_(op) {
+ inputs_[0] = left;
+ inputs_[1] = right;
}
- LOperand* context() { return inputs_[1]; }
- LOperand* value() { return inputs_[0]; }
- LOperand* temp() { return temps_[0]; }
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ BuiltinFunctionId op() const { return op_; }
- DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
+ virtual Opcode opcode() const V8_OVERRIDE {
+ return LInstruction::kBinarySIMDOperation;
+ }
+ virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
+ virtual const char* Mnemonic() const V8_OVERRIDE;
+ static LBinarySIMDOperation* cast(LInstruction* instr) {
+ ASSERT(instr->IsBinarySIMDOperation());
+ return reinterpret_cast<LBinarySIMDOperation*>(instr);
+ }
+
+ DECLARE_HYDROGEN_ACCESSOR(BinarySIMDOperation)
+
+ private:
+ BuiltinFunctionId op_;
+};
+
+
+class LTernarySIMDOperation V8_FINAL : public LTemplateInstruction<1, 3, 0> {
+ public:
+ LTernarySIMDOperation(LOperand* first, LOperand* second, LOperand* third,
+ BuiltinFunctionId op)
+ : op_(op) {
+ inputs_[0] = first;
+ inputs_[1] = second;
+ inputs_[2] = third;
+ }
+
+ LOperand* first() { return inputs_[0]; }
+ LOperand* second() { return inputs_[1]; }
+ LOperand* third() { return inputs_[2]; }
+ BuiltinFunctionId op() const { return op_; }
+
+ virtual Opcode opcode() const V8_OVERRIDE {
+ return LInstruction::kTernarySIMDOperation;
+ }
+ virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
+ virtual const char* Mnemonic() const V8_OVERRIDE;
+ static LTernarySIMDOperation* cast(LInstruction* instr) {
+ ASSERT(instr->IsTernarySIMDOperation());
+ return reinterpret_cast<LTernarySIMDOperation*>(instr);
+ }
+
+ DECLARE_HYDROGEN_ACCESSOR(TernarySIMDOperation)
+
+ private:
+ BuiltinFunctionId op_;
+};
+
+
+class LQuarternarySIMDOperation V8_FINAL
+ : public LTemplateInstruction<1, 4, 0> {
+ public:
+ LQuarternarySIMDOperation(LOperand* x, LOperand* y, LOperand* z,
+ LOperand* w, BuiltinFunctionId op)
+ : op_(op) {
+ inputs_[0] = x;
+ inputs_[1] = y;
+ inputs_[2] = z;
+ inputs_[3] = w;
+ }
+
+ LOperand* x() { return inputs_[0]; }
+ LOperand* y() { return inputs_[1]; }
+ LOperand* z() { return inputs_[2]; }
+ LOperand* w() { return inputs_[3]; }
+ BuiltinFunctionId op() const { return op_; }
+
+ virtual Opcode opcode() const V8_OVERRIDE {
+ return LInstruction::kQuarternarySIMDOperation;
+ }
+ virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
+ virtual const char* Mnemonic() const V8_OVERRIDE;
+ static LQuarternarySIMDOperation* cast(LInstruction* instr) {
+ ASSERT(instr->IsQuarternarySIMDOperation());
+ return reinterpret_cast<LQuarternarySIMDOperation*>(instr);
+ }
+
+ DECLARE_HYDROGEN_ACCESSOR(QuarternarySIMDOperation)
+
+ private:
+ BuiltinFunctionId op_;
};
};
+class LCompareMinusZeroAndBranch V8_FINAL : public LControlInstruction<1, 1> {
+ public:
+ LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
+ inputs_[0] = value;
+ temps_[0] = temp;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
+ "cmp-minus-zero-and-branch")
+ DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
+};
+
+
class LIsObjectAndBranch V8_FINAL : public LControlInstruction<1, 1> {
public:
LIsObjectAndBranch(LOperand* value, LOperand* temp) {
inputs_[2] = right;
}
+ LOperand* context() { return inputs_[1]; }
LOperand* left() { return inputs_[1]; }
LOperand* right() { return inputs_[2]; }
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
+ LOperand* context() { return inputs_[0]; }
Token::Value op() const { return hydrogen()->token(); }
};
temps_[0] = temp;
}
+ LOperand* context() { return inputs_[0]; }
LOperand* value() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
};
-class LElementsKind V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LElementsKind(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
- DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
-};
-
-
-class LValueOf V8_FINAL : public LTemplateInstruction<1, 1, 1> {
- public:
- LValueOf(LOperand* value, LOperand* temp) {
- inputs_[0] = value;
- temps_[0] = temp;
- }
-
- LOperand* value() { return inputs_[0]; }
- LOperand* temp() { return temps_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
- DECLARE_HYDROGEN_ACCESSOR(ValueOf)
-};
-
-
class LDateField V8_FINAL : public LTemplateInstruction<1, 1, 1> {
public:
LDateField(LOperand* date, LOperand* temp, Smi* index)
};
-class LSeqStringSetChar V8_FINAL : public LTemplateInstruction<1, 3, 0> {
+class LSeqStringGetChar V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
- LSeqStringSetChar(String::Encoding encoding,
- LOperand* string,
- LOperand* index,
- LOperand* value) : encoding_(encoding) {
+ LSeqStringGetChar(LOperand* string, LOperand* index) {
inputs_[0] = string;
inputs_[1] = index;
- inputs_[2] = value;
}
- String::Encoding encoding() { return encoding_; }
- LOperand* string() { return inputs_[0]; }
- LOperand* index() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
+ LOperand* string() const { return inputs_[0]; }
+ LOperand* index() const { return inputs_[1]; }
- DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
- DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
-
- private:
- String::Encoding encoding_;
+ DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar, "seq-string-get-char")
+ DECLARE_HYDROGEN_ACCESSOR(SeqStringGetChar)
};
-class LThrow V8_FINAL : public LTemplateInstruction<0, 2, 0> {
+class LSeqStringSetChar V8_FINAL : public LTemplateInstruction<1, 4, 0> {
public:
- LThrow(LOperand* context, LOperand* value) {
+ LSeqStringSetChar(LOperand* context,
+ LOperand* string,
+ LOperand* index,
+ LOperand* value) {
inputs_[0] = context;
- inputs_[1] = value;
+ inputs_[1] = string;
+ inputs_[2] = index;
+ inputs_[3] = value;
}
- LOperand* context() { return inputs_[0]; }
- LOperand* value() { return inputs_[1]; }
+ LOperand* string() { return inputs_[1]; }
+ LOperand* index() { return inputs_[2]; }
+ LOperand* value() { return inputs_[3]; }
- DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
+ DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
+ DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
};
};
-class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 3> {
- public:
- LRandom(LOperand* global_object,
- LOperand* scratch,
- LOperand* scratch2,
- LOperand* scratch3) {
- inputs_[0] = global_object;
- temps_[0] = scratch;
- temps_[1] = scratch2;
- temps_[2] = scratch3;
- }
-
- LOperand* global_object() const { return inputs_[0]; }
- LOperand* scratch() const { return temps_[0]; }
- LOperand* scratch2() const { return temps_[1]; }
- LOperand* scratch3() const { return temps_[2]; }
-
- DECLARE_CONCRETE_INSTRUCTION(Random, "random")
- DECLARE_HYDROGEN_ACCESSOR(Random)
-};
-
-
class LArithmeticD V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
class LReturn V8_FINAL : public LTemplateInstruction<0, 3, 0> {
public:
- explicit LReturn(LOperand* value, LOperand* context,
+ explicit LReturn(LOperand* value,
+ LOperand* context,
LOperand* parameter_count) {
inputs_[0] = value;
inputs_[1] = context;
};
-class LLoadExternalArrayPointer V8_FINAL
- : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LLoadExternalArrayPointer(LOperand* object) {
- inputs_[0] = object;
- }
-
- LOperand* object() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
- "load-external-array-pointer")
-};
-
-
-class LLoadKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> {
+class LLoadKeyed V8_FINAL : public LTemplateInstruction<1, 2, 1> {
public:
- LLoadKeyed(LOperand* elements, LOperand* key) {
+ LLoadKeyed(LOperand* elements, LOperand* key, LOperand* temp) {
inputs_[0] = elements;
inputs_[1] = key;
+ temps_[0] = temp;
}
LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
ElementsKind elements_kind() const {
return hydrogen()->elements_kind();
}
bool is_external() const {
return hydrogen()->is_external();
}
+ bool is_fixed_typed_array() const {
+ return hydrogen()->is_fixed_typed_array();
+ }
+ bool is_typed_elements() const {
+ return is_external() || is_fixed_typed_array();
+ }
DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
};
+inline static bool ExternalArrayOpRequiresPreScale(
+ Representation key_representation,
+ ElementsKind kind) {
+ int shift_size = ElementsKindToShiftSize(kind);
+ return key_representation.IsSmi()
+ ? shift_size > static_cast<int>(maximal_scale_factor) + kSmiTagSize
+ : shift_size > static_cast<int>(maximal_scale_factor);
+}
+
+
inline static bool ExternalArrayOpRequiresTemp(
Representation key_representation,
ElementsKind elements_kind) {
- // Operations that require the key to be divided by two to be converted into
- // an index cannot fold the scale operation into a load and need an extra
- // temp register to do the work.
- return key_representation.IsSmi() &&
- (elements_kind == EXTERNAL_BYTE_ELEMENTS ||
- elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS ||
- elements_kind == EXTERNAL_PIXEL_ELEMENTS);
+ // Operations that require the key to be scaled by a factor or divided by two
+ // to be converted into an index cannot fold the scale operation into a load
+ // and need an extra temp register to do the work.
+ return ExternalArrayOpRequiresPreScale(key_representation, elements_kind) ||
+ (key_representation.IsSmi() &&
+ (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));
}
};
-class LStoreGlobalGeneric V8_FINAL : public LTemplateInstruction<0, 3, 0> {
- public:
- LStoreGlobalGeneric(LOperand* context,
- LOperand* global_object,
- LOperand* value) {
- inputs_[0] = context;
- inputs_[1] = global_object;
- inputs_[2] = value;
- }
-
- LOperand* context() { return inputs_[0]; }
- LOperand* global_object() { return inputs_[1]; }
- LOperand* value() { return inputs_[2]; }
-
- DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic")
- DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric)
-
- Handle<Object> name() const { return hydrogen()->name(); }
- StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
-};
-
-
class LLoadContextSlot V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public:
explicit LLoadContextSlot(LOperand* context) {
};
-class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 2, 0> {
public:
- explicit LInnerAllocatedObject(LOperand* base_object) {
+ LInnerAllocatedObject(LOperand* base_object, LOperand* offset) {
inputs_[0] = base_object;
+ inputs_[1] = offset;
}
- LOperand* base_object() { return inputs_[0]; }
- int offset() { return hydrogen()->offset(); }
+ LOperand* base_object() const { return inputs_[0]; }
+ LOperand* offset() const { return inputs_[1]; }
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
- DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
+ DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
};
};
-class LOuterContext V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LOuterContext(LOperand* context) {
- inputs_[0] = context;
- }
-
- LOperand* context() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
-};
-
-
class LDeclareGlobals V8_FINAL : public LTemplateInstruction<0, 1, 0> {
public:
explicit LDeclareGlobals(LOperand* context) {
};
-class LGlobalObject V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LGlobalObject(LOperand* context) {
- inputs_[0] = context;
- }
-
- LOperand* context() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
-};
-
-
-class LGlobalReceiver V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LCallJSFunction V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public:
- explicit LGlobalReceiver(LOperand* global_object) {
- inputs_[0] = global_object;
+ explicit LCallJSFunction(LOperand* function) {
+ inputs_[0] = function;
}
- LOperand* global() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
-};
+ LOperand* function() { return inputs_[0]; }
-
-class LCallConstantFunction V8_FINAL : public LTemplateInstruction<1, 0, 0> {
- public:
- DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
- DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
+ DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
+ DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
- Handle<JSFunction> function() { return hydrogen()->function(); }
int arity() const { return hydrogen()->argument_count() - 1; }
};
-class LInvokeFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> {
+class LCallWithDescriptor V8_FINAL : public LTemplateResultInstruction<1> {
public:
- LInvokeFunction(LOperand* context, LOperand* function) {
- inputs_[0] = context;
- inputs_[1] = function;
+ LCallWithDescriptor(const CallInterfaceDescriptor* descriptor,
+ ZoneList<LOperand*>& operands,
+ Zone* zone)
+ : inputs_(descriptor->environment_length() + 1, zone) {
+ ASSERT(descriptor->environment_length() + 1 == operands.length());
+ inputs_.AddAll(operands, zone);
}
- LOperand* context() { return inputs_[0]; }
- LOperand* function() { return inputs_[1]; }
+ LOperand* target() const { return inputs_[0]; }
- DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
- DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
+ private:
+ DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
+ DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
int arity() const { return hydrogen()->argument_count() - 1; }
-};
-
-
-class LCallKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> {
- public:
- LCallKeyed(LOperand* context, LOperand* key) {
- inputs_[0] = context;
- inputs_[1] = key;
- }
-
- LOperand* context() { return inputs_[0]; }
- LOperand* key() { return inputs_[1]; }
- DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
- DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
+ ZoneList<LOperand*> inputs_;
- virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
+ // Iterator support.
+ virtual int InputCount() V8_FINAL V8_OVERRIDE { return inputs_.length(); }
+ virtual LOperand* InputAt(int i) V8_FINAL V8_OVERRIDE { return inputs_[i]; }
- int arity() const { return hydrogen()->argument_count() - 1; }
+ virtual int TempCount() V8_FINAL V8_OVERRIDE { return 0; }
+ virtual LOperand* TempAt(int i) V8_FINAL V8_OVERRIDE { return NULL; }
};
-class LCallNamed V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LInvokeFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
- explicit LCallNamed(LOperand* context) {
+ LInvokeFunction(LOperand* context, LOperand* function) {
inputs_[0] = context;
+ inputs_[1] = function;
}
LOperand* context() { return inputs_[0]; }
+ LOperand* function() { return inputs_[1]; }
- DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
- DECLARE_HYDROGEN_ACCESSOR(CallNamed)
+ DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
+ DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
- Handle<String> name() const { return hydrogen()->name(); }
int arity() const { return hydrogen()->argument_count() - 1; }
};
};
-class LCallGlobal V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LCallGlobal(LOperand* context) {
- inputs_[0] = context;
- }
-
- LOperand* context() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
- DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
-
- virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-
- Handle<String> name() const {return hydrogen()->name(); }
- int arity() const { return hydrogen()->argument_count() - 1; }
-};
-
-
-class LCallKnownGlobal V8_FINAL : public LTemplateInstruction<1, 0, 0> {
- public:
- DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
- DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
-
- virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-
- int arity() const { return hydrogen()->argument_count() - 1; }
-};
-
-
class LCallNew V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
LCallNew(LOperand* context, LOperand* constructor) {
};
+class LSIMD128ToTagged V8_FINAL : public LTemplateInstruction<1, 1, 1> {
+ public:
+ explicit LSIMD128ToTagged(LOperand* value, LOperand* temp) {
+ inputs_[0] = value;
+ temps_[0] = temp;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(SIMD128ToTagged, "simd128-tag")
+ DECLARE_HYDROGEN_ACCESSOR(Change)
+};
+
+
// Sometimes truncating conversion from a tagged value to an int32.
class LDoubleToI V8_FINAL : public LTemplateInstruction<1, 1, 1> {
public:
};
+class LTaggedToSIMD128 V8_FINAL : public LTemplateInstruction<1, 1, 1> {
+ public:
+ explicit LTaggedToSIMD128(LOperand* value, LOperand* temp,
+ Representation representation) : representation_(representation) {
+ inputs_[0] = value;
+ temps_[0] = temp;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ Representation representation() const { return representation_; }
+
+ DECLARE_CONCRETE_INSTRUCTION(TaggedToSIMD128, "simd128-untag")
+ DECLARE_HYDROGEN_ACCESSOR(Change);
+ private:
+ Representation representation_;
+};
+
+
class LSmiUntag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public:
LSmiUntag(LOperand* value, bool needs_check)
};
-class LStoreKeyed V8_FINAL : public LTemplateInstruction<0, 3, 0> {
+class LStoreKeyed V8_FINAL : public LTemplateInstruction<0, 3, 1> {
public:
- LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) {
+ LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val, LOperand* temp) {
inputs_[0] = obj;
inputs_[1] = key;
inputs_[2] = val;
+ temps_[0] = temp;
}
bool is_external() const { return hydrogen()->is_external(); }
+ bool is_fixed_typed_array() const {
+ return hydrogen()->is_fixed_typed_array();
+ }
+ bool is_typed_elements() const {
+ return is_external() || is_fixed_typed_array();
+ }
LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
+ LOperand* temp() { return temps_[0]; }
ElementsKind elements_kind() const {
return hydrogen()->elements_kind();
}
};
-class LChunkBuilder V8_FINAL BASE_EMBEDDED {
+class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
public:
LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
- : chunk_(NULL),
+ : LChunkBuilderBase(graph->zone()),
+ chunk_(NULL),
info_(info),
graph_(graph),
- zone_(graph->zone()),
status_(UNUSED),
current_instruction_(NULL),
current_block_(NULL),
next_block_(NULL),
- argument_count_(0),
allocator_(allocator),
instruction_pending_deoptimization_environment_(NULL),
pending_deoptimization_ast_id_(BailoutId::None()) { }
HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
#undef DECLARE_DO
- static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
-
LInstruction* DoMathFloor(HUnaryMathOperation* instr);
LInstruction* DoMathRound(HUnaryMathOperation* instr);
LInstruction* DoMathAbs(HUnaryMathOperation* instr);
LInstruction* DoMathLog(HUnaryMathOperation* instr);
- LInstruction* DoMathSin(HUnaryMathOperation* instr);
- LInstruction* DoMathCos(HUnaryMathOperation* instr);
- LInstruction* DoMathTan(HUnaryMathOperation* instr);
LInstruction* DoMathExp(HUnaryMathOperation* instr);
LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
LPlatformChunk* chunk() const { return chunk_; }
CompilationInfo* info() const { return info_; }
HGraph* graph() const { return graph_; }
- Zone* zone() const { return zone_; }
bool is_unused() const { return status_ == UNUSED; }
bool is_building() const { return status_ == BUILDING; }
MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
+ // An input operand in a fixed register or a constant operand.
+ MUST_USE_RESULT LOperand* UseFixedOrConstant(HValue* value,
+ Register fixed_register);
+
// An input operand in a register or a constant operand.
MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
// An input operand in register, stack slot or a constant operand.
// Will not be moved to a register even if one is freely available.
- MUST_USE_RESULT LOperand* UseAny(HValue* value);
+ virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) V8_OVERRIDE;
// Temporary operand that must be in a register.
MUST_USE_RESULT LUnallocated* TempRegister();
// Methods for setting up define-use relationships.
// Return the same instruction that they are passed.
- template<int I, int T>
- LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
- LUnallocated* result);
- template<int I, int T>
- LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
- template<int I, int T>
- LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
- int index);
- template<int I, int T>
- LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
- template<int I, int T>
- LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
- Register reg);
- template<int I, int T>
- LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
- XMMRegister reg);
- template<int I, int T>
- LInstruction* DefineX87TOS(LTemplateInstruction<1, I, T>* instr);
+ LInstruction* Define(LTemplateResultInstruction<1>* instr,
+ LUnallocated* result);
+ LInstruction* DefineAsRegister(LTemplateResultInstruction<1>* instr);
+ LInstruction* DefineAsSpilled(LTemplateResultInstruction<1>* instr,
+ int index);
+ LInstruction* DefineSameAsFirst(LTemplateResultInstruction<1>* instr);
+ LInstruction* DefineFixed(LTemplateResultInstruction<1>* instr,
+ Register reg);
+ LInstruction* DefineFixedDouble(LTemplateResultInstruction<1>* instr,
+ XMMRegister reg);
+ LInstruction* DefineX87TOS(LTemplateResultInstruction<1>* instr);
// Assigns an environment to an instruction. An instruction which can
// deoptimize must have an environment.
LInstruction* AssignEnvironment(LInstruction* instr);
enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
+ LOperand* GetSeqStringSetCharOperand(HSeqStringSetChar* instr);
+
// Marks a call for the register allocator. Assigns a pointer map to
// support GC and lazy deoptimization. Assigns an environment to support
// eager deoptimization if CAN_DEOPTIMIZE_EAGERLY.
HInstruction* hinstr,
CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
- LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
- int* argument_index_accumulator,
- ZoneList<HValue*>* objects_to_materialize);
-
void VisitInstruction(HInstruction* current);
void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
LPlatformChunk* chunk_;
CompilationInfo* info_;
HGraph* const graph_;
- Zone* zone_;
Status status_;
HInstruction* current_instruction_;
HBasicBlock* current_block_;
HBasicBlock* next_block_;
- int argument_count_;
LAllocator* allocator_;
LInstruction* instruction_pending_deoptimization_environment_;
BailoutId pending_deoptimization_ast_id_;