| 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 2403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2414 } | 2414 } |
| 2415 } | 2415 } |
| 2416 | 2416 |
| 2417 | 2417 |
| 2418 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { | 2418 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { |
| 2419 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two | 2419 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two |
| 2420 // double arguments and XMM0 to return the result. Unfortunately | 2420 // double arguments and XMM0 to return the result. Unfortunately |
| 2421 // currently we can't specify these registers because ParallelMoveResolver | 2421 // currently we can't specify these registers because ParallelMoveResolver |
| 2422 // assumes that XMM0 is free at all times. | 2422 // assumes that XMM0 is free at all times. |
| 2423 // TODO(vegorov): allow XMM0 to be used. | 2423 // TODO(vegorov): allow XMM0 to be used. |
| 2424 if (recognized_kind() == MethodRecognizer::kDoubleMod) { |
| 2425 ASSERT(InputCount() == 2); |
| 2426 const intptr_t kNumTemps = 2; |
| 2427 LocationSummary* result = |
| 2428 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
| 2429 result->set_in(0, Location::FpuRegisterLocation(XMM1, Location::kDouble)); |
| 2430 result->set_in(1, Location::FpuRegisterLocation(XMM2, Location::kDouble)); |
| 2431 result->set_out(Location::FpuRegisterLocation(XMM1, Location::kDouble)); |
| 2432 result->set_temp(0, Location::FpuRegisterLocation(XMM2, Location::kDouble)); |
| 2433 result->set_temp(1, Location::FpuRegisterLocation(XMM3, Location::kDouble)); |
| 2434 return result; |
| 2435 } |
| 2424 ASSERT((InputCount() == 1) || (InputCount() == 2)); | 2436 ASSERT((InputCount() == 1) || (InputCount() == 2)); |
| 2425 const intptr_t kNumTemps = 0; | 2437 const intptr_t kNumTemps = 0; |
| 2426 LocationSummary* result = | 2438 LocationSummary* result = |
| 2427 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 2439 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
| 2428 result->set_in(0, Location::FpuRegisterLocation(XMM1, Location::kDouble)); | 2440 result->set_in(0, Location::FpuRegisterLocation(XMM1, Location::kDouble)); |
| 2429 if (InputCount() == 2) { | 2441 if (InputCount() == 2) { |
| 2430 result->set_in(1, Location::FpuRegisterLocation(XMM2, Location::kDouble)); | 2442 result->set_in(1, Location::FpuRegisterLocation(XMM2, Location::kDouble)); |
| 2431 } | 2443 } |
| 2432 result->set_out(Location::FpuRegisterLocation(XMM1, Location::kDouble)); | 2444 result->set_out(Location::FpuRegisterLocation(XMM1, Location::kDouble)); |
| 2433 return result; | 2445 return result; |
| 2434 } | 2446 } |
| 2435 | 2447 |
| 2436 | 2448 |
| 2437 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2449 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2450 if (recognized_kind() == MethodRecognizer::kDoubleMod) { |
| 2451 // Preserve right argument. |
| 2452 __ pushq(RAX); |
| 2453 __ movsd(Address(RSP, 0), locs()->in(1).fpu_reg()); |
| 2454 } |
| 2455 |
| 2438 ASSERT(locs()->in(0).fpu_reg() == XMM1); | 2456 ASSERT(locs()->in(0).fpu_reg() == XMM1); |
| 2439 __ EnterFrame(0); | 2457 __ EnterFrame(0); |
| 2440 __ ReserveAlignedFrameSpace(0); | 2458 __ ReserveAlignedFrameSpace(0); |
| 2441 __ movaps(XMM0, locs()->in(0).fpu_reg()); | 2459 __ movaps(XMM0, locs()->in(0).fpu_reg()); |
| 2442 if (InputCount() == 2) { | 2460 if (InputCount() == 2) { |
| 2443 ASSERT(locs()->in(1).fpu_reg() == XMM2); | 2461 ASSERT(locs()->in(1).fpu_reg() == XMM2); |
| 2444 __ movaps(XMM1, locs()->in(1).fpu_reg()); | 2462 __ movaps(XMM1, locs()->in(1).fpu_reg()); |
| 2445 } | 2463 } |
| 2446 __ CallRuntime(TargetFunction()); | 2464 __ CallRuntime(TargetFunction()); |
| 2447 __ movaps(locs()->out().fpu_reg(), XMM0); | 2465 __ movaps(locs()->out().fpu_reg(), XMM0); |
| 2448 __ leave(); | 2466 __ leave(); |
| 2467 |
| 2468 if (recognized_kind() == MethodRecognizer::kDoubleMod) { |
| 2469 // Result of C call is remainder, convert it to modulo. |
| 2470 Label done, equal_zero, right_greater_equal_zero; |
| 2471 XmmRegister remainder = locs()->out().fpu_reg(); |
| 2472 XmmRegister zero_temp = locs()->temp(0).fpu_reg(); |
| 2473 XmmRegister right_temp = locs()->temp(1).fpu_reg(); |
| 2474 |
| 2475 __ xorpd(zero_temp, zero_temp); // 0.0 -> 'temp'. |
| 2476 __ comisd(remainder, zero_temp); |
| 2477 __ j(PARITY_EVEN, &done, Assembler::kNearJump); // NaN -> false; |
| 2478 __ j(EQUAL, &equal_zero, Assembler::kNearJump); |
| 2479 __ j(ABOVE, &done, Assembler::kNearJump); // (remainder) > 0 -> done. |
| 2480 // remainder < 0. |
| 2481 // Load preserved right argument. |
| 2482 __ movsd(right_temp, Address(RSP, 0)); |
| 2483 __ comisd(right_temp, zero_temp); |
| 2484 __ j(ABOVE_EQUAL, &right_greater_equal_zero, Assembler::kNearJump); |
| 2485 // right < 0. |
| 2486 __ subsd(remainder, right_temp); |
| 2487 __ jmp(&done, Assembler::kNearJump); |
| 2488 |
| 2489 __ Bind(&right_greater_equal_zero); |
| 2490 __ addsd(remainder, right_temp); |
| 2491 __ jmp(&done); |
| 2492 |
| 2493 __ Bind(&equal_zero); |
| 2494 // Switch to the positive 0.0 (just in case it was negative). |
| 2495 __ movsd(remainder, zero_temp); |
| 2496 |
| 2497 __ Bind(&done); |
| 2498 __ Drop(1); // Remove preserved right argument. |
| 2499 } |
| 2449 } | 2500 } |
| 2450 | 2501 |
| 2451 | 2502 |
| 2452 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 2503 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
| 2453 return MakeCallSummary(); | 2504 return MakeCallSummary(); |
| 2454 } | 2505 } |
| 2455 | 2506 |
| 2456 | 2507 |
| 2457 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2508 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2458 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 2509 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2994 PcDescriptors::kOther, | 3045 PcDescriptors::kOther, |
| 2995 locs()); | 3046 locs()); |
| 2996 __ Drop(2); // Discard type arguments and receiver. | 3047 __ Drop(2); // Discard type arguments and receiver. |
| 2997 } | 3048 } |
| 2998 | 3049 |
| 2999 } // namespace dart | 3050 } // namespace dart |
| 3000 | 3051 |
| 3001 #undef __ | 3052 #undef __ |
| 3002 | 3053 |
| 3003 #endif // defined TARGET_ARCH_X64 | 3054 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |