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 |