Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 10968059: Support for unboxed 64-bit integer bitwise operations and equality on ia32. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: fixed boxing of smis and added one more test Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 UNREACHABLE(); 255 UNREACHABLE();
256 return OVERFLOW; 256 return OVERFLOW;
257 } 257 }
258 } 258 }
259 259
260 260
261 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { 261 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const {
262 const intptr_t kNumInputs = 2; 262 const intptr_t kNumInputs = 2;
263 const bool is_checked_strict_equal = 263 const bool is_checked_strict_equal =
264 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 264 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
265 if (receiver_class_id() == kMintCid) {
266 const intptr_t kNumTemps = 1;
267 LocationSummary* locs =
268 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
269 locs->set_in(0, Location::RequiresXmmRegister());
270 locs->set_in(1, Location::RequiresXmmRegister());
271 locs->set_temp(0, Location::RequiresRegister());
272 locs->set_out(Location::RequiresRegister());
273 return locs;
274 }
265 if (receiver_class_id() == kDoubleCid) { 275 if (receiver_class_id() == kDoubleCid) {
266 const intptr_t kNumTemps = 0; 276 const intptr_t kNumTemps = 0;
267 LocationSummary* locs = 277 LocationSummary* locs =
268 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 278 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
269 locs->set_in(0, Location::RequiresXmmRegister()); 279 locs->set_in(0, Location::RequiresXmmRegister());
270 locs->set_in(1, Location::RequiresXmmRegister()); 280 locs->set_in(1, Location::RequiresXmmRegister());
271 locs->set_out(Location::RequiresRegister()); 281 locs->set_out(Location::RequiresRegister());
272 return locs; 282 return locs;
273 } 283 }
274 if (receiver_class_id() == kSmiCid) { 284 if (receiver_class_id() == kSmiCid) {
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 __ j(true_condition, &is_true); 620 __ j(true_condition, &is_true);
611 __ LoadObject(result, compiler->bool_false()); 621 __ LoadObject(result, compiler->bool_false());
612 __ jmp(&done); 622 __ jmp(&done);
613 __ Bind(&is_true); 623 __ Bind(&is_true);
614 __ LoadObject(result, compiler->bool_true()); 624 __ LoadObject(result, compiler->bool_true());
615 __ Bind(&done); 625 __ Bind(&done);
616 } 626 }
617 } 627 }
618 628
619 629
630 static Condition TokenKindToMintCondition(Token::Kind kind) {
631 switch (kind) {
632 case Token::kEQ: return EQUAL;
633 case Token::kNE: return NOT_EQUAL;
634 default:
635 UNREACHABLE();
636 return OVERFLOW;
637 }
638 }
639
640
641 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
642 const LocationSummary& locs,
643 Token::Kind kind,
644 BranchInstr* branch) {
645 ASSERT(Token::IsEqualityOperator(kind));
646 XmmRegister left = locs.in(0).xmm_reg();
647 XmmRegister right = locs.in(1).xmm_reg();
648 Register temp = locs.temp(0).reg();
649 __ movaps(XMM0, left);
650 __ pcmpeqq(XMM0, right);
651 __ movd(temp, XMM0);
652
653 Condition true_condition = TokenKindToMintCondition(kind);
654 __ cmpl(temp, Immediate(-1));
655
656 if (branch != NULL) {
657 branch->EmitBranchOnCondition(compiler, true_condition);
658 } else {
659 Register result = locs.out().reg();
660 Label done, is_true;
661 __ j(true_condition, &is_true);
662 __ LoadObject(result, compiler->bool_false());
663 __ jmp(&done);
664 __ Bind(&is_true);
665 __ LoadObject(result, compiler->bool_true());
666 __ Bind(&done);
667 }
668 }
669
670
620 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 671 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
621 switch (kind) { 672 switch (kind) {
622 case Token::kEQ: return EQUAL; 673 case Token::kEQ: return EQUAL;
623 case Token::kNE: return NOT_EQUAL; 674 case Token::kNE: return NOT_EQUAL;
624 case Token::kLT: return BELOW; 675 case Token::kLT: return BELOW;
625 case Token::kGT: return ABOVE; 676 case Token::kGT: return ABOVE;
626 case Token::kLTE: return BELOW_EQUAL; 677 case Token::kLTE: return BELOW_EQUAL;
627 case Token::kGTE: return ABOVE_EQUAL; 678 case Token::kGTE: return ABOVE_EQUAL;
628 default: 679 default:
629 UNREACHABLE(); 680 UNREACHABLE();
(...skipping 21 matching lines...) Expand all
651 702
652 703
653 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 704 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
654 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 705 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
655 BranchInstr* kNoBranch = NULL; 706 BranchInstr* kNoBranch = NULL;
656 if (receiver_class_id() == kSmiCid) { 707 if (receiver_class_id() == kSmiCid) {
657 // Deoptimizes if both arguments not Smi. 708 // Deoptimizes if both arguments not Smi.
658 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); 709 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
659 return; 710 return;
660 } 711 }
712 if (receiver_class_id() == kMintCid) {
713 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch);
714 return;
715 }
661 if (receiver_class_id() == kDoubleCid) { 716 if (receiver_class_id() == kDoubleCid) {
662 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); 717 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
663 return; 718 return;
664 } 719 }
665 const bool is_checked_strict_equal = 720 const bool is_checked_strict_equal =
666 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 721 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
667 if (is_checked_strict_equal) { 722 if (is_checked_strict_equal) {
668 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, 723 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch,
669 deopt_id()); 724 deopt_id());
670 return; 725 return;
(...skipping 13 matching lines...) Expand all
684 739
685 740
686 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 741 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
687 BranchInstr* branch) { 742 BranchInstr* branch) {
688 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 743 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
689 if (receiver_class_id() == kSmiCid) { 744 if (receiver_class_id() == kSmiCid) {
690 // Deoptimizes if both arguments not Smi. 745 // Deoptimizes if both arguments not Smi.
691 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 746 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
692 return; 747 return;
693 } 748 }
749 if (receiver_class_id() == kMintCid) {
750 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch);
751 return;
752 }
694 if (receiver_class_id() == kDoubleCid) { 753 if (receiver_class_id() == kDoubleCid) {
695 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 754 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
696 return; 755 return;
697 } 756 }
698 const bool is_checked_strict_equal = 757 const bool is_checked_strict_equal =
699 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 758 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
700 if (is_checked_strict_equal) { 759 if (is_checked_strict_equal) {
701 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, 760 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch,
702 deopt_id()); 761 deopt_id());
703 return; 762 return;
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 UNREACHABLE(); 1740 UNREACHABLE();
1682 break; 1741 break;
1683 } 1742 }
1684 default: 1743 default:
1685 UNREACHABLE(); 1744 UNREACHABLE();
1686 break; 1745 break;
1687 } 1746 }
1688 } 1747 }
1689 1748
1690 1749
1691 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const {
1692 const intptr_t kNumInputs = 2;
1693 ASSERT(op_kind() == Token::kBIT_AND);
1694 const intptr_t kNumTemps = 1;
1695 LocationSummary* summary =
1696 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1697 summary->set_in(0, Location::RegisterLocation(EAX));
1698 summary->set_in(1, Location::RegisterLocation(ECX));
1699 summary->set_temp(0, Location::RegisterLocation(EDX));
1700 summary->set_out(Location::RegisterLocation(EAX));
1701 return summary;
1702 }
1703
1704
1705 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1706 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi
1707 // receiver and a Mint or Smi argument. We fall back to the run time call if
1708 // both receiver and argument are Mint or if one of them is Mint and the other
1709 // is a negative Smi.
1710 Register left = locs()->in(0).reg();
1711 Register right = locs()->in(1).reg();
1712 Register result = locs()->out().reg();
1713 Register temp = locs()->temp(0).reg();
1714 ASSERT(left == result);
1715 ASSERT(op_kind() == Token::kBIT_AND);
1716 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1717 kDeoptBinaryMintOp);
1718 Label mint_static_call, smi_static_call, non_smi, smi_smi, done;
1719 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi?
1720 __ j(NOT_ZERO, &non_smi);
1721 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi?
1722 __ j(ZERO, &smi_smi);
1723 __ CompareClassId(right, kMintCid, temp); // Is argument Mint?
1724 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint.
1725 __ cmpl(left, Immediate(0));
1726 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument.
1727
1728 // Positive Smi receiver, Mint argument.
1729 // Load lower argument Mint word, convert to Smi. It is OK to loose bits.
1730 __ movl(right, FieldAddress(right, Mint::value_offset()));
1731 __ SmiTag(right);
1732 __ andl(result, right);
1733 __ jmp(&done);
1734
1735 __ Bind(&non_smi); // Receiver is non-Smi.
1736 __ CompareClassId(left, kMintCid, temp); // Is receiver Mint?
1737 __ j(NOT_EQUAL, deopt); // Receiver neither Smi nor Mint.
1738 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi?
1739 __ j(NOT_ZERO, &mint_static_call); // Mint receiver, non-Smi argument.
1740 __ cmpl(right, Immediate(0));
1741 __ j(LESS, &mint_static_call); // Mint receiver, negative Smi argument.
1742
1743 // Mint receiver, positive Smi argument.
1744 // Load lower receiver Mint word, convert to Smi. It is OK to loose bits.
1745 __ movl(result, FieldAddress(left, Mint::value_offset()));
1746 __ SmiTag(result);
1747 __ Bind(&smi_smi);
1748 __ andl(result, right);
1749 __ jmp(&done);
1750
1751 __ Bind(&smi_static_call);
1752 {
1753 Function& target = Function::ZoneHandle(
1754 ic_data()->GetTargetForReceiverClassId(kSmiCid));
1755 if (target.IsNull()) {
1756 __ jmp(deopt);
1757 } else {
1758 __ pushl(left);
1759 __ pushl(right);
1760 compiler->GenerateStaticCall(
1761 instance_call()->deopt_id(),
1762 instance_call()->token_pos(),
1763 target,
1764 instance_call()->ArgumentCount(),
1765 instance_call()->argument_names(),
1766 locs());
1767 ASSERT(result == EAX);
1768 __ jmp(&done);
1769 }
1770 }
1771
1772 __ Bind(&mint_static_call);
1773 {
1774 Function& target = Function::ZoneHandle(
1775 ic_data()->GetTargetForReceiverClassId(kMintCid));
1776 if (target.IsNull()) {
1777 __ jmp(deopt);
1778 } else {
1779 __ pushl(left);
1780 __ pushl(right);
1781 compiler->GenerateStaticCall(
1782 instance_call()->deopt_id(),
1783 instance_call()->token_pos(),
1784 target,
1785 instance_call()->ArgumentCount(),
1786 instance_call()->argument_names(),
1787 locs());
1788 ASSERT(result == EAX);
1789 }
1790 }
1791 __ Bind(&done);
1792 }
1793
1794
1795 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { 1750 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const {
1796 ASSERT((left()->ResultCid() != kDoubleCid) && 1751 ASSERT((left()->ResultCid() != kDoubleCid) &&
1797 (right()->ResultCid() != kDoubleCid)); 1752 (right()->ResultCid() != kDoubleCid));
1798 const intptr_t kNumInputs = 2; 1753 const intptr_t kNumInputs = 2;
1799 const intptr_t kNumTemps = 1; 1754 const intptr_t kNumTemps = 1;
1800 LocationSummary* summary = 1755 LocationSummary* summary =
1801 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1756 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1802 summary->set_in(0, Location::RequiresRegister()); 1757 summary->set_in(0, Location::RequiresRegister());
1803 summary->set_in(1, Location::RequiresRegister()); 1758 summary->set_in(1, Location::RequiresRegister());
1804 summary->set_temp(0, Location::RequiresRegister()); 1759 summary->set_temp(0, Location::RequiresRegister());
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
2214 __ j(ABOVE_EQUAL, deopt); 2169 __ j(ABOVE_EQUAL, deopt);
2215 } else { 2170 } else {
2216 Register receiver = locs()->in(0).reg(); 2171 Register receiver = locs()->in(0).reg();
2217 Register index = locs()->in(1).reg(); 2172 Register index = locs()->in(1).reg();
2218 __ cmpl(index, FieldAddress(receiver, length_offset)); 2173 __ cmpl(index, FieldAddress(receiver, length_offset));
2219 __ j(ABOVE_EQUAL, deopt); 2174 __ j(ABOVE_EQUAL, deopt);
2220 } 2175 }
2221 } 2176 }
2222 2177
2223 2178
2179 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const {
2180 const intptr_t kNumInputs = 1;
2181 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0;
2182 LocationSummary* summary =
2183 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2184 summary->set_in(0, Location::RequiresRegister());
2185 if (CanDeoptimize()) summary->set_temp(0, Location::RequiresRegister());
2186 summary->set_out(Location::RequiresXmmRegister());
2187 return summary;
2188 }
2189
2190
2191 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2192 const intptr_t value_cid = value()->ResultCid();
2193 const Register value = locs()->in(0).reg();
2194 const XmmRegister result = locs()->out().xmm_reg();
2195
2196 if (value_cid == kMintCid) {
2197 __ movsd(result, FieldAddress(value, Mint::value_offset()));
2198 } else if (value_cid == kSmiCid) {
2199 __ SmiUntag(value); // Untag input before conversion.
2200 __ movd(result, value);
2201 __ pmovsxdq(result, result);
2202 __ SmiTag(value); // Restore input register.
2203 } else {
2204 Register temp = locs()->temp(0).reg();
2205 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
2206 Label is_smi, done;
2207 __ testl(value, Immediate(kSmiTagMask));
2208 __ j(ZERO, &is_smi);
2209 __ CompareClassId(value, kMintCid, temp);
2210 __ j(NOT_EQUAL, deopt);
2211 __ movsd(result, FieldAddress(value, Mint::value_offset()));
2212 __ jmp(&done);
2213 __ Bind(&is_smi);
2214 __ movl(temp, value);
2215 __ SmiUntag(temp);
2216 __ movd(result, temp);
2217 __ pmovsxdq(result, result);
2218 __ Bind(&done);
2219 }
2220 }
2221
2222
2223 LocationSummary* BoxIntegerInstr::MakeLocationSummary() const {
2224 const intptr_t kNumInputs = 1;
2225 const intptr_t kNumTemps = 2;
2226 LocationSummary* summary =
2227 new LocationSummary(kNumInputs,
2228 kNumTemps,
2229 LocationSummary::kCallOnSlowPath);
2230 summary->set_in(0, Location::RequiresXmmRegister());
2231 summary->set_temp(0, Location::RegisterLocation(EAX));
2232 summary->set_temp(1, Location::RegisterLocation(EDX));
2233 // TODO(fschneider): Save one temp by using result register as a temp.
2234 summary->set_out(Location::RequiresRegister());
2235 return summary;
2236 }
2237
2238
2239 class BoxIntegerSlowPath : public SlowPathCode {
2240 public:
2241 explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction)
2242 : instruction_(instruction) { }
2243
2244 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2245 __ Bind(entry_label());
2246 const Class& mint_class =
2247 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class());
2248 const Code& stub =
2249 Code::Handle(StubCode::GetAllocationStubForClass(mint_class));
2250 const ExternalLabel label(mint_class.ToCString(), stub.EntryPoint());
2251
2252 LocationSummary* locs = instruction_->locs();
2253 locs->live_registers()->Remove(locs->out());
2254 // Temps contain untagged values. Must only save tagged values.
2255 locs->live_registers()->Remove(locs->temp(0));
2256 locs->live_registers()->Remove(locs->temp(1));
2257
2258 compiler->SaveLiveRegisters(locs);
2259 compiler->GenerateCall(0, // No token pos.
2260 &label,
2261 PcDescriptors::kOther,
2262 locs);
2263 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX);
2264 compiler->RestoreLiveRegisters(locs);
2265
2266 __ jmp(exit_label());
2267 }
2268
2269 private:
2270 BoxIntegerInstr* instruction_;
2271 };
2272
2273
2274 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2275 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this);
2276 compiler->AddSlowPathCode(slow_path);
2277
2278 Register out_reg = locs()->out().reg();
2279 XmmRegister value = locs()->in(0).xmm_reg();
2280
2281 // Check if result fits into a smi.
2282 Label not_smi, done;
2283 __ pextrd(EDX, value, Immediate(1)); // Upper half.
2284 __ pextrd(EAX, value, Immediate(0)); // Lower half.
2285 // 1. Compute (x + -kMinSmi) which has to be in the range
2286 // 0 .. -kMinSmi+kMaxSmi for x to fit into a smi.
2287 __ addl(EAX, Immediate(0x40000000));
2288 __ adcl(EDX, Immediate(0));
2289 // 2. Unsigned compare to -kMinSmi+kMaxSmi.
2290 __ cmpl(EAX, Immediate(0x80000000));
2291 __ sbbl(EDX, Immediate(0));
2292 __ j(ABOVE_EQUAL, &not_smi);
2293 // 3. Restore lower half if results is a smi.
2294 __ subl(EAX, Immediate(0x40000000));
2295
2296 __ SmiTag(EAX);
2297 __ movl(out_reg, EAX);
2298 __ jmp(&done);
2299
2300 __ Bind(&not_smi);
2301 AssemblerMacros::TryAllocate(
2302 compiler->assembler(),
2303 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()),
2304 slow_path->entry_label(),
2305 Assembler::kFarJump,
2306 out_reg);
2307 __ Bind(slow_path->exit_label());
2308 __ movsd(FieldAddress(out_reg, Mint::value_offset()), value);
2309 __ Bind(&done);
2310 }
2311
2312
2313 LocationSummary* UnboxedMintBinaryOpInstr::MakeLocationSummary() const {
2314 const intptr_t kNumInputs = 2;
2315 const intptr_t kNumTemps = 0;
2316 LocationSummary* summary =
2317 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2318 summary->set_in(0, Location::RequiresXmmRegister());
2319 summary->set_in(1, Location::RequiresXmmRegister());
2320 summary->set_out(Location::SameAsFirstInput());
2321 return summary;
2322 }
2323
2324
2325 void UnboxedMintBinaryOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2326 XmmRegister left = locs()->in(0).xmm_reg();
2327 XmmRegister right = locs()->in(1).xmm_reg();
2328
2329 ASSERT(locs()->out().xmm_reg() == left);
2330
2331 switch (op_kind()) {
2332 case Token::kBIT_AND: __ andpd(left, right); break;
2333 case Token::kBIT_OR: __ orpd(left, right); break;
2334 case Token::kBIT_XOR: __ xorpd(left, right); break;
2335 default: UNREACHABLE();
2336 }
2337 }
2338
2339
2340
2224 } // namespace dart 2341 } // namespace dart
2225 2342
2226 #undef __ 2343 #undef __
2227 2344
2228 #endif // defined TARGET_ARCH_X64 2345 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698