| 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 LESS;
|
| + case Token::kGT: return GREATER;
|
| + case Token::kLTE: return LESS_EQUAL;
|
| + case Token::kGTE: return GREATER_EQUAL;
|
| default:
|
| - UNIMPLEMENTED();
|
| + UNREACHABLE();
|
| return OVERFLOW;
|
| }
|
| }
|
| @@ -682,6 +686,71 @@
|
| }
|
|
|
|
|
| +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 left_tmp = locs.temp(0).reg();
|
| + Register right_tmp = locs.temp(1).reg();
|
| + Register result = branch == NULL ? locs.out().reg() : kNoRegister;
|
| +
|
| + Condition hi_cond = OVERFLOW, lo_cond = OVERFLOW;
|
| + switch (kind) {
|
| + case Token::kLT:
|
| + hi_cond = LESS;
|
| + lo_cond = BELOW;
|
| + break;
|
| + case Token::kGT:
|
| + hi_cond = GREATER;
|
| + lo_cond = ABOVE;
|
| + break;
|
| + case Token::kLTE:
|
| + hi_cond = LESS;
|
| + lo_cond = BELOW_EQUAL;
|
| + break;
|
| + case Token::kGTE:
|
| + hi_cond = GREATER;
|
| + lo_cond = ABOVE_EQUAL;
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + ASSERT(hi_cond != OVERFLOW && lo_cond != OVERFLOW);
|
| + Label is_true, is_false;
|
| + // Compare upper halves first.
|
| + __ pextrd(left_tmp, left, Immediate(1));
|
| + __ pextrd(right_tmp, right, Immediate(1));
|
| + __ cmpl(left_tmp, right_tmp);
|
| + if (branch != NULL) {
|
| + __ j(hi_cond, compiler->GetBlockLabel(branch->true_successor()));
|
| + __ j(FlowGraphCompiler::FlipCondition(hi_cond),
|
| + compiler->GetBlockLabel(branch->false_successor()));
|
| + } else {
|
| + __ j(hi_cond, &is_true);
|
| + __ j(FlowGraphCompiler::FlipCondition(hi_cond), &is_false);
|
| + }
|
| +
|
| + // If upper is equal, compare lower half.
|
| + __ pextrd(left_tmp, left, Immediate(0));
|
| + __ pextrd(right_tmp, right, Immediate(0));
|
| + __ cmpl(left_tmp, right_tmp);
|
| + if (branch != NULL) {
|
| + branch->EmitBranchOnCondition(compiler, lo_cond);
|
| + } else {
|
| + Label done;
|
| + __ j(lo_cond, &is_true);
|
| + __ Bind(&is_false);
|
| + __ 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 +870,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 +911,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 +974,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 +2532,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) {
|
|
|