Chromium Code Reviews| 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 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 984 | 984 |
| 985 CompileType LoadIndexedInstr::ComputeType() const { | 985 CompileType LoadIndexedInstr::ComputeType() const { |
| 986 switch (class_id_) { | 986 switch (class_id_) { |
| 987 case kArrayCid: | 987 case kArrayCid: |
| 988 case kImmutableArrayCid: | 988 case kImmutableArrayCid: |
| 989 return CompileType::Dynamic(); | 989 return CompileType::Dynamic(); |
| 990 | 990 |
| 991 case kTypedDataFloat32ArrayCid: | 991 case kTypedDataFloat32ArrayCid: |
| 992 case kTypedDataFloat64ArrayCid: | 992 case kTypedDataFloat64ArrayCid: |
| 993 return CompileType::FromCid(kDoubleCid); | 993 return CompileType::FromCid(kDoubleCid); |
| 994 case kTypedDataFloat32x4ArrayCid: | |
| 995 return CompileType::FromCid(kFloat32x4Cid); | |
| 994 | 996 |
| 995 case kTypedDataInt8ArrayCid: | 997 case kTypedDataInt8ArrayCid: |
| 996 case kTypedDataUint8ArrayCid: | 998 case kTypedDataUint8ArrayCid: |
| 997 case kTypedDataUint8ClampedArrayCid: | 999 case kTypedDataUint8ClampedArrayCid: |
| 998 case kExternalTypedDataUint8ArrayCid: | 1000 case kExternalTypedDataUint8ArrayCid: |
| 999 case kExternalTypedDataUint8ClampedArrayCid: | 1001 case kExternalTypedDataUint8ClampedArrayCid: |
| 1000 case kTypedDataInt16ArrayCid: | 1002 case kTypedDataInt16ArrayCid: |
| 1001 case kTypedDataUint16ArrayCid: | 1003 case kTypedDataUint16ArrayCid: |
| 1002 case kOneByteStringCid: | 1004 case kOneByteStringCid: |
| 1003 case kTwoByteStringCid: | 1005 case kTwoByteStringCid: |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1024 case kTypedDataInt16ArrayCid: | 1026 case kTypedDataInt16ArrayCid: |
| 1025 case kTypedDataUint16ArrayCid: | 1027 case kTypedDataUint16ArrayCid: |
| 1026 case kOneByteStringCid: | 1028 case kOneByteStringCid: |
| 1027 case kTwoByteStringCid: | 1029 case kTwoByteStringCid: |
| 1028 case kTypedDataInt32ArrayCid: | 1030 case kTypedDataInt32ArrayCid: |
| 1029 case kTypedDataUint32ArrayCid: | 1031 case kTypedDataUint32ArrayCid: |
| 1030 return kTagged; | 1032 return kTagged; |
| 1031 case kTypedDataFloat32ArrayCid: | 1033 case kTypedDataFloat32ArrayCid: |
| 1032 case kTypedDataFloat64ArrayCid: | 1034 case kTypedDataFloat64ArrayCid: |
| 1033 return kUnboxedDouble; | 1035 return kUnboxedDouble; |
| 1036 case kTypedDataFloat32x4ArrayCid: | |
| 1037 return kUnboxedFloat32x4; | |
| 1034 default: | 1038 default: |
| 1035 UNIMPLEMENTED(); | 1039 UNIMPLEMENTED(); |
| 1036 return kTagged; | 1040 return kTagged; |
| 1037 } | 1041 } |
| 1038 } | 1042 } |
| 1039 | 1043 |
| 1040 | 1044 |
| 1041 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1045 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 1042 const intptr_t kNumInputs = 2; | 1046 const intptr_t kNumInputs = 2; |
| 1043 const intptr_t kNumTemps = 0; | 1047 const intptr_t kNumTemps = 0; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1083 } else { | 1087 } else { |
| 1084 ASSERT(this->array()->definition()->representation() == kTagged); | 1088 ASSERT(this->array()->definition()->representation() == kTagged); |
| 1085 element_address = index.IsRegister() | 1089 element_address = index.IsRegister() |
| 1086 ? FlowGraphCompiler::ElementAddressForRegIndex( | 1090 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1087 class_id(), index_scale(), array, index.reg()) | 1091 class_id(), index_scale(), array, index.reg()) |
| 1088 : FlowGraphCompiler::ElementAddressForIntIndex( | 1092 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1089 class_id(), index_scale(), array, | 1093 class_id(), index_scale(), array, |
| 1090 Smi::Cast(index.constant()).Value()); | 1094 Smi::Cast(index.constant()).Value()); |
| 1091 } | 1095 } |
| 1092 | 1096 |
| 1093 if (representation() == kUnboxedDouble) { | 1097 if ((representation() == kUnboxedDouble) || |
| 1098 (representation() == kUnboxedFloat32x4)) { | |
| 1094 if ((index_scale() == 1) && index.IsRegister()) { | 1099 if ((index_scale() == 1) && index.IsRegister()) { |
| 1095 __ SmiUntag(index.reg()); | 1100 __ SmiUntag(index.reg()); |
| 1096 } | 1101 } |
| 1097 | 1102 |
| 1098 XmmRegister result = locs()->out().fpu_reg(); | 1103 XmmRegister result = locs()->out().fpu_reg(); |
| 1099 if (class_id() == kTypedDataFloat32ArrayCid) { | 1104 if (class_id() == kTypedDataFloat32ArrayCid) { |
| 1100 // Load single precision float. | 1105 // Load single precision float. |
| 1101 __ movss(result, element_address); | 1106 __ movss(result, element_address); |
| 1102 // Promote to double. | 1107 // Promote to double. |
| 1103 __ cvtss2sd(result, locs()->out().fpu_reg()); | 1108 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 1109 } else if (class_id() == kTypedDataFloat64ArrayCid) { | |
| 1110 __ movsd(result, element_address); | |
| 1104 } else { | 1111 } else { |
| 1105 ASSERT(class_id() == kTypedDataFloat64ArrayCid); | 1112 ASSERT(class_id() == kTypedDataFloat32x4ArrayCid); |
| 1106 __ movsd(result, element_address); | 1113 __ movups(result, element_address); |
| 1107 } | 1114 } |
| 1108 return; | 1115 return; |
| 1109 } | 1116 } |
| 1110 | 1117 |
| 1111 if ((index_scale() == 1) && index.IsRegister()) { | 1118 if ((index_scale() == 1) && index.IsRegister()) { |
| 1112 __ SmiUntag(index.reg()); | 1119 __ SmiUntag(index.reg()); |
| 1113 } | 1120 } |
| 1114 Register result = locs()->out().reg(); | 1121 Register result = locs()->out().reg(); |
| 1115 switch (class_id()) { | 1122 switch (class_id()) { |
| 1116 case kTypedDataInt8ArrayCid: | 1123 case kTypedDataInt8ArrayCid: |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1163 case kTypedDataUint8ClampedArrayCid: | 1170 case kTypedDataUint8ClampedArrayCid: |
| 1164 case kExternalTypedDataUint8ClampedArrayCid: | 1171 case kExternalTypedDataUint8ClampedArrayCid: |
| 1165 case kTypedDataInt16ArrayCid: | 1172 case kTypedDataInt16ArrayCid: |
| 1166 case kTypedDataUint16ArrayCid: | 1173 case kTypedDataUint16ArrayCid: |
| 1167 case kTypedDataInt32ArrayCid: | 1174 case kTypedDataInt32ArrayCid: |
| 1168 case kTypedDataUint32ArrayCid: | 1175 case kTypedDataUint32ArrayCid: |
| 1169 return kTagged; | 1176 return kTagged; |
| 1170 case kTypedDataFloat32ArrayCid: | 1177 case kTypedDataFloat32ArrayCid: |
| 1171 case kTypedDataFloat64ArrayCid: | 1178 case kTypedDataFloat64ArrayCid: |
| 1172 return kUnboxedDouble; | 1179 return kUnboxedDouble; |
| 1180 case kTypedDataFloat32x4ArrayCid: | |
| 1181 return kUnboxedFloat32x4; | |
| 1173 default: | 1182 default: |
| 1174 UNIMPLEMENTED(); | 1183 UNIMPLEMENTED(); |
| 1175 return kTagged; | 1184 return kTagged; |
| 1176 } | 1185 } |
| 1177 } | 1186 } |
| 1178 | 1187 |
| 1179 | 1188 |
| 1180 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1189 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 1181 const intptr_t kNumInputs = 3; | 1190 const intptr_t kNumInputs = 3; |
| 1182 const intptr_t kNumTemps = 0; | 1191 const intptr_t kNumTemps = 0; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1219 locs->set_in(2, Location::WritableRegister()); | 1228 locs->set_in(2, Location::WritableRegister()); |
| 1220 break; | 1229 break; |
| 1221 case kTypedDataFloat32ArrayCid: | 1230 case kTypedDataFloat32ArrayCid: |
| 1222 // Need temp register for float-to-double conversion. | 1231 // Need temp register for float-to-double conversion. |
| 1223 locs->AddTemp(Location::RequiresFpuRegister()); | 1232 locs->AddTemp(Location::RequiresFpuRegister()); |
| 1224 // Fall through. | 1233 // Fall through. |
| 1225 case kTypedDataFloat64ArrayCid: | 1234 case kTypedDataFloat64ArrayCid: |
| 1226 // TODO(srdjan): Support Float64 constants. | 1235 // TODO(srdjan): Support Float64 constants. |
| 1227 locs->set_in(2, Location::RequiresFpuRegister()); | 1236 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1228 break; | 1237 break; |
| 1238 case kTypedDataFloat32x4ArrayCid: | |
| 1239 locs->set_in(2, Location::RequiresFpuRegister()); | |
| 1240 break; | |
| 1229 default: | 1241 default: |
| 1230 UNREACHABLE(); | 1242 UNREACHABLE(); |
| 1231 return NULL; | 1243 return NULL; |
| 1232 } | 1244 } |
| 1233 return locs; | 1245 return locs; |
| 1234 } | 1246 } |
| 1235 | 1247 |
| 1236 | 1248 |
| 1237 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1249 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1238 Register array = locs()->in(0).reg(); | 1250 Register array = locs()->in(0).reg(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1332 } | 1344 } |
| 1333 case kTypedDataFloat32ArrayCid: | 1345 case kTypedDataFloat32ArrayCid: |
| 1334 // Convert to single precision. | 1346 // Convert to single precision. |
| 1335 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); | 1347 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
| 1336 // Store. | 1348 // Store. |
| 1337 __ movss(element_address, locs()->temp(0).fpu_reg()); | 1349 __ movss(element_address, locs()->temp(0).fpu_reg()); |
| 1338 break; | 1350 break; |
| 1339 case kTypedDataFloat64ArrayCid: | 1351 case kTypedDataFloat64ArrayCid: |
| 1340 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1352 __ movsd(element_address, locs()->in(2).fpu_reg()); |
| 1341 break; | 1353 break; |
| 1354 case kTypedDataFloat32x4ArrayCid: | |
| 1355 __ movups(element_address, locs()->in(2).fpu_reg()); | |
| 1356 break; | |
| 1342 default: | 1357 default: |
| 1343 UNREACHABLE(); | 1358 UNREACHABLE(); |
| 1344 } | 1359 } |
| 1345 } | 1360 } |
| 1346 | 1361 |
| 1347 | 1362 |
| 1348 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1363 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { |
| 1349 const intptr_t kNumInputs = 1; | 1364 const intptr_t kNumInputs = 1; |
| 1350 LocationSummary* summary = | 1365 LocationSummary* summary = |
| 1351 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); | 1366 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); |
| (...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2552 __ movsd(result, FieldAddress(value, Double::value_offset())); | 2567 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 2553 __ jmp(&done); | 2568 __ jmp(&done); |
| 2554 __ Bind(&is_smi); | 2569 __ Bind(&is_smi); |
| 2555 __ SmiUntag(value); | 2570 __ SmiUntag(value); |
| 2556 __ cvtsi2sd(result, value); | 2571 __ cvtsi2sd(result, value); |
| 2557 __ Bind(&done); | 2572 __ Bind(&done); |
| 2558 } | 2573 } |
| 2559 } | 2574 } |
| 2560 | 2575 |
| 2561 | 2576 |
| 2577 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary() const { | |
| 2578 const intptr_t kNumInputs = 1; | |
| 2579 const intptr_t kNumTemps = 0; | |
| 2580 LocationSummary* summary = | |
| 2581 new LocationSummary(kNumInputs, | |
| 2582 kNumTemps, | |
| 2583 LocationSummary::kCallOnSlowPath); | |
| 2584 summary->set_in(0, Location::RequiresFpuRegister()); | |
| 2585 summary->set_out(Location::RequiresRegister()); | |
| 2586 return summary; | |
| 2587 } | |
| 2588 | |
| 2589 | |
| 2590 class BoxFloat32x4SlowPath : public SlowPathCode { | |
| 2591 public: | |
| 2592 explicit BoxFloat32x4SlowPath(BoxFloat32x4Instr* instruction) | |
| 2593 : instruction_(instruction) { } | |
| 2594 | |
| 2595 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 2596 __ Comment("BoxFloat32x4SlowPath"); | |
| 2597 __ Bind(entry_label()); | |
| 2598 const Class& float32x4_class = compiler->float32x4_class(); | |
| 2599 const Code& stub = | |
| 2600 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class)); | |
| 2601 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint()); | |
| 2602 | |
| 2603 LocationSummary* locs = instruction_->locs(); | |
| 2604 locs->live_registers()->Remove(locs->out()); | |
| 2605 | |
| 2606 compiler->SaveLiveRegisters(locs); | |
| 2607 compiler->GenerateCall(instruction_->token_pos(), | |
| 2608 &label, | |
| 2609 PcDescriptors::kOther, | |
| 2610 locs); | |
| 2611 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX); | |
|
srdjan
2013/04/10 15:33:23
ditto
Cutch
2013/04/10 16:36:13
Done.
| |
| 2612 compiler->RestoreLiveRegisters(locs); | |
| 2613 | |
| 2614 __ jmp(exit_label()); | |
| 2615 } | |
| 2616 | |
| 2617 private: | |
| 2618 BoxFloat32x4Instr* instruction_; | |
| 2619 }; | |
| 2620 | |
| 2621 | |
| 2622 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 2623 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); | |
| 2624 compiler->AddSlowPathCode(slow_path); | |
| 2625 | |
| 2626 Register out_reg = locs()->out().reg(); | |
| 2627 XmmRegister value = locs()->in(0).fpu_reg(); | |
| 2628 | |
| 2629 __ TryAllocate(compiler->float32x4_class(), | |
| 2630 slow_path->entry_label(), | |
| 2631 Assembler::kFarJump, | |
| 2632 out_reg); | |
| 2633 __ Bind(slow_path->exit_label()); | |
| 2634 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); | |
| 2635 } | |
| 2636 | |
| 2637 | |
| 2638 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { | |
| 2639 const intptr_t kNumInputs = 1; | |
| 2640 const intptr_t kNumTemps = 0; | |
| 2641 LocationSummary* summary = | |
| 2642 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 2643 summary->set_in(0, Location::RequiresRegister()); | |
| 2644 summary->set_out(Location::RequiresFpuRegister()); | |
| 2645 return summary; | |
| 2646 } | |
| 2647 | |
| 2648 | |
| 2649 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 2650 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 2651 const Register value = locs()->in(0).reg(); | |
| 2652 const XmmRegister result = locs()->out().fpu_reg(); | |
| 2653 | |
| 2654 if (value_cid == kFloat32x4Cid) { | |
| 2655 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | |
| 2656 } else { | |
| 2657 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | |
| 2658 __ CompareClassId(value, kFloat32x4Cid); | |
| 2659 __ j(NOT_EQUAL, deopt); | |
| 2660 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | |
| 2661 } | |
| 2662 } | |
| 2663 | |
| 2664 | |
| 2562 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 2665 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { |
| 2563 const intptr_t kNumInputs = 2; | 2666 const intptr_t kNumInputs = 2; |
| 2564 const intptr_t kNumTemps = 0; | 2667 const intptr_t kNumTemps = 0; |
| 2565 LocationSummary* summary = | 2668 LocationSummary* summary = |
| 2566 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2669 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2567 summary->set_in(0, Location::RequiresFpuRegister()); | 2670 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2568 summary->set_in(1, Location::RequiresFpuRegister()); | 2671 summary->set_in(1, Location::RequiresFpuRegister()); |
| 2569 summary->set_out(Location::SameAsFirstInput()); | 2672 summary->set_out(Location::SameAsFirstInput()); |
| 2570 return summary; | 2673 return summary; |
| 2571 } | 2674 } |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3356 PcDescriptors::kOther, | 3459 PcDescriptors::kOther, |
| 3357 locs()); | 3460 locs()); |
| 3358 __ Drop(2); // Discard type arguments and receiver. | 3461 __ Drop(2); // Discard type arguments and receiver. |
| 3359 } | 3462 } |
| 3360 | 3463 |
| 3361 } // namespace dart | 3464 } // namespace dart |
| 3362 | 3465 |
| 3363 #undef __ | 3466 #undef __ |
| 3364 | 3467 |
| 3365 #endif // defined TARGET_ARCH_X64 | 3468 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |