| Index: runtime/vm/intermediate_language_x64.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_x64.cc (revision 30464)
|
| +++ runtime/vm/intermediate_language_x64.cc (working copy)
|
| @@ -131,16 +131,7 @@
|
|
|
|
|
| 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()));
|
| + LocationSummary* locs = comparison()->MakeLocationSummary();
|
| // TODO(vegorov): support byte register constraints in the register allocator.
|
| locs->set_out(Location::RegisterLocation(RDX));
|
| return locs;
|
| @@ -149,31 +140,15 @@
|
|
|
| void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| ASSERT(locs()->out().reg() == RDX);
|
| - ASSERT(Token::IsEqualityOperator(kind()));
|
|
|
| - Location left = locs()->in(0);
|
| - Location right = locs()->in(1);
|
| - ASSERT(!left.IsConstant() || !right.IsConstant());
|
| -
|
| // Clear upper part of the out register. We are going to use setcc on it
|
| // which is a byte move.
|
| __ xorq(RDX, RDX);
|
|
|
| - // 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(right.reg(), left.constant(), PP);
|
| - } else if (right.IsConstant()) {
|
| - __ CompareObject(left.reg(), right.constant(), PP);
|
| - } else {
|
| - __ cmpq(left.reg(), right.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)) ? EQUAL
|
| - : NOT_EQUAL;
|
| -
|
| const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
|
|
|
| intptr_t true_value = if_true_;
|
| @@ -420,10 +395,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) {
|
| Location left = locs.in(0);
|
| Location right = locs.in(1);
|
| ASSERT(!left.IsConstant() || !right.IsConstant());
|
| @@ -440,7 +415,7 @@
|
| } else {
|
| __ cmpq(left.reg(), right.reg());
|
| }
|
| - EmitBranchOnCondition(compiler, true_condition, labels);
|
| + return true_condition;
|
| }
|
|
|
|
|
| @@ -459,10 +434,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) {
|
| XmmRegister left = locs.in(0).fpu_reg();
|
| XmmRegister right = locs.in(1).fpu_reg();
|
|
|
| @@ -472,22 +447,29 @@
|
| Label* nan_result = (true_condition == NOT_EQUAL)
|
| ? labels.true_label : labels.false_label;
|
| __ j(PARITY_EVEN, nan_result);
|
| - EmitBranchOnCondition(compiler, true_condition, labels);
|
| + return true_condition;
|
| }
|
|
|
|
|
| +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);
|
| + }
|
| +}
|
| +
|
| +
|
| void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
|
|
|
| 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);
|
| @@ -504,13 +486,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);
|
| }
|
|
|
|
|
| @@ -527,17 +504,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 branch_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
|
| +Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
|
| + BranchLabels labels) {
|
| Register left_reg = locs()->in(0).reg();
|
| Location right = locs()->in(1);
|
| if (right.IsConstant()) {
|
| @@ -548,10 +516,25 @@
|
| } else {
|
| __ testq(left_reg, right.reg());
|
| }
|
| - EmitBranchOnCondition(compiler, branch_condition, labels);
|
| + Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
|
| + 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);
|
| +}
|
| +
|
| +
|
| LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 2;
|
| const intptr_t kNumTemps = 0;
|
| @@ -577,16 +560,23 @@
|
| }
|
|
|
|
|
| -void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - Label is_true, is_false;
|
| - BranchLabels labels = { &is_true, &is_false, &is_false };
|
| -
|
| +Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
|
| + BranchLabels labels) {
|
| if (operation_cid() == kSmiCid) {
|
| - EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
|
| + return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
|
| } else {
|
| ASSERT(operation_cid() == kDoubleCid);
|
| - EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
|
| + return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
|
| }
|
| +}
|
| +
|
| +
|
| +void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + Label is_true, is_false;
|
| + BranchLabels labels = { &is_true, &is_false, &is_false };
|
| + Condition true_condition = EmitComparisonCode(compiler, labels);
|
| + EmitBranchOnCondition(compiler, true_condition, labels);
|
| +
|
| Register result = locs()->out().reg();
|
| Label done;
|
| __ Bind(&is_false);
|
| @@ -601,13 +591,8 @@
|
| void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
|
| BranchInstr* branch) {
|
| 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);
|
| }
|
|
|
|
|
| @@ -4402,46 +4387,41 @@
|
| }
|
|
|
|
|
| -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) ? EQUAL : NOT_EQUAL;
|
| - EmitBranchOnCondition(compiler, true_condition, labels);
|
| + Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
|
| + return true_condition;
|
| }
|
|
|
|
|
| -// Special code for numbers (compare values instead of references.)
|
| void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
|
|
|
| Label is_true, is_false;
|
| BranchLabels labels = { &is_true, &is_false, &is_false };
|
|
|
| - EmitStrictComparison(compiler, this, labels);
|
| + Condition true_condition = EmitComparisonCode(compiler, labels);
|
| + EmitBranchOnCondition(compiler, true_condition, labels);
|
|
|
| Register result = locs()->out().reg();
|
| Label done;
|
| @@ -4459,8 +4439,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);
|
| }
|
|
|
|
|
|
|