| Index: src/mips/lithium-codegen-mips.cc
|
| diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
|
| index b255ed7aacecbb4a174da22ec12ac1cbe6fb63d4..c50e066d07aaf2499b5e469134afdfcb70902e32 100644
|
| --- a/src/mips/lithium-codegen-mips.cc
|
| +++ b/src/mips/lithium-codegen-mips.cc
|
| @@ -1970,12 +1970,13 @@ int LCodeGen::GetNextEmittedBlock() const {
|
| return -1;
|
| }
|
|
|
| -
|
| -void LCodeGen::EmitBranch(int left_block, int right_block,
|
| +template<class InstrType>
|
| +void LCodeGen::EmitBranch(InstrType instr,
|
| Condition cc, Register src1, const Operand& src2) {
|
| + int right_block = instr->FalseDestination(chunk_);
|
| + int left_block = instr->TrueDestination(chunk_);
|
| +
|
| int next_block = GetNextEmittedBlock();
|
| - right_block = chunk_->LookupDestination(right_block);
|
| - left_block = chunk_->LookupDestination(left_block);
|
| if (right_block == left_block) {
|
| EmitGoto(left_block);
|
| } else if (left_block == next_block) {
|
| @@ -1990,11 +1991,13 @@ void LCodeGen::EmitBranch(int left_block, int right_block,
|
| }
|
|
|
|
|
| -void LCodeGen::EmitBranchF(int left_block, int right_block,
|
| +template<class InstrType>
|
| +void LCodeGen::EmitBranchF(InstrType instr,
|
| Condition cc, FPURegister src1, FPURegister src2) {
|
| + int right_block = instr->FalseDestination(chunk_);
|
| + int left_block = instr->TrueDestination(chunk_);
|
| +
|
| int next_block = GetNextEmittedBlock();
|
| - right_block = chunk_->LookupDestination(right_block);
|
| - left_block = chunk_->LookupDestination(left_block);
|
| if (right_block == left_block) {
|
| EmitGoto(left_block);
|
| } else if (left_block == next_block) {
|
| @@ -2015,19 +2018,16 @@ void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
|
|
|
|
|
| void LCodeGen::DoBranch(LBranch* instr) {
|
| - int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| - int false_block = chunk_->LookupDestination(instr->false_block_id());
|
| -
|
| Representation r = instr->hydrogen()->value()->representation();
|
| if (r.IsInteger32() || r.IsSmi()) {
|
| ASSERT(!info()->IsStub());
|
| Register reg = ToRegister(instr->value());
|
| - EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
|
| + EmitBranch(instr, ne, reg, Operand(zero_reg));
|
| } else if (r.IsDouble()) {
|
| ASSERT(!info()->IsStub());
|
| DoubleRegister reg = ToDoubleRegister(instr->value());
|
| // Test the double value. Zero and NaN are false.
|
| - EmitBranchF(true_block, false_block, nue, reg, kDoubleRegZero);
|
| + EmitBranchF(instr, nue, reg, kDoubleRegZero);
|
| } else {
|
| ASSERT(r.IsTagged());
|
| Register reg = ToRegister(instr->value());
|
| @@ -2035,14 +2035,11 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
| if (type.IsBoolean()) {
|
| ASSERT(!info()->IsStub());
|
| __ LoadRoot(at, Heap::kTrueValueRootIndex);
|
| - EmitBranch(true_block, false_block, eq, reg, Operand(at));
|
| + EmitBranch(instr, eq, reg, Operand(at));
|
| } else if (type.IsSmi()) {
|
| ASSERT(!info()->IsStub());
|
| - EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
|
| + EmitBranch(instr, ne, reg, Operand(zero_reg));
|
| } else {
|
| - Label* true_label = chunk_->GetAssemblyLabel(true_block);
|
| - Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
| -
|
| ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
|
| // Avoid deopts in the case where we've never executed this path before.
|
| if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
|
| @@ -2050,25 +2047,25 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
| if (expected.Contains(ToBooleanStub::UNDEFINED)) {
|
| // undefined -> false.
|
| __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
|
| - __ Branch(false_label, eq, reg, Operand(at));
|
| + __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
|
| }
|
| if (expected.Contains(ToBooleanStub::BOOLEAN)) {
|
| // Boolean -> its value.
|
| __ LoadRoot(at, Heap::kTrueValueRootIndex);
|
| - __ Branch(true_label, eq, reg, Operand(at));
|
| + __ Branch(instr->TrueLabel(chunk_), eq, reg, Operand(at));
|
| __ LoadRoot(at, Heap::kFalseValueRootIndex);
|
| - __ Branch(false_label, eq, reg, Operand(at));
|
| + __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
|
| }
|
| if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
|
| // 'null' -> false.
|
| __ LoadRoot(at, Heap::kNullValueRootIndex);
|
| - __ Branch(false_label, eq, reg, Operand(at));
|
| + __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
|
| }
|
|
|
| if (expected.Contains(ToBooleanStub::SMI)) {
|
| // Smis: 0 -> false, all other -> true.
|
| - __ Branch(false_label, eq, reg, Operand(zero_reg));
|
| - __ JumpIfSmi(reg, true_label);
|
| + __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg));
|
| + __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
|
| } else if (expected.NeedsMap()) {
|
| // If we need a map later and have a Smi -> deopt.
|
| __ And(at, reg, Operand(kSmiTagMask));
|
| @@ -2082,14 +2079,15 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
| // Undetectable -> false.
|
| __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
|
| __ And(at, at, Operand(1 << Map::kIsUndetectable));
|
| - __ Branch(false_label, ne, at, Operand(zero_reg));
|
| + __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg));
|
| }
|
| }
|
|
|
| if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
|
| // spec object -> true.
|
| __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset));
|
| - __ Branch(true_label, ge, at, Operand(FIRST_SPEC_OBJECT_TYPE));
|
| + __ Branch(instr->TrueLabel(chunk_),
|
| + ge, at, Operand(FIRST_SPEC_OBJECT_TYPE));
|
| }
|
|
|
| if (expected.Contains(ToBooleanStub::STRING)) {
|
| @@ -2098,8 +2096,8 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
| __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset));
|
| __ Branch(¬_string, ge , at, Operand(FIRST_NONSTRING_TYPE));
|
| __ lw(at, FieldMemOperand(reg, String::kLengthOffset));
|
| - __ Branch(true_label, ne, at, Operand(zero_reg));
|
| - __ Branch(false_label);
|
| + __ Branch(instr->TrueLabel(chunk_), ne, at, Operand(zero_reg));
|
| + __ Branch(instr->FalseLabel(chunk_));
|
| __ bind(¬_string);
|
| }
|
|
|
| @@ -2107,7 +2105,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
| // Symbol value -> true.
|
| const Register scratch = scratch1();
|
| __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
|
| - __ Branch(true_label, eq, scratch, Operand(SYMBOL_TYPE));
|
| + __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE));
|
| }
|
|
|
| if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
|
| @@ -2117,9 +2115,10 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
| __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
|
| __ Branch(¬_heap_number, ne, map, Operand(at));
|
| __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
|
| - __ BranchF(true_label, false_label, ne, dbl_scratch, kDoubleRegZero);
|
| + __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
|
| + ne, dbl_scratch, kDoubleRegZero);
|
| // Falls through if dbl_scratch == 0.
|
| - __ Branch(false_label);
|
| + __ Branch(instr->FalseLabel(chunk_));
|
| __ bind(¬_heap_number);
|
| }
|
|
|
| @@ -2132,7 +2131,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
|
|
| void LCodeGen::EmitGoto(int block) {
|
| if (!IsNextEmittedBlock(block)) {
|
| - __ jmp(chunk_->GetAssemblyLabel(chunk_->LookupDestination(block)));
|
| + __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
|
| }
|
| }
|
|
|
| @@ -2173,18 +2172,14 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
|
| void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
|
| LOperand* left = instr->left();
|
| LOperand* right = instr->right();
|
| - int false_block = chunk_->LookupDestination(instr->false_block_id());
|
| - int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| -
|
| Condition cond = TokenToCondition(instr->op(), false);
|
|
|
| if (left->IsConstantOperand() && right->IsConstantOperand()) {
|
| // We can statically evaluate the comparison.
|
| double left_val = ToDouble(LConstantOperand::cast(left));
|
| double right_val = ToDouble(LConstantOperand::cast(right));
|
| - int next_block =
|
| - EvalComparison(instr->op(), left_val, right_val) ? true_block
|
| - : false_block;
|
| + int next_block = EvalComparison(instr->op(), left_val, right_val) ?
|
| + instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
|
| EmitGoto(next_block);
|
| } else {
|
| if (instr->is_double()) {
|
| @@ -2195,10 +2190,10 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
|
|
|
| // If a NaN is involved, i.e. the result is unordered,
|
| // jump to false block label.
|
| - __ BranchF(NULL, chunk_->GetAssemblyLabel(false_block), eq,
|
| + __ BranchF(NULL, instr->FalseLabel(chunk_), eq,
|
| left_reg, right_reg);
|
|
|
| - EmitBranchF(true_block, false_block, cond, left_reg, right_reg);
|
| + EmitBranchF(instr, cond, left_reg, right_reg);
|
| } else {
|
| Register cmp_left;
|
| Operand cmp_right = Operand(0);
|
| @@ -2228,7 +2223,7 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
|
| cmp_right = Operand(ToRegister(right));
|
| }
|
|
|
| - EmitBranch(true_block, false_block, cond, cmp_left, cmp_right);
|
| + EmitBranch(instr, cond, cmp_left, cmp_right);
|
| }
|
| }
|
| }
|
| @@ -2237,20 +2232,15 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
|
| void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
|
| Register left = ToRegister(instr->left());
|
| Register right = ToRegister(instr->right());
|
| - int false_block = chunk_->LookupDestination(instr->false_block_id());
|
| - int true_block = chunk_->LookupDestination(instr->true_block_id());
|
|
|
| - EmitBranch(true_block, false_block, eq, left, Operand(right));
|
| + EmitBranch(instr, eq, left, Operand(right));
|
| }
|
|
|
|
|
| void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
|
| Register left = ToRegister(instr->left());
|
| - int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| - int false_block = chunk_->LookupDestination(instr->false_block_id());
|
|
|
| - EmitBranch(true_block, false_block, eq, left,
|
| - Operand(instr->hydrogen()->right()));
|
| + EmitBranch(instr, eq, left, Operand(instr->hydrogen()->right()));
|
| }
|
|
|
|
|
| @@ -2285,15 +2275,11 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
|
| Register temp1 = ToRegister(instr->temp());
|
| Register temp2 = scratch0();
|
|
|
| - 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);
|
| - Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
| -
|
| Condition true_cond =
|
| - EmitIsObject(reg, temp1, temp2, false_label, true_label);
|
| + EmitIsObject(reg, temp1, temp2,
|
| + instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
|
|
|
| - EmitBranch(true_block, false_block, true_cond, temp2,
|
| + EmitBranch(instr, true_cond, temp2,
|
| Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
| }
|
|
|
| @@ -2312,25 +2298,18 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
|
| Register reg = ToRegister(instr->value());
|
| Register temp1 = ToRegister(instr->temp());
|
|
|
| - int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| - int false_block = chunk_->LookupDestination(instr->false_block_id());
|
| - Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
| -
|
| Condition true_cond =
|
| - EmitIsString(reg, temp1, false_label);
|
| + EmitIsString(reg, temp1, instr->FalseLabel(chunk_));
|
|
|
| - EmitBranch(true_block, false_block, true_cond, temp1,
|
| + EmitBranch(instr, true_cond, temp1,
|
| Operand(FIRST_NONSTRING_TYPE));
|
| }
|
|
|
|
|
| void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
|
| - int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| - int false_block = chunk_->LookupDestination(instr->false_block_id());
|
| -
|
| Register input_reg = EmitLoadRegister(instr->value(), at);
|
| __ And(at, input_reg, kSmiTagMask);
|
| - EmitBranch(true_block, false_block, eq, at, Operand(zero_reg));
|
| + EmitBranch(instr, eq, at, Operand(zero_reg));
|
| }
|
|
|
|
|
| @@ -2338,14 +2317,11 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
|
| Register input = ToRegister(instr->value());
|
| Register temp = ToRegister(instr->temp());
|
|
|
| - int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| - int false_block = chunk_->LookupDestination(instr->false_block_id());
|
| -
|
| - __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
|
| + __ JumpIfSmi(input, instr->FalseLabel(chunk_));
|
| __ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset));
|
| __ lbu(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
|
| __ And(at, temp, Operand(1 << Map::kIsUndetectable));
|
| - EmitBranch(true_block, false_block, ne, at, Operand(zero_reg));
|
| + EmitBranch(instr, ne, at, Operand(zero_reg));
|
| }
|
|
|
|
|
| @@ -2371,15 +2347,13 @@ static Condition ComputeCompareCondition(Token::Value op) {
|
|
|
| void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
| Token::Value op = instr->op();
|
| - int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| - int false_block = chunk_->LookupDestination(instr->false_block_id());
|
|
|
| Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
|
| CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
|
|
| Condition condition = ComputeCompareCondition(op);
|
|
|
| - EmitBranch(true_block, false_block, condition, v0, Operand(zero_reg));
|
| + EmitBranch(instr, condition, v0, Operand(zero_reg));
|
| }
|
|
|
|
|
| @@ -2407,16 +2381,10 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
|
| Register scratch = scratch0();
|
| Register input = ToRegister(instr->value());
|
|
|
| - int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| - int false_block = chunk_->LookupDestination(instr->false_block_id());
|
| -
|
| - Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
| -
|
| - __ JumpIfSmi(input, false_label);
|
| + __ JumpIfSmi(input, instr->FalseLabel(chunk_));
|
|
|
| __ GetObjectType(input, scratch, scratch);
|
| - EmitBranch(true_block,
|
| - false_block,
|
| + EmitBranch(instr,
|
| BranchCondition(instr->hydrogen()),
|
| scratch,
|
| Operand(TestType(instr->hydrogen())));
|
| @@ -2439,13 +2407,10 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch(
|
| Register input = ToRegister(instr->value());
|
| Register scratch = scratch0();
|
|
|
| - int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| - int false_block = chunk_->LookupDestination(instr->false_block_id());
|
| -
|
| __ lw(scratch,
|
| FieldMemOperand(input, String::kHashFieldOffset));
|
| __ And(at, scratch, Operand(String::kContainsCachedArrayIndexMask));
|
| - EmitBranch(true_block, false_block, eq, at, Operand(zero_reg));
|
| + EmitBranch(instr, eq, at, Operand(zero_reg));
|
| }
|
|
|
|
|
| @@ -2521,26 +2486,19 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
|
| Register temp2 = ToRegister(instr->temp());
|
| Handle<String> class_name = instr->hydrogen()->class_name();
|
|
|
| - 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);
|
| - Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
| -
|
| - EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
|
| + EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
|
| + class_name, input, temp, temp2);
|
|
|
| - EmitBranch(true_block, false_block, eq, temp, Operand(class_name));
|
| + EmitBranch(instr, eq, temp, Operand(class_name));
|
| }
|
|
|
|
|
| void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
|
| Register reg = ToRegister(instr->value());
|
| Register temp = ToRegister(instr->temp());
|
| - int true_block = instr->true_block_id();
|
| - int false_block = instr->false_block_id();
|
|
|
| __ lw(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
|
| - EmitBranch(true_block, false_block, eq, temp, Operand(instr->map()));
|
| + EmitBranch(instr, eq, temp, Operand(instr->map()));
|
| }
|
|
|
|
|
| @@ -5534,16 +5492,12 @@ void LCodeGen::DoTypeof(LTypeof* instr) {
|
|
|
| void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
|
| Register input = ToRegister(instr->value());
|
| - 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);
|
| - Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
|
|
| Register cmp1 = no_reg;
|
| Operand cmp2 = Operand(no_reg);
|
|
|
| - Condition final_branch_condition = EmitTypeofIs(true_label,
|
| - false_label,
|
| + Condition final_branch_condition = EmitTypeofIs(instr->TrueLabel(chunk_),
|
| + instr->FalseLabel(chunk_),
|
| input,
|
| instr->type_literal(),
|
| cmp1,
|
| @@ -5553,7 +5507,7 @@ void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
|
| ASSERT(!cmp2.is_reg() || cmp2.rm().is_valid());
|
|
|
| if (final_branch_condition != kNoCondition) {
|
| - EmitBranch(true_block, false_block, final_branch_condition, cmp1, cmp2);
|
| + EmitBranch(instr, final_branch_condition, cmp1, cmp2);
|
| }
|
| }
|
|
|
| @@ -5666,12 +5620,10 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
|
|
|
| void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
|
| Register temp1 = ToRegister(instr->temp());
|
| - int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| - int false_block = chunk_->LookupDestination(instr->false_block_id());
|
|
|
| EmitIsConstructCall(temp1, scratch0());
|
|
|
| - EmitBranch(true_block, false_block, eq, temp1,
|
| + EmitBranch(instr, eq, temp1,
|
| Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
|
| }
|
|
|
|
|