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

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 QRegister qresult = locs()->out().fpu_reg();
1207 DRegister result = static_cast<DRegister>(qresult * 2);
1207 switch (class_id()) { 1208 switch (class_id()) {
1208 case kTypedDataInt32ArrayCid: 1209 case kTypedDataInt32ArrayCid:
1209 UNIMPLEMENTED(); 1210 UNIMPLEMENTED();
1210 break; 1211 break;
1211 case kTypedDataUint32ArrayCid: 1212 case kTypedDataUint32ArrayCid:
1212 UNIMPLEMENTED(); 1213 UNIMPLEMENTED();
1213 break; 1214 break;
1214 case kTypedDataFloat32ArrayCid: 1215 case kTypedDataFloat32ArrayCid:
1215 // Load single precision float and promote to double. 1216 // Load single precision float and promote to double.
1216 // vldrs does not support indexed addressing. 1217 // vldrs does not support indexed addressing.
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 if (value()->IsSmiValue()) { 1464 if (value()->IsSmiValue()) {
1464 ASSERT(RequiredInputRepresentation(2) == kTagged); 1465 ASSERT(RequiredInputRepresentation(2) == kTagged);
1465 Register value = locs()->in(2).reg(); 1466 Register value = locs()->in(2).reg();
1466 __ SmiUntag(value); 1467 __ SmiUntag(value);
1467 __ str(value, element_address); 1468 __ str(value, element_address);
1468 } else { 1469 } else {
1469 UNIMPLEMENTED(); 1470 UNIMPLEMENTED();
1470 } 1471 }
1471 break; 1472 break;
1472 } 1473 }
1473 case kTypedDataFloat32ArrayCid: 1474 case kTypedDataFloat32ArrayCid: {
1475 DRegister in2 = static_cast<DRegister>(locs()->in(2).fpu_reg() * 2);
1474 // Convert to single precision. 1476 // Convert to single precision.
1475 __ vcvtsd(STMP, locs()->in(2).fpu_reg()); 1477 __ vcvtsd(STMP, in2);
1476 // Store. 1478 // Store.
1477 __ add(index.reg(), index.reg(), ShifterOperand(array)); 1479 __ add(index.reg(), index.reg(), ShifterOperand(array));
1478 __ StoreSToOffset(STMP, index.reg(), 0); 1480 __ StoreSToOffset(STMP, index.reg(), 0);
1479 break; 1481 break;
1480 case kTypedDataFloat64ArrayCid: 1482 }
1483 case kTypedDataFloat64ArrayCid: {
1484 DRegister in2 = static_cast<DRegister>(locs()->in(2).fpu_reg() * 2);
1481 __ add(index.reg(), index.reg(), ShifterOperand(array)); 1485 __ add(index.reg(), index.reg(), ShifterOperand(array));
1482 __ StoreDToOffset(locs()->in(2).fpu_reg(), index.reg(), 0); 1486 __ StoreDToOffset(in2, index.reg(), 0);
1483 break; 1487 break;
1488 }
1484 case kTypedDataFloat32x4ArrayCid: 1489 case kTypedDataFloat32x4ArrayCid:
1485 UNIMPLEMENTED(); 1490 UNIMPLEMENTED();
1486 break; 1491 break;
1487 default: 1492 default:
1488 UNREACHABLE(); 1493 UNREACHABLE();
1489 } 1494 }
1490 } 1495 }
1491 1496
1492 1497
1493 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { 1498 LocationSummary* GuardFieldInstr::MakeLocationSummary() const {
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after
2458 case Token::kBIT_XOR: { 2463 case Token::kBIT_XOR: {
2459 // No overflow check. 2464 // No overflow check.
2460 __ eor(result, left, ShifterOperand(right)); 2465 __ eor(result, left, ShifterOperand(right));
2461 break; 2466 break;
2462 } 2467 }
2463 case Token::kTRUNCDIV: { 2468 case Token::kTRUNCDIV: {
2464 // Handle divide by zero in runtime. 2469 // Handle divide by zero in runtime.
2465 __ cmp(right, ShifterOperand(0)); 2470 __ cmp(right, ShifterOperand(0));
2466 __ b(deopt, EQ); 2471 __ b(deopt, EQ);
2467 Register temp = locs()->temp(0).reg(); 2472 Register temp = locs()->temp(0).reg();
2468 DRegister dtemp = locs()->temp(1).fpu_reg(); 2473 QRegister qtemp = locs()->temp(1).fpu_reg();
2474 DRegister dtemp = static_cast<DRegister>(qtemp * 2);
2469 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 2475 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp.
2470 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. 2476 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
2471 2477
2472 __ IntegerDivide(result, temp, IP, dtemp, DTMP); 2478 __ IntegerDivide(result, temp, IP, dtemp, DTMP);
2473 2479
2474 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 2480 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
2475 // case we cannot tag the result. 2481 // case we cannot tag the result.
2476 __ CompareImmediate(result, 0x40000000); 2482 __ CompareImmediate(result, 0x40000000);
2477 __ b(deopt, EQ); 2483 __ b(deopt, EQ);
2478 __ SmiTag(result); 2484 __ SmiTag(result);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2597 2603
2598 private: 2604 private:
2599 BoxDoubleInstr* instruction_; 2605 BoxDoubleInstr* instruction_;
2600 }; 2606 };
2601 2607
2602 2608
2603 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2609 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2604 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2610 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
2605 compiler->AddSlowPathCode(slow_path); 2611 compiler->AddSlowPathCode(slow_path);
2606 2612
2607 Register out_reg = locs()->out().reg(); 2613 const Register out_reg = locs()->out().reg();
2608 DRegister value = locs()->in(0).fpu_reg(); 2614 const QRegister qvalue = locs()->in(0).fpu_reg();
2615 const DRegister value = static_cast<DRegister>(qvalue * 2);
2609 2616
2610 __ TryAllocate(compiler->double_class(), 2617 __ TryAllocate(compiler->double_class(),
2611 slow_path->entry_label(), 2618 slow_path->entry_label(),
2612 out_reg); 2619 out_reg);
2613 __ Bind(slow_path->exit_label()); 2620 __ Bind(slow_path->exit_label());
2614 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); 2621 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag);
2615 } 2622 }
2616 2623
2617 2624
2618 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { 2625 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const {
2619 const intptr_t kNumInputs = 1; 2626 const intptr_t kNumInputs = 1;
2620 const intptr_t value_cid = value()->Type()->ToCid(); 2627 const intptr_t value_cid = value()->Type()->ToCid();
2621 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); 2628 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid));
2622 const bool needs_writable_input = (value_cid == kSmiCid); 2629 const bool needs_writable_input = (value_cid == kSmiCid);
2623 const intptr_t kNumTemps = needs_temp ? 1 : 0; 2630 const intptr_t kNumTemps = needs_temp ? 1 : 0;
2624 LocationSummary* summary = 2631 LocationSummary* summary =
2625 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2632 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2626 summary->set_in(0, needs_writable_input 2633 summary->set_in(0, needs_writable_input
2627 ? Location::WritableRegister() 2634 ? Location::WritableRegister()
2628 : Location::RequiresRegister()); 2635 : Location::RequiresRegister());
2629 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); 2636 if (needs_temp) summary->set_temp(0, Location::RequiresRegister());
2630 summary->set_out(Location::RequiresFpuRegister()); 2637 summary->set_out(Location::RequiresFpuRegister());
2631 return summary; 2638 return summary;
2632 } 2639 }
2633 2640
2634 2641
2635 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2642 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2636 const intptr_t value_cid = value()->Type()->ToCid(); 2643 const intptr_t value_cid = value()->Type()->ToCid();
2637 const Register value = locs()->in(0).reg(); 2644 const Register value = locs()->in(0).reg();
2638 const DRegister result = locs()->out().fpu_reg(); 2645 const DRegister result = static_cast<DRegister>(locs()->out().fpu_reg() * 2);
2639 2646
2640 if (value_cid == kDoubleCid) { 2647 if (value_cid == kDoubleCid) {
2641 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); 2648 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag);
2642 } else if (value_cid == kSmiCid) { 2649 } else if (value_cid == kSmiCid) {
2643 __ SmiUntag(value); // Untag input before conversion. 2650 __ SmiUntag(value); // Untag input before conversion.
2644 __ vmovsr(STMP, value); 2651 __ vmovsr(STMP, value);
2645 __ vcvtdi(result, STMP); 2652 __ vcvtdi(result, STMP);
2646 } else { 2653 } else {
2647 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); 2654 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
2648 Register temp = locs()->temp(0).reg(); 2655 Register temp = locs()->temp(0).reg();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2713 LocationSummary* summary = 2720 LocationSummary* summary =
2714 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2721 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2715 summary->set_in(0, Location::RequiresFpuRegister()); 2722 summary->set_in(0, Location::RequiresFpuRegister());
2716 summary->set_in(1, Location::RequiresFpuRegister()); 2723 summary->set_in(1, Location::RequiresFpuRegister());
2717 summary->set_out(Location::RequiresFpuRegister()); 2724 summary->set_out(Location::RequiresFpuRegister());
2718 return summary; 2725 return summary;
2719 } 2726 }
2720 2727
2721 2728
2722 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2729 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2723 DRegister left = locs()->in(0).fpu_reg(); 2730 DRegister left = static_cast<DRegister>(locs()->in(0).fpu_reg() * 2);
2724 DRegister right = locs()->in(1).fpu_reg(); 2731 DRegister right = static_cast<DRegister>(locs()->in(1).fpu_reg() * 2);
2725 DRegister result = locs()->out().fpu_reg(); 2732 DRegister result = static_cast<DRegister>(locs()->out().fpu_reg() * 2);
2726 switch (op_kind()) { 2733 switch (op_kind()) {
2727 case Token::kADD: __ vaddd(result, left, right); break; 2734 case Token::kADD: __ vaddd(result, left, right); break;
2728 case Token::kSUB: __ vsubd(result, left, right); break; 2735 case Token::kSUB: __ vsubd(result, left, right); break;
2729 case Token::kMUL: __ vmuld(result, left, right); break; 2736 case Token::kMUL: __ vmuld(result, left, right); break;
2730 case Token::kDIV: __ vdivd(result, left, right); break; 2737 case Token::kDIV: __ vdivd(result, left, right); break;
2731 default: UNREACHABLE(); 2738 default: UNREACHABLE();
2732 } 2739 }
2733 } 2740 }
2734 2741
2735 2742
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
2946 const intptr_t kNumTemps = 0; 2953 const intptr_t kNumTemps = 0;
2947 LocationSummary* summary = 2954 LocationSummary* summary =
2948 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2955 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2949 summary->set_in(0, Location::RequiresFpuRegister()); 2956 summary->set_in(0, Location::RequiresFpuRegister());
2950 summary->set_out(Location::RequiresFpuRegister()); 2957 summary->set_out(Location::RequiresFpuRegister());
2951 return summary; 2958 return summary;
2952 } 2959 }
2953 2960
2954 2961
2955 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2962 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2956 __ vsqrtd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); 2963 DRegister val = static_cast<DRegister>(locs()->in(0).fpu_reg() * 2);
2964 DRegister result = static_cast<DRegister>(locs()->out().fpu_reg() * 2);
2965 __ vsqrtd(result, val);
2957 } 2966 }
2958 2967
2959 2968
2960 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 2969 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const {
2961 const intptr_t kNumInputs = 1; 2970 const intptr_t kNumInputs = 1;
2962 const intptr_t kNumTemps = 0; 2971 const intptr_t kNumTemps = 0;
2963 LocationSummary* summary = 2972 LocationSummary* summary =
2964 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2973 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2965 summary->set_in(0, Location::RequiresRegister()); 2974 summary->set_in(0, Location::RequiresRegister());
2966 // We make use of 3-operand instructions by not requiring result register 2975 // 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 = 3007 LocationSummary* result =
2999 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3008 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3000 result->set_in(0, Location::WritableRegister()); 3009 result->set_in(0, Location::WritableRegister());
3001 result->set_out(Location::RequiresFpuRegister()); 3010 result->set_out(Location::RequiresFpuRegister());
3002 return result; 3011 return result;
3003 } 3012 }
3004 3013
3005 3014
3006 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3015 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3007 Register value = locs()->in(0).reg(); 3016 Register value = locs()->in(0).reg();
3008 FpuRegister result = locs()->out().fpu_reg(); 3017 DRegister result = static_cast<DRegister>(locs()->out().fpu_reg() * 2);
3009 __ SmiUntag(value); 3018 __ SmiUntag(value);
3010 __ vmovsr(STMP, value); 3019 __ vmovsr(STMP, value);
3011 __ vcvtdi(result, STMP); 3020 __ vcvtdi(result, STMP);
3012 } 3021 }
3013 3022
3014 3023
3015 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { 3024 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const {
3016 const intptr_t kNumInputs = 1; 3025 const intptr_t kNumInputs = 1;
3017 const intptr_t kNumTemps = 0; 3026 const intptr_t kNumTemps = 0;
3018 LocationSummary* result = 3027 LocationSummary* result =
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3063 kNumInputs, kNumTemps, LocationSummary::kNoCall); 3072 kNumInputs, kNumTemps, LocationSummary::kNoCall);
3064 result->set_in(0, Location::RequiresFpuRegister()); 3073 result->set_in(0, Location::RequiresFpuRegister());
3065 result->set_out(Location::RequiresRegister()); 3074 result->set_out(Location::RequiresRegister());
3066 return result; 3075 return result;
3067 } 3076 }
3068 3077
3069 3078
3070 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3079 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3071 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); 3080 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
3072 Register result = locs()->out().reg(); 3081 Register result = locs()->out().reg();
3073 DRegister value = locs()->in(0).fpu_reg(); 3082 QRegister qvalue = locs()->in(0).fpu_reg();
3083 DRegister value = static_cast<DRegister>(qvalue * 2);
3074 __ vcvtid(STMP, value); 3084 __ vcvtid(STMP, value);
3075 __ vmovrs(result, STMP); 3085 __ vmovrs(result, STMP);
3076 // Check for overflow and that it fits into Smi. 3086 // Check for overflow and that it fits into Smi.
3077 __ CompareImmediate(result, 0xC0000000); 3087 __ CompareImmediate(result, 0xC0000000);
3078 __ b(deopt, MI); 3088 __ b(deopt, MI);
3079 __ SmiTag(result); 3089 __ SmiTag(result);
3080 } 3090 }
3081 3091
3082 3092
3083 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { 3093 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const {
3084 const intptr_t kNumInputs = 1; 3094 const intptr_t kNumInputs = 1;
3085 const intptr_t kNumTemps = 0; 3095 const intptr_t kNumTemps = 0;
3086 LocationSummary* result = 3096 LocationSummary* result =
3087 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3097 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3088 result->set_in(0, Location::RequiresFpuRegister()); 3098 result->set_in(0, Location::RequiresFpuRegister());
3089 result->set_out(Location::RequiresFpuRegister()); 3099 result->set_out(Location::RequiresFpuRegister());
3090 return result; 3100 return result;
3091 } 3101 }
3092 3102
3093 3103
3094 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3104 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3095 // DRegister value = locs()->in(0).fpu_reg(); 3105 // QRegister value = locs()->in(0).fpu_reg();
3096 // DRegister result = locs()->out().fpu_reg(); 3106 // QRegister result = locs()->out().fpu_reg();
3097 switch (recognized_kind()) { 3107 switch (recognized_kind()) {
3098 case MethodRecognizer::kDoubleTruncate: 3108 case MethodRecognizer::kDoubleTruncate:
3099 UNIMPLEMENTED(); 3109 UNIMPLEMENTED();
3100 // __ roundsd(result, value, Assembler::kRoundToZero); 3110 // __ roundsd(result, value, Assembler::kRoundToZero);
3101 break; 3111 break;
3102 case MethodRecognizer::kDoubleFloor: 3112 case MethodRecognizer::kDoubleFloor:
3103 UNIMPLEMENTED(); 3113 UNIMPLEMENTED();
3104 // __ roundsd(result, value, Assembler::kRoundDown); 3114 // __ roundsd(result, value, Assembler::kRoundDown);
3105 break; 3115 break;
3106 case MethodRecognizer::kDoubleCeil: 3116 case MethodRecognizer::kDoubleCeil:
3107 UNIMPLEMENTED(); 3117 UNIMPLEMENTED();
3108 // __ roundsd(result, value, Assembler::kRoundUp); 3118 // __ roundsd(result, value, Assembler::kRoundUp);
3109 break; 3119 break;
3110 default: 3120 default:
3111 UNREACHABLE(); 3121 UNREACHABLE();
3112 } 3122 }
3113 } 3123 }
3114 3124
3115 3125
3116 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { 3126 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const {
3117 ASSERT((InputCount() == 1) || (InputCount() == 2)); 3127 ASSERT((InputCount() == 1) || (InputCount() == 2));
3118 const intptr_t kNumTemps = 0; 3128 const intptr_t kNumTemps = 0;
3119 LocationSummary* result = 3129 LocationSummary* result =
3120 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 3130 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
3121 result->set_in(0, Location::FpuRegisterLocation(D0)); 3131 result->set_in(0, Location::FpuRegisterLocation(Q0));
3122 if (InputCount() == 2) { 3132 if (InputCount() == 2) {
3123 result->set_in(1, Location::FpuRegisterLocation(D1)); 3133 result->set_in(1, Location::FpuRegisterLocation(Q1));
3124 } 3134 }
3125 result->set_out(Location::FpuRegisterLocation(D0)); 3135 result->set_out(Location::FpuRegisterLocation(Q0));
3126 return result; 3136 return result;
3127 } 3137 }
3128 3138
3129 3139
3130 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3140 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3131 // For pow-function return NAN if exponent is NAN. 3141 // For pow-function return NAN if exponent is NAN.
3132 Label do_call, skip_call; 3142 Label do_call, skip_call;
3133 if (recognized_kind() == MethodRecognizer::kDoublePow) { 3143 if (recognized_kind() == MethodRecognizer::kDoublePow) {
3134 DRegister exp = locs()->in(1).fpu_reg(); 3144 DRegister exp = static_cast<DRegister>(locs()->in(1).fpu_reg() * 2);
3145 DRegister result = static_cast<DRegister>(locs()->out().fpu_reg() * 2);
3135 __ vcmpd(exp, exp); 3146 __ vcmpd(exp, exp);
3136 __ vmstat(); 3147 __ vmstat();
3137 __ b(&do_call, VC); // NaN -> false; 3148 __ b(&do_call, VC); // NaN -> false;
3138 // Exponent is NaN, return NaN. 3149 // Exponent is NaN, return NaN.
3139 __ vmovd(locs()->out().fpu_reg(), exp); 3150 __ vmovd(result, exp);
3140 __ b(&skip_call); 3151 __ b(&skip_call);
3141 } 3152 }
3142 __ Bind(&do_call); 3153 __ Bind(&do_call);
3143 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp' 3154 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp'
3144 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values 3155 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values
3145 // are passed and returned in vfp registers rather than in integer 3156 // are passed and returned in vfp registers rather than in integer
3146 // register pairs. 3157 // register pairs.
3158 if (InputCount() == 2) {
3159 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1.
3160 __ vmovd(D1, D2);
3161 }
3147 __ CallRuntime(TargetFunction()); 3162 __ CallRuntime(TargetFunction());
3148 __ Bind(&skip_call); 3163 __ Bind(&skip_call);
3149 } 3164 }
3150 3165
3151 3166
3152 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { 3167 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const {
3153 return MakeCallSummary(); 3168 return MakeCallSummary();
3154 } 3169 }
3155 3170
3156 3171
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
3648 compiler->GenerateCall(token_pos(), 3663 compiler->GenerateCall(token_pos(),
3649 &label, 3664 &label,
3650 PcDescriptors::kOther, 3665 PcDescriptors::kOther,
3651 locs()); 3666 locs());
3652 __ Drop(2); // Discard type arguments and receiver. 3667 __ Drop(2); // Discard type arguments and receiver.
3653 } 3668 }
3654 3669
3655 } // namespace dart 3670 } // namespace dart
3656 3671
3657 #endif // defined TARGET_ARCH_ARM 3672 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698