| 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/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 5523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5534 // Both inputs must be writable because they will be untagged. | 5534 // Both inputs must be writable because they will be untagged. |
| 5535 summary->set_in(0, Location::RegisterLocation(EAX)); | 5535 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 5536 summary->set_in(1, Location::WritableRegister()); | 5536 summary->set_in(1, Location::WritableRegister()); |
| 5537 // Output is a pair of registers. | 5537 // Output is a pair of registers. |
| 5538 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), | 5538 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), |
| 5539 Location::RegisterLocation(EDX))); | 5539 Location::RegisterLocation(EDX))); |
| 5540 return summary; | 5540 return summary; |
| 5541 } | 5541 } |
| 5542 if (kind() == MergedMathInstr::kSinCos) { | 5542 if (kind() == MergedMathInstr::kSinCos) { |
| 5543 const intptr_t kNumInputs = 1; | 5543 const intptr_t kNumInputs = 1; |
| 5544 const intptr_t kNumTemps = 0; | 5544 const intptr_t kNumTemps = 2; |
| 5545 LocationSummary* summary = new(zone) LocationSummary( | 5545 LocationSummary* summary = new(zone) LocationSummary( |
| 5546 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5546 zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
| 5547 summary->set_in(0, Location::RequiresFpuRegister()); | 5547 // Because we always call into the runtime (LocationSummary::kCall) we |
| 5548 summary->set_out(0, Location::Pair(Location::RequiresFpuRegister(), | 5548 // must specify each input, temp, and output register explicitly. |
| 5549 Location::RequiresFpuRegister())); | 5549 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); |
| 5550 // EDI is chosen because it is callee saved so we do not need to back it |
| 5551 // up before calling into the runtime. |
| 5552 summary->set_temp(0, Location::RegisterLocation(EDI)); |
| 5553 summary->set_temp(1, Location::RegisterLocation(EBX)); |
| 5554 summary->set_out(0, Location::Pair(Location::FpuRegisterLocation(XMM2), |
| 5555 Location::FpuRegisterLocation(XMM3))); |
| 5550 return summary; | 5556 return summary; |
| 5551 } | 5557 } |
| 5552 UNIMPLEMENTED(); | 5558 UNIMPLEMENTED(); |
| 5553 return NULL; | 5559 return NULL; |
| 5554 } | 5560 } |
| 5555 | 5561 |
| 5556 | 5562 |
| 5557 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); | 5563 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); |
| 5558 | 5564 |
| 5559 extern const RuntimeEntry kSinCosRuntimeEntry( | 5565 extern const RuntimeEntry kSinCosRuntimeEntry( |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5624 __ subl(EDX, right); | 5630 __ subl(EDX, right); |
| 5625 } | 5631 } |
| 5626 __ Bind(&done); | 5632 __ Bind(&done); |
| 5627 | 5633 |
| 5628 __ SmiTag(EAX); | 5634 __ SmiTag(EAX); |
| 5629 __ SmiTag(EDX); | 5635 __ SmiTag(EDX); |
| 5630 return; | 5636 return; |
| 5631 } | 5637 } |
| 5632 | 5638 |
| 5633 if (kind() == MergedMathInstr::kSinCos) { | 5639 if (kind() == MergedMathInstr::kSinCos) { |
| 5634 XmmRegister in = locs()->in(0).fpu_reg(); | |
| 5635 ASSERT(locs()->out(0).IsPairLocation()); | 5640 ASSERT(locs()->out(0).IsPairLocation()); |
| 5636 PairLocation* pair = locs()->out(0).AsPairLocation(); | 5641 PairLocation* pair = locs()->out(0).AsPairLocation(); |
| 5637 XmmRegister out1 = pair->At(0).fpu_reg(); | 5642 XmmRegister out1 = pair->At(0).fpu_reg(); |
| 5638 XmmRegister out2 = pair->At(1).fpu_reg(); | 5643 XmmRegister out2 = pair->At(1).fpu_reg(); |
| 5639 | 5644 |
| 5640 // Do x87 sincos, since the ia32 compilers may not fuse sin/cos into | 5645 // Save ESP. |
| 5641 // sincos. | 5646 __ movl(locs()->temp(0).reg(), ESP); |
| 5642 __ pushl(EAX); | 5647 // +-------------------------------+ |
| 5643 __ pushl(EAX); | 5648 // | double-argument | <- TOS |
| 5644 __ movsd(Address(ESP, 0), in); | 5649 // +-------------------------------+ |
| 5645 __ fldl(Address(ESP, 0)); | 5650 // | address-cos-result | +8 |
| 5646 __ fsincos(); | 5651 // +-------------------------------+ |
| 5647 __ fstpl(Address(ESP, 0)); | 5652 // | address-sin-result | +12 |
| 5648 __ movsd(out1, Address(ESP, 0)); | 5653 // +-------------------------------+ |
| 5649 __ fstpl(Address(ESP, 0)); | 5654 // | double-storage-for-cos-result | +16 |
| 5650 __ movsd(out2, Address(ESP, 0)); | 5655 // +-------------------------------+ |
| 5651 __ addl(ESP, Immediate(2 * kWordSize)); | 5656 // | double-storage-for-sin-result | +24 |
| 5657 // +-------------------------------+ |
| 5658 // .... |
| 5659 __ ReserveAlignedFrameSpace(kDoubleSize * 3 + kWordSize * 2); |
| 5660 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg()); |
| 5661 |
| 5662 Address cos_result(ESP, 2 * kWordSize + kDoubleSize); |
| 5663 Address sin_result(ESP, 2 * kWordSize + 2 * kDoubleSize); |
| 5664 |
| 5665 // 'cos' result storage address. |
| 5666 __ leal(locs()->temp(1).reg(), cos_result); |
| 5667 __ movl(Address(ESP, kDoubleSize), locs()->temp(1).reg()); |
| 5668 |
| 5669 // 'sin' result storage address. |
| 5670 __ leal(locs()->temp(1).reg(), sin_result); |
| 5671 __ movl(Address(ESP, kDoubleSize + kWordSize), locs()->temp(1).reg()); |
| 5672 |
| 5673 __ CallRuntime(kSinCosRuntimeEntry, InputCount()); |
| 5674 __ movsd(out2, sin_result); // sin. |
| 5675 __ movsd(out1, cos_result); // cos. |
| 5676 // Restore RSP. |
| 5677 __ movl(ESP, locs()->temp(0).reg()); |
| 5678 |
| 5652 return; | 5679 return; |
| 5653 } | 5680 } |
| 5654 | |
| 5655 UNIMPLEMENTED(); | 5681 UNIMPLEMENTED(); |
| 5656 } | 5682 } |
| 5657 | 5683 |
| 5658 | 5684 |
| 5659 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( | 5685 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( |
| 5660 Zone* zone, bool opt) const { | 5686 Zone* zone, bool opt) const { |
| 5661 return MakeCallSummary(zone); | 5687 return MakeCallSummary(zone); |
| 5662 } | 5688 } |
| 5663 | 5689 |
| 5664 | 5690 |
| (...skipping 1183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6848 __ Drop(1); | 6874 __ Drop(1); |
| 6849 __ popl(result); | 6875 __ popl(result); |
| 6850 } | 6876 } |
| 6851 | 6877 |
| 6852 | 6878 |
| 6853 } // namespace dart | 6879 } // namespace dart |
| 6854 | 6880 |
| 6855 #undef __ | 6881 #undef __ |
| 6856 | 6882 |
| 6857 #endif // defined TARGET_ARCH_IA32 | 6883 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |