OLD | NEW |
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/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 5640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5651 LocationSummary* summary = new (zone) | 5651 LocationSummary* summary = new (zone) |
5652 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5652 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5653 // Both inputs must be writable because they will be untagged. | 5653 // Both inputs must be writable because they will be untagged. |
5654 summary->set_in(0, Location::RegisterLocation(EAX)); | 5654 summary->set_in(0, Location::RegisterLocation(EAX)); |
5655 summary->set_in(1, Location::WritableRegister()); | 5655 summary->set_in(1, Location::WritableRegister()); |
5656 // Output is a pair of registers. | 5656 // Output is a pair of registers. |
5657 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), | 5657 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), |
5658 Location::RegisterLocation(EDX))); | 5658 Location::RegisterLocation(EDX))); |
5659 return summary; | 5659 return summary; |
5660 } | 5660 } |
5661 if (kind() == MergedMathInstr::kSinCos) { | |
5662 const intptr_t kNumInputs = 1; | |
5663 const intptr_t kNumTemps = 2; | |
5664 LocationSummary* summary = new (zone) | |
5665 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | |
5666 // Because we always call into the runtime (LocationSummary::kCall) we | |
5667 // must specify each input, temp, and output register explicitly. | |
5668 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); | |
5669 // EDI is chosen because it is callee saved so we do not need to back it | |
5670 // up before calling into the runtime. | |
5671 summary->set_temp(0, Location::RegisterLocation(EDI)); | |
5672 summary->set_temp(1, Location::RegisterLocation(EBX)); | |
5673 summary->set_out(0, Location::Pair(Location::FpuRegisterLocation(XMM2), | |
5674 Location::FpuRegisterLocation(XMM3))); | |
5675 return summary; | |
5676 } | |
5677 UNIMPLEMENTED(); | 5661 UNIMPLEMENTED(); |
5678 return NULL; | 5662 return NULL; |
5679 } | 5663 } |
5680 | 5664 |
5681 | 5665 |
5682 typedef void (*SinCosCFunction)(double x, double* res_sin, double* res_cos); | |
5683 | |
5684 extern const RuntimeEntry kSinCosRuntimeEntry( | |
5685 "libc_sincos", | |
5686 reinterpret_cast<RuntimeFunction>(static_cast<SinCosCFunction>(&SinCos)), | |
5687 1, | |
5688 true, | |
5689 true); | |
5690 | |
5691 | |
5692 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5666 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5693 Label* deopt = NULL; | 5667 Label* deopt = NULL; |
5694 if (CanDeoptimize()) { | 5668 if (CanDeoptimize()) { |
5695 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); | 5669 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
5696 } | 5670 } |
5697 | 5671 |
5698 if (kind() == MergedMathInstr::kTruncDivMod) { | 5672 if (kind() == MergedMathInstr::kTruncDivMod) { |
5699 Register left = locs()->in(0).reg(); | 5673 Register left = locs()->in(0).reg(); |
5700 Register right = locs()->in(1).reg(); | 5674 Register right = locs()->in(1).reg(); |
5701 ASSERT(locs()->out(0).IsPairLocation()); | 5675 ASSERT(locs()->out(0).IsPairLocation()); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5750 } else { | 5724 } else { |
5751 // Right is negative. | 5725 // Right is negative. |
5752 __ subl(EDX, right); | 5726 __ subl(EDX, right); |
5753 } | 5727 } |
5754 __ Bind(&done); | 5728 __ Bind(&done); |
5755 | 5729 |
5756 __ SmiTag(EAX); | 5730 __ SmiTag(EAX); |
5757 __ SmiTag(EDX); | 5731 __ SmiTag(EDX); |
5758 return; | 5732 return; |
5759 } | 5733 } |
5760 | |
5761 if (kind() == MergedMathInstr::kSinCos) { | |
5762 ASSERT(locs()->out(0).IsPairLocation()); | |
5763 PairLocation* pair = locs()->out(0).AsPairLocation(); | |
5764 XmmRegister out1 = pair->At(0).fpu_reg(); | |
5765 XmmRegister out2 = pair->At(1).fpu_reg(); | |
5766 | |
5767 // Save ESP. | |
5768 __ movl(locs()->temp(0).reg(), ESP); | |
5769 // +-------------------------------+ | |
5770 // | double-argument | <- TOS | |
5771 // +-------------------------------+ | |
5772 // | address-cos-result | +8 | |
5773 // +-------------------------------+ | |
5774 // | address-sin-result | +12 | |
5775 // +-------------------------------+ | |
5776 // | double-storage-for-cos-result | +16 | |
5777 // +-------------------------------+ | |
5778 // | double-storage-for-sin-result | +24 | |
5779 // +-------------------------------+ | |
5780 // .... | |
5781 __ ReserveAlignedFrameSpace(kDoubleSize * 3 + kWordSize * 2); | |
5782 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg()); | |
5783 | |
5784 Address cos_result(ESP, 2 * kWordSize + kDoubleSize); | |
5785 Address sin_result(ESP, 2 * kWordSize + 2 * kDoubleSize); | |
5786 | |
5787 // 'cos' result storage address. | |
5788 __ leal(locs()->temp(1).reg(), cos_result); | |
5789 __ movl(Address(ESP, kDoubleSize), locs()->temp(1).reg()); | |
5790 | |
5791 // 'sin' result storage address. | |
5792 __ leal(locs()->temp(1).reg(), sin_result); | |
5793 __ movl(Address(ESP, kDoubleSize + kWordSize), locs()->temp(1).reg()); | |
5794 | |
5795 __ CallRuntime(kSinCosRuntimeEntry, InputCount()); | |
5796 __ movsd(out2, sin_result); // sin. | |
5797 __ movsd(out1, cos_result); // cos. | |
5798 // Restore RSP. | |
5799 __ movl(ESP, locs()->temp(0).reg()); | |
5800 | |
5801 return; | |
5802 } | |
5803 UNIMPLEMENTED(); | 5734 UNIMPLEMENTED(); |
5804 } | 5735 } |
5805 | 5736 |
5806 | 5737 |
5807 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( | 5738 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( |
5808 Zone* zone, | 5739 Zone* zone, |
5809 bool opt) const { | 5740 bool opt) const { |
5810 return MakeCallSummary(zone); | 5741 return MakeCallSummary(zone); |
5811 } | 5742 } |
5812 | 5743 |
(...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6939 __ Drop(1); | 6870 __ Drop(1); |
6940 __ popl(result); | 6871 __ popl(result); |
6941 } | 6872 } |
6942 | 6873 |
6943 | 6874 |
6944 } // namespace dart | 6875 } // namespace dart |
6945 | 6876 |
6946 #undef __ | 6877 #undef __ |
6947 | 6878 |
6948 #endif // defined TARGET_ARCH_IA32 | 6879 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |