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

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

Issue 13818006: Unboxed load/store indexed of Float32x4 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 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_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
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
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
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
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
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
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 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after
2604 __ Bind(entry_label()); 2620 __ Bind(entry_label());
2605 const Class& double_class = compiler->double_class(); 2621 const Class& double_class = compiler->double_class();
2606 const Code& stub = 2622 const Code& stub =
2607 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2623 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2608 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2624 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2609 2625
2610 LocationSummary* locs = instruction_->locs(); 2626 LocationSummary* locs = instruction_->locs();
2611 locs->live_registers()->Remove(locs->out()); 2627 locs->live_registers()->Remove(locs->out());
2612 2628
2613 compiler->SaveLiveRegisters(locs); 2629 compiler->SaveLiveRegisters(locs);
2614 compiler->GenerateCall(instruction_->token_pos(), 2630 compiler->GenerateCall(0, // No token position.
Vyacheslav Egorov (Google) 2013/04/10 20:00:48 Scanner::kDummyTokenIndex
Cutch 2013/04/11 09:39:07 Done.
2615 &label, 2631 &label,
2616 PcDescriptors::kOther, 2632 PcDescriptors::kOther,
2617 locs); 2633 locs);
2618 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX); 2634 __ MoveRegister(locs->out().reg(), EAX);
2619 compiler->RestoreLiveRegisters(locs); 2635 compiler->RestoreLiveRegisters(locs);
2620 2636
2621 __ jmp(exit_label()); 2637 __ jmp(exit_label());
2622 } 2638 }
2623 2639
2624 private: 2640 private:
2625 BoxDoubleInstr* instruction_; 2641 BoxDoubleInstr* instruction_;
2626 }; 2642 };
2627 2643
2628 2644
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
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(0, // No token position.
Vyacheslav Egorov (Google) 2013/04/10 20:00:48 Scanner::kDummyTokenIndex
Cutch 2013/04/11 09:39:07 Done.
2738 &label,
2739 PcDescriptors::kOther,
2740 locs);
2741 __ MoveRegister(locs->out().reg(), EAX);
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()));
Vyacheslav Egorov (Google) 2013/04/10 20:00:48 move movups down and make if (value_cid != kFloat3
Cutch 2013/04/11 09:39:07 Done.
2786 } else {
2787 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
2788 Register temp = locs()->temp(0).reg();
2789 __ CompareClassId(value, kFloat32x4Cid, temp);
Vyacheslav Egorov (Google) 2013/04/10 20:00:48 This will crash if value is a Smi. This is also j
Cutch 2013/04/11 09:39:07 I've added a CheckNonSmi instruction and insert it
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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
3177 const Class& mint_class = 3282 const Class& mint_class =
3178 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()); 3283 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class());
3179 const Code& stub = 3284 const Code& stub =
3180 Code::Handle(StubCode::GetAllocationStubForClass(mint_class)); 3285 Code::Handle(StubCode::GetAllocationStubForClass(mint_class));
3181 const ExternalLabel label(mint_class.ToCString(), stub.EntryPoint()); 3286 const ExternalLabel label(mint_class.ToCString(), stub.EntryPoint());
3182 3287
3183 LocationSummary* locs = instruction_->locs(); 3288 LocationSummary* locs = instruction_->locs();
3184 locs->live_registers()->Remove(locs->out()); 3289 locs->live_registers()->Remove(locs->out());
3185 3290
3186 compiler->SaveLiveRegisters(locs); 3291 compiler->SaveLiveRegisters(locs);
3187 compiler->GenerateCall(0, // No token pos. 3292 compiler->GenerateCall(0, // No token position.
Vyacheslav Egorov (Google) 2013/04/10 20:00:48 Scanner::kDummyTokenIndex
Cutch 2013/04/11 09:39:07 Done.
3188 &label, 3293 &label,
3189 PcDescriptors::kOther, 3294 PcDescriptors::kOther,
3190 locs); 3295 locs);
3191 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX); 3296 __ MoveRegister(locs->out().reg(), EAX);
3192 compiler->RestoreLiveRegisters(locs); 3297 compiler->RestoreLiveRegisters(locs);
3193 3298
3194 __ jmp(exit_label()); 3299 __ jmp(exit_label());
3195 } 3300 }
3196 3301
3197 private: 3302 private:
3198 BoxIntegerInstr* instruction_; 3303 BoxIntegerInstr* instruction_;
3199 }; 3304 };
3200 3305
3201 3306
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698