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

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

Issue 16244007: Enable language tests on SIMARM and mark 14 of them as failing. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 257 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
258 Register obj = locs()->in(0).reg(); 258 Register obj = locs()->in(0).reg();
259 Register result = locs()->out().reg(); 259 Register result = locs()->out().reg();
260 260
261 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); 261 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
262 ASSERT(obj == result); 262 ASSERT(obj == result);
263 } 263 }
264 264
265 265
266 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const { 266 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const {
267 UNIMPLEMENTED(); 267 const intptr_t kNumInputs = 1;
268 return NULL; 268 const intptr_t kNumTemps = 0;
269 LocationSummary* locs =
270 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
271 locs->set_in(0, Location::RegisterLocation(R0));
272 locs->set_out(Location::RegisterLocation(R0));
273 return locs;
269 } 274 }
270 275
271 276
272 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 277 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
273 UNIMPLEMENTED(); 278 Register saved_args_desc = locs()->in(0).reg();
279 Register result = locs()->out().reg();
280
281 // Push the result place holder initialized to NULL.
282 __ PushObject(Object::ZoneHandle());
283 __ LoadImmediate(IP, Smi::RawValue(formal_parameter_index()));
284 __ Push(IP);
285 __ PushObject(formal_parameter_name());
286 __ Push(saved_args_desc);
287 compiler->GenerateCallRuntime(token_pos(),
288 deopt_id(),
289 kArgumentDefinitionTestRuntimeEntry,
290 locs());
291 __ Drop(3);
292 __ Pop(result); // Pop bool result.
274 } 293 }
275 294
276 295
277 static Condition TokenKindToSmiCondition(Token::Kind kind) { 296 static Condition TokenKindToSmiCondition(Token::Kind kind) {
278 switch (kind) { 297 switch (kind) {
279 case Token::kEQ: return EQ; 298 case Token::kEQ: return EQ;
280 case Token::kNE: return NE; 299 case Token::kNE: return NE;
281 case Token::kLT: return LT; 300 case Token::kLT: return LT;
282 case Token::kGT: return GT; 301 case Token::kGT: return GT;
283 case Token::kLTE: return LE; 302 case Token::kLTE: return LE;
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 } 577 }
559 578
560 579
561 // Emit code when ICData's targets are all Object == (which is ===). 580 // Emit code when ICData's targets are all Object == (which is ===).
562 static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler, 581 static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler,
563 const ICData& ic_data, 582 const ICData& ic_data,
564 const LocationSummary& locs, 583 const LocationSummary& locs,
565 Token::Kind kind, 584 Token::Kind kind,
566 BranchInstr* branch, 585 BranchInstr* branch,
567 intptr_t deopt_id) { 586 intptr_t deopt_id) {
568 UNIMPLEMENTED(); 587 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
588 Register left = locs.in(0).reg();
589 Register right = locs.in(1).reg();
590 Register temp = locs.temp(0).reg();
591 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality);
592 __ tst(left, ShifterOperand(kSmiTagMask));
593 __ b(deopt, EQ);
594 // 'left' is not Smi.
595 Label identity_compare;
596 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
597 __ cmp(right, ShifterOperand(IP));
598 __ b(&identity_compare, EQ);
599 __ cmp(left, ShifterOperand(IP));
600 __ b(&identity_compare, EQ);
601
602 __ LoadClassId(temp, left);
603 const intptr_t len = ic_data.NumberOfChecks();
604 for (intptr_t i = 0; i < len; i++) {
605 __ CompareImmediate(temp, ic_data.GetReceiverClassIdAt(i));
606 if (i == (len - 1)) {
607 __ b(deopt, NE);
608 } else {
609 __ b(&identity_compare, EQ);
610 }
611 }
612 __ Bind(&identity_compare);
613 __ cmp(left, ShifterOperand(right));
614 if (branch == NULL) {
615 Register result = locs.out().reg();
616 __ LoadObject(result,
617 (kind == Token::kEQ) ? Bool::True() : Bool::False(), EQ);
618 __ LoadObject(result,
619 (kind == Token::kEQ) ? Bool::False() : Bool::True(), NE);
620 } else {
621 Condition cond = TokenKindToSmiCondition(kind);
622 branch->EmitBranchOnCondition(compiler, cond);
623 }
569 } 624 }
570 625
571 626
572 // First test if receiver is NULL, in which case === is applied. 627 // First test if receiver is NULL, in which case === is applied.
573 // If type feedback was provided (lists of <class-id, target>), do a 628 // If type feedback was provided (lists of <class-id, target>), do a
574 // type by type check (either === or static call to the operator. 629 // type by type check (either === or static call to the operator.
575 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, 630 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
576 LocationSummary* locs, 631 LocationSummary* locs,
577 Token::Kind kind, 632 Token::Kind kind,
578 BranchInstr* branch, 633 BranchInstr* branch,
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 727
673 728
674 static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler, 729 static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
675 const LocationSummary& locs, 730 const LocationSummary& locs,
676 Token::Kind kind, 731 Token::Kind kind,
677 BranchInstr* branch) { 732 BranchInstr* branch) {
678 UNIMPLEMENTED(); 733 UNIMPLEMENTED();
679 } 734 }
680 735
681 736
737 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
738 switch (kind) {
739 case Token::kEQ: return EQ;
740 case Token::kNE: return NE;
741 case Token::kLT: return LT;
742 case Token::kGT: return GT;
743 case Token::kLTE: return LE;
744 case Token::kGTE: return GE;
745 default:
746 UNREACHABLE();
747 return VS;
748 }
749 }
750
751
682 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 752 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
683 const LocationSummary& locs, 753 const LocationSummary& locs,
684 Token::Kind kind, 754 Token::Kind kind,
685 BranchInstr* branch) { 755 BranchInstr* branch) {
686 UNIMPLEMENTED(); 756 DRegister left = locs.in(0).fpu_reg();
757 DRegister right = locs.in(1).fpu_reg();
758
759 Condition true_condition = TokenKindToDoubleCondition(kind);
760 if (branch != NULL) {
761 compiler->EmitDoubleCompareBranch(
762 true_condition, left, right, branch);
763 } else {
764 compiler->EmitDoubleCompareBool(
765 true_condition, left, right, locs.out().reg());
766 }
687 } 767 }
688 768
689 769
690 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 770 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
691 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 771 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
692 BranchInstr* kNoBranch = NULL; 772 BranchInstr* kNoBranch = NULL;
693 if (receiver_class_id() == kSmiCid) { 773 if (receiver_class_id() == kSmiCid) {
694 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); 774 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
695 return; 775 return;
696 } 776 }
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 __ LoadImmediate(R1, NativeArguments::ComputeArgcTag(function())); 1031 __ LoadImmediate(R1, NativeArguments::ComputeArgcTag(function()));
952 compiler->GenerateCall(token_pos(), 1032 compiler->GenerateCall(token_pos(),
953 &StubCode::CallNativeCFunctionLabel(), 1033 &StubCode::CallNativeCFunctionLabel(),
954 PcDescriptors::kOther, 1034 PcDescriptors::kOther,
955 locs()); 1035 locs());
956 __ Pop(result); 1036 __ Pop(result);
957 } 1037 }
958 1038
959 1039
960 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { 1040 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const {
961 UNIMPLEMENTED(); 1041 const intptr_t kNumInputs = 1;
962 return NULL; 1042 // TODO(fschneider): Allow immediate operands for the char code.
1043 return LocationSummary::Make(kNumInputs,
1044 Location::RequiresRegister(),
1045 LocationSummary::kNoCall);
963 } 1046 }
964 1047
965 1048
966 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1049 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
967 UNIMPLEMENTED(); 1050 Register char_code = locs()->in(0).reg();
1051 Register result = locs()->out().reg();
1052 __ LoadImmediate(result,
1053 reinterpret_cast<uword>(Symbols::PredefinedAddress()));
1054 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize);
1055 __ ldr(result, Address(result, char_code, LSL, 1)); // Char code is a smi.
968 } 1056 }
969 1057
970 1058
971 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { 1059 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const {
972 UNIMPLEMENTED(); 1060 UNIMPLEMENTED();
973 return NULL; 1061 return NULL;
974 } 1062 }
975 1063
976 1064
977 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1065 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 compiler->GenerateCall(token_pos(), 1781 compiler->GenerateCall(token_pos(),
1694 &StubCode::AllocateArrayLabel(), 1782 &StubCode::AllocateArrayLabel(),
1695 PcDescriptors::kOther, 1783 PcDescriptors::kOther,
1696 locs()); 1784 locs());
1697 ASSERT(locs()->out().reg() == R0); 1785 ASSERT(locs()->out().reg() == R0);
1698 } 1786 }
1699 1787
1700 1788
1701 LocationSummary* 1789 LocationSummary*
1702 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { 1790 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const {
1703 UNIMPLEMENTED(); 1791 return MakeCallSummary();
1704 return NULL;
1705 } 1792 }
1706 1793
1707 1794
1708 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( 1795 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode(
1709 FlowGraphCompiler* compiler) { 1796 FlowGraphCompiler* compiler) {
1710 UNIMPLEMENTED(); 1797 compiler->GenerateCallRuntime(token_pos(),
1798 deopt_id(),
1799 kAllocateObjectWithBoundsCheckRuntimeEntry,
1800 locs());
1801 __ Drop(3);
1802 ASSERT(locs()->out().reg() == R0);
1803 __ Pop(R0); // Pop new instance.
1711 } 1804 }
1712 1805
1713 1806
1714 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { 1807 LocationSummary* LoadFieldInstr::MakeLocationSummary() const {
1715 return LocationSummary::Make(1, 1808 return LocationSummary::Make(1,
1716 Location::RequiresRegister(), 1809 Location::RequiresRegister(),
1717 LocationSummary::kNoCall); 1810 LocationSummary::kNoCall);
1718 } 1811 }
1719 1812
1720 1813
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1875 const ExternalLabel label("alloc_context", 1968 const ExternalLabel label("alloc_context",
1876 StubCode::AllocateContextEntryPoint()); 1969 StubCode::AllocateContextEntryPoint());
1877 compiler->GenerateCall(token_pos(), 1970 compiler->GenerateCall(token_pos(),
1878 &label, 1971 &label,
1879 PcDescriptors::kOther, 1972 PcDescriptors::kOther,
1880 locs()); 1973 locs());
1881 } 1974 }
1882 1975
1883 1976
1884 LocationSummary* CloneContextInstr::MakeLocationSummary() const { 1977 LocationSummary* CloneContextInstr::MakeLocationSummary() const {
1885 UNIMPLEMENTED(); 1978 const intptr_t kNumInputs = 1;
1886 return NULL; 1979 const intptr_t kNumTemps = 0;
1980 LocationSummary* locs =
1981 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1982 locs->set_in(0, Location::RegisterLocation(R0));
1983 locs->set_out(Location::RegisterLocation(R0));
1984 return locs;
1887 } 1985 }
1888 1986
1889 1987
1890 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1988 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1891 UNIMPLEMENTED(); 1989 Register context_value = locs()->in(0).reg();
1990 Register result = locs()->out().reg();
1991
1992 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1993 __ Push(context_value);
1994 compiler->GenerateCallRuntime(token_pos(),
1995 deopt_id(),
1996 kCloneContextRuntimeEntry,
1997 locs());
1998 __ Drop(1); // Remove argument.
1999 __ Pop(result); // Get result (cloned context).
1892 } 2000 }
1893 2001
1894 2002
1895 LocationSummary* CatchEntryInstr::MakeLocationSummary() const { 2003 LocationSummary* CatchEntryInstr::MakeLocationSummary() const {
1896 return LocationSummary::Make(0, 2004 return LocationSummary::Make(0,
1897 Location::NoLocation(), 2005 Location::NoLocation(),
1898 LocationSummary::kNoCall); 2006 LocationSummary::kNoCall);
1899 } 2007 }
1900 2008
1901 2009
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after
2761 return NULL; 2869 return NULL;
2762 } 2870 }
2763 2871
2764 2872
2765 void BinaryUint32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2873 void BinaryUint32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2766 UNIMPLEMENTED(); 2874 UNIMPLEMENTED();
2767 } 2875 }
2768 2876
2769 2877
2770 LocationSummary* MathSqrtInstr::MakeLocationSummary() const { 2878 LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
2771 UNIMPLEMENTED(); 2879 const intptr_t kNumInputs = 1;
2772 return NULL; 2880 const intptr_t kNumTemps = 0;
2881 LocationSummary* summary =
2882 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2883 summary->set_in(0, Location::RequiresFpuRegister());
2884 summary->set_out(Location::RequiresFpuRegister());
2885 return summary;
2773 } 2886 }
2774 2887
2775 2888
2776 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2889 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2777 UNIMPLEMENTED(); 2890 __ vsqrtd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg());
2778 } 2891 }
2779 2892
2780 2893
2781 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 2894 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const {
2782 const intptr_t kNumInputs = 1; 2895 const intptr_t kNumInputs = 1;
2783 const intptr_t kNumTemps = 0; 2896 const intptr_t kNumTemps = 0;
2784 LocationSummary* summary = 2897 LocationSummary* summary =
2785 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2898 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2786 summary->set_in(0, Location::RequiresRegister()); 2899 summary->set_in(0, Location::RequiresRegister());
2787 // We make use of 3-operand instructions by not requiring result register 2900 // We make use of 3-operand instructions by not requiring result register
(...skipping 19 matching lines...) Expand all
2807 // Remove inverted smi-tag. 2920 // Remove inverted smi-tag.
2808 __ bic(result, result, ShifterOperand(kSmiTagMask)); 2921 __ bic(result, result, ShifterOperand(kSmiTagMask));
2809 break; 2922 break;
2810 default: 2923 default:
2811 UNREACHABLE(); 2924 UNREACHABLE();
2812 } 2925 }
2813 } 2926 }
2814 2927
2815 2928
2816 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { 2929 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const {
2817 UNIMPLEMENTED(); 2930 const intptr_t kNumInputs = 1;
2818 return NULL; 2931 const intptr_t kNumTemps = 0;
2932 LocationSummary* result =
2933 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2934 result->set_in(0, Location::WritableRegister());
2935 result->set_out(Location::RequiresFpuRegister());
2936 return result;
2819 } 2937 }
2820 2938
2821 2939
2822 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2940 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2823 UNIMPLEMENTED(); 2941 Register value = locs()->in(0).reg();
2942 FpuRegister result = locs()->out().fpu_reg();
2943 __ SmiUntag(value);
2944 __ vmovsr(S0, value);
2945 __ vcvtdi(result, S0);
2824 } 2946 }
2825 2947
2826 2948
2827 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { 2949 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const {
2828 UNIMPLEMENTED(); 2950 const intptr_t kNumInputs = 1;
2829 return NULL; 2951 const intptr_t kNumTemps = 0;
2952 LocationSummary* result =
2953 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2954 result->set_in(0, Location::RegisterLocation(R1));
2955 result->set_out(Location::RegisterLocation(R0));
2956 return result;
2830 } 2957 }
2831 2958
2832 2959
2833 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2960 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2834 UNIMPLEMENTED(); 2961 Register result = locs()->out().reg();
2962 Register value_obj = locs()->in(0).reg();
2963 ASSERT(result == R0);
2964 ASSERT(result != value_obj);
2965 __ LoadDFromOffset(D0, value_obj, Double::value_offset() - kHeapObjectTag);
2966 __ vcvtid(S0, D0);
2967 __ vmovrs(result, S0);
2968 // Overflow is signaled with minint.
2969 Label do_call, done;
2970 // Check for overflow and that it fits into Smi.
2971 __ CompareImmediate(result, 0xC0000000);
2972 __ b(&do_call, MI);
2973 __ SmiTag(result);
2974 __ b(&done);
2975 __ Bind(&do_call);
2976 __ Push(value_obj);
2977 ASSERT(instance_call()->HasICData());
2978 const ICData& ic_data = *instance_call()->ic_data();
2979 ASSERT((ic_data.NumberOfChecks() == 1));
2980 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
2981
2982 const intptr_t kNumberOfArguments = 1;
2983 compiler->GenerateStaticCall(deopt_id(),
2984 instance_call()->token_pos(),
2985 target,
2986 kNumberOfArguments,
2987 Array::Handle(), // No argument names.,
2988 locs());
2989 __ Bind(&done);
2835 } 2990 }
2836 2991
2837 2992
2838 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { 2993 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const {
2839 UNIMPLEMENTED(); 2994 const intptr_t kNumInputs = 1;
2840 return NULL; 2995 const intptr_t kNumTemps = 0;
2996 LocationSummary* result = new LocationSummary(
2997 kNumInputs, kNumTemps, LocationSummary::kNoCall);
2998 result->set_in(0, Location::RequiresFpuRegister());
2999 result->set_out(Location::RequiresRegister());
3000 return result;
2841 } 3001 }
2842 3002
2843 3003
2844 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3004 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2845 UNIMPLEMENTED(); 3005 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
3006 Register result = locs()->out().reg();
3007 DRegister value = locs()->in(0).fpu_reg();
3008 __ vcvtid(S0, value);
3009 __ vmovrs(result, S0);
3010 // Check for overflow and that it fits into Smi.
3011 __ CompareImmediate(result, 0xC0000000);
3012 __ b(deopt, MI);
3013 __ SmiTag(result);
2846 } 3014 }
2847 3015
2848 3016
2849 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { 3017 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const {
2850 UNIMPLEMENTED(); 3018 const intptr_t kNumInputs = 1;
2851 return NULL; 3019 const intptr_t kNumTemps = 0;
3020 LocationSummary* result =
3021 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3022 result->set_in(0, Location::RequiresFpuRegister());
3023 result->set_out(Location::RequiresFpuRegister());
3024 return result;
2852 } 3025 }
2853 3026
2854 3027
2855 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3028 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2856 UNIMPLEMENTED(); 3029 // DRegister value = locs()->in(0).fpu_reg();
3030 // DRegister result = locs()->out().fpu_reg();
3031 switch (recognized_kind()) {
3032 case MethodRecognizer::kDoubleTruncate:
3033 UNIMPLEMENTED();
3034 // __ roundsd(result, value, Assembler::kRoundToZero);
3035 break;
3036 case MethodRecognizer::kDoubleFloor:
3037 UNIMPLEMENTED();
3038 // __ roundsd(result, value, Assembler::kRoundDown);
3039 break;
3040 case MethodRecognizer::kDoubleCeil:
3041 UNIMPLEMENTED();
3042 // __ roundsd(result, value, Assembler::kRoundUp);
3043 break;
3044 default:
3045 UNREACHABLE();
3046 }
2857 } 3047 }
2858 3048
2859 3049
2860 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { 3050 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const {
2861 UNIMPLEMENTED(); 3051 ASSERT((InputCount() == 1) || (InputCount() == 2));
2862 return NULL; 3052 const intptr_t kNumTemps = 0;
3053 LocationSummary* result =
3054 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
3055 result->set_in(0, Location::FpuRegisterLocation(D1));
3056 if (InputCount() == 2) {
3057 result->set_in(1, Location::FpuRegisterLocation(D2));
3058 }
3059 result->set_out(Location::FpuRegisterLocation(D1));
3060 return result;
2863 } 3061 }
2864 3062
2865 3063
2866 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3064 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2867 UNIMPLEMENTED(); 3065 // For pow-function return NAN if exponent is NAN.
3066 Label do_call, skip_call;
3067 if (recognized_kind() == MethodRecognizer::kDoublePow) {
3068 DRegister exp = locs()->in(1).fpu_reg();
3069 __ vcmpd(exp, exp);
3070 __ vmstat();
3071 __ b(&do_call, VC); // NaN -> false;
3072 // Exponent is NaN, return NaN.
3073 __ vmovd(locs()->out().fpu_reg(), exp);
3074 __ b(&skip_call);
3075 }
3076 __ Bind(&do_call);
3077 // TODO(regis): Using D0 as the reserved scratch value is not a good idea.
3078 __ vmovd(D0, locs()->in(0).fpu_reg());
3079 if (InputCount() == 2) {
3080 __ vmovd(D1, locs()->in(1).fpu_reg());
3081 }
3082 UNIMPLEMENTED(); // TODO(regis): We need to support double type leaf calls.
3083 __ CallRuntime(TargetFunction());
3084 __ vmovd(locs()->out().fpu_reg(), D0);
3085 __ Bind(&skip_call);
2868 } 3086 }
2869 3087
2870 3088
2871 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { 3089 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const {
2872 return MakeCallSummary(); 3090 return MakeCallSummary();
2873 } 3091 }
2874 3092
2875 3093
2876 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3094 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2877 Label* deopt = compiler->AddDeoptStub(deopt_id(), 3095 Label* deopt = compiler->AddDeoptStub(deopt_id(),
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
3367 compiler->GenerateCall(token_pos(), 3585 compiler->GenerateCall(token_pos(),
3368 &label, 3586 &label,
3369 PcDescriptors::kOther, 3587 PcDescriptors::kOther,
3370 locs()); 3588 locs());
3371 __ Drop(2); // Discard type arguments and receiver. 3589 __ Drop(2); // Discard type arguments and receiver.
3372 } 3590 }
3373 3591
3374 } // namespace dart 3592 } // namespace dart
3375 3593
3376 #endif // defined TARGET_ARCH_ARM 3594 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698