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

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

Powered by Google App Engine
This is Rietveld 408576698