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

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

Issue 215363004: Support for multiple register values (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 4826 matching lines...) Expand 10 before | Expand all | Expand 10 after
4837 4837
4838 __ CallRuntime(TargetFunction(), InputCount()); 4838 __ CallRuntime(TargetFunction(), InputCount());
4839 __ fstpl(Address(ESP, 0)); 4839 __ fstpl(Address(ESP, 0));
4840 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0)); 4840 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0));
4841 __ Bind(&skip_call); 4841 __ Bind(&skip_call);
4842 // Restore ESP. 4842 // Restore ESP.
4843 __ movl(ESP, locs()->temp(kSavedSpTempIndex).reg()); 4843 __ movl(ESP, locs()->temp(kSavedSpTempIndex).reg());
4844 } 4844 }
4845 4845
4846 4846
4847 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const {
4848 // Only use this instruction in optimized code.
4849 ASSERT(opt);
4850 const intptr_t kNumInputs = 1;
4851 LocationSummary* summary =
4852 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
4853 if (representation() == kUnboxedDouble) {
4854 if (index() == 0) {
4855 summary->set_in(0, Location::Pair(Location::RequiresFpuRegister(),
4856 Location::Any()));
4857 } else {
4858 ASSERT(index() == 1);
4859 summary->set_in(0, Location::Pair(Location::Any(),
4860 Location::RequiresFpuRegister()));
4861 }
4862 summary->set_out(0, Location::RequiresFpuRegister());
4863 } else {
4864 ASSERT(representation() == kTagged);
4865 if (index() == 0) {
4866 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
4867 Location::Any()));
4868 } else {
4869 ASSERT(index() == 1);
4870 summary->set_in(0, Location::Pair(Location::Any(),
4871 Location::RequiresRegister()));
4872 }
4873 summary->set_out(0, Location::RequiresRegister());
4874 }
4875 return summary;
4876 }
4877
4878
4879 void ExtractNthOutputInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4880 ASSERT(locs()->in(0).IsPairLocation());
4881 PairLocation* pair = locs()->in(0).AsPairLocation();
4882 Location in_loc = pair->At(index());
4883 if (representation() == kUnboxedDouble) {
4884 XmmRegister out = locs()->out(0).fpu_reg();
4885 XmmRegister in = in_loc.fpu_reg();
4886 __ movaps(out, in);
4887 } else {
4888 ASSERT(representation() == kTagged);
4889 Register out = locs()->out(0).reg();
4890 Register in = in_loc.reg();
4891 __ movl(out, in);
4892 }
4893 }
4894
4895
4847 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { 4896 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
4848 if (kind() == MergedMathInstr::kTruncDivMod) { 4897 if (kind() == MergedMathInstr::kTruncDivMod) {
4849 const intptr_t kNumInputs = 2; 4898 const intptr_t kNumInputs = 2;
4850 const intptr_t kNumTemps = 1; 4899 const intptr_t kNumTemps = 1;
4851 LocationSummary* summary = 4900 LocationSummary* summary =
4852 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4901 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4853 // Both inputs must be writable because they will be untagged. 4902 // Both inputs must be writable because they will be untagged.
4854 summary->set_in(0, Location::RegisterLocation(EAX)); 4903 summary->set_in(0, Location::RegisterLocation(EAX));
4855 summary->set_in(1, Location::WritableRegister()); 4904 summary->set_in(1, Location::WritableRegister());
4856 summary->set_out(0, Location::RequiresRegister()); 4905 // Output is a pair of registers.
4906 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
Florian Schneider 2014/04/08 09:48:45 How about making the output a pair EDX:EAX instead
Cutch 2014/04/08 15:56:16 Done.
4907 Location::RequiresRegister()));
4857 // Will be used for sign extension and division. 4908 // Will be used for sign extension and division.
4858 summary->set_temp(0, Location::RegisterLocation(EDX)); 4909 summary->set_temp(0, Location::RegisterLocation(EDX));
4859 return summary; 4910 return summary;
4860 } 4911 }
4861 if (kind() == MergedMathInstr::kSinCos) { 4912 if (kind() == MergedMathInstr::kSinCos) {
4862 const intptr_t kNumInputs = 1; 4913 const intptr_t kNumInputs = 1;
4863 const intptr_t kNumTemps = 0; 4914 const intptr_t kNumTemps = 0;
4864 LocationSummary* summary = 4915 LocationSummary* summary =
4865 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4916 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4866 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 4917 summary->set_in(0, Location::RequiresFpuRegister());
4867 summary->set_out(0, Location::RegisterLocation(EAX)); 4918 summary->set_out(0, Location::Pair(Location::RequiresFpuRegister(),
4919 Location::RequiresFpuRegister()));
4868 return summary; 4920 return summary;
4869 } 4921 }
4870 UNIMPLEMENTED(); 4922 UNIMPLEMENTED();
4871 return NULL; 4923 return NULL;
4872 } 4924 }
4873 4925
4874 4926
4875 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); 4927 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos);
4876 4928
4877 extern const RuntimeEntry kSinCosRuntimeEntry( 4929 extern const RuntimeEntry kSinCosRuntimeEntry(
4878 "libc_sincos", reinterpret_cast<RuntimeFunction>( 4930 "libc_sincos", reinterpret_cast<RuntimeFunction>(
4879 static_cast<SinCosCFunction>(&SinCos)), 1, true, true); 4931 static_cast<SinCosCFunction>(&SinCos)), 1, true, true);
4880 4932
4881 4933
4882 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4934 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4883 Label* deopt = NULL; 4935 Label* deopt = NULL;
4884 if (CanDeoptimize()) { 4936 if (CanDeoptimize()) {
4885 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 4937 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
4886 } 4938 }
4887 4939
4888 if (kind() == MergedMathInstr::kTruncDivMod) { 4940 if (kind() == MergedMathInstr::kTruncDivMod) {
4889 Register left = locs()->in(0).reg(); 4941 Register left = locs()->in(0).reg();
4890 Register right = locs()->in(1).reg(); 4942 Register right = locs()->in(1).reg();
4891 Register result = locs()->out(0).reg(); 4943 ASSERT(locs()->out(0).IsPairLocation());
4944 PairLocation* pair = locs()->out(0).AsPairLocation();
4945 Register result1 = pair->At(0).reg();
4946 Register result2 = pair->At(1).reg();
4892 Range* right_range = InputAt(1)->definition()->range(); 4947 Range* right_range = InputAt(1)->definition()->range();
4893 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 4948 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
4894 // Handle divide by zero in runtime. 4949 // Handle divide by zero in runtime.
4895 __ testl(right, right); 4950 __ testl(right, right);
4896 __ j(ZERO, deopt); 4951 __ j(ZERO, deopt);
4897 } 4952 }
4898 ASSERT(left == EAX); 4953 ASSERT(left == EAX);
4899 ASSERT((right != EDX) && (right != EAX)); 4954 ASSERT((right != EDX) && (right != EAX));
4900 ASSERT(locs()->temp(0).reg() == EDX); 4955 ASSERT(locs()->temp(0).reg() == EDX);
4901 ASSERT((result != EDX) && (result != EAX)); 4956 ASSERT((result1 != EDX) && (result1 != EAX));
4957 ASSERT((result2 != EDX) && (result2 != EAX));
4902 __ SmiUntag(left); 4958 __ SmiUntag(left);
4903 __ SmiUntag(right); 4959 __ SmiUntag(right);
4904 __ cdq(); // Sign extend EAX -> EDX:EAX. 4960 __ cdq(); // Sign extend EAX -> EDX:EAX.
4905 __ idivl(right); // EAX: quotient, EDX: remainder. 4961 __ idivl(right); // EAX: quotient, EDX: remainder.
4906 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 4962 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
4907 // case we cannot tag the result. 4963 // case we cannot tag the result.
4908 // TODO(srdjan): We could store instead untagged intermediate results in a 4964 // TODO(srdjan): We could store instead untagged intermediate results in a
4909 // typed array, but then the load indexed instructions would need to be 4965 // typed array, but then the load indexed instructions would need to be
4910 // able to deoptimize. 4966 // able to deoptimize.
4911 __ cmpl(EAX, Immediate(0x40000000)); 4967 __ cmpl(EAX, Immediate(0x40000000));
(...skipping 21 matching lines...) Expand all
4933 __ subl(EDX, right); 4989 __ subl(EDX, right);
4934 } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) { 4990 } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
4935 // Right is positive. 4991 // Right is positive.
4936 __ addl(EDX, right); 4992 __ addl(EDX, right);
4937 } else { 4993 } else {
4938 // Right is negative. 4994 // Right is negative.
4939 __ subl(EDX, right); 4995 __ subl(EDX, right);
4940 } 4996 }
4941 __ Bind(&done); 4997 __ Bind(&done);
4942 4998
4943 __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld)));
4944 const intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(kArrayCid);
4945 Address trunc_div_address(
4946 FlowGraphCompiler::ElementAddressForIntIndex(
4947 kArrayCid, index_scale, result,
4948 MergedMathInstr::ResultIndexOf(Token::kTRUNCDIV)));
4949 Address mod_address(
4950 FlowGraphCompiler::ElementAddressForIntIndex(
4951 kArrayCid, index_scale, result,
4952 MergedMathInstr::ResultIndexOf(Token::kMOD)));
4953 __ SmiTag(EAX); 4999 __ SmiTag(EAX);
4954 __ SmiTag(EDX); 5000 __ SmiTag(EDX);
4955 __ StoreIntoObjectNoBarrier(result, trunc_div_address, EAX); 5001 __ movl(result1, EAX);
4956 __ StoreIntoObjectNoBarrier(result, mod_address, EDX); 5002 __ movl(result2, EDX);
4957 return; 5003 return;
4958 } 5004 }
4959 5005
4960 if (kind() == MergedMathInstr::kSinCos) { 5006 if (kind() == MergedMathInstr::kSinCos) {
5007 XmmRegister in = locs()->in(0).fpu_reg();
5008 ASSERT(locs()->out(0).IsPairLocation());
5009 PairLocation* pair = locs()->out(0).AsPairLocation();
5010 XmmRegister out1 = pair->At(0).fpu_reg();
5011 XmmRegister out2 = pair->At(1).fpu_reg();
5012
4961 // Do x87 sincos, since the ia32 compilers may not fuse sin/cos into 5013 // Do x87 sincos, since the ia32 compilers may not fuse sin/cos into
4962 // sincos. 5014 // sincos.
4963 __ pushl(EAX); 5015 __ pushl(EAX);
4964 __ pushl(EAX); 5016 __ pushl(EAX);
4965 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg()); 5017 __ movsd(Address(ESP, 0), in);
4966 __ fldl(Address(ESP, 0)); 5018 __ fldl(Address(ESP, 0));
4967 __ fsincos(); 5019 __ fsincos();
4968 __ fstpl(Address(ESP, 0)); 5020 __ fstpl(Address(ESP, 0));
4969 __ movsd(XMM1, Address(ESP, 0)); 5021 __ movsd(out1, Address(ESP, 0));
4970 __ fstpl(Address(ESP, 0)); 5022 __ fstpl(Address(ESP, 0));
4971 __ movsd(XMM0, Address(ESP, 0)); 5023 __ movsd(out2, Address(ESP, 0));
4972 __ addl(ESP, Immediate(2 * kWordSize)); 5024 __ addl(ESP, Immediate(2 * kWordSize));
4973
4974 Register result = locs()->out(0).reg();
4975 const TypedData& res_array = TypedData::ZoneHandle(
4976 TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld));
4977 __ LoadObject(result, res_array);
4978 const intptr_t index_scale =
4979 FlowGraphCompiler::ElementSizeFor(kTypedDataFloat64ArrayCid);
4980 Address sin_address(
4981 FlowGraphCompiler::ElementAddressForIntIndex(
4982 kTypedDataFloat64ArrayCid, index_scale, result,
4983 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathSin)));
4984 Address cos_address(
4985 FlowGraphCompiler::ElementAddressForIntIndex(
4986 kTypedDataFloat64ArrayCid, index_scale, result,
4987 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathCos)));
4988 __ movsd(sin_address, XMM0);
4989 __ movsd(cos_address, XMM1);
4990 return; 5025 return;
4991 } 5026 }
4992 5027
4993 UNIMPLEMENTED(); 5028 UNIMPLEMENTED();
4994 } 5029 }
4995 5030
4996 5031
4997 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( 5032 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
4998 bool opt) const { 5033 bool opt) const {
4999 return MakeCallSummary(); 5034 return MakeCallSummary();
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
5839 PcDescriptors::kOther, 5874 PcDescriptors::kOther,
5840 locs()); 5875 locs());
5841 __ Drop(ArgumentCount()); // Discard arguments. 5876 __ Drop(ArgumentCount()); // Discard arguments.
5842 } 5877 }
5843 5878
5844 } // namespace dart 5879 } // namespace dart
5845 5880
5846 #undef __ 5881 #undef __
5847 5882
5848 #endif // defined TARGET_ARCH_IA32 5883 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698