| 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_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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1695 const intptr_t kNumTemps = 0; | 1695 const intptr_t kNumTemps = 0; |
| 1696 LocationSummary* summary = | 1696 LocationSummary* summary = |
| 1697 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1697 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1698 summary->set_in(0, Location::RequiresRegister()); | 1698 summary->set_in(0, Location::RequiresRegister()); |
| 1699 summary->set_in(1, Location::Constant(right_constant->value())); | 1699 summary->set_in(1, Location::Constant(right_constant->value())); |
| 1700 summary->set_out(Location::SameAsFirstInput()); | 1700 summary->set_out(Location::SameAsFirstInput()); |
| 1701 return summary; | 1701 return summary; |
| 1702 } | 1702 } |
| 1703 | 1703 |
| 1704 if (op_kind() == Token::kTRUNCDIV) { | 1704 if (op_kind() == Token::kTRUNCDIV) { |
| 1705 const intptr_t kNumTemps = 3; | 1705 const intptr_t kNumTemps = 1; |
| 1706 LocationSummary* summary = | 1706 LocationSummary* summary = |
| 1707 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1707 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1708 // Both inputs must be writable because they will be untagged. |
| 1708 summary->set_in(0, Location::RegisterLocation(RAX)); | 1709 summary->set_in(0, Location::RegisterLocation(RAX)); |
| 1709 summary->set_in(1, Location::RegisterLocation(RCX)); | 1710 summary->set_in(1, Location::WritableRegister()); |
| 1710 summary->set_out(Location::SameAsFirstInput()); | 1711 summary->set_out(Location::SameAsFirstInput()); |
| 1711 summary->set_temp(0, Location::RegisterLocation(RBX)); | 1712 // Will be used for sign extension and division. |
| 1712 // Will be used for for sign extension. | 1713 summary->set_temp(0, Location::RegisterLocation(RDX)); |
| 1713 summary->set_temp(1, Location::RegisterLocation(RDX)); | |
| 1714 summary->set_temp(2, Location::RequiresRegister()); | |
| 1715 return summary; | 1714 return summary; |
| 1716 } else if (op_kind() == Token::kSHR) { | 1715 } else if (op_kind() == Token::kSHR) { |
| 1717 const intptr_t kNumTemps = 0; | 1716 const intptr_t kNumTemps = 0; |
| 1718 LocationSummary* summary = | 1717 LocationSummary* summary = |
| 1719 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1718 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1720 summary->set_in(0, Location::RequiresRegister()); | 1719 summary->set_in(0, Location::RequiresRegister()); |
| 1721 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX)); | 1720 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX)); |
| 1722 summary->set_out(Location::SameAsFirstInput()); | 1721 summary->set_out(Location::SameAsFirstInput()); |
| 1723 return summary; | 1722 return summary; |
| 1724 } else if (op_kind() == Token::kSHL) { | 1723 } else if (op_kind() == Token::kSHL) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1868 // No overflow check. | 1867 // No overflow check. |
| 1869 __ orq(left, right); | 1868 __ orq(left, right); |
| 1870 break; | 1869 break; |
| 1871 } | 1870 } |
| 1872 case Token::kBIT_XOR: { | 1871 case Token::kBIT_XOR: { |
| 1873 // No overflow check. | 1872 // No overflow check. |
| 1874 __ xorq(left, right); | 1873 __ xorq(left, right); |
| 1875 break; | 1874 break; |
| 1876 } | 1875 } |
| 1877 case Token::kTRUNCDIV: { | 1876 case Token::kTRUNCDIV: { |
| 1878 Register temp = locs()->temp(0).reg(); | |
| 1879 // Handle divide by zero in runtime. | 1877 // Handle divide by zero in runtime. |
| 1880 // Deoptimization requires that temp and right are preserved. | |
| 1881 __ testq(right, right); | 1878 __ testq(right, right); |
| 1882 __ j(ZERO, deopt); | 1879 __ j(ZERO, deopt); |
| 1883 ASSERT(left == RAX); | 1880 ASSERT(left == RAX); |
| 1884 ASSERT((right != RDX) && (right != RAX)); | 1881 ASSERT((right != RDX) && (right != RAX)); |
| 1885 ASSERT((temp != RDX) && (temp != RAX)); | 1882 ASSERT(locs()->temp(0).reg() == RDX); |
| 1886 ASSERT(locs()->temp(1).reg() == RDX); | |
| 1887 ASSERT(result == RAX); | 1883 ASSERT(result == RAX); |
| 1888 Register right_temp = locs()->temp(2).reg(); | |
| 1889 __ movq(right_temp, right); | |
| 1890 __ SmiUntag(left); | 1884 __ SmiUntag(left); |
| 1891 __ SmiUntag(right_temp); | 1885 __ SmiUntag(right); |
| 1892 __ cqo(); // Sign extend RAX -> RDX:RAX. | 1886 __ cqo(); // Sign extend RAX -> RDX:RAX. |
| 1893 __ idivq(right_temp); // RAX: quotient, RDX: remainder. | 1887 __ idivq(right); // RAX: quotient, RDX: remainder. |
| 1894 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 1888 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 1895 // case we cannot tag the result. | 1889 // case we cannot tag the result. |
| 1896 __ cmpq(result, Immediate(0x4000000000000000)); | 1890 __ cmpq(result, Immediate(0x4000000000000000)); |
| 1897 __ j(EQUAL, deopt); | 1891 __ j(EQUAL, deopt); |
| 1898 __ SmiTag(result); | 1892 __ SmiTag(result); |
| 1899 break; | 1893 break; |
| 1900 } | 1894 } |
| 1901 case Token::kSHR: { | 1895 case Token::kSHR: { |
| 1902 if (CanDeoptimize()) { | 1896 if (CanDeoptimize()) { |
| 1903 __ cmpq(right, Immediate(0)); | 1897 __ cmpq(right, Immediate(0)); |
| (...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2859 PcDescriptors::kOther, | 2853 PcDescriptors::kOther, |
| 2860 locs()); | 2854 locs()); |
| 2861 __ Drop(2); // Discard type arguments and receiver. | 2855 __ Drop(2); // Discard type arguments and receiver. |
| 2862 } | 2856 } |
| 2863 | 2857 |
| 2864 } // namespace dart | 2858 } // namespace dart |
| 2865 | 2859 |
| 2866 #undef __ | 2860 #undef __ |
| 2867 | 2861 |
| 2868 #endif // defined TARGET_ARCH_X64 | 2862 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |