Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 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 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 721 UNREACHABLE(); | 721 UNREACHABLE(); |
| 722 return VS; | 722 return VS; |
| 723 } | 723 } |
| 724 } | 724 } |
| 725 | 725 |
| 726 | 726 |
| 727 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, | 727 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, |
| 728 const LocationSummary& locs, | 728 const LocationSummary& locs, |
| 729 Token::Kind kind, | 729 Token::Kind kind, |
| 730 BranchInstr* branch) { | 730 BranchInstr* branch) { |
| 731 DRegister left = locs.in(0).fpu_reg(); | 731 QRegister left = locs.in(0).fpu_reg(); |
| 732 DRegister right = locs.in(1).fpu_reg(); | 732 QRegister right = locs.in(1).fpu_reg(); |
| 733 | 733 |
| 734 Condition true_condition = TokenKindToDoubleCondition(kind); | 734 Condition true_condition = TokenKindToDoubleCondition(kind); |
| 735 if (branch != NULL) { | 735 if (branch != NULL) { |
| 736 compiler->EmitDoubleCompareBranch( | 736 compiler->EmitDoubleCompareBranch( |
| 737 true_condition, left, right, branch); | 737 true_condition, left, right, branch); |
| 738 } else { | 738 } else { |
| 739 compiler->EmitDoubleCompareBool( | 739 compiler->EmitDoubleCompareBool( |
| 740 true_condition, left, right, locs.out().reg()); | 740 true_condition, left, right, locs.out().reg()); |
| 741 } | 741 } |
| 742 } | 742 } |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1196 if (!IsExternal()) { | 1196 if (!IsExternal()) { |
| 1197 ASSERT(this->array()->definition()->representation() == kTagged); | 1197 ASSERT(this->array()->definition()->representation() == kTagged); |
| 1198 __ AddImmediate(index.reg(), | 1198 __ AddImmediate(index.reg(), |
| 1199 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); | 1199 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); |
| 1200 } | 1200 } |
| 1201 element_address = Address(array, index.reg(), LSL, 0); | 1201 element_address = Address(array, index.reg(), LSL, 0); |
| 1202 | 1202 |
| 1203 if ((representation() == kUnboxedDouble) || | 1203 if ((representation() == kUnboxedDouble) || |
| 1204 (representation() == kUnboxedMint) || | 1204 (representation() == kUnboxedMint) || |
| 1205 (representation() == kUnboxedFloat32x4)) { | 1205 (representation() == kUnboxedFloat32x4)) { |
| 1206 DRegister result = locs()->out().fpu_reg(); | 1206 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 1207 switch (class_id()) { | 1207 switch (class_id()) { |
| 1208 case kTypedDataInt32ArrayCid: | 1208 case kTypedDataInt32ArrayCid: |
| 1209 UNIMPLEMENTED(); | 1209 UNIMPLEMENTED(); |
| 1210 break; | 1210 break; |
| 1211 case kTypedDataUint32ArrayCid: | 1211 case kTypedDataUint32ArrayCid: |
| 1212 UNIMPLEMENTED(); | 1212 UNIMPLEMENTED(); |
| 1213 break; | 1213 break; |
| 1214 case kTypedDataFloat32ArrayCid: | 1214 case kTypedDataFloat32ArrayCid: |
| 1215 // Load single precision float and promote to double. | 1215 // Load single precision float and promote to double. |
| 1216 // vldrs does not support indexed addressing. | 1216 // vldrs does not support indexed addressing. |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1463 if (value()->IsSmiValue()) { | 1463 if (value()->IsSmiValue()) { |
| 1464 ASSERT(RequiredInputRepresentation(2) == kTagged); | 1464 ASSERT(RequiredInputRepresentation(2) == kTagged); |
| 1465 Register value = locs()->in(2).reg(); | 1465 Register value = locs()->in(2).reg(); |
| 1466 __ SmiUntag(value); | 1466 __ SmiUntag(value); |
| 1467 __ str(value, element_address); | 1467 __ str(value, element_address); |
| 1468 } else { | 1468 } else { |
| 1469 UNIMPLEMENTED(); | 1469 UNIMPLEMENTED(); |
| 1470 } | 1470 } |
| 1471 break; | 1471 break; |
| 1472 } | 1472 } |
| 1473 case kTypedDataFloat32ArrayCid: | 1473 case kTypedDataFloat32ArrayCid: { |
| 1474 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); | |
| 1474 // Convert to single precision. | 1475 // Convert to single precision. |
| 1475 __ vcvtsd(STMP, locs()->in(2).fpu_reg()); | 1476 __ vcvtsd(STMP, in2); |
| 1476 // Store. | 1477 // Store. |
| 1477 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1478 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1478 __ StoreSToOffset(STMP, index.reg(), 0); | 1479 __ StoreSToOffset(STMP, index.reg(), 0); |
| 1479 break; | 1480 break; |
| 1480 case kTypedDataFloat64ArrayCid: | 1481 } |
| 1482 case kTypedDataFloat64ArrayCid: { | |
| 1483 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); | |
| 1481 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1484 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1482 __ StoreDToOffset(locs()->in(2).fpu_reg(), index.reg(), 0); | 1485 __ StoreDToOffset(in2, index.reg(), 0); |
| 1483 break; | 1486 break; |
| 1487 } | |
| 1484 case kTypedDataFloat32x4ArrayCid: | 1488 case kTypedDataFloat32x4ArrayCid: |
| 1485 UNIMPLEMENTED(); | 1489 UNIMPLEMENTED(); |
| 1486 break; | 1490 break; |
| 1487 default: | 1491 default: |
| 1488 UNREACHABLE(); | 1492 UNREACHABLE(); |
| 1489 } | 1493 } |
| 1490 } | 1494 } |
| 1491 | 1495 |
| 1492 | 1496 |
| 1493 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1497 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { |
| (...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2458 case Token::kBIT_XOR: { | 2462 case Token::kBIT_XOR: { |
| 2459 // No overflow check. | 2463 // No overflow check. |
| 2460 __ eor(result, left, ShifterOperand(right)); | 2464 __ eor(result, left, ShifterOperand(right)); |
| 2461 break; | 2465 break; |
| 2462 } | 2466 } |
| 2463 case Token::kTRUNCDIV: { | 2467 case Token::kTRUNCDIV: { |
| 2464 // Handle divide by zero in runtime. | 2468 // Handle divide by zero in runtime. |
| 2465 __ cmp(right, ShifterOperand(0)); | 2469 __ cmp(right, ShifterOperand(0)); |
| 2466 __ b(deopt, EQ); | 2470 __ b(deopt, EQ); |
| 2467 Register temp = locs()->temp(0).reg(); | 2471 Register temp = locs()->temp(0).reg(); |
| 2468 DRegister dtemp = locs()->temp(1).fpu_reg(); | 2472 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
| 2469 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. | 2473 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. |
| 2470 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. | 2474 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 2471 | 2475 |
| 2472 __ IntegerDivide(result, temp, IP, dtemp, DTMP); | 2476 __ IntegerDivide(result, temp, IP, dtemp, DTMP); |
| 2473 | 2477 |
| 2474 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 2478 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 2475 // case we cannot tag the result. | 2479 // case we cannot tag the result. |
| 2476 __ CompareImmediate(result, 0x40000000); | 2480 __ CompareImmediate(result, 0x40000000); |
| 2477 __ b(deopt, EQ); | 2481 __ b(deopt, EQ); |
| 2478 __ SmiTag(result); | 2482 __ SmiTag(result); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2597 | 2601 |
| 2598 private: | 2602 private: |
| 2599 BoxDoubleInstr* instruction_; | 2603 BoxDoubleInstr* instruction_; |
| 2600 }; | 2604 }; |
| 2601 | 2605 |
| 2602 | 2606 |
| 2603 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2607 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2604 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 2608 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 2605 compiler->AddSlowPathCode(slow_path); | 2609 compiler->AddSlowPathCode(slow_path); |
| 2606 | 2610 |
| 2607 Register out_reg = locs()->out().reg(); | 2611 const Register out_reg = locs()->out().reg(); |
| 2608 DRegister value = locs()->in(0).fpu_reg(); | 2612 const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 2609 | 2613 |
| 2610 __ TryAllocate(compiler->double_class(), | 2614 __ TryAllocate(compiler->double_class(), |
| 2611 slow_path->entry_label(), | 2615 slow_path->entry_label(), |
| 2612 out_reg); | 2616 out_reg); |
| 2613 __ Bind(slow_path->exit_label()); | 2617 __ Bind(slow_path->exit_label()); |
| 2614 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); | 2618 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); |
| 2615 } | 2619 } |
| 2616 | 2620 |
| 2617 | 2621 |
| 2618 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { | 2622 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { |
| 2619 const intptr_t kNumInputs = 1; | 2623 const intptr_t kNumInputs = 1; |
| 2620 const intptr_t value_cid = value()->Type()->ToCid(); | 2624 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2621 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); | 2625 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); |
| 2622 const bool needs_writable_input = (value_cid == kSmiCid); | 2626 const bool needs_writable_input = (value_cid == kSmiCid); |
| 2623 const intptr_t kNumTemps = needs_temp ? 1 : 0; | 2627 const intptr_t kNumTemps = needs_temp ? 1 : 0; |
| 2624 LocationSummary* summary = | 2628 LocationSummary* summary = |
| 2625 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2629 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2626 summary->set_in(0, needs_writable_input | 2630 summary->set_in(0, needs_writable_input |
| 2627 ? Location::WritableRegister() | 2631 ? Location::WritableRegister() |
| 2628 : Location::RequiresRegister()); | 2632 : Location::RequiresRegister()); |
| 2629 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); | 2633 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); |
| 2630 summary->set_out(Location::RequiresFpuRegister()); | 2634 summary->set_out(Location::RequiresFpuRegister()); |
| 2631 return summary; | 2635 return summary; |
| 2632 } | 2636 } |
| 2633 | 2637 |
| 2634 | 2638 |
| 2635 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2639 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2636 const intptr_t value_cid = value()->Type()->ToCid(); | 2640 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2637 const Register value = locs()->in(0).reg(); | 2641 const Register value = locs()->in(0).reg(); |
| 2638 const DRegister result = locs()->out().fpu_reg(); | 2642 const DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 2639 | 2643 |
| 2640 if (value_cid == kDoubleCid) { | 2644 if (value_cid == kDoubleCid) { |
| 2641 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); | 2645 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); |
| 2642 } else if (value_cid == kSmiCid) { | 2646 } else if (value_cid == kSmiCid) { |
| 2643 __ SmiUntag(value); // Untag input before conversion. | 2647 __ SmiUntag(value); // Untag input before conversion. |
| 2644 __ vmovsr(STMP, value); | 2648 __ vmovsr(STMP, value); |
| 2645 __ vcvtdi(result, STMP); | 2649 __ vcvtdi(result, STMP); |
| 2646 } else { | 2650 } else { |
| 2647 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); | 2651 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); |
| 2648 Register temp = locs()->temp(0).reg(); | 2652 Register temp = locs()->temp(0).reg(); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2713 LocationSummary* summary = | 2717 LocationSummary* summary = |
| 2714 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2718 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2715 summary->set_in(0, Location::RequiresFpuRegister()); | 2719 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2716 summary->set_in(1, Location::RequiresFpuRegister()); | 2720 summary->set_in(1, Location::RequiresFpuRegister()); |
| 2717 summary->set_out(Location::RequiresFpuRegister()); | 2721 summary->set_out(Location::RequiresFpuRegister()); |
| 2718 return summary; | 2722 return summary; |
| 2719 } | 2723 } |
| 2720 | 2724 |
| 2721 | 2725 |
| 2722 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2726 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2723 DRegister left = locs()->in(0).fpu_reg(); | 2727 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 2724 DRegister right = locs()->in(1).fpu_reg(); | 2728 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 2725 DRegister result = locs()->out().fpu_reg(); | 2729 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 2726 switch (op_kind()) { | 2730 switch (op_kind()) { |
| 2727 case Token::kADD: __ vaddd(result, left, right); break; | 2731 case Token::kADD: __ vaddd(result, left, right); break; |
| 2728 case Token::kSUB: __ vsubd(result, left, right); break; | 2732 case Token::kSUB: __ vsubd(result, left, right); break; |
| 2729 case Token::kMUL: __ vmuld(result, left, right); break; | 2733 case Token::kMUL: __ vmuld(result, left, right); break; |
| 2730 case Token::kDIV: __ vdivd(result, left, right); break; | 2734 case Token::kDIV: __ vdivd(result, left, right); break; |
| 2731 default: UNREACHABLE(); | 2735 default: UNREACHABLE(); |
| 2732 } | 2736 } |
| 2733 } | 2737 } |
| 2734 | 2738 |
| 2735 | 2739 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2946 const intptr_t kNumTemps = 0; | 2950 const intptr_t kNumTemps = 0; |
| 2947 LocationSummary* summary = | 2951 LocationSummary* summary = |
| 2948 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2952 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2949 summary->set_in(0, Location::RequiresFpuRegister()); | 2953 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2950 summary->set_out(Location::RequiresFpuRegister()); | 2954 summary->set_out(Location::RequiresFpuRegister()); |
| 2951 return summary; | 2955 return summary; |
| 2952 } | 2956 } |
| 2953 | 2957 |
| 2954 | 2958 |
| 2955 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2959 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2956 __ vsqrtd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); | 2960 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 2961 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | |
| 2962 __ vsqrtd(result, val); | |
| 2957 } | 2963 } |
| 2958 | 2964 |
| 2959 | 2965 |
| 2960 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 2966 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
| 2961 const intptr_t kNumInputs = 1; | 2967 const intptr_t kNumInputs = 1; |
| 2962 const intptr_t kNumTemps = 0; | 2968 const intptr_t kNumTemps = 0; |
| 2963 LocationSummary* summary = | 2969 LocationSummary* summary = |
| 2964 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2970 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2965 summary->set_in(0, Location::RequiresRegister()); | 2971 summary->set_in(0, Location::RequiresRegister()); |
| 2966 // We make use of 3-operand instructions by not requiring result register | 2972 // We make use of 3-operand instructions by not requiring result register |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2998 LocationSummary* result = | 3004 LocationSummary* result = |
| 2999 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3005 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3000 result->set_in(0, Location::WritableRegister()); | 3006 result->set_in(0, Location::WritableRegister()); |
| 3001 result->set_out(Location::RequiresFpuRegister()); | 3007 result->set_out(Location::RequiresFpuRegister()); |
| 3002 return result; | 3008 return result; |
| 3003 } | 3009 } |
| 3004 | 3010 |
| 3005 | 3011 |
| 3006 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3012 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3007 Register value = locs()->in(0).reg(); | 3013 Register value = locs()->in(0).reg(); |
| 3008 FpuRegister result = locs()->out().fpu_reg(); | 3014 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 3009 __ SmiUntag(value); | 3015 __ SmiUntag(value); |
| 3010 __ vmovsr(STMP, value); | 3016 __ vmovsr(STMP, value); |
| 3011 __ vcvtdi(result, STMP); | 3017 __ vcvtdi(result, STMP); |
| 3012 } | 3018 } |
| 3013 | 3019 |
| 3014 | 3020 |
| 3015 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { | 3021 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { |
| 3016 const intptr_t kNumInputs = 1; | 3022 const intptr_t kNumInputs = 1; |
| 3017 const intptr_t kNumTemps = 0; | 3023 const intptr_t kNumTemps = 0; |
| 3018 LocationSummary* result = | 3024 LocationSummary* result = |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3071 kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3077 kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3072 result->set_in(0, Location::RequiresFpuRegister()); | 3078 result->set_in(0, Location::RequiresFpuRegister()); |
| 3073 result->set_out(Location::RequiresRegister()); | 3079 result->set_out(Location::RequiresRegister()); |
| 3074 return result; | 3080 return result; |
| 3075 } | 3081 } |
| 3076 | 3082 |
| 3077 | 3083 |
| 3078 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3084 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3079 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); | 3085 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); |
| 3080 Register result = locs()->out().reg(); | 3086 Register result = locs()->out().reg(); |
| 3081 DRegister value = locs()->in(0).fpu_reg(); | 3087 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 3082 // First check for NaN. Checking for minint after the conversion doesn't work | 3088 // First check for NaN. Checking for minint after the conversion doesn't work |
| 3083 // on ARM because vcvtid gives 0 for NaN. | 3089 // on ARM because vcvtid gives 0 for NaN. |
| 3084 __ vcmpd(value, value); | 3090 __ vcmpd(value, value); |
| 3085 __ vmstat(); | 3091 __ vmstat(); |
| 3086 __ b(deopt, VS); | 3092 __ b(deopt, VS); |
| 3087 | 3093 |
| 3088 __ vcvtid(STMP, value); | 3094 __ vcvtid(STMP, value); |
| 3089 __ vmovrs(result, STMP); | 3095 __ vmovrs(result, STMP); |
| 3090 // Check for overflow and that it fits into Smi. | 3096 // Check for overflow and that it fits into Smi. |
| 3091 __ CompareImmediate(result, 0xC0000000); | 3097 __ CompareImmediate(result, 0xC0000000); |
| 3092 __ b(deopt, MI); | 3098 __ b(deopt, MI); |
| 3093 __ SmiTag(result); | 3099 __ SmiTag(result); |
| 3094 } | 3100 } |
| 3095 | 3101 |
| 3096 | 3102 |
| 3097 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { | 3103 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { |
| 3098 const intptr_t kNumInputs = 1; | 3104 const intptr_t kNumInputs = 1; |
| 3099 const intptr_t kNumTemps = 0; | 3105 const intptr_t kNumTemps = 0; |
| 3100 LocationSummary* result = | 3106 LocationSummary* result = |
| 3101 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3107 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3102 result->set_in(0, Location::RequiresFpuRegister()); | 3108 result->set_in(0, Location::RequiresFpuRegister()); |
| 3103 result->set_out(Location::RequiresFpuRegister()); | 3109 result->set_out(Location::RequiresFpuRegister()); |
| 3104 return result; | 3110 return result; |
| 3105 } | 3111 } |
| 3106 | 3112 |
| 3107 | 3113 |
| 3108 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3114 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3109 // DRegister value = locs()->in(0).fpu_reg(); | 3115 // QRegister value = locs()->in(0).fpu_reg(); |
| 3110 // DRegister result = locs()->out().fpu_reg(); | 3116 // QRegister result = locs()->out().fpu_reg(); |
|
regis
2013/07/16 00:18:42
Why are those lines commented out?
| |
| 3111 switch (recognized_kind()) { | 3117 switch (recognized_kind()) { |
| 3112 case MethodRecognizer::kDoubleTruncate: | 3118 case MethodRecognizer::kDoubleTruncate: |
| 3113 UNIMPLEMENTED(); | 3119 UNIMPLEMENTED(); |
| 3114 // __ roundsd(result, value, Assembler::kRoundToZero); | 3120 // __ roundsd(result, value, Assembler::kRoundToZero); |
| 3115 break; | 3121 break; |
| 3116 case MethodRecognizer::kDoubleFloor: | 3122 case MethodRecognizer::kDoubleFloor: |
| 3117 UNIMPLEMENTED(); | 3123 UNIMPLEMENTED(); |
| 3118 // __ roundsd(result, value, Assembler::kRoundDown); | 3124 // __ roundsd(result, value, Assembler::kRoundDown); |
| 3119 break; | 3125 break; |
| 3120 case MethodRecognizer::kDoubleCeil: | 3126 case MethodRecognizer::kDoubleCeil: |
| 3121 UNIMPLEMENTED(); | 3127 UNIMPLEMENTED(); |
| 3122 // __ roundsd(result, value, Assembler::kRoundUp); | 3128 // __ roundsd(result, value, Assembler::kRoundUp); |
| 3123 break; | 3129 break; |
| 3124 default: | 3130 default: |
| 3125 UNREACHABLE(); | 3131 UNREACHABLE(); |
| 3126 } | 3132 } |
| 3127 } | 3133 } |
| 3128 | 3134 |
| 3129 | 3135 |
| 3130 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { | 3136 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { |
| 3131 ASSERT((InputCount() == 1) || (InputCount() == 2)); | 3137 ASSERT((InputCount() == 1) || (InputCount() == 2)); |
| 3132 const intptr_t kNumTemps = 0; | 3138 const intptr_t kNumTemps = 0; |
| 3133 LocationSummary* result = | 3139 LocationSummary* result = |
| 3134 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 3140 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
| 3135 result->set_in(0, Location::FpuRegisterLocation(D0)); | 3141 result->set_in(0, Location::FpuRegisterLocation(Q0)); |
| 3136 if (InputCount() == 2) { | 3142 if (InputCount() == 2) { |
| 3137 result->set_in(1, Location::FpuRegisterLocation(D1)); | 3143 result->set_in(1, Location::FpuRegisterLocation(Q1)); |
| 3138 } | 3144 } |
| 3139 result->set_out(Location::FpuRegisterLocation(D0)); | 3145 result->set_out(Location::FpuRegisterLocation(Q0)); |
| 3140 return result; | 3146 return result; |
| 3141 } | 3147 } |
| 3142 | 3148 |
| 3143 | 3149 |
| 3144 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3150 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3145 // For pow-function return NAN if exponent is NAN. | 3151 // For pow-function return NAN if exponent is NAN. |
| 3146 Label do_call, skip_call; | 3152 Label do_call, skip_call; |
| 3147 if (recognized_kind() == MethodRecognizer::kDoublePow) { | 3153 if (recognized_kind() == MethodRecognizer::kDoublePow) { |
| 3148 DRegister exp = locs()->in(1).fpu_reg(); | 3154 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 3155 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | |
| 3149 __ vcmpd(exp, exp); | 3156 __ vcmpd(exp, exp); |
| 3150 __ vmstat(); | 3157 __ vmstat(); |
| 3151 __ b(&do_call, VC); // NaN -> false; | 3158 __ b(&do_call, VC); // NaN -> false; |
| 3152 // Exponent is NaN, return NaN. | 3159 // Exponent is NaN, return NaN. |
| 3153 __ vmovd(locs()->out().fpu_reg(), exp); | 3160 __ vmovd(result, exp); |
| 3154 __ b(&skip_call); | 3161 __ b(&skip_call); |
| 3155 } | 3162 } |
| 3156 __ Bind(&do_call); | 3163 __ Bind(&do_call); |
| 3157 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp' | 3164 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp' |
| 3158 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values | 3165 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values |
| 3159 // are passed and returned in vfp registers rather than in integer | 3166 // are passed and returned in vfp registers rather than in integer |
| 3160 // register pairs. | 3167 // register pairs. |
| 3168 if (InputCount() == 2) { | |
| 3169 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. | |
| 3170 __ vmovd(D1, D2); | |
| 3171 } | |
| 3161 __ CallRuntime(TargetFunction()); | 3172 __ CallRuntime(TargetFunction()); |
| 3162 __ Bind(&skip_call); | 3173 __ Bind(&skip_call); |
| 3163 } | 3174 } |
| 3164 | 3175 |
| 3165 | 3176 |
| 3166 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 3177 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
| 3167 return MakeCallSummary(); | 3178 return MakeCallSummary(); |
| 3168 } | 3179 } |
| 3169 | 3180 |
| 3170 | 3181 |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3662 compiler->GenerateCall(token_pos(), | 3673 compiler->GenerateCall(token_pos(), |
| 3663 &label, | 3674 &label, |
| 3664 PcDescriptors::kOther, | 3675 PcDescriptors::kOther, |
| 3665 locs()); | 3676 locs()); |
| 3666 __ Drop(2); // Discard type arguments and receiver. | 3677 __ Drop(2); // Discard type arguments and receiver. |
| 3667 } | 3678 } |
| 3668 | 3679 |
| 3669 } // namespace dart | 3680 } // namespace dart |
| 3670 | 3681 |
| 3671 #endif // defined TARGET_ARCH_ARM | 3682 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |