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

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

Issue 18684008: Begins implementation of ARM neon instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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) 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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698