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 |