| Index: runtime/vm/intermediate_language_mips.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_mips.cc (revision 30464)
|
| +++ runtime/vm/intermediate_language_mips.cc (working copy)
|
| @@ -135,24 +135,12 @@
|
|
|
|
|
| LocationSummary* IfThenElseInstr::MakeLocationSummary() const {
|
| - const intptr_t kNumInputs = 2;
|
| - const intptr_t kNumTemps = 0;
|
| - LocationSummary* locs =
|
| - new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| - locs->set_in(0, Location::RegisterOrConstant(left()));
|
| - // Only one of the inputs can be a constant. Choose register if the first one
|
| - // is a constant.
|
| - locs->set_in(1, locs->in(0).IsConstant()
|
| - ? Location::RequiresRegister()
|
| - : Location::RegisterOrConstant(right()));
|
| - locs->set_out(Location::RequiresRegister());
|
| - return locs;
|
| + return comparison()->MakeLocationSummary();
|
| }
|
|
|
|
|
| void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| const Register result = locs()->out().reg();
|
| - ASSERT(Token::IsEqualityOperator(kind()));
|
|
|
| Location left = locs()->in(0);
|
| Location right = locs()->in(1);
|
| @@ -161,21 +149,10 @@
|
| // Clear out register.
|
| __ mov(result, ZR);
|
|
|
| - // Compare left and right. For now only equality comparison is supported.
|
| - // TODO(vegorov): reuse code from the other comparison instructions instead of
|
| - // generating it inline here.
|
| - if (left.IsConstant()) {
|
| - __ CompareObject(CMPRES1, CMPRES2, right.reg(), left.constant());
|
| - } else if (right.IsConstant()) {
|
| - __ CompareObject(CMPRES1, CMPRES2, left.reg(), right.constant());
|
| - } else {
|
| - __ slt(CMPRES1, left.reg(), right.reg());
|
| - __ slt(CMPRES2, right.reg(), left.reg());
|
| - }
|
| + // Emit comparison code. This must not overwrite the result register.
|
| + BranchLabels labels = { NULL, NULL, NULL };
|
| + Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
|
|
|
| - Condition true_condition =
|
| - ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQ : NE;
|
| -
|
| const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
|
|
|
| intptr_t true_value = if_true_;
|
| @@ -197,12 +174,29 @@
|
| }
|
| }
|
|
|
| - if (true_condition == EQ) {
|
| - __ xor_(result, CMPRES1, CMPRES2);
|
| - __ xori(result, result, Immediate(1));
|
| - } else {
|
| - ASSERT(true_condition == NE);
|
| - __ xor_(result, CMPRES1, CMPRES2);
|
| + switch (true_condition) {
|
| + case EQ:
|
| + __ xor_(result, CMPRES1, CMPRES2);
|
| + __ xori(result, result, Immediate(1));
|
| + break;
|
| + case NE:
|
| + __ xor_(result, CMPRES1, CMPRES2);
|
| + break;
|
| + case GT:
|
| + __ mov(result, CMPRES2);
|
| + break;
|
| + case GE:
|
| + __ xori(result, CMPRES1, Immediate(1));
|
| + break;
|
| + case LT:
|
| + __ mov(result, CMPRES1);
|
| + break;
|
| + case LE:
|
| + __ xori(result, CMPRES2, Immediate(1));
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + break;
|
| }
|
|
|
| if (is_power_of_two_kind) {
|
| @@ -482,10 +476,10 @@
|
| }
|
|
|
|
|
| -static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
|
| - const LocationSummary& locs,
|
| - Token::Kind kind,
|
| - BranchLabels labels) {
|
| +static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
|
| + const LocationSummary& locs,
|
| + Token::Kind kind,
|
| + BranchLabels labels) {
|
| __ TraceSimMsg("EmitSmiComparisonOp");
|
| __ Comment("EmitSmiComparisonOp");
|
| Location left = locs.in(0);
|
| @@ -503,7 +497,7 @@
|
| __ slt(CMPRES1, left.reg(), right.reg());
|
| __ slt(CMPRES2, right.reg(), left.reg());
|
| }
|
| - EmitBranchOnCondition(compiler, true_condition, labels);
|
| + return true_condition;
|
| }
|
|
|
|
|
| @@ -522,10 +516,10 @@
|
| }
|
|
|
|
|
| -static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
|
| - const LocationSummary& locs,
|
| - Token::Kind kind,
|
| - BranchLabels labels) {
|
| +static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
|
| + const LocationSummary& locs,
|
| + Token::Kind kind,
|
| + BranchLabels labels) {
|
| DRegister left = locs.in(0).fpu_reg();
|
| DRegister right = locs.in(1).fpu_reg();
|
|
|
| @@ -551,6 +545,7 @@
|
| }
|
| }
|
|
|
| + // Ordering is expected to be described by CMPRES1, CMPRES2.
|
| __ LoadImmediate(TMP, 1);
|
| if (true_condition == NE) {
|
| __ movf(CMPRES1, ZR);
|
| @@ -560,9 +555,18 @@
|
| __ movt(CMPRES1, ZR);
|
| }
|
| __ mov(CMPRES2, ZR);
|
| + return EQ;
|
| +}
|
|
|
| - // EmitBranchOnCondition expects ordering to be described by CMPRES1, CMPRES2.
|
| - EmitBranchOnCondition(compiler, EQ, labels);
|
| +
|
| +Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
|
| + BranchLabels labels) {
|
| + if (operation_cid() == kSmiCid) {
|
| + return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
|
| + } else {
|
| + ASSERT(operation_cid() == kDoubleCid);
|
| + return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
|
| + }
|
| }
|
|
|
|
|
| @@ -572,13 +576,9 @@
|
|
|
| Label is_true, is_false;
|
| BranchLabels labels = { &is_true, &is_false, &is_false };
|
| + Condition true_condition = EmitComparisonCode(compiler, labels);
|
| + EmitBranchOnCondition(compiler, true_condition, labels);
|
|
|
| - if (operation_cid() == kSmiCid) {
|
| - EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
|
| - } else {
|
| - ASSERT(operation_cid() == kDoubleCid);
|
| - EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
|
| - }
|
| Register result = locs()->out().reg();
|
| Label done;
|
| __ Bind(&is_false);
|
| @@ -597,13 +597,8 @@
|
| ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
|
|
|
| BranchLabels labels = compiler->CreateBranchLabels(branch);
|
| -
|
| - if (operation_cid() == kSmiCid) {
|
| - EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
|
| - } else {
|
| - ASSERT(operation_cid() == kDoubleCid);
|
| - EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
|
| - }
|
| + Condition true_condition = EmitComparisonCode(compiler, labels);
|
| + EmitBranchOnCondition(compiler, true_condition, labels);
|
| }
|
|
|
|
|
| @@ -620,17 +615,8 @@
|
| }
|
|
|
|
|
| -void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - // Never emitted outside of the BranchInstr.
|
| - UNREACHABLE();
|
| -}
|
| -
|
| -
|
| -void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
|
| - BranchInstr* branch) {
|
| - BranchLabels labels = compiler->CreateBranchLabels(branch);
|
| -
|
| - Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
|
| +Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
|
| + BranchLabels labels) {
|
| Register left = locs()->in(0).reg();
|
| Location right = locs()->in(1);
|
| if (right.IsConstant()) {
|
| @@ -642,6 +628,21 @@
|
| __ and_(CMPRES1, left, right.reg());
|
| }
|
| __ mov(CMPRES2, ZR);
|
| + Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
|
| + return true_condition;
|
| +}
|
| +
|
| +
|
| +void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + // Never emitted outside of the BranchInstr.
|
| + UNREACHABLE();
|
| +}
|
| +
|
| +
|
| +void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
|
| + BranchInstr* branch) {
|
| + BranchLabels labels = compiler->CreateBranchLabels(branch);
|
| + Condition true_condition = EmitComparisonCode(compiler, labels);
|
| EmitBranchOnCondition(compiler, true_condition, labels);
|
| }
|
|
|
| @@ -682,18 +683,25 @@
|
| }
|
|
|
|
|
| +Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
|
| + BranchLabels labels) {
|
| + if (operation_cid() == kSmiCid) {
|
| + return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
|
| + } else {
|
| + ASSERT(operation_cid() == kDoubleCid);
|
| + return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
|
| + }
|
| +}
|
| +
|
| +
|
| void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| __ TraceSimMsg("RelationalOpInstr");
|
|
|
| Label is_true, is_false;
|
| BranchLabels labels = { &is_true, &is_false, &is_false };
|
| + Condition true_condition = EmitComparisonCode(compiler, labels);
|
| + EmitBranchOnCondition(compiler, true_condition, labels);
|
|
|
| - if (operation_cid() == kSmiCid) {
|
| - EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
|
| - } else {
|
| - ASSERT(operation_cid() == kDoubleCid);
|
| - EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
|
| - }
|
| Register result = locs()->out().reg();
|
| Label done;
|
| __ Bind(&is_false);
|
| @@ -710,13 +718,8 @@
|
| __ TraceSimMsg("RelationalOpInstr");
|
|
|
| BranchLabels labels = compiler->CreateBranchLabels(branch);
|
| -
|
| - if (operation_cid() == kSmiCid) {
|
| - EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
|
| - } else {
|
| - ASSERT(operation_cid() == kDoubleCid);
|
| - EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
|
| - }
|
| + Condition true_condition = EmitComparisonCode(compiler, labels);
|
| + EmitBranchOnCondition(compiler, true_condition, labels);
|
| }
|
|
|
|
|
| @@ -3755,37 +3758,32 @@
|
| }
|
|
|
|
|
| -static void EmitStrictComparison(FlowGraphCompiler* compiler,
|
| - StrictCompareInstr* compare,
|
| - BranchLabels labels) {
|
| - LocationSummary* locs = compare->locs();
|
| - bool needs_number_check = compare->needs_number_check();
|
| - intptr_t token_pos = compare->token_pos();
|
| - Token::Kind kind = compare->kind();
|
| - Location left = locs->in(0);
|
| - Location right = locs->in(1);
|
| +Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
|
| + BranchLabels labels) {
|
| + Location left = locs()->in(0);
|
| + Location right = locs()->in(1);
|
| ASSERT(!left.IsConstant() || !right.IsConstant());
|
| if (left.IsConstant()) {
|
| compiler->EmitEqualityRegConstCompare(right.reg(),
|
| left.constant(),
|
| - needs_number_check,
|
| - token_pos);
|
| + needs_number_check(),
|
| + token_pos());
|
| } else if (right.IsConstant()) {
|
| compiler->EmitEqualityRegConstCompare(left.reg(),
|
| right.constant(),
|
| - needs_number_check,
|
| - token_pos);
|
| + needs_number_check(),
|
| + token_pos());
|
| } else {
|
| compiler->EmitEqualityRegRegCompare(left.reg(),
|
| right.reg(),
|
| - needs_number_check,
|
| - token_pos);
|
| + needs_number_check(),
|
| + token_pos());
|
| }
|
| - Condition true_condition = (kind == Token::kEQ_STRICT) ? EQ : NE;
|
| - EmitBranchOnCondition(compiler, true_condition, labels);
|
| + Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
|
| + return true_condition;
|
| }
|
|
|
| -// Special code for numbers (compare values instead of references.)
|
| +
|
| void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| __ TraceSimMsg("StrictCompareInstr");
|
| __ Comment("StrictCompareInstr");
|
| @@ -3793,9 +3791,9 @@
|
|
|
| Label is_true, is_false;
|
| BranchLabels labels = { &is_true, &is_false, &is_false };
|
| + Condition true_condition = EmitComparisonCode(compiler, labels);
|
| + EmitBranchOnCondition(compiler, true_condition, labels);
|
|
|
| - EmitStrictComparison(compiler, this, labels);
|
| -
|
| Register result = locs()->out().reg();
|
| Label done;
|
| __ Bind(&is_false);
|
| @@ -3813,8 +3811,8 @@
|
| ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
|
|
|
| BranchLabels labels = compiler->CreateBranchLabels(branch);
|
| -
|
| - EmitStrictComparison(compiler, this, labels);
|
| + Condition true_condition = EmitComparisonCode(compiler, labels);
|
| + EmitBranchOnCondition(compiler, true_condition, labels);
|
| }
|
|
|
|
|
|
|