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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1117 | 1117 |
| 1118 CompileType LoadIndexedInstr::ComputeType() const { | 1118 CompileType LoadIndexedInstr::ComputeType() const { |
| 1119 switch (class_id_) { | 1119 switch (class_id_) { |
| 1120 case kArrayCid: | 1120 case kArrayCid: |
| 1121 case kImmutableArrayCid: | 1121 case kImmutableArrayCid: |
| 1122 return CompileType::Dynamic(); | 1122 return CompileType::Dynamic(); |
| 1123 | 1123 |
| 1124 case kTypedDataFloat32ArrayCid: | 1124 case kTypedDataFloat32ArrayCid: |
| 1125 case kTypedDataFloat64ArrayCid: | 1125 case kTypedDataFloat64ArrayCid: |
| 1126 return CompileType::FromCid(kDoubleCid); | 1126 return CompileType::FromCid(kDoubleCid); |
| 1127 case kTypedDataFloat32x4ArrayCid: | |
| 1128 return CompileType::FromCid(kFloat32x4Cid); | |
| 1127 | 1129 |
| 1128 case kTypedDataInt8ArrayCid: | 1130 case kTypedDataInt8ArrayCid: |
| 1129 case kTypedDataUint8ArrayCid: | 1131 case kTypedDataUint8ArrayCid: |
| 1130 case kTypedDataUint8ClampedArrayCid: | 1132 case kTypedDataUint8ClampedArrayCid: |
| 1131 case kExternalTypedDataUint8ArrayCid: | 1133 case kExternalTypedDataUint8ArrayCid: |
| 1132 case kExternalTypedDataUint8ClampedArrayCid: | 1134 case kExternalTypedDataUint8ClampedArrayCid: |
| 1133 case kTypedDataInt16ArrayCid: | 1135 case kTypedDataInt16ArrayCid: |
| 1134 case kTypedDataUint16ArrayCid: | 1136 case kTypedDataUint16ArrayCid: |
| 1135 case kOneByteStringCid: | 1137 case kOneByteStringCid: |
| 1136 case kTwoByteStringCid: | 1138 case kTwoByteStringCid: |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1166 case kTwoByteStringCid: | 1168 case kTwoByteStringCid: |
| 1167 return kTagged; | 1169 return kTagged; |
| 1168 case kTypedDataInt32ArrayCid: | 1170 case kTypedDataInt32ArrayCid: |
| 1169 case kTypedDataUint32ArrayCid: | 1171 case kTypedDataUint32ArrayCid: |
| 1170 // Instruction can deoptimize if we optimistically assumed that the result | 1172 // Instruction can deoptimize if we optimistically assumed that the result |
| 1171 // fits into Smi. | 1173 // fits into Smi. |
| 1172 return CanDeoptimize() ? kTagged : kUnboxedMint; | 1174 return CanDeoptimize() ? kTagged : kUnboxedMint; |
| 1173 case kTypedDataFloat32ArrayCid: | 1175 case kTypedDataFloat32ArrayCid: |
| 1174 case kTypedDataFloat64ArrayCid: | 1176 case kTypedDataFloat64ArrayCid: |
| 1175 return kUnboxedDouble; | 1177 return kUnboxedDouble; |
| 1178 case kTypedDataFloat32x4ArrayCid: | |
| 1179 return kUnboxedFloat32x4; | |
| 1176 default: | 1180 default: |
| 1177 UNIMPLEMENTED(); | 1181 UNIMPLEMENTED(); |
| 1178 return kTagged; | 1182 return kTagged; |
| 1179 } | 1183 } |
| 1180 } | 1184 } |
| 1181 | 1185 |
| 1182 | 1186 |
| 1183 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1187 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 1184 const intptr_t kNumInputs = 2; | 1188 const intptr_t kNumInputs = 2; |
| 1185 const intptr_t kNumTemps = 0; | 1189 const intptr_t kNumTemps = 0; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1223 ASSERT(this->array()->definition()->representation() == kTagged); | 1227 ASSERT(this->array()->definition()->representation() == kTagged); |
| 1224 element_address = index.IsRegister() | 1228 element_address = index.IsRegister() |
| 1225 ? FlowGraphCompiler::ElementAddressForRegIndex( | 1229 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1226 class_id(), index_scale(), array, index.reg()) | 1230 class_id(), index_scale(), array, index.reg()) |
| 1227 : FlowGraphCompiler::ElementAddressForIntIndex( | 1231 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1228 class_id(), index_scale(), array, | 1232 class_id(), index_scale(), array, |
| 1229 Smi::Cast(index.constant()).Value()); | 1233 Smi::Cast(index.constant()).Value()); |
| 1230 } | 1234 } |
| 1231 | 1235 |
| 1232 if ((representation() == kUnboxedDouble) || | 1236 if ((representation() == kUnboxedDouble) || |
| 1233 (representation() == kUnboxedMint)) { | 1237 (representation() == kUnboxedMint) || |
| 1238 (representation() == kUnboxedFloat32x4)) { | |
| 1234 XmmRegister result = locs()->out().fpu_reg(); | 1239 XmmRegister result = locs()->out().fpu_reg(); |
| 1235 if ((index_scale() == 1) && index.IsRegister()) { | 1240 if ((index_scale() == 1) && index.IsRegister()) { |
| 1236 __ SmiUntag(index.reg()); | 1241 __ SmiUntag(index.reg()); |
| 1237 } | 1242 } |
| 1238 switch (class_id()) { | 1243 switch (class_id()) { |
| 1239 case kTypedDataInt32ArrayCid: | 1244 case kTypedDataInt32ArrayCid: |
| 1240 __ movss(result, element_address); | 1245 __ movss(result, element_address); |
| 1241 __ pmovsxdq(result, result); | 1246 __ pmovsxdq(result, result); |
| 1242 break; | 1247 break; |
| 1243 case kTypedDataUint32ArrayCid: | 1248 case kTypedDataUint32ArrayCid: |
| 1244 __ xorpd(result, result); | 1249 __ xorpd(result, result); |
| 1245 __ movss(result, element_address); | 1250 __ movss(result, element_address); |
| 1246 break; | 1251 break; |
| 1247 case kTypedDataFloat32ArrayCid: | 1252 case kTypedDataFloat32ArrayCid: |
| 1248 // Load single precision float and promote to double. | 1253 // Load single precision float and promote to double. |
| 1249 __ movss(result, element_address); | 1254 __ movss(result, element_address); |
| 1250 __ cvtss2sd(result, locs()->out().fpu_reg()); | 1255 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 1251 break; | 1256 break; |
| 1252 case kTypedDataFloat64ArrayCid: | 1257 case kTypedDataFloat64ArrayCid: |
| 1253 __ movsd(result, element_address); | 1258 __ movsd(result, element_address); |
| 1254 break; | 1259 break; |
| 1260 case kTypedDataFloat32x4ArrayCid: | |
| 1261 __ movups(result, element_address); | |
| 1262 break; | |
| 1255 } | 1263 } |
| 1256 return; | 1264 return; |
| 1257 } | 1265 } |
| 1258 | 1266 |
| 1259 Register result = locs()->out().reg(); | 1267 Register result = locs()->out().reg(); |
| 1260 if ((index_scale() == 1) && index.IsRegister()) { | 1268 if ((index_scale() == 1) && index.IsRegister()) { |
| 1261 __ SmiUntag(index.reg()); | 1269 __ SmiUntag(index.reg()); |
| 1262 } | 1270 } |
| 1263 switch (class_id()) { | 1271 switch (class_id()) { |
| 1264 case kTypedDataInt8ArrayCid: | 1272 case kTypedDataInt8ArrayCid: |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1325 case kExternalTypedDataUint8ClampedArrayCid: | 1333 case kExternalTypedDataUint8ClampedArrayCid: |
| 1326 case kTypedDataInt16ArrayCid: | 1334 case kTypedDataInt16ArrayCid: |
| 1327 case kTypedDataUint16ArrayCid: | 1335 case kTypedDataUint16ArrayCid: |
| 1328 return kTagged; | 1336 return kTagged; |
| 1329 case kTypedDataInt32ArrayCid: | 1337 case kTypedDataInt32ArrayCid: |
| 1330 case kTypedDataUint32ArrayCid: | 1338 case kTypedDataUint32ArrayCid: |
| 1331 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 1339 return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
| 1332 case kTypedDataFloat32ArrayCid: | 1340 case kTypedDataFloat32ArrayCid: |
| 1333 case kTypedDataFloat64ArrayCid: | 1341 case kTypedDataFloat64ArrayCid: |
| 1334 return kUnboxedDouble; | 1342 return kUnboxedDouble; |
| 1343 case kTypedDataFloat32x4ArrayCid: | |
| 1344 return kUnboxedFloat32x4; | |
| 1335 default: | 1345 default: |
| 1336 UNIMPLEMENTED(); | 1346 UNIMPLEMENTED(); |
| 1337 return kTagged; | 1347 return kTagged; |
| 1338 } | 1348 } |
| 1339 } | 1349 } |
| 1340 | 1350 |
| 1341 | 1351 |
| 1342 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1352 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 1343 const intptr_t kNumInputs = 3; | 1353 const intptr_t kNumInputs = 3; |
| 1344 const intptr_t kNumTemps = 0; | 1354 const intptr_t kNumTemps = 0; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1387 : Location::RequiresFpuRegister()); | 1397 : Location::RequiresFpuRegister()); |
| 1388 break; | 1398 break; |
| 1389 case kTypedDataFloat32ArrayCid: | 1399 case kTypedDataFloat32ArrayCid: |
| 1390 // Need temp register for float-to-double conversion. | 1400 // Need temp register for float-to-double conversion. |
| 1391 locs->AddTemp(Location::RequiresFpuRegister()); | 1401 locs->AddTemp(Location::RequiresFpuRegister()); |
| 1392 // Fall through. | 1402 // Fall through. |
| 1393 case kTypedDataFloat64ArrayCid: | 1403 case kTypedDataFloat64ArrayCid: |
| 1394 // TODO(srdjan): Support Float64 constants. | 1404 // TODO(srdjan): Support Float64 constants. |
| 1395 locs->set_in(2, Location::RequiresFpuRegister()); | 1405 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1396 break; | 1406 break; |
| 1407 case kTypedDataFloat32x4ArrayCid: | |
| 1408 locs->set_in(2, Location::RequiresFpuRegister()); | |
| 1409 break; | |
| 1397 default: | 1410 default: |
| 1398 UNREACHABLE(); | 1411 UNREACHABLE(); |
| 1399 return NULL; | 1412 return NULL; |
| 1400 } | 1413 } |
| 1401 return locs; | 1414 return locs; |
| 1402 } | 1415 } |
| 1403 | 1416 |
| 1404 | 1417 |
| 1405 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1418 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1406 Register array = locs()->in(0).reg(); | 1419 Register array = locs()->in(0).reg(); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1503 break; | 1516 break; |
| 1504 case kTypedDataFloat32ArrayCid: | 1517 case kTypedDataFloat32ArrayCid: |
| 1505 // Convert to single precision. | 1518 // Convert to single precision. |
| 1506 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); | 1519 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
| 1507 // Store. | 1520 // Store. |
| 1508 __ movss(element_address, locs()->temp(0).fpu_reg()); | 1521 __ movss(element_address, locs()->temp(0).fpu_reg()); |
| 1509 break; | 1522 break; |
| 1510 case kTypedDataFloat64ArrayCid: | 1523 case kTypedDataFloat64ArrayCid: |
| 1511 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1524 __ movsd(element_address, locs()->in(2).fpu_reg()); |
| 1512 break; | 1525 break; |
| 1526 case kTypedDataFloat32x4ArrayCid: | |
| 1527 __ movups(element_address, locs()->in(2).fpu_reg()); | |
| 1528 break; | |
| 1513 default: | 1529 default: |
| 1514 UNREACHABLE(); | 1530 UNREACHABLE(); |
| 1515 } | 1531 } |
| 1516 } | 1532 } |
| 1517 | 1533 |
| 1518 | 1534 |
| 1519 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1535 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { |
| 1520 const intptr_t kNumInputs = 1; | 1536 const intptr_t kNumInputs = 1; |
| 1521 LocationSummary* summary = | 1537 LocationSummary* summary = |
| 1522 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); | 1538 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); |
| (...skipping 1158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2681 __ jmp(&done); | 2697 __ jmp(&done); |
| 2682 __ Bind(&is_smi); | 2698 __ Bind(&is_smi); |
| 2683 __ movl(temp, value); | 2699 __ movl(temp, value); |
| 2684 __ SmiUntag(temp); | 2700 __ SmiUntag(temp); |
| 2685 __ cvtsi2sd(result, temp); | 2701 __ cvtsi2sd(result, temp); |
| 2686 __ Bind(&done); | 2702 __ Bind(&done); |
| 2687 } | 2703 } |
| 2688 } | 2704 } |
| 2689 | 2705 |
| 2690 | 2706 |
| 2707 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary() const { | |
| 2708 const intptr_t kNumInputs = 1; | |
| 2709 const intptr_t kNumTemps = 0; | |
| 2710 LocationSummary* summary = | |
| 2711 new LocationSummary(kNumInputs, | |
| 2712 kNumTemps, | |
| 2713 LocationSummary::kCallOnSlowPath); | |
| 2714 summary->set_in(0, Location::RequiresFpuRegister()); | |
| 2715 summary->set_out(Location::RequiresRegister()); | |
| 2716 return summary; | |
| 2717 } | |
| 2718 | |
| 2719 | |
| 2720 class BoxFloat32x4SlowPath : public SlowPathCode { | |
| 2721 public: | |
| 2722 explicit BoxFloat32x4SlowPath(BoxFloat32x4Instr* instruction) | |
| 2723 : instruction_(instruction) { } | |
| 2724 | |
| 2725 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 2726 __ Comment("BoxFloat32x4SlowPath"); | |
| 2727 __ Bind(entry_label()); | |
| 2728 const Class& float32x4_class = compiler->float32x4_class(); | |
| 2729 const Code& stub = | |
| 2730 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class)); | |
| 2731 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint()); | |
| 2732 | |
| 2733 LocationSummary* locs = instruction_->locs(); | |
| 2734 locs->live_registers()->Remove(locs->out()); | |
| 2735 | |
| 2736 compiler->SaveLiveRegisters(locs); | |
| 2737 compiler->GenerateCall(instruction_->token_pos(), | |
| 2738 &label, | |
| 2739 PcDescriptors::kOther, | |
| 2740 locs); | |
| 2741 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX); | |
|
srdjan
2013/04/10 15:33:23
Use MoveRegister(locs->out().reg(), EAX), it emits
Cutch
2013/04/10 16:36:13
Done. I also made this change in the BoxDoubleSlow
| |
| 2742 compiler->RestoreLiveRegisters(locs); | |
| 2743 | |
| 2744 __ jmp(exit_label()); | |
| 2745 } | |
| 2746 | |
| 2747 private: | |
| 2748 BoxFloat32x4Instr* instruction_; | |
| 2749 }; | |
| 2750 | |
| 2751 | |
| 2752 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 2753 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); | |
| 2754 compiler->AddSlowPathCode(slow_path); | |
| 2755 | |
| 2756 Register out_reg = locs()->out().reg(); | |
| 2757 XmmRegister value = locs()->in(0).fpu_reg(); | |
| 2758 | |
| 2759 __ TryAllocate(compiler->float32x4_class(), | |
| 2760 slow_path->entry_label(), | |
| 2761 Assembler::kFarJump, | |
| 2762 out_reg); | |
| 2763 __ Bind(slow_path->exit_label()); | |
| 2764 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); | |
| 2765 } | |
| 2766 | |
| 2767 | |
| 2768 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { | |
| 2769 const intptr_t kNumInputs = 1; | |
| 2770 const intptr_t kNumTemps = 0; | |
| 2771 LocationSummary* summary = | |
| 2772 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 2773 summary->set_in(0, Location::RequiresRegister()); | |
| 2774 summary->set_out(Location::RequiresFpuRegister()); | |
| 2775 return summary; | |
| 2776 } | |
| 2777 | |
| 2778 | |
| 2779 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 2780 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 2781 const Register value = locs()->in(0).reg(); | |
| 2782 const XmmRegister result = locs()->out().fpu_reg(); | |
| 2783 | |
| 2784 if (value_cid == kFloat32x4Cid) { | |
| 2785 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | |
| 2786 } else { | |
| 2787 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | |
| 2788 Register temp = locs()->temp(0).reg(); | |
| 2789 __ CompareClassId(value, kFloat32x4Cid, temp); | |
| 2790 __ j(NOT_EQUAL, deopt); | |
| 2791 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | |
| 2792 } | |
| 2793 } | |
| 2794 | |
| 2795 | |
| 2691 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 2796 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { |
| 2692 const intptr_t kNumInputs = 2; | 2797 const intptr_t kNumInputs = 2; |
| 2693 const intptr_t kNumTemps = 0; | 2798 const intptr_t kNumTemps = 0; |
| 2694 LocationSummary* summary = | 2799 LocationSummary* summary = |
| 2695 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2800 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2696 summary->set_in(0, Location::RequiresFpuRegister()); | 2801 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2697 summary->set_in(1, Location::RequiresFpuRegister()); | 2802 summary->set_in(1, Location::RequiresFpuRegister()); |
| 2698 summary->set_out(Location::SameAsFirstInput()); | 2803 summary->set_out(Location::SameAsFirstInput()); |
| 2699 return summary; | 2804 return summary; |
| 2700 } | 2805 } |
| (...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3719 PcDescriptors::kOther, | 3824 PcDescriptors::kOther, |
| 3720 locs()); | 3825 locs()); |
| 3721 __ Drop(2); // Discard type arguments and receiver. | 3826 __ Drop(2); // Discard type arguments and receiver. |
| 3722 } | 3827 } |
| 3723 | 3828 |
| 3724 } // namespace dart | 3829 } // namespace dart |
| 3725 | 3830 |
| 3726 #undef __ | 3831 #undef __ |
| 3727 | 3832 |
| 3728 #endif // defined TARGET_ARCH_IA32 | 3833 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |