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

Side by Side Diff: runtime/vm/intermediate_language_x64.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_mips.cc ('k') | runtime/vm/locations.h » ('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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 4734 matching lines...) Expand 10 before | Expand all | Expand 10 after
4745 __ Bind(&do_pow); 4745 __ Bind(&do_pow);
4746 } 4746 }
4747 __ CallRuntime(TargetFunction(), InputCount()); 4747 __ CallRuntime(TargetFunction(), InputCount());
4748 __ movaps(locs()->out(0).fpu_reg(), XMM0); 4748 __ movaps(locs()->out(0).fpu_reg(), XMM0);
4749 __ Bind(&skip_call); 4749 __ Bind(&skip_call);
4750 // Restore RSP. 4750 // Restore RSP.
4751 __ movq(RSP, locs()->temp(kSavedSpTempIndex).reg()); 4751 __ movq(RSP, locs()->temp(kSavedSpTempIndex).reg());
4752 } 4752 }
4753 4753
4754 4754
4755 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const {
4756 // Only use this instruction in optimized code.
4757 ASSERT(opt);
4758 const intptr_t kNumInputs = 1;
4759 LocationSummary* summary =
4760 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
4761 if (representation() == kUnboxedDouble) {
4762 if (index() == 0) {
4763 summary->set_in(0, Location::Pair(Location::RequiresFpuRegister(),
4764 Location::Any()));
4765 } else {
4766 ASSERT(index() == 1);
4767 summary->set_in(0, Location::Pair(Location::Any(),
4768 Location::RequiresFpuRegister()));
4769 }
4770 summary->set_out(0, Location::RequiresFpuRegister());
4771 } else {
4772 ASSERT(representation() == kTagged);
4773 if (index() == 0) {
4774 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
4775 Location::Any()));
4776 } else {
4777 ASSERT(index() == 1);
4778 summary->set_in(0, Location::Pair(Location::Any(),
4779 Location::RequiresRegister()));
4780 }
4781 summary->set_out(0, Location::RequiresRegister());
4782 }
4783 return summary;
4784 }
4785
4786
4787 void ExtractNthOutputInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4788 ASSERT(locs()->in(0).IsPairLocation());
4789 PairLocation* pair = locs()->in(0).AsPairLocation();
4790 Location in_loc = pair->At(index());
4791 if (representation() == kUnboxedDouble) {
4792 XmmRegister out = locs()->out(0).fpu_reg();
4793 XmmRegister in = in_loc.fpu_reg();
4794 __ movaps(out, in);
4795 } else {
4796 ASSERT(representation() == kTagged);
4797 Register out = locs()->out(0).reg();
4798 Register in = in_loc.reg();
4799 __ movq(out, in);
4800 }
4801 }
4802
4803
4755 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { 4804 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
4756 if (kind() == MergedMathInstr::kTruncDivMod) { 4805 if (kind() == MergedMathInstr::kTruncDivMod) {
4757 const intptr_t kNumInputs = 2; 4806 const intptr_t kNumInputs = 2;
4758 const intptr_t kNumTemps = 1; 4807 const intptr_t kNumTemps = 0;
4759 LocationSummary* summary = 4808 LocationSummary* summary =
4760 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4809 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4761 // Both inputs must be writable because they will be untagged. 4810 // Both inputs must be writable because they will be untagged.
4762 summary->set_in(0, Location::RegisterLocation(RAX)); 4811 summary->set_in(0, Location::RegisterLocation(RAX));
4763 summary->set_in(1, Location::WritableRegister()); 4812 summary->set_in(1, Location::WritableRegister());
4764 summary->set_out(0, Location::RequiresRegister()); 4813 summary->set_out(0, Location::Pair(Location::RegisterLocation(RAX),
4765 // Will be used for sign extension and division. 4814 Location::RegisterLocation(RDX)));
4766 summary->set_temp(0, Location::RegisterLocation(RDX));
4767 return summary; 4815 return summary;
4768 } 4816 }
4769 if (kind() == MergedMathInstr::kSinCos) { 4817 if (kind() == MergedMathInstr::kSinCos) {
4770 const intptr_t kNumInputs = 1; 4818 const intptr_t kNumInputs = 1;
4771 const intptr_t kNumTemps = 1; 4819 const intptr_t kNumTemps = 1;
4772 LocationSummary* summary = 4820 LocationSummary* summary =
4773 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4821 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4822 // Because we always call into the runtime (LocationSummary::kCall) we
4823 // must specify each input, temp, and output register explicitly.
4774 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 4824 summary->set_in(0, Location::FpuRegisterLocation(XMM1));
4775 // R13 is chosen because it is callee saved so we do not need to back it 4825 // R13 is chosen because it is callee saved so we do not need to back it
4776 // up before calling into the runtime. 4826 // up before calling into the runtime.
4777 summary->set_temp(0, Location::RegisterLocation(R13)); 4827 summary->set_temp(0, Location::RegisterLocation(R13));
4778 summary->set_out(0, Location::RegisterLocation(RAX)); 4828 summary->set_out(0, Location::Pair(Location::FpuRegisterLocation(XMM2),
4829 Location::FpuRegisterLocation(XMM3)));
4779 return summary; 4830 return summary;
4780 } 4831 }
4781 UNIMPLEMENTED(); 4832 UNIMPLEMENTED();
4782 return NULL; 4833 return NULL;
4783 } 4834 }
4784 4835
4785 4836
4786 4837
4787 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); 4838 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos);
4788 4839
4789 extern const RuntimeEntry kSinCosRuntimeEntry( 4840 extern const RuntimeEntry kSinCosRuntimeEntry(
4790 "libc_sincos", reinterpret_cast<RuntimeFunction>( 4841 "libc_sincos", reinterpret_cast<RuntimeFunction>(
4791 static_cast<SinCosCFunction>(&SinCos)), 1, true, true); 4842 static_cast<SinCosCFunction>(&SinCos)), 1, true, true);
4792 4843
4793 4844
4794 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4845 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4795 Label* deopt = NULL; 4846 Label* deopt = NULL;
4796 if (CanDeoptimize()) { 4847 if (CanDeoptimize()) {
4797 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 4848 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
4798 } 4849 }
4799 if (kind() == MergedMathInstr::kTruncDivMod) { 4850 if (kind() == MergedMathInstr::kTruncDivMod) {
4800 Register left = locs()->in(0).reg(); 4851 Register left = locs()->in(0).reg();
4801 Register right = locs()->in(1).reg(); 4852 Register right = locs()->in(1).reg();
4802 Register result = locs()->out(0).reg(); 4853 ASSERT(locs()->out(0).IsPairLocation());
4854 PairLocation* pair = locs()->out(0).AsPairLocation();
4855 Register result1 = pair->At(0).reg();
4856 Register result2 = pair->At(1).reg();
4803 Label not_32bit, done; 4857 Label not_32bit, done;
4804 Register temp = locs()->temp(0).reg(); 4858 Register temp = RDX;
4805 ASSERT(left == RAX); 4859 ASSERT(left == RAX);
4806 ASSERT((right != RDX) && (right != RAX)); 4860 ASSERT((right != RDX) && (right != RAX));
4807 ASSERT(temp == RDX); 4861 ASSERT(result1 == RAX);
4808 ASSERT((result != RDX) && (result != RAX)); 4862 ASSERT(result2 == RDX);
4809
4810 Range* right_range = InputAt(1)->definition()->range(); 4863 Range* right_range = InputAt(1)->definition()->range();
4811 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 4864 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
4812 // Handle divide by zero in runtime. 4865 // Handle divide by zero in runtime.
4813 __ testq(right, right); 4866 __ testq(right, right);
4814 __ j(ZERO, deopt); 4867 __ j(ZERO, deopt);
4815 } 4868 }
4816 // Check if both operands fit into 32bits as idiv with 64bit operands 4869 // Check if both operands fit into 32bits as idiv with 64bit operands
4817 // requires twice as many cycles and has much higher latency. 4870 // requires twice as many cycles and has much higher latency.
4818 // We are checking this before untagging them to avoid corner case 4871 // We are checking this before untagging them to avoid corner case
4819 // dividing INT_MAX by -1 that raises exception because quotient is 4872 // dividing INT_MAX by -1 that raises exception because quotient is
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4868 __ Bind(&subtract); 4921 __ Bind(&subtract);
4869 __ subq(RDX, right); 4922 __ subq(RDX, right);
4870 } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) { 4923 } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
4871 // Right is positive. 4924 // Right is positive.
4872 __ addq(RDX, right); 4925 __ addq(RDX, right);
4873 } else { 4926 } else {
4874 // Right is negative. 4927 // Right is negative.
4875 __ subq(RDX, right); 4928 __ subq(RDX, right);
4876 } 4929 }
4877 __ Bind(&all_done); 4930 __ Bind(&all_done);
4878 __ SmiTag(result);
4879 4931
4880 __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld)), PP);
4881 const intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(kArrayCid);
4882 Address trunc_div_address(
4883 FlowGraphCompiler::ElementAddressForIntIndex(
4884 kArrayCid, index_scale, result,
4885 MergedMathInstr::ResultIndexOf(Token::kTRUNCDIV)));
4886 Address mod_address(
4887 FlowGraphCompiler::ElementAddressForIntIndex(
4888 kArrayCid, index_scale, result,
4889 MergedMathInstr::ResultIndexOf(Token::kMOD)));
4890 __ SmiTag(RAX); 4932 __ SmiTag(RAX);
4891 __ SmiTag(RDX); 4933 __ SmiTag(RDX);
4892 __ StoreIntoObjectNoBarrier(result, trunc_div_address, RAX);
4893 __ StoreIntoObjectNoBarrier(result, mod_address, RDX);
4894 // FLAG_throw_on_javascript_int_overflow: not needed. 4934 // FLAG_throw_on_javascript_int_overflow: not needed.
4895 // Note that the result of an integer division/modulo of two 4935 // Note that the result of an integer division/modulo of two
4896 // in-range arguments, cannot create out-of-range result. 4936 // in-range arguments, cannot create out-of-range result.
4897 return; 4937 return;
4898 } 4938 }
4899 if (kind() == MergedMathInstr::kSinCos) { 4939 if (kind() == MergedMathInstr::kSinCos) {
4940 ASSERT(locs()->out(0).IsPairLocation());
4941 PairLocation* pair = locs()->out(0).AsPairLocation();
4942 XmmRegister out1 = pair->At(0).fpu_reg();
4943 XmmRegister out2 = pair->At(1).fpu_reg();
4944
4900 // Save RSP. 4945 // Save RSP.
4901 __ movq(locs()->temp(0).reg(), RSP); 4946 __ movq(locs()->temp(0).reg(), RSP);
4902 // +-------------------------------+ 4947 // +-------------------------------+
4903 // | double-argument | <- TOS 4948 // | double-argument | <- TOS
4904 // +-------------------------------+ 4949 // +-------------------------------+
4905 // | address-cos-result | +8 4950 // | address-cos-result | +8
4906 // +-------------------------------+ 4951 // +-------------------------------+
4907 // | address-sin-result | +16 4952 // | address-sin-result | +16
4908 // +-------------------------------+ 4953 // +-------------------------------+
4909 // | double-storage-for-cos-result | +24 4954 // | double-storage-for-cos-result | +24
4910 // +-------------------------------+ 4955 // +-------------------------------+
4911 // | double-storage-for-sin-result | +32 4956 // | double-storage-for-sin-result | +32
4912 // +-------------------------------+ 4957 // +-------------------------------+
4913 // .... 4958 // ....
4914 __ ReserveAlignedFrameSpace(kDoubleSize * 3 + kWordSize * 2); 4959 __ ReserveAlignedFrameSpace(kDoubleSize * 3 + kWordSize * 2);
4915 __ movsd(Address(RSP, 0), locs()->in(0).fpu_reg()); 4960 __ movsd(Address(RSP, 0), locs()->in(0).fpu_reg());
4916 4961
4917 __ leaq(RDI, Address(RSP, 2 * kWordSize + kDoubleSize)); 4962 __ leaq(RDI, Address(RSP, 2 * kWordSize + kDoubleSize));
4918 __ leaq(RSI, Address(RSP, 2 * kWordSize + 2 * kDoubleSize)); 4963 __ leaq(RSI, Address(RSP, 2 * kWordSize + 2 * kDoubleSize));
4919 __ movaps(XMM0, locs()->in(0).fpu_reg()); 4964 __ movaps(XMM0, locs()->in(0).fpu_reg());
4920 4965
4921 __ CallRuntime(kSinCosRuntimeEntry, InputCount()); 4966 __ CallRuntime(kSinCosRuntimeEntry, InputCount());
4922 __ movsd(XMM0, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin. 4967 __ movsd(out2, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin.
4923 __ movsd(XMM1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos. 4968 __ movsd(out1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos.
4924 // Restore RSP. 4969 // Restore RSP.
4925 __ movq(RSP, locs()->temp(0).reg()); 4970 __ movq(RSP, locs()->temp(0).reg());
4926 4971
4927 Register result = locs()->out(0).reg();
4928 const TypedData& res_array = TypedData::ZoneHandle(
4929 TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld));
4930 __ LoadObject(result, res_array, PP);
4931 const intptr_t index_scale =
4932 FlowGraphCompiler::ElementSizeFor(kTypedDataFloat64ArrayCid);
4933 Address sin_address(
4934 FlowGraphCompiler::ElementAddressForIntIndex(
4935 kTypedDataFloat64ArrayCid, index_scale, result,
4936 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathSin)));
4937 Address cos_address(
4938 FlowGraphCompiler::ElementAddressForIntIndex(
4939 kTypedDataFloat64ArrayCid, index_scale, result,
4940 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathCos)));
4941 __ movsd(sin_address, XMM0);
4942 __ movsd(cos_address, XMM1);
4943 return; 4972 return;
4944 } 4973 }
4945 UNIMPLEMENTED(); 4974 UNIMPLEMENTED();
4946 } 4975 }
4947 4976
4948 4977
4949 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( 4978 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
4950 bool opt) const { 4979 bool opt) const {
4951 return MakeCallSummary(); 4980 return MakeCallSummary();
4952 } 4981 }
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
5429 PcDescriptors::kOther, 5458 PcDescriptors::kOther,
5430 locs()); 5459 locs());
5431 __ Drop(ArgumentCount()); // Discard arguments. 5460 __ Drop(ArgumentCount()); // Discard arguments.
5432 } 5461 }
5433 5462
5434 } // namespace dart 5463 } // namespace dart
5435 5464
5436 #undef __ 5465 #undef __
5437 5466
5438 #endif // defined TARGET_ARCH_X64 5467 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/locations.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698