Remove the remaining LOperand-members from concrete LIR instructions.

This change introduces the third template parameters for LIR instructions
to specify the number of temp-operands. This is one step towards
removing the instruction-summaries.

I also added hydrogen-accessors in more places and refactored
the LIR-branch instructions to have common super-classes to 
avoid code duplication.

Added MUST_USE_RESULT to the functions that record uses
and definitions so that all LOperands are stored in the
LIR instructions (and not only in the summaries).



Review URL: http://codereview.chromium.org/6237002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6345 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 437914da
......@@ -706,11 +706,11 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
void LCodeGen::DoModI(LModI* instr) {
LOperand* right = instr->right();
LOperand* right = instr->InputAt(1);
ASSERT(ToRegister(instr->result()).is(edx));
ASSERT(ToRegister(instr->left()).is(eax));
ASSERT(!ToRegister(instr->right()).is(eax));
ASSERT(!ToRegister(instr->right()).is(edx));
ASSERT(ToRegister(instr->InputAt(0)).is(eax));
ASSERT(!ToRegister(instr->InputAt(1)).is(eax));
ASSERT(!ToRegister(instr->InputAt(1)).is(edx));
Register right_reg = ToRegister(right);
......@@ -746,11 +746,11 @@ void LCodeGen::DoModI(LModI* instr) {
void LCodeGen::DoDivI(LDivI* instr) {
LOperand* right = instr->right();
LOperand* right = instr->InputAt(1);
ASSERT(ToRegister(instr->result()).is(eax));
ASSERT(ToRegister(instr->left()).is(eax));
ASSERT(!ToRegister(instr->right()).is(eax));
ASSERT(!ToRegister(instr->right()).is(edx));
ASSERT(ToRegister(instr->InputAt(0)).is(eax));
ASSERT(!ToRegister(instr->InputAt(1)).is(eax));
ASSERT(!ToRegister(instr->InputAt(1)).is(edx));
Register left_reg = eax;
......@@ -792,11 +792,11 @@ void LCodeGen::DoDivI(LDivI* instr) {
void LCodeGen::DoMulI(LMulI* instr) {
Register left = ToRegister(instr->left());
LOperand* right = instr->right();
Register left = ToRegister(instr->InputAt(0));
LOperand* right = instr->InputAt(1);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ mov(ToRegister(instr->temp()), left);
__ mov(ToRegister(instr->TempAt(0)), left);
}
if (right->IsConstantOperand()) {
......@@ -820,7 +820,7 @@ void LCodeGen::DoMulI(LMulI* instr) {
}
} else {
// Test the non-zero operand for negative sign.
__ or_(ToRegister(instr->temp()), ToOperand(right));
__ or_(ToRegister(instr->TempAt(0)), ToOperand(right));
DeoptimizeIf(sign, instr->environment());
}
__ bind(&done);
......@@ -829,8 +829,8 @@ void LCodeGen::DoMulI(LMulI* instr) {
void LCodeGen::DoBitI(LBitI* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
ASSERT(left->Equals(instr->result()));
ASSERT(left->IsRegister());
......@@ -870,8 +870,8 @@ void LCodeGen::DoBitI(LBitI* instr) {
void LCodeGen::DoShiftI(LShiftI* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
ASSERT(left->Equals(instr->result()));
ASSERT(left->IsRegister());
if (right->IsRegister()) {
......@@ -926,8 +926,8 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
void LCodeGen::DoSubI(LSubI* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
ASSERT(left->Equals(instr->result()));
if (right->IsConstantOperand()) {
......@@ -982,22 +982,22 @@ void LCodeGen::DoConstantT(LConstantT* instr) {
void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
Register result = ToRegister(instr->result());
Register array = ToRegister(instr->input());
Register array = ToRegister(instr->InputAt(0));
__ mov(result, FieldOperand(array, JSArray::kLengthOffset));
}
void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
Register result = ToRegister(instr->result());
Register array = ToRegister(instr->input());
Register array = ToRegister(instr->InputAt(0));
__ mov(result, FieldOperand(array, FixedArray::kLengthOffset));
}
void LCodeGen::DoValueOf(LValueOf* instr) {
Register input = ToRegister(instr->input());
Register input = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
Register map = ToRegister(instr->temporary());
Register map = ToRegister(instr->TempAt(0));
ASSERT(input.is(result));
NearLabel done;
// If the object is a smi return the object.
......@@ -1014,14 +1014,14 @@ void LCodeGen::DoValueOf(LValueOf* instr) {
void LCodeGen::DoBitNotI(LBitNotI* instr) {
LOperand* input = instr->input();
LOperand* input = instr->InputAt(0);
ASSERT(input->Equals(instr->result()));
__ not_(ToRegister(input));
}
void LCodeGen::DoThrow(LThrow* instr) {
__ push(ToOperand(instr->input()));
__ push(ToOperand(instr->InputAt(0)));
CallRuntime(Runtime::kThrow, 1, instr);
if (FLAG_debug_code) {
......@@ -1032,8 +1032,8 @@ void LCodeGen::DoThrow(LThrow* instr) {
void LCodeGen::DoAddI(LAddI* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
ASSERT(left->Equals(instr->result()));
if (right->IsConstantOperand()) {
......@@ -1049,8 +1049,8 @@ void LCodeGen::DoAddI(LAddI* instr) {
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
// Modulo uses a fixed result register.
ASSERT(instr->op() == Token::MOD || left->Equals(instr->result()));
switch (instr->op()) {
......@@ -1089,8 +1089,8 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
ASSERT(ToRegister(instr->left()).is(edx));
ASSERT(ToRegister(instr->right()).is(eax));
ASSERT(ToRegister(instr->InputAt(0)).is(edx));
ASSERT(ToRegister(instr->InputAt(1)).is(eax));
ASSERT(ToRegister(instr->result()).is(eax));
TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE);
......@@ -1131,17 +1131,17 @@ void LCodeGen::DoBranch(LBranch* instr) {
Representation r = instr->hydrogen()->representation();
if (r.IsInteger32()) {
Register reg = ToRegister(instr->input());
Register reg = ToRegister(instr->InputAt(0));
__ test(reg, Operand(reg));
EmitBranch(true_block, false_block, not_zero);
} else if (r.IsDouble()) {
XMMRegister reg = ToDoubleRegister(instr->input());
XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
__ xorpd(xmm0, xmm0);
__ ucomisd(reg, xmm0);
EmitBranch(true_block, false_block, not_equal);
} else {
ASSERT(r.IsTagged());
Register reg = ToRegister(instr->input());
Register reg = ToRegister(instr->InputAt(0));
if (instr->hydrogen()->type().IsBoolean()) {
__ cmp(reg, Factory::true_value());
EmitBranch(true_block, false_block, equal);
......@@ -1269,8 +1269,8 @@ void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) {
void LCodeGen::DoCmpID(LCmpID* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
LOperand* result = instr->result();
NearLabel unordered;
......@@ -1295,8 +1295,8 @@ void LCodeGen::DoCmpID(LCmpID* instr) {
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
......@@ -1315,8 +1315,8 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
Register left = ToRegister(instr->left());
Register right = ToRegister(instr->right());
Register left = ToRegister(instr->InputAt(0));
Register right = ToRegister(instr->InputAt(1));
Register result = ToRegister(instr->result());
__ cmp(left, Operand(right));
......@@ -1329,8 +1329,8 @@ void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) {
Register left = ToRegister(instr->left());
Register right = ToRegister(instr->right());
Register left = ToRegister(instr->InputAt(0));
Register right = ToRegister(instr->InputAt(1));
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
......@@ -1340,7 +1340,7 @@ void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) {
void LCodeGen::DoIsNull(LIsNull* instr) {
Register reg = ToRegister(instr->input());
Register reg = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
// TODO(fsc): If the expression is known to be a smi, then it's
......@@ -1378,7 +1378,7 @@ void LCodeGen::DoIsNull(LIsNull* instr) {
void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
Register reg = ToRegister(instr->input());
Register reg = ToRegister(instr->InputAt(0));
// TODO(fsc): If the expression is known to be a smi, then it's
// definitely not null. Jump to the false block.
......@@ -1399,7 +1399,7 @@ void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
__ j(zero, false_label);
// Check for undetectable objects by looking in the bit field in
// the map. The object has already been smi checked.
Register scratch = ToRegister(instr->temp());
Register scratch = ToRegister(instr->TempAt(0));
__ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
__ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
__ test(scratch, Immediate(1 << Map::kIsUndetectable));
......@@ -1438,9 +1438,9 @@ Condition LCodeGen::EmitIsObject(Register input,
void LCodeGen::DoIsObject(LIsObject* instr) {
Register reg = ToRegister(instr->input());
Register reg = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
Register temp = ToRegister(instr->temp());
Register temp = ToRegister(instr->TempAt(0));
Label is_false, is_true, done;
Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true);
......@@ -1458,9 +1458,9 @@ void LCodeGen::DoIsObject(LIsObject* instr) {
void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
Register reg = ToRegister(instr->input());
Register temp = ToRegister(instr->temp());
Register temp2 = ToRegister(instr->temp2());
Register reg = ToRegister(instr->InputAt(0));
Register temp = ToRegister(instr->TempAt(0));
Register temp2 = ToRegister(instr->TempAt(1));
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
......@@ -1474,7 +1474,7 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
void LCodeGen::DoIsSmi(LIsSmi* instr) {
Operand input = ToOperand(instr->input());
Operand input = ToOperand(instr->InputAt(0));
Register result = ToRegister(instr->result());
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
......@@ -1488,7 +1488,7 @@ void LCodeGen::DoIsSmi(LIsSmi* instr) {
void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
Operand input = ToOperand(instr->input());
Operand input = ToOperand(instr->InputAt(0));
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
......@@ -1498,9 +1498,9 @@ void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
}
InstanceType LHasInstanceType::TestType() {
InstanceType from = hydrogen()->from();
InstanceType to = hydrogen()->to();
static InstanceType TestType(HHasInstanceType* instr) {
InstanceType from = instr->from();
InstanceType to = instr->to();
if (from == FIRST_TYPE) return to;
ASSERT(from == to || to == LAST_TYPE);
return from;
......@@ -1508,9 +1508,9 @@ InstanceType LHasInstanceType::TestType() {
Condition LHasInstanceType::BranchCondition() {
InstanceType from = hydrogen()->from();
InstanceType to = hydrogen()->to();
static Condition BranchCondition(HHasInstanceType* instr) {
InstanceType from = instr->from();
InstanceType to = instr->to();
if (from == to) return equal;
if (to == LAST_TYPE) return above_equal;
if (from == FIRST_TYPE) return below_equal;
......@@ -1520,15 +1520,15 @@ Condition LHasInstanceType::BranchCondition() {
void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
Register input = ToRegister(instr->input());
Register input = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
__ test(input, Immediate(kSmiTagMask));
NearLabel done, is_false;
__ j(zero, &is_false);
__ CmpObjectType(input, instr->TestType(), result);
__ j(NegateCondition(instr->BranchCondition()), &is_false);
__ CmpObjectType(input, TestType(instr->hydrogen()), result);
__ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false);
__ mov(result, Handle<Object>(Heap::true_value()));
__ jmp(&done);
__ bind(&is_false);
......@@ -1538,8 +1538,8 @@ void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
Register input = ToRegister(instr->input());
Register temp = ToRegister(instr->temp());
Register input = ToRegister(instr->InputAt(0));
Register temp = ToRegister(instr->TempAt(0));
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
......@@ -1549,13 +1549,13 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
__ test(input, Immediate(kSmiTagMask));
__ j(zero, false_label);
__ CmpObjectType(input, instr->TestType(), temp);
EmitBranch(true_block, false_block, instr->BranchCondition());
__ CmpObjectType(input, TestType(instr->hydrogen()), temp);
EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
}
void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
Register input = ToRegister(instr->input());
Register input = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
......@@ -1571,7 +1571,7 @@ void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
void LCodeGen::DoHasCachedArrayIndexAndBranch(
LHasCachedArrayIndexAndBranch* instr) {
Register input = ToRegister(instr->input());
Register input = ToRegister(instr->InputAt(0));
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
......@@ -1640,10 +1640,10 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
Register input = ToRegister(instr->input());
Register input = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
ASSERT(input.is(result));
Register temp = ToRegister(instr->temporary());
Register temp = ToRegister(instr->TempAt(0));
Handle<String> class_name = instr->hydrogen()->class_name();
NearLabel done;
Label is_true, is_false;
......@@ -1663,9 +1663,9 @@ void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
Register input = ToRegister(instr->input());
Register temp = ToRegister(instr->temporary());
Register temp2 = ToRegister(instr->temporary2());
Register input = ToRegister(instr->InputAt(0));
Register temp = ToRegister(instr->TempAt(0));
Register temp2 = ToRegister(instr->TempAt(1));
if (input.is(temp)) {
// Swap.
Register swapper = temp;
......@@ -1687,7 +1687,7 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
Register reg = ToRegister(instr->input());
Register reg = ToRegister(instr->InputAt(0));
int true_block = instr->true_block_id();
int false_block = instr->false_block_id();
......@@ -1744,8 +1744,8 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
deferred = new DeferredInstanceOfKnownGlobal(this, instr);
Label done, false_result;
Register object = ToRegister(instr->input());
Register temp = ToRegister(instr->temp());
Register object = ToRegister(instr->InputAt(0));
Register temp = ToRegister(instr->TempAt(0));
// A Smi is not instance of anything.
__ test(object, Immediate(kSmiTagMask));
......@@ -1755,7 +1755,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
// hole value will be patched to the last map/result pair generated by the
// instanceof stub.
NearLabel cache_miss;
Register map = ToRegister(instr->temp());
Register map = ToRegister(instr->TempAt(0));
__ mov(map, FieldOperand(object, HeapObject::kMapOffset));
__ bind(deferred->map_check()); // Label for calculating code patching.
__ cmp(map, Factory::the_hole_value()); // Patched to cached map.
......@@ -1803,7 +1803,7 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
// Get the temp register reserved by the instruction. This needs to be edi as
// its slot of the pushing of safepoint registers is used to communicate the
// offset to the location of the map check.
Register temp = ToRegister(instr->temp());
Register temp = ToRegister(instr->TempAt(0));
ASSERT(temp.is(edi));
__ mov(InstanceofStub::right(), Immediate(instr->function()));
static const int kAdditionalDelta = 13;
......@@ -1908,7 +1908,7 @@ void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) {
void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
Register value = ToRegister(instr->input());
Register value = ToRegister(instr->InputAt(0));
__ mov(Operand::Cell(instr->hydrogen()->cell()), value);
}
......@@ -1922,7 +1922,7 @@ void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
Register object = ToRegister(instr->input());
Register object = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
if (instr->hydrogen()->is_in_object()) {
__ mov(result, FieldOperand(object, instr->hydrogen()->offset()));
......@@ -1945,7 +1945,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
Register function = ToRegister(instr->function());
Register temp = ToRegister(instr->temporary());
Register temp = ToRegister(instr->TempAt(0));
Register result = ToRegister(instr->result());
// Check that the function really is a function.
......@@ -1986,8 +1986,8 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
void LCodeGen::DoLoadElements(LLoadElements* instr) {
ASSERT(instr->result()->Equals(instr->input()));
Register reg = ToRegister(instr->input());
ASSERT(instr->result()->Equals(instr->InputAt(0)));
Register reg = ToRegister(instr->InputAt(0));
__ mov(reg, FieldOperand(reg, JSObject::kElementsOffset));
if (FLAG_debug_code) {
NearLabel done;
......@@ -2067,7 +2067,7 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
Operand elem = ToOperand(instr->input());
Operand elem = ToOperand(instr->InputAt(0));
Register result = ToRegister(instr->result());
NearLabel done;
......@@ -2141,7 +2141,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
void LCodeGen::DoPushArgument(LPushArgument* instr) {
LOperand* argument = instr->input();
LOperand* argument = instr->InputAt(0);
if (argument->IsConstantOperand()) {
__ push(ToImmediate(argument));
} else {
......@@ -2207,7 +2207,7 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
Register input_reg = ToRegister(instr->input());
Register input_reg = ToRegister(instr->InputAt(0));
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
Factory::heap_number_map());
DeoptimizeIf(not_equal, instr->environment());
......@@ -2274,17 +2274,17 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
LUnaryMathOperation* instr_;
};
ASSERT(instr->input()->Equals(instr->result()));
ASSERT(instr->InputAt(0)->Equals(instr->result()));
Representation r = instr->hydrogen()->value()->representation();
if (r.IsDouble()) {
XMMRegister scratch = xmm0;
XMMRegister input_reg = ToDoubleRegister(instr->input());
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
__ pxor(scratch, scratch);
__ subsd(scratch, input_reg);
__ pand(input_reg, scratch);
} else if (r.IsInteger32()) {
Register input_reg = ToRegister(instr->input());
Register input_reg = ToRegister(instr->InputAt(0));
__ test(input_reg, Operand(input_reg));
Label is_positive;
__ j(not_sign, &is_positive);
......@@ -2296,7 +2296,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
DeferredMathAbsTaggedHeapNumber* deferred =
new DeferredMathAbsTaggedHeapNumber(this, instr);
Label not_smi;
Register input_reg = ToRegister(instr->input());
Register input_reg = ToRegister(instr->InputAt(0));
// Smi check.
__ test(input_reg, Immediate(kSmiTagMask));
__ j(not_zero, deferred->entry());
......@@ -2317,7 +2317,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
XMMRegister xmm_scratch = xmm0;
Register output_reg = ToRegister(instr->result());
XMMRegister input_reg = ToDoubleRegister(instr->input());
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
__ xorpd(xmm_scratch, xmm_scratch); // Zero the register.
__ ucomisd(input_reg, xmm_scratch);
......@@ -2339,7 +2339,7 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
XMMRegister xmm_scratch = xmm0;
Register output_reg = ToRegister(instr->result());
XMMRegister input_reg = ToDoubleRegister(instr->input());
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
// xmm_scratch = 0.5
ExternalReference one_half = ExternalReference::address_of_one_half();
......@@ -2372,7 +2372,7 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
XMMRegister input_reg = ToDoubleRegister(instr->input());
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
__ sqrtsd(input_reg, input_reg);
}
......@@ -2380,7 +2380,7 @@ void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
XMMRegister xmm_scratch = xmm0;
XMMRegister input_reg = ToDoubleRegister(instr->input());
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
ExternalReference negative_infinity =
ExternalReference::address_of_negative_infinity();
......@@ -2392,8 +2392,8 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
void LCodeGen::DoPower(LPower* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
DoubleRegister result_reg = ToDoubleRegister(instr->result());
Representation exponent_type = instr->hydrogen()->right()->representation();
if (exponent_type.IsDouble()) {
......@@ -2555,7 +2555,7 @@ void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
void LCodeGen::DoCallNew(LCallNew* instr) {
ASSERT(ToRegister(instr->input()).is(edi));
ASSERT(ToRegister(instr->InputAt(0)).is(edi));
ASSERT(ToRegister(instr->result()).is(eax));
Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall));
......@@ -2582,12 +2582,12 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
if (instr->is_in_object()) {
__ mov(FieldOperand(object, offset), value);
if (instr->needs_write_barrier()) {
Register temp = ToRegister(instr->temp());
Register temp = ToRegister(instr->TempAt(0));
// Update the write barrier for the object for in-object properties.
__ RecordWrite(object, offset, value, temp);
}
} else {
Register temp = ToRegister(instr->temp());
Register temp = ToRegister(instr->TempAt(0));
__ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset));
__ mov(FieldOperand(temp, offset), value);
if (instr->needs_write_barrier()) {
......@@ -2651,7 +2651,7 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
LOperand* input = instr->input();
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister() || input->IsStackSlot());
LOperand* output = instr->result();
ASSERT(output->IsDoubleRegister());
......@@ -2669,7 +2669,7 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
LNumberTagI* instr_;
};
LOperand* input = instr->input();
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister() && input->Equals(instr->result()));
Register reg = ToRegister(input);
......@@ -2682,7 +2682,7 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
Label slow;
Register reg = ToRegister(instr->input());
Register reg = ToRegister(instr->InputAt(0));
Register tmp = reg.is(eax) ? ecx : eax;
// Preserve the value of all registers.
......@@ -2732,9 +2732,9 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
LNumberTagD* instr_;
};
XMMRegister input_reg = ToDoubleRegister(instr->input());
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
Register reg = ToRegister(instr->result());
Register tmp = ToRegister(instr->temp());
Register tmp = ToRegister(instr->TempAt(0));
DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr);
if (FLAG_inline_new) {
......@@ -2764,7 +2764,7 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
void LCodeGen::DoSmiTag(LSmiTag* instr) {
LOperand* input = instr->input();
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister() && input->Equals(instr->result()));
ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
__ SmiTag(ToRegister(input));
......@@ -2772,7 +2772,7 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) {
void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
LOperand* input = instr->input();
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister() && input->Equals(instr->result()));
if (instr->needs_check()) {
__ test(ToRegister(input), Immediate(kSmiTagMask));
......@@ -2832,7 +2832,7 @@ class DeferredTaggedToI: public LDeferredCode {
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
NearLabel done, heap_number;
Register input_reg = ToRegister(instr->input());
Register input_reg = ToRegister(instr->InputAt(0));
// Heap number map check.
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
......@@ -2875,7 +2875,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
__ add(Operand(esp), Immediate(kDoubleSize));
} else {
NearLabel deopt;
XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
__ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ cvttsd2si(input_reg, Operand(xmm0));
__ cmp(input_reg, 0x80000000u);
......@@ -2892,7 +2892,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
// Deoptimize if we don't have a heap number.
DeoptimizeIf(not_equal, instr->environment());
XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
__ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ cvttsd2si(input_reg, Operand(xmm0));
__ cvtsi2sd(xmm_temp, Operand(input_reg));
......@@ -2912,7 +2912,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
LOperand* input = instr->input();
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister());
ASSERT(input->Equals(instr->result()));
......@@ -2932,7 +2932,7 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
LOperand* input = instr->input();
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister());
LOperand* result = instr->result();
ASSERT(result->IsDoubleRegister());
......@@ -2945,7 +2945,7 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
LOperand* input = instr->input();
LOperand* input = instr->InputAt(0);
ASSERT(input->IsDoubleRegister());
LOperand* result = instr->result();
ASSERT(result->IsRegister());
......@@ -2983,7 +2983,7 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
__ bind(&done);
} else {
NearLabel done;
Register temp_reg = ToRegister(instr->temporary());
Register temp_reg = ToRegister(instr->TempAt(0));
XMMRegister xmm_scratch = xmm0;
// If cvttsd2si succeeded, we're done. Otherwise, we attempt
......@@ -3062,7 +3062,7 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
LOperand* input = instr->input();
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister());
__ test(ToRegister(input), Immediate(kSmiTagMask));
DeoptimizeIf(instr->condition(), instr->environment());
......@@ -3070,8 +3070,8 @@ void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
Register input = ToRegister(instr->input());
Register temp = ToRegister(instr->temp());
Register input = ToRegister(instr->InputAt(0));
Register temp = ToRegister(instr->TempAt(0));
InstanceType first = instr->hydrogen()->first();
InstanceType last = instr->hydrogen()->last();
......@@ -3095,15 +3095,15 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
ASSERT(instr->input()->IsRegister());
Register reg = ToRegister(instr->input());
ASSERT(instr->InputAt(0)->IsRegister());
Register reg = ToRegister(instr->InputAt(0));
__ cmp(reg, instr->hydrogen()->target());
DeoptimizeIf(not_equal, instr->environment());
}
void LCodeGen::DoCheckMap(LCheckMap* instr) {
LOperand* input = instr->input();
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister());
Register reg = ToRegister(input);
__ cmp(FieldOperand(reg, HeapObject::kMapOffset),
......@@ -3124,7 +3124,7 @@ void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) {
void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
Register reg = ToRegister(instr->temp());
Register reg = ToRegister(instr->TempAt(0));
Handle<JSObject> holder = instr->holder();
Handle<JSObject> current_prototype = instr->prototype();
......@@ -3268,7 +3268,7 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
void LCodeGen::DoTypeof(LTypeof* instr) {
LOperand* input = instr->input();
LOperand* input = instr->InputAt(0);
if (input->IsConstantOperand()) {
__ push(ToImmediate(input));
} else {
......@@ -3279,7 +3279,7 @@ void LCodeGen::DoTypeof(LTypeof* instr) {
void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
Register input = ToRegister(instr->input());
Register input = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
Label true_label;
Label false_label;
......@@ -3302,7 +3302,7 @@ void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
Register input = ToRegister(instr->input());
Register input = ToRegister(instr->InputAt(0));
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* true_label = chunk_->GetAssemblyLabel(true_block);
......
......@@ -90,18 +90,22 @@ void LInstruction::PrintTo(StringStream* stream) {
template<int R, int I, int T>
void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
for (int i = 0; i < I; i++) {
stream->Add(i == 0 ? "= " : " ");
inputs_.at(i)->PrintTo(stream);
}
stream->Add("= ");
inputs_.PrintOperandsTo(stream);
}
template<int R, int I, int T>
void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
if (this->HasResult()) {
this->result()->PrintTo(stream);
stream->Add(" ");
results_.PrintOperandsTo(stream);
}
template<typename T, int N>
void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
for (int i = 0; i < N; i++) {
if (i > 0) stream->Add(" ");
elems_[i]->PrintTo(stream);
}
}
......@@ -172,22 +176,22 @@ void LGoto::PrintDataTo(StringStream* stream) {
void LBranch::PrintDataTo(StringStream* stream) {
stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
}
void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
left()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
stream->Add(" %s ", Token::String(op()));
right()->PrintTo(stream);
InputAt(1)->PrintTo(stream);
stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
}
void LIsNullAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
stream->Add(is_strict() ? " === null" : " == null");
stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
}
......@@ -195,35 +199,35 @@ void LIsNullAndBranch::PrintDataTo(StringStream* stream) {
void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_object(");
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if is_smi(");
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if has_instance_type(");
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if has_cached_array_index(");
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
}
void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if class_of_test(");
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
stream->Add(", \"%o\") then B%d else B%d",
*hydrogen()->class_name(),
true_block_id(),
......@@ -232,14 +236,14 @@ void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
void LTypeofIs::PrintDataTo(StringStream* stream) {
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString());
}
void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if typeof ");
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
stream->Add(" == \"%s\" then B%d else B%d",
*hydrogen()->type_literal()->ToCString(),
true_block_id(), false_block_id());
......@@ -253,7 +257,7 @@ void LCallConstantFunction::PrintDataTo(StringStream* stream) {
void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
stream->Add("/%s ", hydrogen()->OpName());
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
}
......@@ -286,14 +290,14 @@ void LCallKnownGlobal::PrintDataTo(StringStream* stream) {
void LCallNew::PrintDataTo(StringStream* stream) {
stream->Add("= ");
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
stream->Add(" #%d / ", arity());
}
void LClassOfTest::PrintDataTo(StringStream* stream) {
stream->Add("= class_of_test(");
input()->PrintTo(stream);
InputAt(0)->PrintTo(stream);
stream->Add(", \"%o\")", *hydrogen()->class_name());
}
......@@ -883,8 +887,17 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
if (FLAG_stress_environments && !instr->HasEnvironment()) {
instr = AssignEnvironment(instr);
}
if (current->IsBranch()) {
instr->set_hydrogen_value(HBranch::cast(current)->value());
if (current->IsBranch() && !instr->IsGoto()) {
// TODO(fschneider): Handle branch instructions uniformly like
// other instructions. This requires us to generate the right
// branch instruction already at the HIR level.
ASSERT(instr->IsControl());
HBranch* branch = HBranch::cast(current);
instr->set_hydrogen_value(branch->value());
HBasicBlock* first = branch->FirstSuccessor();
HBasicBlock* second = branch->SecondSuccessor();
ASSERT(first != NULL && second != NULL);
instr->SetBranchTargets(first->block_id(), second->block_id());
} else {
instr->set_hydrogen_value(current);
}
......@@ -945,12 +958,6 @@ LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
HValue* v = instr->value();
HBasicBlock* first = instr->FirstSuccessor();
HBasicBlock* second = instr->SecondSuccessor();
ASSERT(first != NULL && second != NULL);
int first_id = first->block_id();
int second_id = second->block_id();
if (v->EmitAtUses()) {
if (v->IsClassOfTest()) {
HClassOfTest* compare = HClassOfTest::cast(v);
......@@ -958,9 +965,7 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
return new LClassOfTestAndBranch(UseTempRegister(compare->value()),
TempRegister(),
TempRegister(),
first_id,
second_id);
TempRegister());
} else if (v->IsCompare()) {
HCompare* compare = HCompare::cast(v);
Token::Value op = compare->token();
......@@ -972,17 +977,13 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
ASSERT(right->representation().IsInteger32());
return new LCmpIDAndBranch(UseRegisterAtStart(left),
UseOrConstantAtStart(right),
first_id,
second_id);
UseOrConstantAtStart(right));
} else if (r.IsDouble()) {
ASSERT(left->representation().IsDouble());
ASSERT(right->representation().IsDouble());
return new LCmpIDAndBranch(UseRegisterAtStart(left),
UseRegisterAtStart(right),
first_id,
second_id);
UseRegisterAtStart(right));
} else {
ASSERT(left->representation().IsTagged());
ASSERT(right->representation().IsTagged());
......@@ -990,32 +991,26 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
LOperand* left_operand = UseFixed(left, reversed ? eax : edx);
LOperand* right_operand = UseFixed(right, reversed ? edx : eax);
LCmpTAndBranch* result = new LCmpTAndBranch(left_operand,
right_operand,
first_id,
second_id);
right_operand);
return MarkAsCall(result, instr);
}
} else if (v->IsIsSmi()) {
HIsSmi* compare = HIsSmi::cast(v);
ASSERT(compare->value()->representation().IsTagged());
return new LIsSmiAndBranch(Use(compare->value()),
first_id,
second_id);
return new LIsSmiAndBranch(Use(compare->value()));
} else if (v->IsHasInstanceType()) {
HHasInstanceType* compare = HHasInstanceType::cast(v);
ASSERT(compare->value()->representation().IsTagged());
return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()),
TempRegister(),
first_id,
second_id);
TempRegister());
} else if (v->IsHasCachedArrayIndex()) {
HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v);
ASSERT(compare->value()->representation().IsTagged());
return new LHasCachedArrayIndexAndBranch(
UseRegisterAtStart(compare->value()), first_id, second_id);
UseRegisterAtStart(compare->value()));
} else if (v->IsIsNull()) {
HIsNull* compare = HIsNull::cast(v);
ASSERT(compare->value()->representation().IsTagged());
......@@ -1023,9 +1018,7 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
// We only need a temp register for non-strict compare.
LOperand* temp = compare->is_strict() ? NULL : TempRegister();
return new LIsNullAndBranch(UseRegisterAtStart(compare->value()),
temp,
first_id,
second_id);
temp);
} else if (v->IsIsObject()) {
HIsObject* compare = HIsObject::cast(v);
ASSERT(compare->value()->representation().IsTagged());
......@@ -1034,42 +1027,34 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
LOperand* temp2 = TempRegister();
return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()),
temp1,
temp2,
first_id,
second_id);
temp2);
} else if (v->IsCompareJSObjectEq()) {
HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
UseRegisterAtStart(compare->right()),
first_id,
second_id);
UseRegisterAtStart(compare->right()));
} else if (v->IsInstanceOf()) {
HInstanceOf* instance_of = HInstanceOf::cast(v);
LInstanceOfAndBranch* result =
new LInstanceOfAndBranch(
UseFixed(instance_of->left(), InstanceofStub::left()),
UseFixed(instance_of->right(), InstanceofStub::right()),
first_id,
second_id);
UseFixed(instance_of->right(), InstanceofStub::right()));
return MarkAsCall(result, instr);
} else if (v->IsTypeofIs()) {
HTypeofIs* typeof_is = HTypeofIs::cast(v);
return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()),
first_id,
second_id);
return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
} else {
if (v->IsConstant()) {
if (HConstant::cast(v)->handle()->IsTrue()) {
return new LGoto(first_id);
return new LGoto(instr->FirstSuccessor()->block_id());
} else if (HConstant::cast(v)->handle()->IsFalse()) {
return new LGoto(second_id);
return new LGoto(instr->SecondSuccessor()->block_id());
}
}
Abort("Undefined compare before branch");
return NULL;
}
}
return new LBranch(UseRegisterAtStart(v), first_id, second_id);
return new LBranch(UseRegisterAtStart(v));
}
......@@ -1178,8 +1163,8 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
ASSERT(instr->key()->representation().IsTagged());
argument_count_ -= instr->argument_count();
UseFixed(instr->key(), ecx);
return MarkAsCall(DefineFixed(new LCallKeyed, eax), instr);
LOperand* temp = UseFixed(instr->key(), ecx);
return MarkAsCall(DefineFixed(new LCallKeyed(temp), eax), instr);
}
......@@ -1266,10 +1251,11 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
} else if (instr->representation().IsInteger32()) {
// The temporary operand is necessary to ensure that right is not allocated
// into edx.
FixedTemp(edx);
LOperand* temp = FixedTemp(edx);
LOperand* value = UseFixed(instr->left(), eax);
LOperand* divisor = UseRegister(instr->right());
return AssignEnvironment(DefineFixed(new LDivI(value, divisor), eax));
LDivI* result = new LDivI(value, divisor, temp);
return AssignEnvironment(DefineFixed(result, eax));
} else {
ASSERT(instr->representation().IsTagged());
return DoArithmeticT(Token::DIV, instr);
......@@ -1283,10 +1269,10 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
ASSERT(instr->right()->representation().IsInteger32());
// The temporary operand is necessary to ensure that right is not allocated
// into edx.
FixedTemp(edx);
LOperand* temp = FixedTemp(edx);
LOperand* value = UseFixed(instr->left(), eax);
LOperand* divisor = UseRegister(instr->right());
LModI* mod = new LModI(value, divisor);
LModI* mod = new LModI(value, divisor, temp);
LInstruction* result = DefineFixed(mod, edx);
return (instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
instr->CheckFlag(HValue::kCanBeDivByZero))
......
......@@ -43,10 +43,22 @@ class LCodeGen;
// Type hierarchy:
//
// LInstruction
// LAccessArgumentsAt
// LArgumentsElements
// LArgumentsLength
// LBinaryOperation
// LTemplateInstruction
// LControlInstruction
// LBranch
// LClassOfTestAndBranch
// LCmpJSObjectEqAndBranch
// LCmpIDAndBranch
// LHasCachedArrayIndexAndBranch
// LHasInstanceTypeAndBranch
// LInstanceOfAndBranch
// LIsNullAndBranch
// LIsObjectAndBranch
// LIsSmiAndBranch
// LTypeofIsAndBranch
// LAccessArgumentsAt
// LArgumentsElements
// LArgumentsLength
// LAddI
// LApplyArguments
// LArithmeticD
......@@ -54,13 +66,10 @@ class LCodeGen;
// LBitI
// LBoundsCheck
// LCmpID
// LCmpIDAndBranch
// LCmpJSObjectEq
// LCmpJSObjectEqAndBranch
// LCmpT
// LDivI
// LInstanceOf
// LInstanceOfAndBranch
// LInstanceOfKnownGlobal
// LLoadKeyedFastElement
// LLoadKeyedGeneric
......@@ -69,67 +78,59 @@ class LCodeGen;
// LPower
// LShiftI
// LSubI
// LCallConstantFunction
// LCallFunction
// LCallGlobal
// LCallKeyed
// LCallKnownGlobal
// LCallNamed
// LCallRuntime
// LCallStub
// LCheckPrototypeMaps
// LConstant
// LConstantD
// LConstantI
// LConstantT
// LDeoptimize
// LFunctionLiteral
// LGap
// LLabel
// LGlobalObject
// LGlobalReceiver
// LGoto
// LLazyBailout
// LLoadContextSlot
// LLoadGlobal
// LMaterializedLiteral
// LCallConstantFunction
// LCallFunction
// LCallGlobal
// LCallKeyed
// LCallKnownGlobal
// LCallNamed
// LCallRuntime
// LCallStub
// LConstant
// LConstantD
// LConstantI
// LConstantT
// LDeoptimize
// LFunctionLiteral
// LGap
// LLabel
// LGlobalObject
// LGlobalReceiver
// LGoto
// LLazyBailout
// LLoadGlobal
// LCheckPrototypeMaps
// LLoadContextSlot
// LArrayLiteral
// LObjectLiteral
// LRegExpLiteral
// LOsrEntry
// LParameter
// LRegExpConstructResult
// LStackCheck
// LStoreKeyed
// LStoreKeyedFastElement
// LStoreKeyedGeneric
// LStoreNamed
// LStoreNamedField
// LStoreNamedGeneric
// LUnaryOperation
// LOsrEntry
// LParameter
// LRegExpConstructResult
// LStackCheck
// LStoreKeyed
// LStoreKeyedFastElement
// LStoreKeyedGeneric
// LStoreNamed
// LStoreNamedField
// LStoreNamedGeneric
// LBitNotI
// LBranch
// LCallNew
// LCheckFunction
// LCheckPrototypeMaps
// LCheckInstanceType
// LCheckMap
// LCheckSmi
// LClassOfTest
// LClassOfTestAndBranch
// LDeleteProperty
// LDoubleToI
// LFixedArrayLength
// LHasCachedArrayIndex
// LHasCachedArrayIndexAndBranch
// LHasInstanceType
// LHasInstanceTypeAndBranch
// LInteger32ToDouble
// LIsNull
// LIsNullAndBranch
// LIsObject
// LIsObjectAndBranch
// LIsSmi
// LIsSmiAndBranch
// LJSArrayLength
// LLoadNamedField
// LLoadNamedGeneric
......@@ -144,19 +145,16 @@ class LCodeGen;
// LThrow
// LTypeof
// LTypeofIs
// LTypeofIsAndBranch
// LUnaryMathOperation
// LValueOf
// LUnknownOSRValue
// LUnknownOSRValue
#define LITHIUM_ALL_INSTRUCTION_LIST(V) \
V(BinaryOperation) \
V(ControlInstruction) \
V(Constant) \
V(Call) \
V(MaterializedLiteral) \
V(StoreKeyed) \
V(StoreNamed) \
V(UnaryOperation) \
LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
......@@ -302,7 +300,9 @@ class LInstruction: public ZoneObject {
#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO)
#undef DECLARE_DO
virtual bool IsControl() const { return false; }
virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
void set_environment(LEnvironment* env) { environment_.set(env); }
LEnvironment* environment() const { return environment_.get(); }
......@@ -341,9 +341,13 @@ class OperandContainer {
OperandContainer() {
for (int i = 0; i < N; i++) elems_[i] = NULL;
}
int length() const { return N; }
T at(int i) const { return elems_[i]; }
void set_at(int i, T value) { elems_[i] = value; }
int length() { return N; }
T& operator[](int i) {
ASSERT(i < length());
return elems_[i];
}
void PrintOperandsTo(StringStream* stream);
private:
T elems_[N];
};
......@@ -352,38 +356,31 @@ class OperandContainer {
template<typename T>
class OperandContainer<T, 0> {
public:
int length() const { return 0; }
T at(int i) const {
UNREACHABLE();
return NULL;
}
void set_at(int i, T value) {
UNREACHABLE();
}
int length() { return 0; }
void PrintOperandsTo(StringStream* stream) { }
};
template<int R, int I, int T>
template<int R, int I, int T = 0>
class LTemplateInstruction: public LInstruction {
public:
// Allow 0 or 1 output operands.
STATIC_ASSERT(R == 0 || R == 1);
virtual bool HasResult() const { return R != 0; }
void set_result(LOperand* operand) { outputs_.set_at(0, operand); }
LOperand* result() const { return outputs_.at(0); }
void set_result(LOperand* operand) { results_[0] = operand; }
LOperand* result() { return results_[0]; }
int InputCount() const { return inputs_.length(); }
LOperand* InputAt(int i) const { return inputs_.at(i); }
void SetInputAt(int i, LOperand* operand) { inputs_.set_at(i, operand); }
int InputCount() { return I; }
LOperand* InputAt(int i) { return inputs_[i]; }
int TempCount() const { return temps_.length(); }
LOperand* TempAt(int i) const { return temps_.at(i); }
int TempCount() { return T; }
LOperand* TempAt(int i) { return temps_[i]; }
virtual void PrintDataTo(StringStream* stream);
virtual void PrintOutputOperandTo(StringStream* stream);
private:
OperandContainer<LOperand*, R> outputs_;
protected:
OperandContainer<LOperand*, R> results_;
OperandContainer<LOperand*, I> inputs_;
OperandContainer<LOperand*, T> temps_;
};
......@@ -515,31 +512,22 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
};
template<int R>
class LUnaryOperation: public LTemplateInstruction<R, 1, 0> {
template<int I, int T = 0>
class LControlInstruction: public LTemplateInstruction<0, I, T> {
public:
explicit LUnaryOperation<R>(LOperand* input) {
this->SetInputAt(0, input);
}
LOperand* input() const { return this->InputAt(0); }
DECLARE_INSTRUCTION(UnaryOperation)
};
DECLARE_INSTRUCTION(ControlInstruction)
virtual bool IsControl() const { return true; }
template<int R>
class LBinaryOperation: public LTemplateInstruction<R, 2, 0> {
public:
LBinaryOperation(LOperand* left, LOperand* right) {
this->SetInputAt(0, left);
this->SetInputAt(1, right);
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
void SetBranchTargets(int true_block_id, int false_block_id) {
true_block_id_ = true_block_id;
false_block_id_ = false_block_id;
}
DECLARE_INSTRUCTION(BinaryOperation)
LOperand* left() const { return this->InputAt(0); }
LOperand* right() const { return this->InputAt(1); }
private:
int true_block_id_;
int false_block_id_;
};
......@@ -549,43 +537,44 @@ class LApplyArguments: public LTemplateInstruction<1, 4, 0> {
LOperand* receiver,
LOperand* length,
LOperand* elements) {
this->SetInputAt(0, function);
this->SetInputAt(1, receiver);
this->SetInputAt(2, length);
this->SetInputAt(3, elements);
inputs_[0] = function;
inputs_[1] = receiver;
inputs_[2] = length;
inputs_[3] = elements;
}
DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
LOperand* function() const { return InputAt(0); }
LOperand* receiver() const { return InputAt(1); }
LOperand* length() const { return InputAt(2); }
LOperand* elements() const { return InputAt(3); }
LOperand* function() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* length() { return inputs_[2]; }
LOperand* elements() { return inputs_[3]; }
};
class LAccessArgumentsAt: public LTemplateInstruction<1, 3, 0> {
public:
LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
this->SetInputAt(0, arguments);
this->SetInputAt(1, length);
this->SetInputAt(2, index);
inputs_[0] = arguments;
inputs_[1] = length;
inputs_[2] = index;
}
DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
LOperand* arguments() const { return this->InputAt(0); }
LOperand* length() const { return this->InputAt(1); }
LOperand* index() const { return this->InputAt(2); }
LOperand* arguments() { return inputs_[0]; }
LOperand* length() { return inputs_[1]; }
LOperand* index() { return inputs_[2]; }
virtual void PrintDataTo(StringStream* stream);
};
class LArgumentsLength: public LUnaryOperation<1> {
class LArgumentsLength: public LTemplateInstruction<1, 1> {
public:
explicit LArgumentsLength(LOperand* elements)
: LUnaryOperation<1>(elements) {}
explicit LArgumentsLength(LOperand* elements) {
inputs_[0] = elements;
}
DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
};
......@@ -599,82 +588,86 @@ class LArgumentsElements: public LTemplateInstruction<1, 0, 0> {
};
class LModI: public LBinaryOperation<1> {
class LModI: public LTemplateInstruction<1, 2, 1> {
public:
LModI(LOperand* left, LOperand* right) : LBinaryOperation<1>(left, right) { }
LModI(LOperand* left, LOperand* right, LOperand* temp) {
inputs_[0] = left;
inputs_[1] = right;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
DECLARE_HYDROGEN_ACCESSOR(Mod)
};
class LDivI: public LBinaryOperation<1> {
class LDivI: public LTemplateInstruction<1, 2, 1> {
public:
LDivI(LOperand* left, LOperand* right)
: LBinaryOperation<1>(left, right) { }
LDivI(LOperand* left, LOperand* right, LOperand* temp) {
inputs_[0] = left;
inputs_[1] = right;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
DECLARE_HYDROGEN_ACCESSOR(Div)
};
class LMulI: public LBinaryOperation<1> {
class LMulI: public LTemplateInstruction<1, 2, 1> {
public:
LMulI(LOperand* left, LOperand* right, LOperand* temp)
: LBinaryOperation<1>(left, right), temp_(temp) { }
LMulI(LOperand* left, LOperand* right, LOperand* temp) {
inputs_[0] = left;
inputs_[1] = right;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
DECLARE_HYDROGEN_ACCESSOR(Mul)
LOperand* temp() const { return temp_; }
private:
LOperand* temp_;
};
class LCmpID: public LBinaryOperation<1> {
class LCmpID: public LTemplateInstruction<1, 2> {
public:
LCmpID(LOperand* left, LOperand* right)
: LBinaryOperation<1>(left, right) { }
LCmpID(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id")
DECLARE_HYDROGEN_ACCESSOR(Compare)
Token::Value op() const { return hydrogen()->token(); }
bool is_double() const {
return hydrogen()->GetInputRepresentation().IsDouble();
}
DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id")
DECLARE_HYDROGEN_ACCESSOR(Compare)
};
class LCmpIDAndBranch: public LCmpID {
class LCmpIDAndBranch: public LControlInstruction<2> {
public:
LCmpIDAndBranch(LOperand* left,
LOperand* right,
int true_block_id,
int false_block_id)
: LCmpID(left, right),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
LCmpIDAndBranch(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
virtual void PrintDataTo(StringStream* stream);
virtual bool IsControl() const { return true; }
DECLARE_HYDROGEN_ACCESSOR(Compare)
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
Token::Value op() const { return hydrogen()->token(); }
bool is_double() const {
return hydrogen()->GetInputRepresentation().IsDouble();
}
private:
int true_block_id_;
int false_block_id_;
virtual void PrintDataTo(StringStream* stream);
};
class LUnaryMathOperation: public LUnaryOperation<1> {
class LUnaryMathOperation: public LTemplateInstruction<1, 1> {
public:
explicit LUnaryMathOperation(LOperand* value)
: LUnaryOperation<1>(value) { }
explicit LUnaryMathOperation(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation")
DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
......@@ -684,40 +677,34 @@ class LUnaryMathOperation: public LUnaryOperation<1> {
};
class LCmpJSObjectEq: public LBinaryOperation<1> {
class LCmpJSObjectEq: public LTemplateInstruction<1, 2> {
public:
LCmpJSObjectEq(LOperand* left, LOperand* right)
: LBinaryOperation<1>(left, right) {}
LCmpJSObjectEq(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEq, "cmp-jsobject-eq")
};
class LCmpJSObjectEqAndBranch: public LCmpJSObjectEq {
class LCmpJSObjectEqAndBranch: public LControlInstruction<2> {
public:
LCmpJSObjectEqAndBranch(LOperand* left,
LOperand* right,
int true_block_id,
int false_block_id)
: LCmpJSObjectEq(left, right),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
LCmpJSObjectEqAndBranch(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEqAndBranch,
"cmp-jsobject-eq-and-branch")
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
private:
int true_block_id_;
int false_block_id_;
};
class LIsNull: public LUnaryOperation<1> {
class LIsNull: public LTemplateInstruction<1, 1> {
public:
explicit LIsNull(LOperand* value) : LUnaryOperation<1>(value) { }
explicit LIsNull(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(IsNull, "is-null")
DECLARE_HYDROGEN_ACCESSOR(IsNull)
......@@ -726,227 +713,155 @@ class LIsNull: public LUnaryOperation<1> {
};
class LIsNullAndBranch: public LIsNull {
class LIsNullAndBranch: public LControlInstruction<1, 1> {
public:
LIsNullAndBranch(LOperand* value,
LOperand* temp,
int true_block_id,
int false_block_id)
: LIsNull(value),
temp_(temp),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
LIsNullAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch, "is-null-and-branch")
virtual void PrintDataTo(StringStream* stream);
virtual bool IsControl() const { return true; }
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
DECLARE_HYDROGEN_ACCESSOR(IsNull)
LOperand* temp() const { return temp_; }
bool is_strict() const { return hydrogen()->is_strict(); }
private:
LOperand* temp_;
int true_block_id_;
int false_block_id_;
virtual void PrintDataTo(StringStream* stream);
};
class LIsObject: public LUnaryOperation<1> {
class LIsObject: public LTemplateInstruction<1, 1, 1> {
public:
LIsObject(LOperand* value, LOperand* temp)
: LUnaryOperation<1>(value), temp_(temp) {}
LIsObject(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
LOperand* temp() const { return temp_; }
private:
LOperand* temp_;
};
class LIsObjectAndBranch: public LIsObject {
class LIsObjectAndBranch: public LControlInstruction<1, 2> {
public:
LIsObjectAndBranch(LOperand* value,
LOperand* temp,
LOperand* temp2,
int true_block_id,
int false_block_id)
: LIsObject(value, temp),
temp2_(temp2),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
LIsObjectAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
inputs_[0] = value;
temps_[0] = temp;
temps_[1] = temp2;
}
DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
virtual void PrintDataTo(StringStream* stream);
virtual bool IsControl() const { return true; }
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
LOperand* temp2() const { return temp2_; }
private:
LOperand* temp2_;
int true_block_id_;
int false_block_id_;
virtual void PrintDataTo(StringStream* stream);
};
class LIsSmi: public LUnaryOperation<1> {
class LIsSmi: public LTemplateInstruction<1, 1> {
public:
explicit LIsSmi(LOperand* value) : LUnaryOperation<1>(value) {}
explicit LIsSmi(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is-smi")
DECLARE_HYDROGEN_ACCESSOR(IsSmi)
};
class LIsSmiAndBranch: public LIsSmi {
class LIsSmiAndBranch: public LControlInstruction<1> {
public:
LIsSmiAndBranch(LOperand* value,
int true_block_id,
int false_block_id)
: LIsSmi(value),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
explicit LIsSmiAndBranch(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
virtual void PrintDataTo(StringStream* stream);
virtual bool IsControl() const { return true; }
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
private:
int true_block_id_;
int false_block_id_;
virtual void PrintDataTo(StringStream* stream);
};
class LHasInstanceType: public LUnaryOperation<1> {
class LHasInstanceType: public LTemplateInstruction<1, 1> {
public:
explicit LHasInstanceType(LOperand* value)
: LUnaryOperation<1>(value) { }
explicit LHasInstanceType(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has-instance-type")
DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
InstanceType TestType(); // The type to test against when generating code.
Condition BranchCondition(); // The branch condition for 'true'.
};
class LHasInstanceTypeAndBranch: public LHasInstanceType {
class LHasInstanceTypeAndBranch: public LControlInstruction<1, 1> {
public:
LHasInstanceTypeAndBranch(LOperand* value,
LOperand* temporary,
int true_block_id,
int false_block_id)
: LHasInstanceType(value),
temp_(temporary),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
LHasInstanceTypeAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
"has-instance-type-and-branch")
virtual void PrintDataTo(StringStream* stream);
virtual bool IsControl() const { return true; }
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
LOperand* temp() { return temp_; }
DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
private:
LOperand* temp_;
int true_block_id_;
int false_block_id_;
virtual void PrintDataTo(StringStream* stream);
};
class LHasCachedArrayIndex: public LUnaryOperation<1> {
class LHasCachedArrayIndex: public LTemplateInstruction<1, 1> {
public:
explicit LHasCachedArrayIndex(LOperand* value) : LUnaryOperation<1>(value) {}
explicit LHasCachedArrayIndex(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has-cached-array-index")
DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndex)
};
class LHasCachedArrayIndexAndBranch: public LHasCachedArrayIndex {
class LHasCachedArrayIndexAndBranch: public LControlInstruction<1> {
public:
LHasCachedArrayIndexAndBranch(LOperand* value,
int true_block_id,
int false_block_id)
: LHasCachedArrayIndex(value),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
"has-cached-array-index-and-branch")
virtual void PrintDataTo(StringStream* stream);
virtual bool IsControl() const { return true; }
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
private:
int true_block_id_;
int false_block_id_;
};
class LClassOfTest: public LUnaryOperation<1> {
class LClassOfTest: public LTemplateInstruction<1, 1, 1> {
public:
LClassOfTest(LOperand* value, LOperand* temp)
: LUnaryOperation<1>(value), temporary_(temp) {}
LClassOfTest(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class-of-test")
DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
virtual void PrintDataTo(StringStream* stream);
LOperand* temporary() { return temporary_; }
private:
LOperand* temporary_;
};
class LClassOfTestAndBranch: public LClassOfTest {
class LClassOfTestAndBranch: public LControlInstruction<1, 2> {
public:
LClassOfTestAndBranch(LOperand* value,
LOperand* temporary,
LOperand* temporary2,
int true_block_id,
int false_block_id)
: LClassOfTest(value, temporary),
temporary2_(temporary2),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
inputs_[0] = value;
temps_[0] = temp;
temps_[1] = temp2;
}
DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
"class-of-test-and-branch")
virtual void PrintDataTo(StringStream* stream);
virtual bool IsControl() const { return true; }
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
LOperand* temporary2() { return temporary2_; }
DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
private:
LOperand* temporary2_;
int true_block_id_;
int false_block_id_;
virtual void PrintDataTo(StringStream* stream);
};
class LCmpT: public LBinaryOperation<1> {
class LCmpT: public LTemplateInstruction<1, 2> {
public:
LCmpT(LOperand* left, LOperand* right) : LBinaryOperation<1>(left, right) {}
LCmpT(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
DECLARE_HYDROGEN_ACCESSOR(Compare)
......@@ -955,90 +870,78 @@ class LCmpT: public LBinaryOperation<1> {
};
class LCmpTAndBranch: public LCmpT {
class LCmpTAndBranch: public LControlInstruction<2> {
public:
LCmpTAndBranch(LOperand* left,
LOperand* right,
int true_block_id,
int false_block_id)
: LCmpT(left, right),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
LCmpTAndBranch(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(CmpTAndBranch, "cmp-t-and-branch")
DECLARE_HYDROGEN_ACCESSOR(Compare)
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
private:
int true_block_id_;
int false_block_id_;
Token::Value op() const { return hydrogen()->token(); }
};
class LInstanceOf: public LBinaryOperation<1> {
class LInstanceOf: public LTemplateInstruction<1, 2> {
public:
LInstanceOf(LOperand* left, LOperand* right)
: LBinaryOperation<1>(left, right) { }
LInstanceOf(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
};
class LInstanceOfAndBranch: public LInstanceOf {
class LInstanceOfAndBranch: public LControlInstruction<2> {
public:
LInstanceOfAndBranch(LOperand* left,
LOperand* right,
int true_block_id,
int false_block_id)
: LInstanceOf(left, right),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
LInstanceOfAndBranch(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(InstanceOfAndBranch, "instance-of-and-branch")
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
private:
int true_block_id_;
int false_block_id_;
};
class LInstanceOfKnownGlobal: public LUnaryOperation<1> {
class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> {
public:
LInstanceOfKnownGlobal(LOperand* left, LOperand* temp)
: LUnaryOperation<1>(left), temp_(temp) { }
LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
"instance-of-known-global")
DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
Handle<JSFunction> function() const { return hydrogen()->function(); }
LOperand* temp() const { return temp_; }
private:
LOperand* temp_;
};
class LBoundsCheck: public LBinaryOperation<0> {
class LBoundsCheck: public LTemplateInstruction<0, 2, 0> {
public:
LBoundsCheck(LOperand* index, LOperand* length)
: LBinaryOperation<0>(index, length) { }
LBoundsCheck(LOperand* index, LOperand* length) {
inputs_[0] = index;
inputs_[1] = length;
}
LOperand* index() const { return left(); }
LOperand* length() const { return right(); }
LOperand* index() { return inputs_[0]; }
LOperand* length() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
};
class LBitI: public LBinaryOperation<1> {
class LBitI: public LTemplateInstruction<1, 2> {
public:
LBitI(Token::Value op, LOperand* left, LOperand* right)
: LBinaryOperation<1>(left, right), op_(op) { }
: op_(op) {
inputs_[0] = left;
inputs_[1] = right;
}
Token::Value op() const { return op_; }
......@@ -1049,10 +952,13 @@ class LBitI: public LBinaryOperation<1> {
};
class LShiftI: public LBinaryOperation<1> {
class LShiftI: public LTemplateInstruction<1, 2> {
public:
LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
: LBinaryOperation<1>(left, right), op_(op), can_deopt_(can_deopt) { }
: op_(op), can_deopt_(can_deopt) {
inputs_[0] = left;
inputs_[1] = right;
}
Token::Value op() const { return op_; }
......@@ -1066,10 +972,12 @@ class LShiftI: public LBinaryOperation<1> {
};
class LSubI: public LBinaryOperation<1> {
class LSubI: public LTemplateInstruction<1, 2> {
public:
LSubI(LOperand* left, LOperand* right)
: LBinaryOperation<1>(left, right) { }
LSubI(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
DECLARE_HYDROGEN_ACCESSOR(Sub)
......@@ -1117,31 +1025,24 @@ class LConstantT: public LConstant {
};
class LBranch: public LUnaryOperation<0> {
class LBranch: public LControlInstruction<1> {
public:
LBranch(LOperand* input, int true_block_id, int false_block_id)
: LUnaryOperation<0>(input),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
explicit LBranch(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
DECLARE_HYDROGEN_ACCESSOR(Value)
virtual void PrintDataTo(StringStream* stream);
virtual bool IsControl() const { return true; }
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
private:
int true_block_id_;
int false_block_id_;
};
class LCmpMapAndBranch: public LUnaryOperation<0> {
class LCmpMapAndBranch: public LTemplateInstruction<0, 1> {
public:
explicit LCmpMapAndBranch(LOperand* value) : LUnaryOperation<0>(value) { }
explicit LCmpMapAndBranch(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMapAndBranch)
......@@ -1158,79 +1059,91 @@ class LCmpMapAndBranch: public LUnaryOperation<0> {
};
class LJSArrayLength: public LUnaryOperation<1> {
class LJSArrayLength: public LTemplateInstruction<1, 1> {
public:
explicit LJSArrayLength(LOperand* input) : LUnaryOperation<1>(input) { }
explicit LJSArrayLength(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
};
class LFixedArrayLength: public LUnaryOperation<1> {
class LFixedArrayLength: public LTemplateInstruction<1, 1> {
public:
explicit LFixedArrayLength(LOperand* input) : LUnaryOperation<1>(input) { }
explicit LFixedArrayLength(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length")
DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength)
};
class LValueOf: public LUnaryOperation<1> {
class LValueOf: public LTemplateInstruction<1, 1, 1> {
public:
LValueOf(LOperand* input, LOperand* temporary)
: LUnaryOperation<1>(input), temporary_(temporary) { }
LOperand* temporary() const { return temporary_; }
LValueOf(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
DECLARE_HYDROGEN_ACCESSOR(ValueOf)
private:
LOperand* temporary_;
};
class LThrow: public LUnaryOperation<0> {
class LThrow: public LTemplateInstruction<0, 1> {
public:
explicit LThrow(LOperand* value) : LUnaryOperation<0>(value) { }
explicit LThrow(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
};
class LBitNotI: public LUnaryOperation<1> {
class LBitNotI: public LTemplateInstruction<1, 1> {
public:
explicit LBitNotI(LOperand* input) : LUnaryOperation<1>(input) { }
explicit LBitNotI(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i")
};
class LAddI: public LBinaryOperation<1> {
class LAddI: public LTemplateInstruction<1, 2> {
public:
LAddI(LOperand* left, LOperand* right)
: LBinaryOperation<1>(left, right) { }
LAddI(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
DECLARE_HYDROGEN_ACCESSOR(Add)
};
class LPower: public LBinaryOperation<1> {
class LPower: public LTemplateInstruction<1, 2> {
public:
LPower(LOperand* left, LOperand* right)
: LBinaryOperation<1>(left, right) { }
LPower(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
DECLARE_CONCRETE_INSTRUCTION(Power, "power")
DECLARE_HYDROGEN_ACCESSOR(Power)
};
class LArithmeticD: public LBinaryOperation<1> {
class LArithmeticD: public LTemplateInstruction<1, 2> {
public:
LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
: LBinaryOperation<1>(left, right), op_(op) { }
: op_(op) {
inputs_[0] = left;
inputs_[1] = right;
}
Token::Value op() const { return op_; }
......@@ -1242,10 +1155,13 @@ class LArithmeticD: public LBinaryOperation<1> {
};
class LArithmeticT: public LBinaryOperation<1> {
class LArithmeticT: public LTemplateInstruction<1, 2> {
public:
LArithmeticT(Token::Value op, LOperand* left, LOperand* right)
: LBinaryOperation<1>(left, right), op_(op) { }
: op_(op) {
inputs_[0] = left;
inputs_[1] = right;
}
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
......@@ -1257,81 +1173,91 @@ class LArithmeticT: public LBinaryOperation<1> {
};
class LReturn: public LUnaryOperation<0> {
class LReturn: public LTemplateInstruction<0, 1> {
public:
explicit LReturn(LOperand* use) : LUnaryOperation<0>(use) { }
explicit LReturn(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(Return, "return")
};
class LLoadNamedField: public LUnaryOperation<1> {
class LLoadNamedField: public LTemplateInstruction<1, 1> {
public:
explicit LLoadNamedField(LOperand* object) : LUnaryOperation<1>(object) { }
explicit LLoadNamedField(LOperand* object) {
inputs_[0] = object;
}
DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
};
class LLoadNamedGeneric: public LUnaryOperation<1> {
class LLoadNamedGeneric: public LTemplateInstruction<1, 1> {
public:
explicit LLoadNamedGeneric(LOperand* object) : LUnaryOperation<1>(object) { }
explicit LLoadNamedGeneric(LOperand* object) {
inputs_[0] = object;
}
DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
LOperand* object() const { return input(); }
LOperand* object() { return inputs_[0]; }
Handle<Object> name() const { return hydrogen()->name(); }
};
class LLoadFunctionPrototype: public LUnaryOperation<1> {
class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 1> {
public:
LLoadFunctionPrototype(LOperand* function, LOperand* temporary)
: LUnaryOperation<1>(function), temporary_(temporary) { }
LLoadFunctionPrototype(LOperand* function, LOperand* temp) {
inputs_[0] = function;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
LOperand* function() const { return input(); }
LOperand* temporary() const { return temporary_; }
private:
LOperand* temporary_;
LOperand* function() { return inputs_[0]; }
};
class LLoadElements: public LUnaryOperation<1> {
class LLoadElements: public LTemplateInstruction<1, 1> {
public:
explicit LLoadElements(LOperand* obj) : LUnaryOperation<1>(obj) { }
explicit LLoadElements(LOperand* object) {
inputs_[0] = object;
}
DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
};
class LLoadKeyedFastElement: public LBinaryOperation<1> {
class LLoadKeyedFastElement: public LTemplateInstruction<1, 2> {
public:
LLoadKeyedFastElement(LOperand* elements, LOperand* key)
: LBinaryOperation<1>(elements, key) { }
LLoadKeyedFastElement(LOperand* elements, LOperand* key) {
inputs_[0] = elements;
inputs_[1] = key;
}
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement)
LOperand* elements() const { return left(); }
LOperand* key() const { return right(); }
LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
};
class LLoadKeyedGeneric: public LBinaryOperation<1> {
class LLoadKeyedGeneric: public LTemplateInstruction<1, 2> {
public:
LLoadKeyedGeneric(LOperand* obj, LOperand* key)
: LBinaryOperation<1>(obj, key) { }
LLoadKeyedGeneric(LOperand* obj, LOperand* key) {
inputs_[0] = obj;
inputs_[1] = key;
}
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
LOperand* object() const { return left(); }
LOperand* key() const { return right(); }
LOperand* object() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
};
......@@ -1342,9 +1268,11 @@ class LLoadGlobal: public LTemplateInstruction<1, 0, 0> {
};
class LStoreGlobal: public LUnaryOperation<0> {
class LStoreGlobal: public LTemplateInstruction<0, 1> {
public:
explicit LStoreGlobal(LOperand* value) : LUnaryOperation<0>(value) {}
explicit LStoreGlobal(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store-global")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobal)
......@@ -1356,18 +1284,18 @@ class LLoadContextSlot: public LTemplateInstruction<1, 0, 0> {
DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
int context_chain_length() const {
return hydrogen()->context_chain_length();
}
int slot_index() const { return hydrogen()->slot_index(); }
int context_chain_length() { return hydrogen()->context_chain_length(); }
int slot_index() { return hydrogen()->slot_index(); }
virtual void PrintDataTo(StringStream* stream);
};
class LPushArgument: public LUnaryOperation<0> {
class LPushArgument: public LTemplateInstruction<0, 1> {
public:
explicit LPushArgument(LOperand* argument) : LUnaryOperation<0>(argument) {}
explicit LPushArgument(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
};
......@@ -1397,8 +1325,12 @@ class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> {
};
class LCallKeyed: public LTemplateInstruction<1, 0, 0> {
class LCallKeyed: public LTemplateInstruction<1, 0, 1> {
public:
explicit LCallKeyed(LOperand* temp) {
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
......@@ -1453,9 +1385,11 @@ class LCallKnownGlobal: public LTemplateInstruction<1, 0, 0> {
};
class LCallNew: public LUnaryOperation<1> {
class LCallNew: public LTemplateInstruction<1, 1> {
public:
explicit LCallNew(LOperand* constructor) : LUnaryOperation<1>(constructor) { }
explicit LCallNew(LOperand* constructor) {
inputs_[0] = constructor;
}
DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
DECLARE_HYDROGEN_ACCESSOR(CallNew)
......@@ -1476,90 +1410,93 @@ class LCallRuntime: public LTemplateInstruction<1, 0, 0> {
};
class LInteger32ToDouble: public LUnaryOperation<1> {
class LInteger32ToDouble: public LTemplateInstruction<1, 1> {
public:
explicit LInteger32ToDouble(LOperand* use) : LUnaryOperation<1>(use) { }
explicit LInteger32ToDouble(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
};
class LNumberTagI: public LUnaryOperation<1> {
class LNumberTagI: public LTemplateInstruction<1, 1> {
public:
explicit LNumberTagI(LOperand* use) : LUnaryOperation<1>(use) { }
explicit LNumberTagI(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
};
class LNumberTagD: public LUnaryOperation<1> {
class LNumberTagD: public LTemplateInstruction<1, 1, 1> {
public:
explicit LNumberTagD(LOperand* value, LOperand* temp)
: LUnaryOperation<1>(value), temp_(temp) { }
explicit LNumberTagD(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
LOperand* temp() const { return temp_; }
private:
LOperand* temp_;
};
// Sometimes truncating conversion from a tagged value to an int32.
class LDoubleToI: public LUnaryOperation<1> {
class LDoubleToI: public LTemplateInstruction<1, 1, 1> {
public:
LDoubleToI(LOperand* value, LOperand* temporary)
: LUnaryOperation<1>(value), temporary_(temporary) { }
LDoubleToI(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
DECLARE_HYDROGEN_ACCESSOR(Change)
bool truncating() { return hydrogen()->CanTruncateToInt32(); }
LOperand* temporary() const { return temporary_; }
private:
LOperand* temporary_;
};
// Truncating conversion from a tagged value to an int32.
class LTaggedToI: public LUnaryOperation<1> {
class LTaggedToI: public LTemplateInstruction<1, 1, 1> {
public:
LTaggedToI(LOperand* value, LOperand* temp)
: LUnaryOperation<1>(value), temp_(temp) { }
LTaggedToI(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
DECLARE_HYDROGEN_ACCESSOR(Change)
bool truncating() { return hydrogen()->CanTruncateToInt32(); }
LOperand* temp() const { return temp_; }
private:
LOperand* temp_;
};
class LSmiTag: public LUnaryOperation<1> {
class LSmiTag: public LTemplateInstruction<1, 1> {
public:
explicit LSmiTag(LOperand* use) : LUnaryOperation<1>(use) { }
explicit LSmiTag(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
};
class LNumberUntagD: public LUnaryOperation<1> {
class LNumberUntagD: public LTemplateInstruction<1, 1> {
public:
explicit LNumberUntagD(LOperand* value) : LUnaryOperation<1>(value) { }
explicit LNumberUntagD(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
};
class LSmiUntag: public LUnaryOperation<1> {
class LSmiUntag: public LTemplateInstruction<1, 1> {
public:
LSmiUntag(LOperand* use, bool needs_check)
: LUnaryOperation<1>(use), needs_check_(needs_check) { }
LSmiUntag(LOperand* value, bool needs_check)
: needs_check_(needs_check) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
......@@ -1570,11 +1507,11 @@ class LSmiUntag: public LUnaryOperation<1> {
};
class LStoreNamed: public LTemplateInstruction<0, 2, 0> {
class LStoreNamed: public LTemplateInstruction<0, 2, 1> {
public:
LStoreNamed(LOperand* obj, LOperand* val) {
this->SetInputAt(0, obj);
this->SetInputAt(1, val);
inputs_[0] = obj;
inputs_[1] = val;
}
DECLARE_INSTRUCTION(StoreNamed)
......@@ -1582,8 +1519,8 @@ class LStoreNamed: public LTemplateInstruction<0, 2, 0> {
virtual void PrintDataTo(StringStream* stream);
LOperand* object() const { return this->InputAt(0); }
LOperand* value() const { return this->InputAt(1); }
LOperand* object() { return inputs_[0]; }
LOperand* value() { return inputs_[1]; }
Handle<Object> name() const { return hydrogen()->name(); }
};
......@@ -1591,7 +1528,9 @@ class LStoreNamed: public LTemplateInstruction<0, 2, 0> {
class LStoreNamedField: public LStoreNamed {
public:
LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp)
: LStoreNamed(obj, val), temp_(temp) { }
: LStoreNamed(obj, val) {
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
......@@ -1600,11 +1539,6 @@ class LStoreNamedField: public LStoreNamed {
int offset() { return hydrogen()->offset(); }
bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
Handle<Map> transition() const { return hydrogen()->transition(); }
LOperand* temp() { return temp_; }
private:
LOperand* temp_;
};
......@@ -1621,18 +1555,18 @@ class LStoreNamedGeneric: public LStoreNamed {
class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
public:
LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) {
this->SetInputAt(0, obj);
this->SetInputAt(1, key);
this->SetInputAt(2, val);
inputs_[0] = obj;
inputs_[1] = key;
inputs_[2] = val;
}
DECLARE_INSTRUCTION(StoreKeyed)
virtual void PrintDataTo(StringStream* stream);
LOperand* object() const { return this->InputAt(0); }
LOperand* key() const { return this->InputAt(1); }
LOperand* value() const { return this->InputAt(2); }
LOperand* object() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
};
......@@ -1656,60 +1590,60 @@ class LStoreKeyedGeneric: public LStoreKeyed {
};
class LCheckFunction: public LUnaryOperation<0> {
class LCheckFunction: public LTemplateInstruction<0, 1> {
public:
explicit LCheckFunction(LOperand* use) : LUnaryOperation<0>(use) { }
explicit LCheckFunction(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
};
class LCheckInstanceType: public LUnaryOperation<0> {
class LCheckInstanceType: public LTemplateInstruction<0, 1, 1> {
public:
LCheckInstanceType(LOperand* use, LOperand* temp)
: LUnaryOperation<0>(use), temp_(temp) { }
LCheckInstanceType(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
LOperand* temp() const { return temp_; }
private:
LOperand* temp_;
};
class LCheckMap: public LUnaryOperation<0> {
class LCheckMap: public LTemplateInstruction<0, 1> {
public:
explicit LCheckMap(LOperand* use) : LUnaryOperation<0>(use) { }
explicit LCheckMap(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map")
DECLARE_HYDROGEN_ACCESSOR(CheckMap)
};
class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 0> {
class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 1> {
public:
explicit LCheckPrototypeMaps(LOperand* temp) : temp_(temp) { }
explicit LCheckPrototypeMaps(LOperand* temp) {
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)
Handle<JSObject> prototype() const { return hydrogen()->prototype(); }
Handle<JSObject> holder() const { return hydrogen()->holder(); }
LOperand* temp() const { return temp_; }
private:
LOperand* temp_;
};
class LCheckSmi: public LUnaryOperation<0> {
class LCheckSmi: public LTemplateInstruction<0, 1> {
public:
LCheckSmi(LOperand* use, Condition condition)
: LUnaryOperation<0>(use), condition_(condition) { }
LCheckSmi(LOperand* value, Condition condition)
: condition_(condition) {
inputs_[0] = value;
}
Condition condition() const { return condition_; }
......@@ -1723,27 +1657,21 @@ class LCheckSmi: public LUnaryOperation<0> {
};
class LMaterializedLiteral: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_INSTRUCTION(MaterializedLiteral)
};
class LArrayLiteral: public LMaterializedLiteral {
class LArrayLiteral: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal")
DECLARE_HYDROGEN_ACCESSOR(ArrayLiteral)
};
class LObjectLiteral: public LMaterializedLiteral {
class LObjectLiteral: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral)
};
class LRegExpLiteral: public LMaterializedLiteral {
class LRegExpLiteral: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
......@@ -1759,58 +1687,57 @@ class LFunctionLiteral: public LTemplateInstruction<1, 0, 0> {
};
class LTypeof: public LUnaryOperation<1> {
class LTypeof: public LTemplateInstruction<1, 1> {
public:
explicit LTypeof(LOperand* input) : LUnaryOperation<1>(input) { }
explicit LTypeof(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
};
class LTypeofIs: public LUnaryOperation<1> {
class LTypeofIs: public LTemplateInstruction<1, 1> {
public:
explicit LTypeofIs(LOperand* input) : LUnaryOperation<1>(input) { }
virtual void PrintDataTo(StringStream* stream);
explicit LTypeofIs(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof-is")
DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
Handle<String> type_literal() { return hydrogen()->type_literal(); }
virtual void PrintDataTo(StringStream* stream);
};
class LTypeofIsAndBranch: public LTypeofIs {
class LTypeofIsAndBranch: public LControlInstruction<1> {
public:
LTypeofIsAndBranch(LOperand* value,
int true_block_id,
int false_block_id)
: LTypeofIs(value),
true_block_id_(true_block_id),
false_block_id_(false_block_id) { }
explicit LTypeofIsAndBranch(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
virtual void PrintDataTo(StringStream* stream);
virtual bool IsControl() const { return true; }
int true_block_id() const { return true_block_id_; }
int false_block_id() const { return false_block_id_; }
Handle<String> type_literal() { return hydrogen()->type_literal(); }
private:
int true_block_id_;
int false_block_id_;
virtual void PrintDataTo(StringStream* stream);
};
class LDeleteProperty: public LBinaryOperation<1> {
class LDeleteProperty: public LTemplateInstruction<1, 2> {
public:
LDeleteProperty(LOperand* obj, LOperand* key)
: LBinaryOperation<1>(obj, key) { }
LDeleteProperty(LOperand* obj, LOperand* key) {
inputs_[0] = obj;
inputs_[1] = key;
}
DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
LOperand* object() const { return left(); }
LOperand* key() const { return right(); }
LOperand* object() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
};
......@@ -1954,9 +1881,10 @@ class LChunkBuilder BASE_EMBEDDED {
LUnallocated* ToUnallocated(XMMRegister reg);
// Methods for setting up define-use relationships.
LOperand* Use(HValue* value, LUnallocated* operand);
LOperand* UseFixed(HValue* value, Register fixed_register);
LOperand* UseFixedDouble(HValue* value, XMMRegister fixed_register);
MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
XMMRegister fixed_register);
// A value that is guaranteed to be allocated to a register.
// Operand created by UseRegister is guaranteed to be live until the end of
......@@ -1966,17 +1894,22 @@ class LChunkBuilder BASE_EMBEDDED {
// instruction start. Register allocator is free to assign the same register
// to some other operand used inside instruction (i.e. temporary or
// output).
LOperand* UseRegister(HValue* value);
LOperand* UseRegisterAtStart(HValue* value);
MUST_USE_RESULT LOperand* UseRegister(HValue* value);
MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
// A value in a register that may be trashed.
LOperand* UseTempRegister(HValue* value);
LOperand* Use(HValue* value);
LOperand* UseAtStart(HValue* value);
LOperand* UseOrConstant(HValue* value);
LOperand* UseOrConstantAtStart(HValue* value);
LOperand* UseRegisterOrConstant(HValue* value);
LOperand* UseRegisterOrConstantAtStart(HValue* value);
MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
MUST_USE_RESULT LOperand* Use(HValue* value);
MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
// Temporary operand that must be in a register.
MUST_USE_RESULT LUnallocated* TempRegister();
MUST_USE_RESULT LOperand* FixedTemp(Register reg);
MUST_USE_RESULT LOperand* FixedTemp(XMMRegister reg);
// Methods for setting up define-use relationships.
// Return the same instruction that they are passed.
......@@ -2018,11 +1951,6 @@ class LChunkBuilder BASE_EMBEDDED {
LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env);
// Temporary operand that must be in a register.
LUnallocated* TempRegister();
LOperand* FixedTemp(Register reg);
LOperand* FixedTemp(XMMRegister reg);
void VisitInstruction(HInstruction* current);
void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment