Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 14174) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -645,8 +645,12 @@ |
| switch (kind) { |
| case Token::kEQ: return EQUAL; |
| case Token::kNE: return NOT_EQUAL; |
| + case Token::kLT: return BELOW; |
| + case Token::kGT: return ABOVE; |
| + case Token::kLTE: return BELOW_EQUAL; |
| + case Token::kGTE: return ABOVE_EQUAL; |
| default: |
| - UNIMPLEMENTED(); |
| + UNREACHABLE(); |
| return OVERFLOW; |
| } |
| } |
| @@ -682,6 +686,46 @@ |
| } |
| +static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler, |
| + const LocationSummary& locs, |
| + Token::Kind kind, |
| + BranchInstr* branch) { |
| + XmmRegister left = locs.in(0).xmm_reg(); |
| + XmmRegister right = locs.in(1).xmm_reg(); |
| + Register lo = locs.temp(0).reg(); |
| + Register hi = locs.temp(1).reg(); |
| + |
| + __ pextrd(lo, left, Immediate(0)); // Lower half |
| + __ pextrd(hi, left, Immediate(1)); // Upper half |
| + __ subl(ESP, Immediate(2 * kWordSize)); |
| + __ movq(Address(ESP, 0), right); |
| + Label compare_lo, compare_done; |
| + __ cmpl(hi, Address(ESP, 1 * kWordSize)); |
| + __ j(EQUAL, &compare_lo); |
| + __ jmp(&compare_done); |
| + __ Bind(&compare_lo); |
| + __ cmpl(lo, Address(ESP, 0 * kWordSize)); |
|
Vyacheslav Egorov (Google)
2012/10/29 12:46:40
can you benchmark another pattern:
extract highe
|
| + |
| + __ Bind(&compare_done); |
| + // Use popl to restore stack instead of add(ESP...) to preserve flags. |
| + __ popl(lo); |
| + __ popl(lo); |
| + Condition true_condition = TokenKindToMintCondition(kind); |
| + if (branch != NULL) { |
| + branch->EmitBranchOnCondition(compiler, true_condition); |
| + } else { |
| + Register result = locs.out().reg(); |
| + Label done, is_true; |
| + __ j(true_condition, &is_true); |
| + __ LoadObject(result, compiler->bool_false()); |
| + __ jmp(&done); |
| + __ Bind(&is_true); |
| + __ LoadObject(result, compiler->bool_true()); |
| + __ Bind(&done); |
| + } |
| +} |
| + |
| + |
| static Condition TokenKindToDoubleCondition(Token::Kind kind) { |
| switch (kind) { |
| case Token::kEQ: return EQUAL; |
| @@ -801,6 +845,17 @@ |
| LocationSummary* RelationalOpInstr::MakeLocationSummary() const { |
| const intptr_t kNumInputs = 2; |
| const intptr_t kNumTemps = 0; |
| + if (operands_class_id() == kMintCid) { |
| + const intptr_t kNumTemps = 2; |
| + LocationSummary* locs = |
| + new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| + locs->set_in(0, Location::RequiresXmmRegister()); |
| + locs->set_in(1, Location::RequiresXmmRegister()); |
| + locs->set_temp(0, Location::RequiresRegister()); |
| + locs->set_temp(1, Location::RequiresRegister()); |
| + locs->set_out(Location::RequiresRegister()); |
| + return locs; |
| + } |
| if (operands_class_id() == kDoubleCid) { |
| LocationSummary* summary = |
| new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| @@ -831,6 +886,10 @@ |
| EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); |
| return; |
| } |
| + if (operands_class_id() == kMintCid) { |
| + EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); |
| + return; |
| + } |
| if (operands_class_id() == kDoubleCid) { |
| EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); |
| return; |
| @@ -890,6 +949,10 @@ |
| EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| return; |
| } |
| + if (operands_class_id() == kMintCid) { |
| + EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); |
| + return; |
| + } |
| if (operands_class_id() == kDoubleCid) { |
| EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| return; |
| @@ -2444,8 +2507,8 @@ |
| Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| kDeoptBinaryMintOp); |
| Label done, overflow; |
| - __ pextrd(lo, right, Immediate(0)); // Lower half left |
| - __ pextrd(hi, right, Immediate(1)); // Upper half left |
| + __ pextrd(lo, right, Immediate(0)); // Lower half |
| + __ pextrd(hi, right, Immediate(1)); // Upper half |
| __ subl(ESP, Immediate(2 * kWordSize)); |
| __ movq(Address(ESP, 0), left); |
| if (op_kind() == Token::kADD) { |