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 "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 const intptr_t kNumInputs = 0; | 246 const intptr_t kNumInputs = 0; |
247 const intptr_t kNumTemps = 0; | 247 const intptr_t kNumTemps = 0; |
248 LocationSummary* locs = new(isolate) LocationSummary( | 248 LocationSummary* locs = new(isolate) LocationSummary( |
249 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 249 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
250 locs->set_out(0, Location::RequiresFpuRegister()); | 250 locs->set_out(0, Location::RequiresFpuRegister()); |
251 return locs; | 251 return locs; |
252 } | 252 } |
253 | 253 |
254 | 254 |
255 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 255 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 256 ASSERT(representation_ == kUnboxedDouble); |
256 // The register allocator drops constant definitions that have no uses. | 257 // The register allocator drops constant definitions that have no uses. |
257 if (!locs()->out(0).IsInvalid()) { | 258 if (!locs()->out(0).IsInvalid()) { |
258 XmmRegister result = locs()->out(0).fpu_reg(); | 259 XmmRegister result = locs()->out(0).fpu_reg(); |
259 if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) { | 260 if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) { |
260 __ xorps(result, result); | 261 __ xorps(result, result); |
261 } else { | 262 } else { |
262 __ LoadObject(TMP, value(), PP); | 263 __ LoadObject(TMP, value(), PP); |
263 __ movsd(result, FieldAddress(TMP, Double::value_offset())); | 264 __ movsd(result, FieldAddress(TMP, Double::value_offset())); |
264 } | 265 } |
265 } | 266 } |
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 bool opt) const { | 964 bool opt) const { |
964 const intptr_t kNumInputs = 2; | 965 const intptr_t kNumInputs = 2; |
965 const intptr_t kNumTemps = 0; | 966 const intptr_t kNumTemps = 0; |
966 LocationSummary* locs = new(isolate) LocationSummary( | 967 LocationSummary* locs = new(isolate) LocationSummary( |
967 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 968 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
968 locs->set_in(0, Location::RequiresRegister()); | 969 locs->set_in(0, Location::RequiresRegister()); |
969 // The smi index is either untagged (element size == 1), or it is left smi | 970 // The smi index is either untagged (element size == 1), or it is left smi |
970 // tagged (for all element sizes > 1). | 971 // tagged (for all element sizes > 1). |
971 if (index_scale() == 1) { | 972 if (index_scale() == 1) { |
972 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 973 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
973 ? Location::Constant( | 974 ? Location::Constant(index()->definition()->AsConstant()) |
974 index()->definition()->AsConstant()->value()) | |
975 : Location::WritableRegister()); | 975 : Location::WritableRegister()); |
976 } else { | 976 } else { |
977 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 977 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
978 ? Location::Constant( | 978 ? Location::Constant(index()->definition()->AsConstant()) |
979 index()->definition()->AsConstant()->value()) | |
980 : Location::RequiresRegister()); | 979 : Location::RequiresRegister()); |
981 } | 980 } |
982 if ((representation() == kUnboxedDouble) || | 981 if ((representation() == kUnboxedDouble) || |
983 (representation() == kUnboxedFloat32x4) || | 982 (representation() == kUnboxedFloat32x4) || |
984 (representation() == kUnboxedInt32x4) || | 983 (representation() == kUnboxedInt32x4) || |
985 (representation() == kUnboxedFloat64x2)) { | 984 (representation() == kUnboxedFloat64x2)) { |
986 locs->set_out(0, Location::RequiresFpuRegister()); | 985 locs->set_out(0, Location::RequiresFpuRegister()); |
987 } else { | 986 } else { |
988 locs->set_out(0, Location::RequiresRegister()); | 987 locs->set_out(0, Location::RequiresRegister()); |
989 } | 988 } |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1106 bool opt) const { | 1105 bool opt) const { |
1107 const intptr_t kNumInputs = 3; | 1106 const intptr_t kNumInputs = 3; |
1108 const intptr_t kNumTemps = 0; | 1107 const intptr_t kNumTemps = 0; |
1109 LocationSummary* locs = new(isolate) LocationSummary( | 1108 LocationSummary* locs = new(isolate) LocationSummary( |
1110 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1109 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1111 locs->set_in(0, Location::RequiresRegister()); | 1110 locs->set_in(0, Location::RequiresRegister()); |
1112 // The smi index is either untagged (element size == 1), or it is left smi | 1111 // The smi index is either untagged (element size == 1), or it is left smi |
1113 // tagged (for all element sizes > 1). | 1112 // tagged (for all element sizes > 1). |
1114 if (index_scale() == 1) { | 1113 if (index_scale() == 1) { |
1115 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 1114 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
1116 ? Location::Constant( | 1115 ? Location::Constant(index()->definition()->AsConstant()) |
1117 index()->definition()->AsConstant()->value()) | |
1118 : Location::WritableRegister()); | 1116 : Location::WritableRegister()); |
1119 } else { | 1117 } else { |
1120 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 1118 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
1121 ? Location::Constant( | 1119 ? Location::Constant(index()->definition()->AsConstant()) |
1122 index()->definition()->AsConstant()->value()) | |
1123 : Location::RequiresRegister()); | 1120 : Location::RequiresRegister()); |
1124 } | 1121 } |
1125 switch (class_id()) { | 1122 switch (class_id()) { |
1126 case kArrayCid: | 1123 case kArrayCid: |
1127 locs->set_in(2, ShouldEmitStoreBarrier() | 1124 locs->set_in(2, ShouldEmitStoreBarrier() |
1128 ? Location::WritableRegister() | 1125 ? Location::WritableRegister() |
1129 : Location::RegisterOrConstant(value())); | 1126 : Location::RegisterOrConstant(value())); |
1130 break; | 1127 break; |
1131 case kExternalTypedDataUint8ArrayCid: | 1128 case kExternalTypedDataUint8ArrayCid: |
1132 case kExternalTypedDataUint8ClampedArrayCid: | 1129 case kExternalTypedDataUint8ClampedArrayCid: |
(...skipping 1513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2646 if ((right_constant != NULL) && | 2643 if ((right_constant != NULL) && |
2647 (op_kind() != Token::kTRUNCDIV) && | 2644 (op_kind() != Token::kTRUNCDIV) && |
2648 (op_kind() != Token::kSHL) && | 2645 (op_kind() != Token::kSHL) && |
2649 (op_kind() != Token::kMUL) && | 2646 (op_kind() != Token::kMUL) && |
2650 (op_kind() != Token::kMOD) && | 2647 (op_kind() != Token::kMOD) && |
2651 CanBeImmediate(right_constant->value())) { | 2648 CanBeImmediate(right_constant->value())) { |
2652 const intptr_t kNumTemps = 0; | 2649 const intptr_t kNumTemps = 0; |
2653 LocationSummary* summary = new(isolate) LocationSummary( | 2650 LocationSummary* summary = new(isolate) LocationSummary( |
2654 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2651 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2655 summary->set_in(0, Location::RequiresRegister()); | 2652 summary->set_in(0, Location::RequiresRegister()); |
2656 summary->set_in(1, Location::Constant(right_constant->value())); | 2653 summary->set_in(1, Location::Constant(right_constant)); |
2657 summary->set_out(0, Location::SameAsFirstInput()); | 2654 summary->set_out(0, Location::SameAsFirstInput()); |
2658 return summary; | 2655 return summary; |
2659 } | 2656 } |
2660 | 2657 |
2661 if (op_kind() == Token::kTRUNCDIV) { | 2658 if (op_kind() == Token::kTRUNCDIV) { |
2662 const intptr_t kNumTemps = 1; | 2659 const intptr_t kNumTemps = 1; |
2663 LocationSummary* summary = new(isolate) LocationSummary( | 2660 LocationSummary* summary = new(isolate) LocationSummary( |
2664 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2661 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2665 if (RightIsPowerOfTwoConstant()) { | 2662 if (RightIsPowerOfTwoConstant()) { |
2666 summary->set_in(0, Location::RequiresRegister()); | 2663 summary->set_in(0, Location::RequiresRegister()); |
2667 ConstantInstr* right_constant = right()->definition()->AsConstant(); | 2664 ConstantInstr* right_constant = right()->definition()->AsConstant(); |
2668 summary->set_in(1, Location::Constant(right_constant->value())); | 2665 summary->set_in(1, Location::Constant(right_constant)); |
2669 summary->set_temp(0, Location::RequiresRegister()); | 2666 summary->set_temp(0, Location::RequiresRegister()); |
2670 summary->set_out(0, Location::SameAsFirstInput()); | 2667 summary->set_out(0, Location::SameAsFirstInput()); |
2671 } else { | 2668 } else { |
2672 // Both inputs must be writable because they will be untagged. | 2669 // Both inputs must be writable because they will be untagged. |
2673 summary->set_in(0, Location::RegisterLocation(RAX)); | 2670 summary->set_in(0, Location::RegisterLocation(RAX)); |
2674 summary->set_in(1, Location::WritableRegister()); | 2671 summary->set_in(1, Location::WritableRegister()); |
2675 summary->set_out(0, Location::SameAsFirstInput()); | 2672 summary->set_out(0, Location::SameAsFirstInput()); |
2676 // Will be used for sign extension and division. | 2673 // Will be used for sign extension and division. |
2677 summary->set_temp(0, Location::RegisterLocation(RDX)); | 2674 summary->set_temp(0, Location::RegisterLocation(RDX)); |
2678 } | 2675 } |
(...skipping 1939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4618 __ cmpq(left, right); | 4615 __ cmpq(left, right); |
4619 ASSERT(result == left); | 4616 ASSERT(result == left); |
4620 if (is_min) { | 4617 if (is_min) { |
4621 __ cmovgeq(result, right); | 4618 __ cmovgeq(result, right); |
4622 } else { | 4619 } else { |
4623 __ cmovlessq(result, right); | 4620 __ cmovlessq(result, right); |
4624 } | 4621 } |
4625 } | 4622 } |
4626 | 4623 |
4627 | 4624 |
| 4625 DEFINE_UNIMPLEMENTED_INSTRUCTION(Int32ToDoubleInstr) |
| 4626 |
| 4627 |
4628 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate, | 4628 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate, |
4629 bool opt) const { | 4629 bool opt) const { |
4630 const intptr_t kNumInputs = 1; | 4630 const intptr_t kNumInputs = 1; |
4631 const intptr_t kNumTemps = 0; | 4631 const intptr_t kNumTemps = 0; |
4632 LocationSummary* result = new(isolate) LocationSummary( | 4632 LocationSummary* result = new(isolate) LocationSummary( |
4633 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4633 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4634 result->set_in(0, Location::WritableRegister()); | 4634 result->set_in(0, Location::WritableRegister()); |
4635 result->set_out(0, Location::RequiresFpuRegister()); | 4635 result->set_out(0, Location::RequiresFpuRegister()); |
4636 return result; | 4636 return result; |
4637 } | 4637 } |
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5505 CompileType ShiftUint32OpInstr::ComputeType() const { | 5505 CompileType ShiftUint32OpInstr::ComputeType() const { |
5506 return CompileType::FromCid(kSmiCid); | 5506 return CompileType::FromCid(kSmiCid); |
5507 } | 5507 } |
5508 | 5508 |
5509 | 5509 |
5510 CompileType UnaryUint32OpInstr::ComputeType() const { | 5510 CompileType UnaryUint32OpInstr::ComputeType() const { |
5511 return CompileType::FromCid(kSmiCid); | 5511 return CompileType::FromCid(kSmiCid); |
5512 } | 5512 } |
5513 | 5513 |
5514 | 5514 |
5515 CompileType BoxUint32Instr::ComputeType() const { | 5515 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr) |
5516 return CompileType::FromCid(kSmiCid); | 5516 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr) |
5517 } | 5517 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr) |
5518 | 5518 DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxInt32Instr) |
5519 | 5519 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnboxInt32Instr) |
5520 CompileType UnboxUint32Instr::ComputeType() const { | 5520 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) |
5521 return CompileType::FromCid(kSmiCid); | 5521 DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxUint32Instr) |
5522 } | 5522 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnboxedIntConverterInstr) |
5523 | |
5524 | |
5525 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, | |
5526 bool opt) const { | |
5527 UNIMPLEMENTED(); | |
5528 return NULL; | |
5529 } | |
5530 | |
5531 | |
5532 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
5533 UNIMPLEMENTED(); | |
5534 } | |
5535 | |
5536 | |
5537 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, | |
5538 bool opt) const { | |
5539 UNIMPLEMENTED(); | |
5540 return NULL; | |
5541 } | |
5542 | |
5543 | |
5544 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
5545 UNIMPLEMENTED(); | |
5546 } | |
5547 | |
5548 | |
5549 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, | |
5550 bool opt) const { | |
5551 UNIMPLEMENTED(); | |
5552 return NULL; | |
5553 } | |
5554 | |
5555 | |
5556 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
5557 UNIMPLEMENTED(); | |
5558 } | |
5559 | 5523 |
5560 | 5524 |
5561 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, | 5525 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, |
5562 bool opt) const { | 5526 bool opt) const { |
5563 const intptr_t kNumInputs = 1; | 5527 const intptr_t kNumInputs = 1; |
5564 const intptr_t kNumTemps = 0; | 5528 const intptr_t kNumTemps = 0; |
5565 LocationSummary* summary = new(isolate) LocationSummary( | 5529 LocationSummary* summary = new(isolate) LocationSummary( |
5566 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5530 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5567 summary->set_in(0, Location::RequiresRegister()); | 5531 summary->set_in(0, Location::RequiresRegister()); |
5568 summary->set_out(0, Location::SameAsFirstInput()); | 5532 summary->set_out(0, Location::SameAsFirstInput()); |
(...skipping 11 matching lines...) Expand all Loading... |
5580 } else { | 5544 } else { |
5581 Label* deopt = compiler->AddDeoptStub(deopt_id_, | 5545 Label* deopt = compiler->AddDeoptStub(deopt_id_, |
5582 ICData::kDeoptUnboxInteger); | 5546 ICData::kDeoptUnboxInteger); |
5583 __ testq(value, Immediate(kSmiTagMask)); | 5547 __ testq(value, Immediate(kSmiTagMask)); |
5584 __ j(NOT_ZERO, deopt); | 5548 __ j(NOT_ZERO, deopt); |
5585 __ SmiUntag(value); | 5549 __ SmiUntag(value); |
5586 } | 5550 } |
5587 } | 5551 } |
5588 | 5552 |
5589 | 5553 |
5590 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate, | |
5591 bool opt) const { | |
5592 UNIMPLEMENTED(); | |
5593 return NULL; | |
5594 } | |
5595 | |
5596 | |
5597 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
5598 UNIMPLEMENTED(); | |
5599 } | |
5600 | |
5601 | |
5602 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | |
5603 bool opt) const { | |
5604 UNIMPLEMENTED(); | |
5605 return NULL; | |
5606 } | |
5607 | |
5608 | |
5609 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
5610 UNIMPLEMENTED(); | |
5611 } | |
5612 | |
5613 | |
5614 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, | 5554 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, |
5615 bool opt) const { | 5555 bool opt) const { |
5616 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); | 5556 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); |
5617 } | 5557 } |
5618 | 5558 |
5619 | 5559 |
5620 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5560 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5621 compiler->GenerateRuntimeCall(token_pos(), | 5561 compiler->GenerateRuntimeCall(token_pos(), |
5622 deopt_id(), | 5562 deopt_id(), |
5623 kThrowRuntimeEntry, | 5563 kThrowRuntimeEntry, |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5899 __ movq(R10, Immediate(kInvalidObjectPointer)); | 5839 __ movq(R10, Immediate(kInvalidObjectPointer)); |
5900 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 5840 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
5901 #endif | 5841 #endif |
5902 } | 5842 } |
5903 | 5843 |
5904 } // namespace dart | 5844 } // namespace dart |
5905 | 5845 |
5906 #undef __ | 5846 #undef __ |
5907 | 5847 |
5908 #endif // defined TARGET_ARCH_X64 | 5848 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |