Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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_DBC. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC. |
| 6 #if defined(TARGET_ARCH_DBC) | 6 #if defined(TARGET_ARCH_DBC) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 M(LoadCodeUnits) \ | 33 M(LoadCodeUnits) \ |
| 34 M(LoadUntagged) \ | 34 M(LoadUntagged) \ |
| 35 M(AllocateUninitializedContext) \ | 35 M(AllocateUninitializedContext) \ |
| 36 M(BinaryInt32Op) \ | 36 M(BinaryInt32Op) \ |
| 37 M(Int32ToDouble) \ | 37 M(Int32ToDouble) \ |
| 38 M(DoubleToInteger) \ | 38 M(DoubleToInteger) \ |
| 39 M(DoubleToDouble) \ | 39 M(DoubleToDouble) \ |
| 40 M(DoubleToFloat) \ | 40 M(DoubleToFloat) \ |
| 41 M(FloatToDouble) \ | 41 M(FloatToDouble) \ |
| 42 M(BoxInt64) \ | 42 M(BoxInt64) \ |
| 43 M(InvokeMathCFunction) \ | |
| 44 M(MergedMath) \ | 43 M(MergedMath) \ |
| 45 M(GuardFieldClass) \ | 44 M(GuardFieldClass) \ |
| 46 M(GuardFieldLength) \ | 45 M(GuardFieldLength) \ |
| 47 M(IfThenElse) \ | 46 M(IfThenElse) \ |
| 48 M(ExtractNthOutput) \ | 47 M(ExtractNthOutput) \ |
| 49 M(BinaryUint32Op) \ | 48 M(BinaryUint32Op) \ |
| 50 M(ShiftUint32Op) \ | 49 M(ShiftUint32Op) \ |
| 51 M(UnaryUint32Op) \ | 50 M(UnaryUint32Op) \ |
| 52 M(UnboxedIntConverter) \ | 51 M(UnboxedIntConverter) \ |
| 53 M(BoxInteger32) \ | 52 M(BoxInteger32) \ |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 M(Float64x2ZeroArg) \ | 99 M(Float64x2ZeroArg) \ |
| 101 M(Float64x2OneArg) \ | 100 M(Float64x2OneArg) \ |
| 102 M(CheckedSmiOp) \ | 101 M(CheckedSmiOp) \ |
| 103 | 102 |
| 104 // Location summaries actually are not used by the unoptimizing DBC compiler | 103 // Location summaries actually are not used by the unoptimizing DBC compiler |
| 105 // because we don't allocate any registers. | 104 // because we don't allocate any registers. |
| 106 static LocationSummary* CreateLocationSummary( | 105 static LocationSummary* CreateLocationSummary( |
| 107 Zone* zone, | 106 Zone* zone, |
| 108 intptr_t num_inputs, | 107 intptr_t num_inputs, |
| 109 Location output = Location::NoLocation(), | 108 Location output = Location::NoLocation(), |
| 110 LocationSummary::ContainsCall contains_call = LocationSummary::kNoCall) { | 109 LocationSummary::ContainsCall contains_call = LocationSummary::kNoCall, |
| 111 const intptr_t kNumTemps = 0; | 110 intptr_t num_temps = 0) { |
| 112 LocationSummary* locs = new(zone) LocationSummary( | 111 LocationSummary* locs = new(zone) LocationSummary( |
| 113 zone, num_inputs, kNumTemps, contains_call); | 112 zone, num_inputs, num_temps, contains_call); |
| 114 for (intptr_t i = 0; i < num_inputs; i++) { | 113 for (intptr_t i = 0; i < num_inputs; i++) { |
| 115 locs->set_in(i, (contains_call == LocationSummary::kNoCall) ? | 114 locs->set_in(i, (contains_call == LocationSummary::kNoCall) ? |
| 116 Location::RequiresRegister() : Location::RegisterLocation(i)); | 115 Location::RequiresRegister() : Location::RegisterLocation(i)); |
| 117 } | 116 } |
| 117 for (intptr_t i = 0; i < num_temps; i++) { | |
| 118 locs->set_temp(i, Location::RequiresRegister()); | |
| 119 } | |
| 118 if (!output.IsInvalid()) { | 120 if (!output.IsInvalid()) { |
| 119 // For instructions that call we default to returning result in R0. | 121 // For instructions that call we default to returning result in R0. |
| 120 locs->set_out(0, output); | 122 locs->set_out(0, output); |
| 121 } | 123 } |
| 122 return locs; | 124 return locs; |
| 123 } | 125 } |
| 124 | 126 |
| 125 | 127 |
| 126 #define DEFINE_MAKE_LOCATION_SUMMARY(Name, ...) \ | 128 #define DEFINE_MAKE_LOCATION_SUMMARY(Name, ...) \ |
| 127 LocationSummary* Name##Instr::MakeLocationSummary(Zone* zone, bool opt) \ | 129 LocationSummary* Name##Instr::MakeLocationSummary(Zone* zone, bool opt) \ |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 __ Push(locs()->in(1).reg()); | 668 __ Push(locs()->in(1).reg()); |
| 667 } | 669 } |
| 668 __ CreateArrayTOS(); | 670 __ CreateArrayTOS(); |
| 669 compiler->RecordSafepoint(locs()); | 671 compiler->RecordSafepoint(locs()); |
| 670 if (compiler->is_optimizing()) { | 672 if (compiler->is_optimizing()) { |
| 671 __ PopLocal(locs()->out(0).reg()); | 673 __ PopLocal(locs()->out(0).reg()); |
| 672 } | 674 } |
| 673 } | 675 } |
| 674 | 676 |
| 675 | 677 |
| 676 EMIT_NATIVE_CODE(StoreIndexed, 3) { | 678 EMIT_NATIVE_CODE(StoreIndexed, 3, Location::NoLocation(), |
| 679 LocationSummary::kNoCall, 1) { | |
| 677 if (compiler->is_optimizing()) { | 680 if (compiler->is_optimizing()) { |
| 678 if (class_id() != kArrayCid) { | 681 if (IsExternal()) { |
| 679 Unsupported(compiler); | 682 Unsupported(compiler); |
| 680 UNREACHABLE(); | 683 UNREACHABLE(); |
| 681 } | 684 } |
| 682 __ StoreIndexed(locs()->in(kArrayPos).reg(), | 685 const Register array = locs()->in(kArrayPos).reg(); |
| 683 locs()->in(kIndexPos).reg(), | 686 const Register index = locs()->in(kIndexPos).reg(); |
| 684 locs()->in(kValuePos).reg()); | 687 const Register value = locs()->in(kValuePos).reg(); |
| 688 const Register temp = locs()->temp(0).reg(); | |
| 689 switch (class_id()) { | |
| 690 case kArrayCid: | |
| 691 __ StoreIndexed(array, index, value); | |
| 692 break; | |
| 693 case kTypedDataFloat64ArrayCid: | |
| 694 if ((index_scale() != 8) && (index_scale() != 1)) { | |
| 695 Unsupported(compiler); | |
| 696 UNREACHABLE(); | |
| 697 } | |
| 698 if (index_scale() == 1) { | |
| 699 __ LoadConstant(temp, Smi::Handle(Smi::New(3))); | |
| 700 __ Shr(temp, index, temp); | |
| 701 __ Nop(0); | |
| 702 } else { | |
| 703 __ Move(temp, index); | |
| 704 } | |
| 705 __ StoreFloat64Indexed(array, temp, value); | |
| 706 break; | |
| 707 default: | |
| 708 Unsupported(compiler); | |
| 709 UNREACHABLE(); | |
| 710 break; | |
| 711 } | |
| 685 } else { | 712 } else { |
| 686 ASSERT(class_id() == kArrayCid); | 713 ASSERT(class_id() == kArrayCid); |
| 687 __ StoreIndexedTOS(); | 714 __ StoreIndexedTOS(); |
| 688 } | 715 } |
| 689 } | 716 } |
| 690 | 717 |
| 691 | 718 |
| 692 EMIT_NATIVE_CODE(LoadIndexed, 2, Location::RequiresRegister()) { | 719 EMIT_NATIVE_CODE(LoadIndexed, 2, Location::RequiresRegister()) { |
| 693 ASSERT(compiler->is_optimizing()); | 720 ASSERT(compiler->is_optimizing()); |
| 694 if (class_id() != kArrayCid) { | 721 if (IsExternal()) { |
| 695 Unsupported(compiler); | 722 Unsupported(compiler); |
| 696 UNREACHABLE(); | 723 UNREACHABLE(); |
| 697 } | 724 } |
| 698 const Register array = locs()->in(0).reg(); | 725 const Register array = locs()->in(0).reg(); |
| 699 const Register index = locs()->in(1).reg(); | 726 const Register index = locs()->in(1).reg(); |
| 700 const Register result = locs()->out(0).reg(); | 727 const Register result = locs()->out(0).reg(); |
| 701 | 728 switch (class_id()) { |
| 702 __ LoadIndexed(result, array, index); | 729 case kArrayCid: |
| 730 __ LoadIndexed(result, array, index); | |
| 731 break; | |
| 732 case kTypedDataFloat64ArrayCid: | |
| 733 if ((index_scale() != 8) && (index_scale() != 1)) { | |
| 734 Unsupported(compiler); | |
| 735 UNREACHABLE(); | |
| 736 } | |
| 737 if (index_scale() == 1) { | |
| 738 __ LoadConstant(result, Smi::Handle(Smi::New(3))); | |
|
Florian Schneider
2016/07/25 20:10:40
Since LoadIndexed operations are very common, I th
zra
2016/07/25 20:39:30
Done.
| |
| 739 __ Shr(index, index, result); | |
| 740 __ Nop(0); | |
| 741 } | |
| 742 __ LoadFloat64Indexed(result, array, index); | |
| 743 break; | |
| 744 case kOneByteStringCid: | |
| 745 ASSERT(index_scale() == 1); | |
| 746 __ LoadOneByteStringIndexed(result, array, index); | |
| 747 break; | |
| 748 case kTwoByteStringCid: | |
| 749 if (index_scale() != 2) { | |
| 750 // TODO(zra): Fix-up index. | |
| 751 Unsupported(compiler); | |
| 752 UNREACHABLE(); | |
| 753 } | |
| 754 __ LoadTwoByteStringIndexed(result, array, index); | |
| 755 break; | |
| 756 default: | |
| 757 Unsupported(compiler); | |
| 758 UNREACHABLE(); | |
| 759 break; | |
| 760 } | |
| 703 } | 761 } |
| 704 | 762 |
| 705 | 763 |
| 706 EMIT_NATIVE_CODE(StringInterpolate, | 764 EMIT_NATIVE_CODE(StringInterpolate, |
| 707 1, Location::RegisterLocation(0), | 765 1, Location::RegisterLocation(0), |
| 708 LocationSummary::kCall) { | 766 LocationSummary::kCall) { |
| 709 if (compiler->is_optimizing()) { | 767 if (compiler->is_optimizing()) { |
| 710 __ Push(locs()->in(0).reg()); | 768 __ Push(locs()->in(0).reg()); |
| 711 } | 769 } |
| 712 const intptr_t kArgumentCount = 1; | 770 const intptr_t kArgumentCount = 1; |
| (...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1312 | 1370 |
| 1313 | 1371 |
| 1314 EMIT_NATIVE_CODE(UnaryDoubleOp, 1, Location::RequiresRegister()) { | 1372 EMIT_NATIVE_CODE(UnaryDoubleOp, 1, Location::RequiresRegister()) { |
| 1315 const Register value = locs()->in(0).reg(); | 1373 const Register value = locs()->in(0).reg(); |
| 1316 const Register result = locs()->out(0).reg(); | 1374 const Register result = locs()->out(0).reg(); |
| 1317 __ DNeg(result, value); | 1375 __ DNeg(result, value); |
| 1318 } | 1376 } |
| 1319 | 1377 |
| 1320 | 1378 |
| 1321 EMIT_NATIVE_CODE(MathUnary, 1, Location::RequiresRegister()) { | 1379 EMIT_NATIVE_CODE(MathUnary, 1, Location::RequiresRegister()) { |
| 1380 const Register value = locs()->in(0).reg(); | |
| 1381 const Register result = locs()->out(0).reg(); | |
| 1322 if (kind() == MathUnaryInstr::kSqrt) { | 1382 if (kind() == MathUnaryInstr::kSqrt) { |
| 1323 const Register value = locs()->in(0).reg(); | |
| 1324 const Register result = locs()->out(0).reg(); | |
| 1325 __ DSqrt(result, value); | 1383 __ DSqrt(result, value); |
| 1326 } else if (kind() == MathUnaryInstr::kDoubleSquare) { | 1384 } else if (kind() == MathUnaryInstr::kDoubleSquare) { |
| 1327 const Register value = locs()->in(0).reg(); | |
| 1328 const Register result = locs()->out(0).reg(); | |
| 1329 __ DMul(result, value, value); | 1385 __ DMul(result, value, value); |
| 1386 } else if (kind() == MathUnaryInstr::kSin) { | |
| 1387 __ DSin(result, value); | |
| 1388 } else if (kind() == MathUnaryInstr::kCos) { | |
| 1389 __ DCos(result, value); | |
| 1330 } else { | 1390 } else { |
| 1331 Unsupported(compiler); | 1391 Unsupported(compiler); |
| 1332 UNREACHABLE(); | 1392 UNREACHABLE(); |
| 1393 } | |
| 1394 } | |
| 1395 | |
| 1396 | |
| 1397 EMIT_NATIVE_CODE(InvokeMathCFunction, | |
| 1398 InputCount(), Location::RequiresRegister()) { | |
| 1399 const Register left = locs()->in(0).reg(); | |
| 1400 const Register result = locs()->out(0).reg(); | |
| 1401 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | |
| 1402 const Register right = locs()->in(1).reg(); | |
| 1403 __ DPow(result, left, right); | |
| 1404 } else if (recognized_kind() == MethodRecognizer::kDoubleMod) { | |
| 1405 const Register right = locs()->in(1).reg(); | |
| 1406 __ DMod(result, left, right); | |
| 1407 } else { | |
| 1408 Unsupported(compiler); | |
| 1409 UNREACHABLE(); | |
| 1333 } | 1410 } |
| 1334 } | 1411 } |
| 1335 | 1412 |
| 1336 | 1413 |
| 1337 EMIT_NATIVE_CODE(MathMinMax, 2, Location::RequiresRegister()) { | 1414 EMIT_NATIVE_CODE(MathMinMax, 2, Location::RequiresRegister()) { |
| 1338 ASSERT((op_kind() == MethodRecognizer::kMathMin) || | 1415 ASSERT((op_kind() == MethodRecognizer::kMathMin) || |
| 1339 (op_kind() == MethodRecognizer::kMathMax)); | 1416 (op_kind() == MethodRecognizer::kMathMax)); |
| 1340 const Register left = locs()->in(0).reg(); | 1417 const Register left = locs()->in(0).reg(); |
| 1341 const Register right = locs()->in(1).reg(); | 1418 const Register right = locs()->in(1).reg(); |
| 1342 const Register result = locs()->out(0).reg(); | 1419 const Register result = locs()->out(0).reg(); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1525 __ IfULe(length, index); | 1602 __ IfULe(length, index); |
| 1526 compiler->EmitDeopt(deopt_id(), | 1603 compiler->EmitDeopt(deopt_id(), |
| 1527 ICData::kDeoptCheckArrayBound, | 1604 ICData::kDeoptCheckArrayBound, |
| 1528 (generalized_ ? ICData::kGeneralized : 0) | | 1605 (generalized_ ? ICData::kGeneralized : 0) | |
| 1529 (licm_hoisted_ ? ICData::kHoisted : 0)); | 1606 (licm_hoisted_ ? ICData::kHoisted : 0)); |
| 1530 } | 1607 } |
| 1531 | 1608 |
| 1532 } // namespace dart | 1609 } // namespace dart |
| 1533 | 1610 |
| 1534 #endif // defined TARGET_ARCH_DBC | 1611 #endif // defined TARGET_ARCH_DBC |
| OLD | NEW |