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

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
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 = 1;
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::RequiresRegister(),
Florian Schneider 2014/04/08 09:48:45 Same here: It should be possible to have the outpu
Cutch 2014/04/08 15:56:16 Done.
4814 Location::RequiresRegister()));
4765 // Will be used for sign extension and division. 4815 // Will be used for sign extension and division.
4766 summary->set_temp(0, Location::RegisterLocation(RDX)); 4816 summary->set_temp(0, Location::RegisterLocation(RDX));
4767 return summary; 4817 return summary;
4768 } 4818 }
4769 if (kind() == MergedMathInstr::kSinCos) { 4819 if (kind() == MergedMathInstr::kSinCos) {
4770 const intptr_t kNumInputs = 1; 4820 const intptr_t kNumInputs = 1;
4771 const intptr_t kNumTemps = 1; 4821 const intptr_t kNumTemps = 1;
4772 LocationSummary* summary = 4822 LocationSummary* summary =
4773 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4823 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4824 // Because we always call into the runtime (LocationSummary::kCall) we
4825 // must specify each input, temp, and output register explicitly.
4774 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 4826 summary->set_in(0, Location::FpuRegisterLocation(XMM1));
4775 // R13 is chosen because it is callee saved so we do not need to back it 4827 // R13 is chosen because it is callee saved so we do not need to back it
4776 // up before calling into the runtime. 4828 // up before calling into the runtime.
4777 summary->set_temp(0, Location::RegisterLocation(R13)); 4829 summary->set_temp(0, Location::RegisterLocation(R13));
4778 summary->set_out(0, Location::RegisterLocation(RAX)); 4830 summary->set_out(0, Location::Pair(Location::FpuRegisterLocation(XMM2),
4831 Location::FpuRegisterLocation(XMM3)));
4779 return summary; 4832 return summary;
4780 } 4833 }
4781 UNIMPLEMENTED(); 4834 UNIMPLEMENTED();
4782 return NULL; 4835 return NULL;
4783 } 4836 }
4784 4837
4785 4838
4786 4839
4787 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); 4840 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos);
4788 4841
4789 extern const RuntimeEntry kSinCosRuntimeEntry( 4842 extern const RuntimeEntry kSinCosRuntimeEntry(
4790 "libc_sincos", reinterpret_cast<RuntimeFunction>( 4843 "libc_sincos", reinterpret_cast<RuntimeFunction>(
4791 static_cast<SinCosCFunction>(&SinCos)), 1, true, true); 4844 static_cast<SinCosCFunction>(&SinCos)), 1, true, true);
4792 4845
4793 4846
4794 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4847 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4795 Label* deopt = NULL; 4848 Label* deopt = NULL;
4796 if (CanDeoptimize()) { 4849 if (CanDeoptimize()) {
4797 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 4850 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
4798 } 4851 }
4799 if (kind() == MergedMathInstr::kTruncDivMod) { 4852 if (kind() == MergedMathInstr::kTruncDivMod) {
4800 Register left = locs()->in(0).reg(); 4853 Register left = locs()->in(0).reg();
4801 Register right = locs()->in(1).reg(); 4854 Register right = locs()->in(1).reg();
4802 Register result = locs()->out(0).reg(); 4855 ASSERT(locs()->out(0).IsPairLocation());
4856 PairLocation* pair = locs()->out(0).AsPairLocation();
4857 Register result1 = pair->At(0).reg();
4858 Register result2 = pair->At(1).reg();
4803 Label not_32bit, done; 4859 Label not_32bit, done;
4804 Register temp = locs()->temp(0).reg(); 4860 Register temp = locs()->temp(0).reg();
4805 ASSERT(left == RAX); 4861 ASSERT(left == RAX);
4806 ASSERT((right != RDX) && (right != RAX)); 4862 ASSERT((right != RDX) && (right != RAX));
4807 ASSERT(temp == RDX); 4863 ASSERT(temp == RDX);
4808 ASSERT((result != RDX) && (result != RAX)); 4864 ASSERT((result1 != RDX) && (result1 != RAX));
4865 ASSERT((result2 != RDX) && (result2 != RAX));
4809 4866
4810 Range* right_range = InputAt(1)->definition()->range(); 4867 Range* right_range = InputAt(1)->definition()->range();
4811 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 4868 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
4812 // Handle divide by zero in runtime. 4869 // Handle divide by zero in runtime.
4813 __ testq(right, right); 4870 __ testq(right, right);
4814 __ j(ZERO, deopt); 4871 __ j(ZERO, deopt);
4815 } 4872 }
4816 // Check if both operands fit into 32bits as idiv with 64bit operands 4873 // Check if both operands fit into 32bits as idiv with 64bit operands
4817 // requires twice as many cycles and has much higher latency. 4874 // requires twice as many cycles and has much higher latency.
4818 // We are checking this before untagging them to avoid corner case 4875 // We are checking this before untagging them to avoid corner case
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4868 __ Bind(&subtract); 4925 __ Bind(&subtract);
4869 __ subq(RDX, right); 4926 __ subq(RDX, right);
4870 } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) { 4927 } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
4871 // Right is positive. 4928 // Right is positive.
4872 __ addq(RDX, right); 4929 __ addq(RDX, right);
4873 } else { 4930 } else {
4874 // Right is negative. 4931 // Right is negative.
4875 __ subq(RDX, right); 4932 __ subq(RDX, right);
4876 } 4933 }
4877 __ Bind(&all_done); 4934 __ Bind(&all_done);
4878 __ SmiTag(result);
4879 4935
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); 4936 __ SmiTag(RAX);
4891 __ SmiTag(RDX); 4937 __ SmiTag(RDX);
4892 __ StoreIntoObjectNoBarrier(result, trunc_div_address, RAX); 4938
4893 __ StoreIntoObjectNoBarrier(result, mod_address, RDX); 4939 __ movq(result1, RAX);
4940 __ movq(result2, RDX);
4894 // FLAG_throw_on_javascript_int_overflow: not needed. 4941 // FLAG_throw_on_javascript_int_overflow: not needed.
4895 // Note that the result of an integer division/modulo of two 4942 // Note that the result of an integer division/modulo of two
4896 // in-range arguments, cannot create out-of-range result. 4943 // in-range arguments, cannot create out-of-range result.
4897 return; 4944 return;
4898 } 4945 }
4899 if (kind() == MergedMathInstr::kSinCos) { 4946 if (kind() == MergedMathInstr::kSinCos) {
4947 ASSERT(locs()->out(0).IsPairLocation());
4948 PairLocation* pair = locs()->out(0).AsPairLocation();
4949 XmmRegister out1 = pair->At(0).fpu_reg();
4950 XmmRegister out2 = pair->At(1).fpu_reg();
4951
4900 // Save RSP. 4952 // Save RSP.
4901 __ movq(locs()->temp(0).reg(), RSP); 4953 __ movq(locs()->temp(0).reg(), RSP);
4902 // +-------------------------------+ 4954 // +-------------------------------+
4903 // | double-argument | <- TOS 4955 // | double-argument | <- TOS
4904 // +-------------------------------+ 4956 // +-------------------------------+
4905 // | address-cos-result | +8 4957 // | address-cos-result | +8
4906 // +-------------------------------+ 4958 // +-------------------------------+
4907 // | address-sin-result | +16 4959 // | address-sin-result | +16
4908 // +-------------------------------+ 4960 // +-------------------------------+
4909 // | double-storage-for-cos-result | +24 4961 // | double-storage-for-cos-result | +24
4910 // +-------------------------------+ 4962 // +-------------------------------+
4911 // | double-storage-for-sin-result | +32 4963 // | double-storage-for-sin-result | +32
4912 // +-------------------------------+ 4964 // +-------------------------------+
4913 // .... 4965 // ....
4914 __ ReserveAlignedFrameSpace(kDoubleSize * 3 + kWordSize * 2); 4966 __ ReserveAlignedFrameSpace(kDoubleSize * 3 + kWordSize * 2);
4915 __ movsd(Address(RSP, 0), locs()->in(0).fpu_reg()); 4967 __ movsd(Address(RSP, 0), locs()->in(0).fpu_reg());
4916 4968
4917 __ leaq(RDI, Address(RSP, 2 * kWordSize + kDoubleSize)); 4969 __ leaq(RDI, Address(RSP, 2 * kWordSize + kDoubleSize));
4918 __ leaq(RSI, Address(RSP, 2 * kWordSize + 2 * kDoubleSize)); 4970 __ leaq(RSI, Address(RSP, 2 * kWordSize + 2 * kDoubleSize));
4919 __ movaps(XMM0, locs()->in(0).fpu_reg()); 4971 __ movaps(XMM0, locs()->in(0).fpu_reg());
4920 4972
4921 __ CallRuntime(kSinCosRuntimeEntry, InputCount()); 4973 __ CallRuntime(kSinCosRuntimeEntry, InputCount());
4922 __ movsd(XMM0, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin. 4974 __ movsd(out2, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin.
4923 __ movsd(XMM1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos. 4975 __ movsd(out1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos.
4924 // Restore RSP. 4976 // Restore RSP.
4925 __ movq(RSP, locs()->temp(0).reg()); 4977 __ movq(RSP, locs()->temp(0).reg());
4926 4978
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; 4979 return;
4944 } 4980 }
4945 UNIMPLEMENTED(); 4981 UNIMPLEMENTED();
4946 } 4982 }
4947 4983
4948 4984
4949 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( 4985 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
4950 bool opt) const { 4986 bool opt) const {
4951 return MakeCallSummary(); 4987 return MakeCallSummary();
4952 } 4988 }
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
5429 PcDescriptors::kOther, 5465 PcDescriptors::kOther,
5430 locs()); 5466 locs());
5431 __ Drop(ArgumentCount()); // Discard arguments. 5467 __ Drop(ArgumentCount()); // Discard arguments.
5432 } 5468 }
5433 5469
5434 } // namespace dart 5470 } // namespace dart
5435 5471
5436 #undef __ 5472 #undef __
5437 5473
5438 #endif // defined TARGET_ARCH_X64 5474 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698