Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(424)

Side by Side Diff: runtime/vm/intermediate_language_x64.cc

Issue 180243013: Stop creating dummy call frames when calling out to C functions (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 3962 matching lines...) Expand 10 before | Expand all | Expand 10 after
3973 3973
3974 3974
3975 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { 3975 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const {
3976 if ((kind() == MethodRecognizer::kMathSin) || 3976 if ((kind() == MethodRecognizer::kMathSin) ||
3977 (kind() == MethodRecognizer::kMathCos)) { 3977 (kind() == MethodRecognizer::kMathCos)) {
3978 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two 3978 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two
3979 // double arguments and XMM0 to return the result. Unfortunately 3979 // double arguments and XMM0 to return the result. Unfortunately
3980 // currently we can't specify these registers because ParallelMoveResolver 3980 // currently we can't specify these registers because ParallelMoveResolver
3981 // assumes that XMM0 is free at all times. 3981 // assumes that XMM0 is free at all times.
3982 // TODO(vegorov): allow XMM0 to be used. 3982 // TODO(vegorov): allow XMM0 to be used.
3983 const intptr_t kNumTemps = 0; 3983 const intptr_t kNumTemps = 1;
3984 LocationSummary* summary = 3984 LocationSummary* summary =
3985 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 3985 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
3986 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 3986 summary->set_in(0, Location::FpuRegisterLocation(XMM1));
3987 summary->set_temp(0, Location::RegisterLocation(CALLEE_SAVED));
regis 2014/02/26 23:53:12 ditto
Cutch 2014/02/27 15:52:37 Done.
3987 summary->set_out(Location::FpuRegisterLocation(XMM1)); 3988 summary->set_out(Location::FpuRegisterLocation(XMM1));
3988 return summary; 3989 return summary;
3989 } 3990 }
3991 ASSERT(kind() == MethodRecognizer::kMathSqrt);
3990 const intptr_t kNumInputs = 1; 3992 const intptr_t kNumInputs = 1;
3991 const intptr_t kNumTemps = 0; 3993 const intptr_t kNumTemps = 0;
3992 LocationSummary* summary = 3994 LocationSummary* summary =
3993 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3995 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3994 summary->set_in(0, Location::RequiresFpuRegister()); 3996 summary->set_in(0, Location::RequiresFpuRegister());
3995 summary->set_out(Location::RequiresFpuRegister()); 3997 summary->set_out(Location::RequiresFpuRegister());
3996 return summary; 3998 return summary;
3997 } 3999 }
3998 4000
3999 4001
4000 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4002 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4001 if (kind() == MethodRecognizer::kMathSqrt) { 4003 if (kind() == MethodRecognizer::kMathSqrt) {
4002 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); 4004 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg());
4003 } else { 4005 } else {
4004 __ EnterFrame(0); 4006 ASSERT((kind() == MethodRecognizer::kMathSin) ||
4007 (kind() == MethodRecognizer::kMathCos));
4008 // Save RSP.
4009 __ movq(locs()->temp(0).reg(), RSP);
4005 __ ReserveAlignedFrameSpace(0); 4010 __ ReserveAlignedFrameSpace(0);
4006 __ movaps(XMM0, locs()->in(0).fpu_reg()); 4011 __ movaps(XMM0, locs()->in(0).fpu_reg());
4007 __ CallRuntime(TargetFunction(), InputCount()); 4012 __ CallRuntime(TargetFunction(), InputCount());
4008 __ movaps(locs()->out().fpu_reg(), XMM0); 4013 __ movaps(locs()->out().fpu_reg(), XMM0);
4009 __ leave(); 4014 // Restore RSP.
4015 __ movq(RSP, locs()->temp(0).reg());
4010 } 4016 }
4011 } 4017 }
4012 4018
4013 4019
4014 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { 4020 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const {
4015 const intptr_t kNumInputs = 1; 4021 const intptr_t kNumInputs = 1;
4016 return LocationSummary::Make(kNumInputs, 4022 return LocationSummary::Make(kNumInputs,
4017 Location::SameAsFirstInput(), 4023 Location::SameAsFirstInput(),
4018 LocationSummary::kNoCall); 4024 LocationSummary::kNoCall);
4019 } 4025 }
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
4315 } 4321 }
4316 4322
4317 4323
4318 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { 4324 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
4319 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two 4325 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two
4320 // double arguments and XMM0 to return the result. Unfortunately 4326 // double arguments and XMM0 to return the result. Unfortunately
4321 // currently we can't specify these registers because ParallelMoveResolver 4327 // currently we can't specify these registers because ParallelMoveResolver
4322 // assumes that XMM0 is free at all times. 4328 // assumes that XMM0 is free at all times.
4323 // TODO(vegorov): allow XMM0 to be used. 4329 // TODO(vegorov): allow XMM0 to be used.
4324 ASSERT((InputCount() == 1) || (InputCount() == 2)); 4330 ASSERT((InputCount() == 1) || (InputCount() == 2));
4325 const intptr_t kNumTemps = 0; 4331 const intptr_t kNumTemps = 1;
4326 LocationSummary* result = 4332 LocationSummary* result =
4327 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 4333 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
4334 result->set_temp(0, Location::RegisterLocation(CALLEE_SAVED));
4328 result->set_in(0, Location::FpuRegisterLocation(XMM2)); 4335 result->set_in(0, Location::FpuRegisterLocation(XMM2));
4329 if (InputCount() == 2) { 4336 if (InputCount() == 2) {
4330 result->set_in(1, Location::FpuRegisterLocation(XMM1)); 4337 result->set_in(1, Location::FpuRegisterLocation(XMM1));
4331 } 4338 }
4332 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4339 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4333 result->AddTemp(Location::RegisterLocation(RAX)); 4340 result->AddTemp(Location::RegisterLocation(RAX));
4334 result->AddTemp(Location::FpuRegisterLocation(XMM4)); 4341 result->AddTemp(Location::FpuRegisterLocation(XMM4));
4335 } 4342 }
4336 result->set_out(Location::FpuRegisterLocation(XMM3)); 4343 result->set_out(Location::FpuRegisterLocation(XMM3));
4337 return result; 4344 return result;
4338 } 4345 }
4339 4346
4340 4347
4341 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4348 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4342 __ EnterFrame(0); 4349 // Save RSP.
4350 __ movq(locs()->temp(0).reg(), RSP);
4343 __ ReserveAlignedFrameSpace(0); 4351 __ ReserveAlignedFrameSpace(0);
4344 __ movaps(XMM0, locs()->in(0).fpu_reg()); 4352 __ movaps(XMM0, locs()->in(0).fpu_reg());
4345 if (InputCount() == 2) { 4353 if (InputCount() == 2) {
4346 ASSERT(locs()->in(1).fpu_reg() == XMM1); 4354 ASSERT(locs()->in(1).fpu_reg() == XMM1);
4347 } 4355 }
4348 // For pow-function return NaN if exponent is NaN. 4356 // For pow-function return NaN if exponent is NaN.
4349 Label do_call, skip_call; 4357 Label do_call, skip_call;
4350 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4358 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4351 // Pseudo code: 4359 // Pseudo code:
4352 // if (exponent == 0.0) return 0.0; 4360 // if (exponent == 0.0) return 0.0;
4353 // if (base == 1.0) return 1.0; 4361 // if (base == 1.0) return 1.0;
4354 // if (base.isNaN || exponent.isNaN) { 4362 // if (base.isNaN || exponent.isNaN) {
4355 // return double.NAN; 4363 // return double.NAN;
4356 // } 4364 // }
4357 XmmRegister base = locs()->in(0).fpu_reg(); 4365 XmmRegister base = locs()->in(0).fpu_reg();
4358 XmmRegister exp = locs()->in(1).fpu_reg(); 4366 XmmRegister exp = locs()->in(1).fpu_reg();
4359 XmmRegister result = locs()->out().fpu_reg(); 4367 XmmRegister result = locs()->out().fpu_reg();
4360 Register temp = locs()->temp(0).reg(); 4368 Register temp = locs()->temp(0).reg();
siva 2014/02/27 00:00:26 Ditto comment about the temp index. I am wondering
Cutch 2014/02/27 15:52:37 Added index constants to instruction.
4361 XmmRegister zero_temp = locs()->temp(1).fpu_reg(); 4369 XmmRegister zero_temp = locs()->temp(1).fpu_reg();
4362 4370
4363 // Check if exponent is 0.0 -> return 1.0; 4371 // Check if exponent is 0.0 -> return 1.0;
4364 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)), PP); 4372 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)), PP);
4365 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset())); 4373 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset()));
4366 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)), PP); 4374 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)), PP);
4367 __ movsd(result, FieldAddress(temp, Double::value_offset())); 4375 __ movsd(result, FieldAddress(temp, Double::value_offset()));
4368 // 'result' contains 1.0. 4376 // 'result' contains 1.0.
4369 Label exp_is_nan; 4377 Label exp_is_nan;
4370 __ comisd(exp, zero_temp); 4378 __ comisd(exp, zero_temp);
(...skipping 17 matching lines...) Expand all
4388 __ comisd(base, result); 4396 __ comisd(base, result);
4389 __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump); 4397 __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump);
4390 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0 4398 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0
4391 __ movsd(result, exp); // result is NaN 4399 __ movsd(result, exp); // result is NaN
4392 __ jmp(&skip_call, Assembler::kNearJump); 4400 __ jmp(&skip_call, Assembler::kNearJump);
4393 } 4401 }
4394 __ Bind(&do_call); 4402 __ Bind(&do_call);
4395 __ CallRuntime(TargetFunction(), InputCount()); 4403 __ CallRuntime(TargetFunction(), InputCount());
4396 __ movaps(locs()->out().fpu_reg(), XMM0); 4404 __ movaps(locs()->out().fpu_reg(), XMM0);
4397 __ Bind(&skip_call); 4405 __ Bind(&skip_call);
4398 __ leave(); 4406 // Restore RSP.
4407 __ movq(RSP, locs()->temp(0).reg());
4399 } 4408 }
4400 4409
4401 4410
4402 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { 4411 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
4403 if (kind() == MergedMathInstr::kTruncDivMod) { 4412 if (kind() == MergedMathInstr::kTruncDivMod) {
4404 const intptr_t kNumInputs = 2; 4413 const intptr_t kNumInputs = 2;
4405 const intptr_t kNumTemps = 1; 4414 const intptr_t kNumTemps = 1;
4406 LocationSummary* summary = 4415 LocationSummary* summary =
4407 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4416 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4408 // Both inputs must be writable because they will be untagged. 4417 // Both inputs must be writable because they will be untagged.
4409 summary->set_in(0, Location::RegisterLocation(RAX)); 4418 summary->set_in(0, Location::RegisterLocation(RAX));
4410 summary->set_in(1, Location::WritableRegister()); 4419 summary->set_in(1, Location::WritableRegister());
4411 summary->set_out(Location::RequiresRegister()); 4420 summary->set_out(Location::RequiresRegister());
4412 // Will be used for sign extension and division. 4421 // Will be used for sign extension and division.
4413 summary->set_temp(0, Location::RegisterLocation(RDX)); 4422 summary->set_temp(0, Location::RegisterLocation(RDX));
4414 return summary; 4423 return summary;
4415 } 4424 }
4416 if (kind() == MergedMathInstr::kSinCos) { 4425 if (kind() == MergedMathInstr::kSinCos) {
4417 const intptr_t kNumInputs = 1; 4426 const intptr_t kNumInputs = 1;
4418 const intptr_t kNumTemps = 0; 4427 const intptr_t kNumTemps = 1;
4419 LocationSummary* summary = 4428 LocationSummary* summary =
4420 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4429 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4421 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 4430 summary->set_in(0, Location::FpuRegisterLocation(XMM1));
4431 summary->set_temp(0, Location::RegisterLocation(CALLEE_SAVED));
4422 summary->set_out(Location::RegisterLocation(RAX)); 4432 summary->set_out(Location::RegisterLocation(RAX));
4423 return summary; 4433 return summary;
4424 } 4434 }
4425 UNIMPLEMENTED(); 4435 UNIMPLEMENTED();
4426 return NULL; 4436 return NULL;
4427 } 4437 }
4428 4438
4429 4439
4430 4440
4431 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); 4441 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
4534 __ SmiTag(RAX); 4544 __ SmiTag(RAX);
4535 __ SmiTag(RDX); 4545 __ SmiTag(RDX);
4536 __ StoreIntoObjectNoBarrier(result, trunc_div_address, RAX); 4546 __ StoreIntoObjectNoBarrier(result, trunc_div_address, RAX);
4537 __ StoreIntoObjectNoBarrier(result, mod_address, RDX); 4547 __ StoreIntoObjectNoBarrier(result, mod_address, RDX);
4538 // FLAG_throw_on_javascript_int_overflow: not needed. 4548 // FLAG_throw_on_javascript_int_overflow: not needed.
4539 // Note that the result of an integer division/modulo of two 4549 // Note that the result of an integer division/modulo of two
4540 // in-range arguments, cannot create out-of-range result. 4550 // in-range arguments, cannot create out-of-range result.
4541 return; 4551 return;
4542 } 4552 }
4543 if (kind() == MergedMathInstr::kSinCos) { 4553 if (kind() == MergedMathInstr::kSinCos) {
4544 __ EnterFrame(0); 4554 // Save RSP.
4555 __ movq(locs()->temp(0).reg(), RSP);
4545 // +-------------------------------+ 4556 // +-------------------------------+
4546 // | double-argument | <- TOS 4557 // | double-argument | <- TOS
4547 // +-------------------------------+ 4558 // +-------------------------------+
4548 // | address-cos-result | +8 4559 // | address-cos-result | +8
4549 // +-------------------------------+ 4560 // +-------------------------------+
4550 // | address-sin-result | +16 4561 // | address-sin-result | +16
4551 // +-------------------------------+ 4562 // +-------------------------------+
4552 // | double-storage-for-cos-result | +24 4563 // | double-storage-for-cos-result | +24
4553 // +-------------------------------+ 4564 // +-------------------------------+
4554 // | double-storage-for-sin-result | +32 4565 // | double-storage-for-sin-result | +32
4555 // +-------------------------------+ 4566 // +-------------------------------+
4556 // .... 4567 // ....
4557 __ ReserveAlignedFrameSpace(kDoubleSize * 3 + kWordSize * 2); 4568 __ ReserveAlignedFrameSpace(kDoubleSize * 3 + kWordSize * 2);
4558 __ movsd(Address(RSP, 0), locs()->in(0).fpu_reg()); 4569 __ movsd(Address(RSP, 0), locs()->in(0).fpu_reg());
4559 4570
4560 __ leaq(RDI, Address(RSP, 2 * kWordSize + kDoubleSize)); 4571 __ leaq(RDI, Address(RSP, 2 * kWordSize + kDoubleSize));
4561 __ leaq(RSI, Address(RSP, 2 * kWordSize + 2 * kDoubleSize)); 4572 __ leaq(RSI, Address(RSP, 2 * kWordSize + 2 * kDoubleSize));
4562 __ movaps(XMM0, locs()->in(0).fpu_reg()); 4573 __ movaps(XMM0, locs()->in(0).fpu_reg());
4563 4574
4564 __ CallRuntime(kSinCosRuntimeEntry, InputCount()); 4575 __ CallRuntime(kSinCosRuntimeEntry, InputCount());
4565 __ movsd(XMM0, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin. 4576 __ movsd(XMM0, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin.
4566 __ movsd(XMM1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos. 4577 __ movsd(XMM1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos.
4567 __ leave(); 4578 // Restore RSP.
4579 __ movq(RSP, locs()->temp(0).reg());
4568 4580
4569 Register result = locs()->out().reg(); 4581 Register result = locs()->out().reg();
4570 const TypedData& res_array = TypedData::ZoneHandle( 4582 const TypedData& res_array = TypedData::ZoneHandle(
4571 TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld)); 4583 TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld));
4572 __ LoadObject(result, res_array, PP); 4584 __ LoadObject(result, res_array, PP);
4573 const intptr_t index_scale = 4585 const intptr_t index_scale =
4574 FlowGraphCompiler::ElementSizeFor(kTypedDataFloat64ArrayCid); 4586 FlowGraphCompiler::ElementSizeFor(kTypedDataFloat64ArrayCid);
4575 Address sin_address( 4587 Address sin_address(
4576 FlowGraphCompiler::ElementAddressForIntIndex( 4588 FlowGraphCompiler::ElementAddressForIntIndex(
4577 kTypedDataFloat64ArrayCid, index_scale, result, 4589 kTypedDataFloat64ArrayCid, index_scale, result,
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
5090 PcDescriptors::kOther, 5102 PcDescriptors::kOther,
5091 locs()); 5103 locs());
5092 __ Drop(2); // Discard type arguments and receiver. 5104 __ Drop(2); // Discard type arguments and receiver.
5093 } 5105 }
5094 5106
5095 } // namespace dart 5107 } // namespace dart
5096 5108
5097 #undef __ 5109 #undef __
5098 5110
5099 #endif // defined TARGET_ARCH_X64 5111 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698