| 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 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 case kTypedDataInt16ArrayCid: | 1129 case kTypedDataInt16ArrayCid: |
| 1130 __ movsxw(result, element_address); | 1130 __ movsxw(result, element_address); |
| 1131 __ SmiTag(result); | 1131 __ SmiTag(result); |
| 1132 break; | 1132 break; |
| 1133 case kTypedDataUint16ArrayCid: | 1133 case kTypedDataUint16ArrayCid: |
| 1134 case kTwoByteStringCid: | 1134 case kTwoByteStringCid: |
| 1135 __ movzxw(result, element_address); | 1135 __ movzxw(result, element_address); |
| 1136 __ SmiTag(result); | 1136 __ SmiTag(result); |
| 1137 break; | 1137 break; |
| 1138 case kTypedDataInt32ArrayCid: | 1138 case kTypedDataInt32ArrayCid: |
| 1139 __ movsxl(result, element_address); | 1139 __ movsxd(result, element_address); |
| 1140 __ SmiTag(result); | 1140 __ SmiTag(result); |
| 1141 break; | 1141 break; |
| 1142 case kTypedDataUint32ArrayCid: | 1142 case kTypedDataUint32ArrayCid: |
| 1143 __ movl(result, element_address); | 1143 __ movl(result, element_address); |
| 1144 __ SmiTag(result); | 1144 __ SmiTag(result); |
| 1145 break; | 1145 break; |
| 1146 default: | 1146 default: |
| 1147 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1147 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1148 __ movq(result, element_address); | 1148 __ movq(result, element_address); |
| 1149 break; | 1149 break; |
| (...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2321 // No overflow check. | 2321 // No overflow check. |
| 2322 __ orq(left, right); | 2322 __ orq(left, right); |
| 2323 break; | 2323 break; |
| 2324 } | 2324 } |
| 2325 case Token::kBIT_XOR: { | 2325 case Token::kBIT_XOR: { |
| 2326 // No overflow check. | 2326 // No overflow check. |
| 2327 __ xorq(left, right); | 2327 __ xorq(left, right); |
| 2328 break; | 2328 break; |
| 2329 } | 2329 } |
| 2330 case Token::kTRUNCDIV: { | 2330 case Token::kTRUNCDIV: { |
| 2331 Label not_32bit, done; |
| 2332 |
| 2333 Register temp = locs()->temp(0).reg(); |
| 2334 ASSERT(left == RAX); |
| 2335 ASSERT((right != RDX) && (right != RAX)); |
| 2336 ASSERT(temp == RDX); |
| 2337 ASSERT(result == RAX); |
| 2338 |
| 2331 // Handle divide by zero in runtime. | 2339 // Handle divide by zero in runtime. |
| 2332 __ testq(right, right); | 2340 __ testq(right, right); |
| 2333 __ j(ZERO, deopt); | 2341 __ j(ZERO, deopt); |
| 2334 ASSERT(left == RAX); | 2342 |
| 2335 ASSERT((right != RDX) && (right != RAX)); | 2343 // Check if both operands fit into 32bits as idiv with 64bit operands |
| 2336 ASSERT(locs()->temp(0).reg() == RDX); | 2344 // requires twice as many cycles and has much higher latency. |
| 2337 ASSERT(result == RAX); | 2345 // We are checking this before untagging them to avoid corner case |
| 2346 // dividing INT_MAX by -1 that raises exception because quotient is |
| 2347 // too large for 32bit register. |
| 2348 __ movsxd(temp, left); |
| 2349 __ cmpq(temp, left); |
| 2350 __ j(NOT_EQUAL, ¬_32bit); |
| 2351 __ movsxd(temp, right); |
| 2352 __ cmpq(temp, right); |
| 2353 __ j(NOT_EQUAL, ¬_32bit); |
| 2354 |
| 2355 // Both operands are 31bit smis. Divide using 32bit idiv. |
| 2356 __ SmiUntag(left); |
| 2357 __ SmiUntag(right); |
| 2358 __ cdq(); |
| 2359 __ idivl(right); |
| 2360 __ movsxd(result, result); |
| 2361 __ jmp(&done); |
| 2362 |
| 2363 // Divide using 64bit idiv. |
| 2364 __ Bind(¬_32bit); |
| 2338 __ SmiUntag(left); | 2365 __ SmiUntag(left); |
| 2339 __ SmiUntag(right); | 2366 __ SmiUntag(right); |
| 2340 __ cqo(); // Sign extend RAX -> RDX:RAX. | 2367 __ cqo(); // Sign extend RAX -> RDX:RAX. |
| 2341 __ idivq(right); // RAX: quotient, RDX: remainder. | 2368 __ idivq(right); // RAX: quotient, RDX: remainder. |
| 2342 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 2369 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 2343 // case we cannot tag the result. | 2370 // case we cannot tag the result. |
| 2344 __ cmpq(result, Immediate(0x4000000000000000)); | 2371 __ cmpq(result, Immediate(0x4000000000000000)); |
| 2345 __ j(EQUAL, deopt); | 2372 __ j(EQUAL, deopt); |
| 2373 __ Bind(&done); |
| 2346 __ SmiTag(result); | 2374 __ SmiTag(result); |
| 2347 break; | 2375 break; |
| 2348 } | 2376 } |
| 2349 case Token::kSHR: { | 2377 case Token::kSHR: { |
| 2350 if (CanDeoptimize()) { | 2378 if (CanDeoptimize()) { |
| 2351 __ cmpq(right, Immediate(0)); | 2379 __ cmpq(right, Immediate(0)); |
| 2352 __ j(LESS, deopt); | 2380 __ j(LESS, deopt); |
| 2353 } | 2381 } |
| 2354 __ SmiUntag(right); | 2382 __ SmiUntag(right); |
| 2355 // sarq operation masks the count to 6 bits. | 2383 // sarq operation masks the count to 6 bits. |
| (...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3329 PcDescriptors::kOther, | 3357 PcDescriptors::kOther, |
| 3330 locs()); | 3358 locs()); |
| 3331 __ Drop(2); // Discard type arguments and receiver. | 3359 __ Drop(2); // Discard type arguments and receiver. |
| 3332 } | 3360 } |
| 3333 | 3361 |
| 3334 } // namespace dart | 3362 } // namespace dart |
| 3335 | 3363 |
| 3336 #undef __ | 3364 #undef __ |
| 3337 | 3365 |
| 3338 #endif // defined TARGET_ARCH_X64 | 3366 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |