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

Side by Side Diff: runtime/vm/intermediate_language_x64.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_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
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
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
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
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
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
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 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2480 __ Bind(entry_label()); 2495 __ Bind(entry_label());
2481 const Class& double_class = compiler->double_class(); 2496 const Class& double_class = compiler->double_class();
2482 const Code& stub = 2497 const Code& stub =
2483 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2498 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2484 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2499 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2485 2500
2486 LocationSummary* locs = instruction_->locs(); 2501 LocationSummary* locs = instruction_->locs();
2487 locs->live_registers()->Remove(locs->out()); 2502 locs->live_registers()->Remove(locs->out());
2488 2503
2489 compiler->SaveLiveRegisters(locs); 2504 compiler->SaveLiveRegisters(locs);
2490 compiler->GenerateCall(instruction_->token_pos(), 2505 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position.
2491 &label, 2506 &label,
2492 PcDescriptors::kOther, 2507 PcDescriptors::kOther,
2493 locs); 2508 locs);
2494 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX); 2509 __ MoveRegister(locs->out().reg(), RAX);
2495 compiler->RestoreLiveRegisters(locs); 2510 compiler->RestoreLiveRegisters(locs);
2496 2511
2497 __ jmp(exit_label()); 2512 __ jmp(exit_label());
2498 } 2513 }
2499 2514
2500 private: 2515 private:
2501 BoxDoubleInstr* instruction_; 2516 BoxDoubleInstr* instruction_;
2502 }; 2517 };
2503 2518
2504 2519
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
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(Scanner::kDummyTokenIndex, // No token position.
2608 &label,
2609 PcDescriptors::kOther,
2610 locs);
2611 __ MoveRegister(locs->out().reg(), RAX);
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 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
2656 __ CompareClassId(value, kFloat32x4Cid);
2657 __ j(NOT_EQUAL, deopt);
2658 }
2659 __ movups(result, FieldAddress(value, Float32x4::value_offset()));
2660 }
2661
2662
2562 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { 2663 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const {
2563 const intptr_t kNumInputs = 2; 2664 const intptr_t kNumInputs = 2;
2564 const intptr_t kNumTemps = 0; 2665 const intptr_t kNumTemps = 0;
2565 LocationSummary* summary = 2666 LocationSummary* summary =
2566 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2667 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2567 summary->set_in(0, Location::RequiresFpuRegister()); 2668 summary->set_in(0, Location::RequiresFpuRegister());
2568 summary->set_in(1, Location::RequiresFpuRegister()); 2669 summary->set_in(1, Location::RequiresFpuRegister());
2569 summary->set_out(Location::SameAsFirstInput()); 2670 summary->set_out(Location::SameAsFirstInput());
2570 return summary; 2671 return summary;
2571 } 2672 }
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
2936 3037
2937 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3038 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2938 Register value = locs()->in(0).reg(); 3039 Register value = locs()->in(0).reg();
2939 Label* deopt = compiler->AddDeoptStub(deopt_id(), 3040 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2940 kDeoptCheckSmi); 3041 kDeoptCheckSmi);
2941 __ testq(value, Immediate(kSmiTagMask)); 3042 __ testq(value, Immediate(kSmiTagMask));
2942 __ j(NOT_ZERO, deopt); 3043 __ j(NOT_ZERO, deopt);
2943 } 3044 }
2944 3045
2945 3046
3047 LocationSummary* CheckNonSmiInstr::MakeLocationSummary() const {
3048 const intptr_t kNumInputs = 1;
3049 const intptr_t kNumTemps = 0;
3050 LocationSummary* summary =
3051 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3052 summary->set_in(0, Location::RequiresRegister());
3053 return summary;
3054 }
3055
3056
3057 void CheckNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3058 Register value = locs()->in(0).reg();
3059 Label* deopt = compiler->AddDeoptStub(deopt_id(),
3060 kDeoptCheckNonSmi);
3061 __ testq(value, Immediate(kSmiTagMask));
3062 __ j(ZERO, deopt);
3063 }
3064
2946 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { 3065 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const {
2947 const intptr_t kNumInputs = 2; 3066 const intptr_t kNumInputs = 2;
2948 const intptr_t kNumTemps = 0; 3067 const intptr_t kNumTemps = 0;
2949 LocationSummary* locs = 3068 LocationSummary* locs =
2950 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3069 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2951 locs->set_in(0, Location::RegisterOrSmiConstant(length())); 3070 locs->set_in(0, Location::RegisterOrSmiConstant(length()));
2952 locs->set_in(1, Location::RegisterOrSmiConstant(index())); 3071 locs->set_in(1, Location::RegisterOrSmiConstant(index()));
2953 return locs; 3072 return locs;
2954 } 3073 }
2955 3074
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
3356 PcDescriptors::kOther, 3475 PcDescriptors::kOther,
3357 locs()); 3476 locs());
3358 __ Drop(2); // Discard type arguments and receiver. 3477 __ Drop(2); // Discard type arguments and receiver.
3359 } 3478 }
3360 3479
3361 } // namespace dart 3480 } // namespace dart
3362 3481
3363 #undef __ 3482 #undef __
3364 3483
3365 #endif // defined TARGET_ARCH_X64 3484 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698