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 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 switch (class_id_) { | 1028 switch (class_id_) { |
1029 case kArrayCid: | 1029 case kArrayCid: |
1030 case kImmutableArrayCid: | 1030 case kImmutableArrayCid: |
1031 return CompileType::Dynamic(); | 1031 return CompileType::Dynamic(); |
1032 | 1032 |
1033 case kTypedDataFloat32ArrayCid: | 1033 case kTypedDataFloat32ArrayCid: |
1034 case kTypedDataFloat64ArrayCid: | 1034 case kTypedDataFloat64ArrayCid: |
1035 return CompileType::FromCid(kDoubleCid); | 1035 return CompileType::FromCid(kDoubleCid); |
1036 case kTypedDataFloat32x4ArrayCid: | 1036 case kTypedDataFloat32x4ArrayCid: |
1037 return CompileType::FromCid(kFloat32x4Cid); | 1037 return CompileType::FromCid(kFloat32x4Cid); |
1038 case kTypedDataUint32x4ArrayCid: | 1038 case kTypedDataInt32x4ArrayCid: |
1039 return CompileType::FromCid(kUint32x4Cid); | 1039 return CompileType::FromCid(kInt32x4Cid); |
1040 | 1040 |
1041 case kTypedDataInt8ArrayCid: | 1041 case kTypedDataInt8ArrayCid: |
1042 case kTypedDataUint8ArrayCid: | 1042 case kTypedDataUint8ArrayCid: |
1043 case kTypedDataUint8ClampedArrayCid: | 1043 case kTypedDataUint8ClampedArrayCid: |
1044 case kExternalTypedDataUint8ArrayCid: | 1044 case kExternalTypedDataUint8ArrayCid: |
1045 case kExternalTypedDataUint8ClampedArrayCid: | 1045 case kExternalTypedDataUint8ClampedArrayCid: |
1046 case kTypedDataInt16ArrayCid: | 1046 case kTypedDataInt16ArrayCid: |
1047 case kTypedDataUint16ArrayCid: | 1047 case kTypedDataUint16ArrayCid: |
1048 case kOneByteStringCid: | 1048 case kOneByteStringCid: |
1049 case kTwoByteStringCid: | 1049 case kTwoByteStringCid: |
(...skipping 20 matching lines...) Expand all Loading... |
1070 case kTypedDataInt16ArrayCid: | 1070 case kTypedDataInt16ArrayCid: |
1071 case kTypedDataUint16ArrayCid: | 1071 case kTypedDataUint16ArrayCid: |
1072 case kOneByteStringCid: | 1072 case kOneByteStringCid: |
1073 case kTwoByteStringCid: | 1073 case kTwoByteStringCid: |
1074 case kTypedDataInt32ArrayCid: | 1074 case kTypedDataInt32ArrayCid: |
1075 case kTypedDataUint32ArrayCid: | 1075 case kTypedDataUint32ArrayCid: |
1076 return kTagged; | 1076 return kTagged; |
1077 case kTypedDataFloat32ArrayCid: | 1077 case kTypedDataFloat32ArrayCid: |
1078 case kTypedDataFloat64ArrayCid: | 1078 case kTypedDataFloat64ArrayCid: |
1079 return kUnboxedDouble; | 1079 return kUnboxedDouble; |
1080 case kTypedDataUint32x4ArrayCid: | 1080 case kTypedDataInt32x4ArrayCid: |
1081 return kUnboxedUint32x4; | 1081 return kUnboxedInt32x4; |
1082 case kTypedDataFloat32x4ArrayCid: | 1082 case kTypedDataFloat32x4ArrayCid: |
1083 return kUnboxedFloat32x4; | 1083 return kUnboxedFloat32x4; |
1084 default: | 1084 default: |
1085 UNIMPLEMENTED(); | 1085 UNIMPLEMENTED(); |
1086 return kTagged; | 1086 return kTagged; |
1087 } | 1087 } |
1088 } | 1088 } |
1089 | 1089 |
1090 | 1090 |
1091 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1091 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
(...skipping 10 matching lines...) Expand all Loading... |
1102 index()->definition()->AsConstant()->value()) | 1102 index()->definition()->AsConstant()->value()) |
1103 : Location::WritableRegister()); | 1103 : Location::WritableRegister()); |
1104 } else { | 1104 } else { |
1105 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 1105 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
1106 ? Location::Constant( | 1106 ? Location::Constant( |
1107 index()->definition()->AsConstant()->value()) | 1107 index()->definition()->AsConstant()->value()) |
1108 : Location::RequiresRegister()); | 1108 : Location::RequiresRegister()); |
1109 } | 1109 } |
1110 if ((representation() == kUnboxedDouble) || | 1110 if ((representation() == kUnboxedDouble) || |
1111 (representation() == kUnboxedFloat32x4) || | 1111 (representation() == kUnboxedFloat32x4) || |
1112 (representation() == kUnboxedUint32x4)) { | 1112 (representation() == kUnboxedInt32x4)) { |
1113 locs->set_out(Location::RequiresFpuRegister()); | 1113 locs->set_out(Location::RequiresFpuRegister()); |
1114 } else { | 1114 } else { |
1115 locs->set_out(Location::RequiresRegister()); | 1115 locs->set_out(Location::RequiresRegister()); |
1116 } | 1116 } |
1117 return locs; | 1117 return locs; |
1118 } | 1118 } |
1119 | 1119 |
1120 | 1120 |
1121 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1121 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1122 Register array = locs()->in(0).reg(); | 1122 Register array = locs()->in(0).reg(); |
(...skipping 14 matching lines...) Expand all Loading... |
1137 element_address = index.IsRegister() | 1137 element_address = index.IsRegister() |
1138 ? FlowGraphCompiler::ElementAddressForRegIndex( | 1138 ? FlowGraphCompiler::ElementAddressForRegIndex( |
1139 class_id(), index_scale(), array, index.reg()) | 1139 class_id(), index_scale(), array, index.reg()) |
1140 : FlowGraphCompiler::ElementAddressForIntIndex( | 1140 : FlowGraphCompiler::ElementAddressForIntIndex( |
1141 class_id(), index_scale(), array, | 1141 class_id(), index_scale(), array, |
1142 Smi::Cast(index.constant()).Value()); | 1142 Smi::Cast(index.constant()).Value()); |
1143 } | 1143 } |
1144 | 1144 |
1145 if ((representation() == kUnboxedDouble) || | 1145 if ((representation() == kUnboxedDouble) || |
1146 (representation() == kUnboxedFloat32x4) || | 1146 (representation() == kUnboxedFloat32x4) || |
1147 (representation() == kUnboxedUint32x4)) { | 1147 (representation() == kUnboxedInt32x4)) { |
1148 if ((index_scale() == 1) && index.IsRegister()) { | 1148 if ((index_scale() == 1) && index.IsRegister()) { |
1149 __ SmiUntag(index.reg()); | 1149 __ SmiUntag(index.reg()); |
1150 } | 1150 } |
1151 | 1151 |
1152 XmmRegister result = locs()->out().fpu_reg(); | 1152 XmmRegister result = locs()->out().fpu_reg(); |
1153 if (class_id() == kTypedDataFloat32ArrayCid) { | 1153 if (class_id() == kTypedDataFloat32ArrayCid) { |
1154 // Load single precision float. | 1154 // Load single precision float. |
1155 __ movss(result, element_address); | 1155 __ movss(result, element_address); |
1156 // Promote to double. | 1156 // Promote to double. |
1157 __ cvtss2sd(result, locs()->out().fpu_reg()); | 1157 __ cvtss2sd(result, locs()->out().fpu_reg()); |
1158 } else if (class_id() == kTypedDataFloat64ArrayCid) { | 1158 } else if (class_id() == kTypedDataFloat64ArrayCid) { |
1159 __ movsd(result, element_address); | 1159 __ movsd(result, element_address); |
1160 } else { | 1160 } else { |
1161 ASSERT((class_id() == kTypedDataUint32x4ArrayCid) || | 1161 ASSERT((class_id() == kTypedDataInt32x4ArrayCid) || |
1162 (class_id() == kTypedDataFloat32x4ArrayCid)); | 1162 (class_id() == kTypedDataFloat32x4ArrayCid)); |
1163 __ movups(result, element_address); | 1163 __ movups(result, element_address); |
1164 } | 1164 } |
1165 return; | 1165 return; |
1166 } | 1166 } |
1167 | 1167 |
1168 if ((index_scale() == 1) && index.IsRegister()) { | 1168 if ((index_scale() == 1) && index.IsRegister()) { |
1169 __ SmiUntag(index.reg()); | 1169 __ SmiUntag(index.reg()); |
1170 } | 1170 } |
1171 Register result = locs()->out().reg(); | 1171 Register result = locs()->out().reg(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 case kTypedDataInt16ArrayCid: | 1223 case kTypedDataInt16ArrayCid: |
1224 case kTypedDataUint16ArrayCid: | 1224 case kTypedDataUint16ArrayCid: |
1225 case kTypedDataInt32ArrayCid: | 1225 case kTypedDataInt32ArrayCid: |
1226 case kTypedDataUint32ArrayCid: | 1226 case kTypedDataUint32ArrayCid: |
1227 return kTagged; | 1227 return kTagged; |
1228 case kTypedDataFloat32ArrayCid: | 1228 case kTypedDataFloat32ArrayCid: |
1229 case kTypedDataFloat64ArrayCid: | 1229 case kTypedDataFloat64ArrayCid: |
1230 return kUnboxedDouble; | 1230 return kUnboxedDouble; |
1231 case kTypedDataFloat32x4ArrayCid: | 1231 case kTypedDataFloat32x4ArrayCid: |
1232 return kUnboxedFloat32x4; | 1232 return kUnboxedFloat32x4; |
1233 case kTypedDataUint32x4ArrayCid: | 1233 case kTypedDataInt32x4ArrayCid: |
1234 return kUnboxedUint32x4; | 1234 return kUnboxedInt32x4; |
1235 default: | 1235 default: |
1236 UNIMPLEMENTED(); | 1236 UNIMPLEMENTED(); |
1237 return kTagged; | 1237 return kTagged; |
1238 } | 1238 } |
1239 } | 1239 } |
1240 | 1240 |
1241 | 1241 |
1242 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1242 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
1243 const intptr_t kNumInputs = 3; | 1243 const intptr_t kNumInputs = 3; |
1244 const intptr_t kNumTemps = 0; | 1244 const intptr_t kNumTemps = 0; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 locs->set_in(2, Location::WritableRegister()); | 1282 locs->set_in(2, Location::WritableRegister()); |
1283 break; | 1283 break; |
1284 case kTypedDataFloat32ArrayCid: | 1284 case kTypedDataFloat32ArrayCid: |
1285 // Need temp register for float-to-double conversion. | 1285 // Need temp register for float-to-double conversion. |
1286 locs->AddTemp(Location::RequiresFpuRegister()); | 1286 locs->AddTemp(Location::RequiresFpuRegister()); |
1287 // Fall through. | 1287 // Fall through. |
1288 case kTypedDataFloat64ArrayCid: | 1288 case kTypedDataFloat64ArrayCid: |
1289 // TODO(srdjan): Support Float64 constants. | 1289 // TODO(srdjan): Support Float64 constants. |
1290 locs->set_in(2, Location::RequiresFpuRegister()); | 1290 locs->set_in(2, Location::RequiresFpuRegister()); |
1291 break; | 1291 break; |
1292 case kTypedDataUint32x4ArrayCid: | 1292 case kTypedDataInt32x4ArrayCid: |
1293 case kTypedDataFloat32x4ArrayCid: | 1293 case kTypedDataFloat32x4ArrayCid: |
1294 locs->set_in(2, Location::RequiresFpuRegister()); | 1294 locs->set_in(2, Location::RequiresFpuRegister()); |
1295 break; | 1295 break; |
1296 default: | 1296 default: |
1297 UNREACHABLE(); | 1297 UNREACHABLE(); |
1298 return NULL; | 1298 return NULL; |
1299 } | 1299 } |
1300 return locs; | 1300 return locs; |
1301 } | 1301 } |
1302 | 1302 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1400 } | 1400 } |
1401 case kTypedDataFloat32ArrayCid: | 1401 case kTypedDataFloat32ArrayCid: |
1402 // Convert to single precision. | 1402 // Convert to single precision. |
1403 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); | 1403 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
1404 // Store. | 1404 // Store. |
1405 __ movss(element_address, locs()->temp(0).fpu_reg()); | 1405 __ movss(element_address, locs()->temp(0).fpu_reg()); |
1406 break; | 1406 break; |
1407 case kTypedDataFloat64ArrayCid: | 1407 case kTypedDataFloat64ArrayCid: |
1408 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1408 __ movsd(element_address, locs()->in(2).fpu_reg()); |
1409 break; | 1409 break; |
1410 case kTypedDataUint32x4ArrayCid: | 1410 case kTypedDataInt32x4ArrayCid: |
1411 case kTypedDataFloat32x4ArrayCid: | 1411 case kTypedDataFloat32x4ArrayCid: |
1412 __ movups(element_address, locs()->in(2).fpu_reg()); | 1412 __ movups(element_address, locs()->in(2).fpu_reg()); |
1413 break; | 1413 break; |
1414 default: | 1414 default: |
1415 UNREACHABLE(); | 1415 UNREACHABLE(); |
1416 } | 1416 } |
1417 } | 1417 } |
1418 | 1418 |
1419 | 1419 |
1420 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1420 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1535 // If length is negative the length guard is either disabled or | 1535 // If length is negative the length guard is either disabled or |
1536 // has not been initialized, either way it is safe to skip the | 1536 // has not been initialized, either way it is safe to skip the |
1537 // length check. | 1537 // length check. |
1538 __ CompareImmediate( | 1538 __ CompareImmediate( |
1539 field_length_operand, Immediate(Smi::RawValue(0)), PP); | 1539 field_length_operand, Immediate(Smi::RawValue(0)), PP); |
1540 __ j(LESS, &skip_length_check); | 1540 __ j(LESS, &skip_length_check); |
1541 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); | 1541 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); |
1542 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1542 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
1543 // Check for typed data array. | 1543 // Check for typed data array. |
1544 __ CompareImmediate( | 1544 __ CompareImmediate( |
1545 value_cid_reg, Immediate(kTypedDataUint32x4ArrayCid), PP); | 1545 value_cid_reg, Immediate(kTypedDataInt32x4ArrayCid), PP); |
1546 // Not a typed array or a regular array. | 1546 // Not a typed array or a regular array. |
1547 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); | 1547 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); |
1548 __ CompareImmediate( | 1548 __ CompareImmediate( |
1549 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); | 1549 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); |
1550 // Could still be a regular array. | 1550 // Could still be a regular array. |
1551 __ j(LESS, &check_array, Assembler::kNearJump); | 1551 __ j(LESS, &check_array, Assembler::kNearJump); |
1552 __ pushq(value_cid_reg); | 1552 __ pushq(value_cid_reg); |
1553 __ movq(value_cid_reg, | 1553 __ movq(value_cid_reg, |
1554 FieldAddress(value_reg, TypedData::length_offset())); | 1554 FieldAddress(value_reg, TypedData::length_offset())); |
1555 __ cmpq(field_length_operand, value_cid_reg); | 1555 __ cmpq(field_length_operand, value_cid_reg); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1615 | 1615 |
1616 if (value_cid == kDynamicCid) { | 1616 if (value_cid == kDynamicCid) { |
1617 __ movq(field_cid_operand, value_cid_reg); | 1617 __ movq(field_cid_operand, value_cid_reg); |
1618 __ movq(field_nullability_operand, value_cid_reg); | 1618 __ movq(field_nullability_operand, value_cid_reg); |
1619 if (field_has_length) { | 1619 if (field_has_length) { |
1620 Label check_array, length_set, no_fixed_length; | 1620 Label check_array, length_set, no_fixed_length; |
1621 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); | 1621 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); |
1622 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1622 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
1623 // Check for typed data array. | 1623 // Check for typed data array. |
1624 __ CompareImmediate(value_cid_reg, | 1624 __ CompareImmediate(value_cid_reg, |
1625 Immediate(kTypedDataUint32x4ArrayCid), PP); | 1625 Immediate(kTypedDataInt32x4ArrayCid), PP); |
1626 // Not a typed array or a regular array. | 1626 // Not a typed array or a regular array. |
1627 __ j(GREATER, &no_fixed_length); | 1627 __ j(GREATER, &no_fixed_length); |
1628 __ CompareImmediate( | 1628 __ CompareImmediate( |
1629 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); | 1629 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); |
1630 // Could still be a regular array. | 1630 // Could still be a regular array. |
1631 __ j(LESS, &check_array, Assembler::kNearJump); | 1631 __ j(LESS, &check_array, Assembler::kNearJump); |
1632 // Destroy value_cid_reg (safe because we are finished with it). | 1632 // Destroy value_cid_reg (safe because we are finished with it). |
1633 __ movq(value_cid_reg, | 1633 __ movq(value_cid_reg, |
1634 FieldAddress(value_reg, TypedData::length_offset())); | 1634 FieldAddress(value_reg, TypedData::length_offset())); |
1635 __ movq(field_length_operand, value_cid_reg); | 1635 __ movq(field_length_operand, value_cid_reg); |
(...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2999 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 2999 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
3000 __ testq(value, Immediate(kSmiTagMask)); | 3000 __ testq(value, Immediate(kSmiTagMask)); |
3001 __ j(ZERO, deopt); | 3001 __ j(ZERO, deopt); |
3002 __ CompareClassId(value, kFloat32x4Cid); | 3002 __ CompareClassId(value, kFloat32x4Cid); |
3003 __ j(NOT_EQUAL, deopt); | 3003 __ j(NOT_EQUAL, deopt); |
3004 } | 3004 } |
3005 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | 3005 __ movups(result, FieldAddress(value, Float32x4::value_offset())); |
3006 } | 3006 } |
3007 | 3007 |
3008 | 3008 |
3009 LocationSummary* BoxUint32x4Instr::MakeLocationSummary() const { | 3009 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { |
3010 const intptr_t kNumInputs = 1; | 3010 const intptr_t kNumInputs = 1; |
3011 const intptr_t kNumTemps = 0; | 3011 const intptr_t kNumTemps = 0; |
3012 LocationSummary* summary = | 3012 LocationSummary* summary = |
3013 new LocationSummary(kNumInputs, | 3013 new LocationSummary(kNumInputs, |
3014 kNumTemps, | 3014 kNumTemps, |
3015 LocationSummary::kCallOnSlowPath); | 3015 LocationSummary::kCallOnSlowPath); |
3016 summary->set_in(0, Location::RequiresFpuRegister()); | 3016 summary->set_in(0, Location::RequiresFpuRegister()); |
3017 summary->set_out(Location::RequiresRegister()); | 3017 summary->set_out(Location::RequiresRegister()); |
3018 return summary; | 3018 return summary; |
3019 } | 3019 } |
3020 | 3020 |
3021 | 3021 |
3022 class BoxUint32x4SlowPath : public SlowPathCode { | 3022 class BoxInt32x4SlowPath : public SlowPathCode { |
3023 public: | 3023 public: |
3024 explicit BoxUint32x4SlowPath(BoxUint32x4Instr* instruction) | 3024 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) |
3025 : instruction_(instruction) { } | 3025 : instruction_(instruction) { } |
3026 | 3026 |
3027 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 3027 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
3028 __ Comment("BoxUint32x4SlowPath"); | 3028 __ Comment("BoxInt32x4SlowPath"); |
3029 __ Bind(entry_label()); | 3029 __ Bind(entry_label()); |
3030 const Class& uint32x4_class = compiler->uint32x4_class(); | 3030 const Class& int32x4_class = compiler->int32x4_class(); |
3031 const Code& stub = | 3031 const Code& stub = |
3032 Code::Handle(StubCode::GetAllocationStubForClass(uint32x4_class)); | 3032 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class)); |
3033 const ExternalLabel label(uint32x4_class.ToCString(), stub.EntryPoint()); | 3033 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint()); |
3034 | 3034 |
3035 LocationSummary* locs = instruction_->locs(); | 3035 LocationSummary* locs = instruction_->locs(); |
3036 locs->live_registers()->Remove(locs->out()); | 3036 locs->live_registers()->Remove(locs->out()); |
3037 | 3037 |
3038 compiler->SaveLiveRegisters(locs); | 3038 compiler->SaveLiveRegisters(locs); |
3039 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. | 3039 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
3040 &label, | 3040 &label, |
3041 PcDescriptors::kOther, | 3041 PcDescriptors::kOther, |
3042 locs); | 3042 locs); |
3043 __ MoveRegister(locs->out().reg(), RAX); | 3043 __ MoveRegister(locs->out().reg(), RAX); |
3044 compiler->RestoreLiveRegisters(locs); | 3044 compiler->RestoreLiveRegisters(locs); |
3045 | 3045 |
3046 __ jmp(exit_label()); | 3046 __ jmp(exit_label()); |
3047 } | 3047 } |
3048 | 3048 |
3049 private: | 3049 private: |
3050 BoxUint32x4Instr* instruction_; | 3050 BoxInt32x4Instr* instruction_; |
3051 }; | 3051 }; |
3052 | 3052 |
3053 | 3053 |
3054 void BoxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3054 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3055 BoxUint32x4SlowPath* slow_path = new BoxUint32x4SlowPath(this); | 3055 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); |
3056 compiler->AddSlowPathCode(slow_path); | 3056 compiler->AddSlowPathCode(slow_path); |
3057 | 3057 |
3058 Register out_reg = locs()->out().reg(); | 3058 Register out_reg = locs()->out().reg(); |
3059 XmmRegister value = locs()->in(0).fpu_reg(); | 3059 XmmRegister value = locs()->in(0).fpu_reg(); |
3060 | 3060 |
3061 __ TryAllocate(compiler->uint32x4_class(), | 3061 __ TryAllocate(compiler->int32x4_class(), |
3062 slow_path->entry_label(), | 3062 slow_path->entry_label(), |
3063 Assembler::kFarJump, | 3063 Assembler::kFarJump, |
3064 out_reg, | 3064 out_reg, |
3065 PP); | 3065 PP); |
3066 __ Bind(slow_path->exit_label()); | 3066 __ Bind(slow_path->exit_label()); |
3067 __ movups(FieldAddress(out_reg, Uint32x4::value_offset()), value); | 3067 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); |
3068 } | 3068 } |
3069 | 3069 |
3070 | 3070 |
3071 LocationSummary* UnboxUint32x4Instr::MakeLocationSummary() const { | 3071 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { |
3072 const intptr_t kNumInputs = 1; | 3072 const intptr_t kNumInputs = 1; |
3073 const intptr_t kNumTemps = 0; | 3073 const intptr_t kNumTemps = 0; |
3074 LocationSummary* summary = | 3074 LocationSummary* summary = |
3075 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3075 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3076 summary->set_in(0, Location::RequiresRegister()); | 3076 summary->set_in(0, Location::RequiresRegister()); |
3077 summary->set_out(Location::RequiresFpuRegister()); | 3077 summary->set_out(Location::RequiresFpuRegister()); |
3078 return summary; | 3078 return summary; |
3079 } | 3079 } |
3080 | 3080 |
3081 | 3081 |
3082 void UnboxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3082 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3083 const intptr_t value_cid = value()->Type()->ToCid(); | 3083 const intptr_t value_cid = value()->Type()->ToCid(); |
3084 const Register value = locs()->in(0).reg(); | 3084 const Register value = locs()->in(0).reg(); |
3085 const XmmRegister result = locs()->out().fpu_reg(); | 3085 const XmmRegister result = locs()->out().fpu_reg(); |
3086 | 3086 |
3087 if (value_cid != kUint32x4Cid) { | 3087 if (value_cid != kInt32x4Cid) { |
3088 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3088 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
3089 __ testq(value, Immediate(kSmiTagMask)); | 3089 __ testq(value, Immediate(kSmiTagMask)); |
3090 __ j(ZERO, deopt); | 3090 __ j(ZERO, deopt); |
3091 __ CompareClassId(value, kUint32x4Cid); | 3091 __ CompareClassId(value, kInt32x4Cid); |
3092 __ j(NOT_EQUAL, deopt); | 3092 __ j(NOT_EQUAL, deopt); |
3093 } | 3093 } |
3094 __ movups(result, FieldAddress(value, Uint32x4::value_offset())); | 3094 __ movups(result, FieldAddress(value, Int32x4::value_offset())); |
3095 } | 3095 } |
3096 | 3096 |
3097 | 3097 |
3098 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 3098 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { |
3099 const intptr_t kNumInputs = 2; | 3099 const intptr_t kNumInputs = 2; |
3100 const intptr_t kNumTemps = 0; | 3100 const intptr_t kNumTemps = 0; |
3101 LocationSummary* summary = | 3101 LocationSummary* summary = |
3102 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3102 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3103 summary->set_in(0, Location::RequiresFpuRegister()); | 3103 summary->set_in(0, Location::RequiresFpuRegister()); |
3104 summary->set_in(1, Location::RequiresFpuRegister()); | 3104 summary->set_in(1, Location::RequiresFpuRegister()); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3178 break; | 3178 break; |
3179 case MethodRecognizer::kFloat32x4ShuffleZ: | 3179 case MethodRecognizer::kFloat32x4ShuffleZ: |
3180 __ shufps(value, value, Immediate(0xAA)); | 3180 __ shufps(value, value, Immediate(0xAA)); |
3181 __ cvtss2sd(value, value); | 3181 __ cvtss2sd(value, value); |
3182 break; | 3182 break; |
3183 case MethodRecognizer::kFloat32x4ShuffleW: | 3183 case MethodRecognizer::kFloat32x4ShuffleW: |
3184 __ shufps(value, value, Immediate(0xFF)); | 3184 __ shufps(value, value, Immediate(0xFF)); |
3185 __ cvtss2sd(value, value); | 3185 __ cvtss2sd(value, value); |
3186 break; | 3186 break; |
3187 case MethodRecognizer::kFloat32x4Shuffle: | 3187 case MethodRecognizer::kFloat32x4Shuffle: |
3188 case MethodRecognizer::kUint32x4Shuffle: | 3188 case MethodRecognizer::kInt32x4Shuffle: |
3189 __ shufps(value, value, Immediate(mask_)); | 3189 __ shufps(value, value, Immediate(mask_)); |
3190 break; | 3190 break; |
3191 default: UNREACHABLE(); | 3191 default: UNREACHABLE(); |
3192 } | 3192 } |
3193 } | 3193 } |
3194 | 3194 |
3195 | 3195 |
3196 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { | 3196 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { |
3197 const intptr_t kNumInputs = 2; | 3197 const intptr_t kNumInputs = 2; |
3198 const intptr_t kNumTemps = 0; | 3198 const intptr_t kNumTemps = 0; |
3199 LocationSummary* summary = | 3199 LocationSummary* summary = |
3200 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3200 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3201 summary->set_in(0, Location::RequiresFpuRegister()); | 3201 summary->set_in(0, Location::RequiresFpuRegister()); |
3202 summary->set_in(1, Location::RequiresFpuRegister()); | 3202 summary->set_in(1, Location::RequiresFpuRegister()); |
3203 summary->set_out(Location::SameAsFirstInput()); | 3203 summary->set_out(Location::SameAsFirstInput()); |
3204 return summary; | 3204 return summary; |
3205 } | 3205 } |
3206 | 3206 |
3207 | 3207 |
3208 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3208 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3209 XmmRegister left = locs()->in(0).fpu_reg(); | 3209 XmmRegister left = locs()->in(0).fpu_reg(); |
3210 XmmRegister right = locs()->in(1).fpu_reg(); | 3210 XmmRegister right = locs()->in(1).fpu_reg(); |
3211 | 3211 |
3212 ASSERT(locs()->out().fpu_reg() == left); | 3212 ASSERT(locs()->out().fpu_reg() == left); |
3213 switch (op_kind()) { | 3213 switch (op_kind()) { |
3214 case MethodRecognizer::kFloat32x4ShuffleMix: | 3214 case MethodRecognizer::kFloat32x4ShuffleMix: |
3215 case MethodRecognizer::kUint32x4ShuffleMix: | 3215 case MethodRecognizer::kInt32x4ShuffleMix: |
3216 __ shufps(left, right, Immediate(mask_)); | 3216 __ shufps(left, right, Immediate(mask_)); |
3217 break; | 3217 break; |
3218 default: UNREACHABLE(); | 3218 default: UNREACHABLE(); |
3219 } | 3219 } |
3220 } | 3220 } |
3221 | 3221 |
3222 | 3222 |
3223 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { | 3223 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { |
3224 const intptr_t kNumInputs = 1; | 3224 const intptr_t kNumInputs = 1; |
3225 const intptr_t kNumTemps = 0; | 3225 const intptr_t kNumTemps = 0; |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3558 __ movss(Address(RSP, 12), replacement); | 3558 __ movss(Address(RSP, 12), replacement); |
3559 // Move updated value into output register. | 3559 // Move updated value into output register. |
3560 __ movups(replacement, Address(RSP, 0)); | 3560 __ movups(replacement, Address(RSP, 0)); |
3561 __ AddImmediate(RSP, Immediate(16), PP); | 3561 __ AddImmediate(RSP, Immediate(16), PP); |
3562 break; | 3562 break; |
3563 default: UNREACHABLE(); | 3563 default: UNREACHABLE(); |
3564 } | 3564 } |
3565 } | 3565 } |
3566 | 3566 |
3567 | 3567 |
3568 LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const { | 3568 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { |
3569 const intptr_t kNumInputs = 1; | 3569 const intptr_t kNumInputs = 1; |
3570 const intptr_t kNumTemps = 0; | 3570 const intptr_t kNumTemps = 0; |
3571 LocationSummary* summary = | 3571 LocationSummary* summary = |
3572 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3572 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3573 summary->set_in(0, Location::RequiresFpuRegister()); | 3573 summary->set_in(0, Location::RequiresFpuRegister()); |
3574 summary->set_out(Location::SameAsFirstInput()); | 3574 summary->set_out(Location::SameAsFirstInput()); |
3575 return summary; | 3575 return summary; |
3576 } | 3576 } |
3577 | 3577 |
3578 | 3578 |
3579 void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3579 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3580 // NOP. | 3580 // NOP. |
3581 } | 3581 } |
3582 | 3582 |
3583 | 3583 |
3584 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const { | 3584 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { |
3585 const intptr_t kNumInputs = 4; | 3585 const intptr_t kNumInputs = 4; |
3586 const intptr_t kNumTemps = 1; | 3586 const intptr_t kNumTemps = 1; |
3587 LocationSummary* summary = | 3587 LocationSummary* summary = |
3588 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3588 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3589 summary->set_in(0, Location::RequiresRegister()); | 3589 summary->set_in(0, Location::RequiresRegister()); |
3590 summary->set_in(1, Location::RequiresRegister()); | 3590 summary->set_in(1, Location::RequiresRegister()); |
3591 summary->set_in(2, Location::RequiresRegister()); | 3591 summary->set_in(2, Location::RequiresRegister()); |
3592 summary->set_in(3, Location::RequiresRegister()); | 3592 summary->set_in(3, Location::RequiresRegister()); |
3593 summary->set_temp(0, Location::RequiresRegister()); | 3593 summary->set_temp(0, Location::RequiresRegister()); |
3594 summary->set_out(Location::RequiresFpuRegister()); | 3594 summary->set_out(Location::RequiresFpuRegister()); |
3595 return summary; | 3595 return summary; |
3596 } | 3596 } |
3597 | 3597 |
3598 | 3598 |
3599 void Uint32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3599 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3600 Register v0 = locs()->in(0).reg(); | 3600 Register v0 = locs()->in(0).reg(); |
3601 Register v1 = locs()->in(1).reg(); | 3601 Register v1 = locs()->in(1).reg(); |
3602 Register v2 = locs()->in(2).reg(); | 3602 Register v2 = locs()->in(2).reg(); |
3603 Register v3 = locs()->in(3).reg(); | 3603 Register v3 = locs()->in(3).reg(); |
3604 Register temp = locs()->temp(0).reg(); | 3604 Register temp = locs()->temp(0).reg(); |
3605 XmmRegister result = locs()->out().fpu_reg(); | 3605 XmmRegister result = locs()->out().fpu_reg(); |
3606 Label x_false, x_done; | 3606 Label x_false, x_done; |
3607 Label y_false, y_done; | 3607 Label y_false, y_done; |
3608 Label z_false, z_done; | 3608 Label z_false, z_done; |
3609 Label w_false, w_done; | 3609 Label w_false, w_done; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3643 __ Bind(&w_false); | 3643 __ Bind(&w_false); |
3644 __ LoadImmediate(temp, Immediate(0x0), PP); | 3644 __ LoadImmediate(temp, Immediate(0x0), PP); |
3645 __ Bind(&w_done); | 3645 __ Bind(&w_done); |
3646 __ movl(Address(RSP, 12), temp); | 3646 __ movl(Address(RSP, 12), temp); |
3647 | 3647 |
3648 __ movups(result, Address(RSP, 0)); | 3648 __ movups(result, Address(RSP, 0)); |
3649 __ AddImmediate(RSP, Immediate(16), PP); | 3649 __ AddImmediate(RSP, Immediate(16), PP); |
3650 } | 3650 } |
3651 | 3651 |
3652 | 3652 |
3653 LocationSummary* Uint32x4GetFlagInstr::MakeLocationSummary() const { | 3653 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { |
3654 const intptr_t kNumInputs = 1; | 3654 const intptr_t kNumInputs = 1; |
3655 const intptr_t kNumTemps = 0; | 3655 const intptr_t kNumTemps = 0; |
3656 LocationSummary* summary = | 3656 LocationSummary* summary = |
3657 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3657 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3658 summary->set_in(0, Location::RequiresFpuRegister()); | 3658 summary->set_in(0, Location::RequiresFpuRegister()); |
3659 summary->set_out(Location::RequiresRegister()); | 3659 summary->set_out(Location::RequiresRegister()); |
3660 return summary; | 3660 return summary; |
3661 } | 3661 } |
3662 | 3662 |
3663 | 3663 |
3664 void Uint32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3664 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3665 XmmRegister value = locs()->in(0).fpu_reg(); | 3665 XmmRegister value = locs()->in(0).fpu_reg(); |
3666 Register result = locs()->out().reg(); | 3666 Register result = locs()->out().reg(); |
3667 Label done; | 3667 Label done; |
3668 Label non_zero; | 3668 Label non_zero; |
3669 __ AddImmediate(RSP, Immediate(-16), PP); | 3669 __ AddImmediate(RSP, Immediate(-16), PP); |
3670 // Move value to stack. | 3670 // Move value to stack. |
3671 __ movups(Address(RSP, 0), value); | 3671 __ movups(Address(RSP, 0), value); |
3672 switch (op_kind()) { | 3672 switch (op_kind()) { |
3673 case MethodRecognizer::kUint32x4GetFlagX: | 3673 case MethodRecognizer::kInt32x4GetFlagX: |
3674 __ movl(result, Address(RSP, 0)); | 3674 __ movl(result, Address(RSP, 0)); |
3675 break; | 3675 break; |
3676 case MethodRecognizer::kUint32x4GetFlagY: | 3676 case MethodRecognizer::kInt32x4GetFlagY: |
3677 __ movl(result, Address(RSP, 4)); | 3677 __ movl(result, Address(RSP, 4)); |
3678 break; | 3678 break; |
3679 case MethodRecognizer::kUint32x4GetFlagZ: | 3679 case MethodRecognizer::kInt32x4GetFlagZ: |
3680 __ movl(result, Address(RSP, 8)); | 3680 __ movl(result, Address(RSP, 8)); |
3681 break; | 3681 break; |
3682 case MethodRecognizer::kUint32x4GetFlagW: | 3682 case MethodRecognizer::kInt32x4GetFlagW: |
3683 __ movl(result, Address(RSP, 12)); | 3683 __ movl(result, Address(RSP, 12)); |
3684 break; | 3684 break; |
3685 default: UNREACHABLE(); | 3685 default: UNREACHABLE(); |
3686 } | 3686 } |
3687 __ AddImmediate(RSP, Immediate(16), PP); | 3687 __ AddImmediate(RSP, Immediate(16), PP); |
3688 __ testl(result, result); | 3688 __ testl(result, result); |
3689 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); | 3689 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); |
3690 __ LoadObject(result, Bool::False(), PP); | 3690 __ LoadObject(result, Bool::False(), PP); |
3691 __ jmp(&done); | 3691 __ jmp(&done); |
3692 __ Bind(&non_zero); | 3692 __ Bind(&non_zero); |
3693 __ LoadObject(result, Bool::True(), PP); | 3693 __ LoadObject(result, Bool::True(), PP); |
3694 __ Bind(&done); | 3694 __ Bind(&done); |
3695 } | 3695 } |
3696 | 3696 |
3697 | 3697 |
3698 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const { | 3698 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { |
3699 const intptr_t kNumInputs = 3; | 3699 const intptr_t kNumInputs = 3; |
3700 const intptr_t kNumTemps = 1; | 3700 const intptr_t kNumTemps = 1; |
3701 LocationSummary* summary = | 3701 LocationSummary* summary = |
3702 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3702 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3703 summary->set_in(0, Location::RequiresFpuRegister()); | 3703 summary->set_in(0, Location::RequiresFpuRegister()); |
3704 summary->set_in(1, Location::RequiresFpuRegister()); | 3704 summary->set_in(1, Location::RequiresFpuRegister()); |
3705 summary->set_in(2, Location::RequiresFpuRegister()); | 3705 summary->set_in(2, Location::RequiresFpuRegister()); |
3706 summary->set_temp(0, Location::RequiresFpuRegister()); | 3706 summary->set_temp(0, Location::RequiresFpuRegister()); |
3707 summary->set_out(Location::SameAsFirstInput()); | 3707 summary->set_out(Location::SameAsFirstInput()); |
3708 return summary; | 3708 return summary; |
3709 } | 3709 } |
3710 | 3710 |
3711 | 3711 |
3712 void Uint32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3712 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3713 XmmRegister mask = locs()->in(0).fpu_reg(); | 3713 XmmRegister mask = locs()->in(0).fpu_reg(); |
3714 XmmRegister trueValue = locs()->in(1).fpu_reg(); | 3714 XmmRegister trueValue = locs()->in(1).fpu_reg(); |
3715 XmmRegister falseValue = locs()->in(2).fpu_reg(); | 3715 XmmRegister falseValue = locs()->in(2).fpu_reg(); |
3716 XmmRegister out = locs()->out().fpu_reg(); | 3716 XmmRegister out = locs()->out().fpu_reg(); |
3717 XmmRegister temp = locs()->temp(0).fpu_reg(); | 3717 XmmRegister temp = locs()->temp(0).fpu_reg(); |
3718 ASSERT(out == mask); | 3718 ASSERT(out == mask); |
3719 // Copy mask. | 3719 // Copy mask. |
3720 __ movaps(temp, mask); | 3720 __ movaps(temp, mask); |
3721 // Invert it. | 3721 // Invert it. |
3722 __ notps(temp); | 3722 __ notps(temp); |
3723 // mask = mask & trueValue. | 3723 // mask = mask & trueValue. |
3724 __ andps(mask, trueValue); | 3724 __ andps(mask, trueValue); |
3725 // temp = temp & falseValue. | 3725 // temp = temp & falseValue. |
3726 __ andps(temp, falseValue); | 3726 __ andps(temp, falseValue); |
3727 // out = mask | temp. | 3727 // out = mask | temp. |
3728 __ orps(mask, temp); | 3728 __ orps(mask, temp); |
3729 } | 3729 } |
3730 | 3730 |
3731 | 3731 |
3732 LocationSummary* Uint32x4SetFlagInstr::MakeLocationSummary() const { | 3732 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { |
3733 const intptr_t kNumInputs = 2; | 3733 const intptr_t kNumInputs = 2; |
3734 const intptr_t kNumTemps = 1; | 3734 const intptr_t kNumTemps = 1; |
3735 LocationSummary* summary = | 3735 LocationSummary* summary = |
3736 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3736 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3737 summary->set_in(0, Location::RequiresFpuRegister()); | 3737 summary->set_in(0, Location::RequiresFpuRegister()); |
3738 summary->set_in(1, Location::RequiresRegister()); | 3738 summary->set_in(1, Location::RequiresRegister()); |
3739 summary->set_temp(0, Location::RequiresRegister()); | 3739 summary->set_temp(0, Location::RequiresRegister()); |
3740 summary->set_out(Location::SameAsFirstInput()); | 3740 summary->set_out(Location::SameAsFirstInput()); |
3741 return summary; | 3741 return summary; |
3742 } | 3742 } |
3743 | 3743 |
3744 | 3744 |
3745 void Uint32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3745 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3746 XmmRegister mask = locs()->in(0).fpu_reg(); | 3746 XmmRegister mask = locs()->in(0).fpu_reg(); |
3747 Register flag = locs()->in(1).reg(); | 3747 Register flag = locs()->in(1).reg(); |
3748 Register temp = locs()->temp(0).reg(); | 3748 Register temp = locs()->temp(0).reg(); |
3749 ASSERT(mask == locs()->out().fpu_reg()); | 3749 ASSERT(mask == locs()->out().fpu_reg()); |
3750 __ AddImmediate(RSP, Immediate(-16), PP); | 3750 __ AddImmediate(RSP, Immediate(-16), PP); |
3751 // Copy mask to stack. | 3751 // Copy mask to stack. |
3752 __ movups(Address(RSP, 0), mask); | 3752 __ movups(Address(RSP, 0), mask); |
3753 Label falsePath, exitPath; | 3753 Label falsePath, exitPath; |
3754 __ CompareObject(flag, Bool::True(), PP); | 3754 __ CompareObject(flag, Bool::True(), PP); |
3755 __ j(NOT_EQUAL, &falsePath); | 3755 __ j(NOT_EQUAL, &falsePath); |
3756 switch (op_kind()) { | 3756 switch (op_kind()) { |
3757 case MethodRecognizer::kUint32x4WithFlagX: | 3757 case MethodRecognizer::kInt32x4WithFlagX: |
3758 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); | 3758 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); |
3759 __ movl(Address(RSP, 0), temp); | 3759 __ movl(Address(RSP, 0), temp); |
3760 __ jmp(&exitPath); | 3760 __ jmp(&exitPath); |
3761 __ Bind(&falsePath); | 3761 __ Bind(&falsePath); |
3762 __ LoadImmediate(temp, Immediate(0x0), PP); | 3762 __ LoadImmediate(temp, Immediate(0x0), PP); |
3763 __ movl(Address(RSP, 0), temp); | 3763 __ movl(Address(RSP, 0), temp); |
3764 break; | 3764 break; |
3765 case MethodRecognizer::kUint32x4WithFlagY: | 3765 case MethodRecognizer::kInt32x4WithFlagY: |
3766 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); | 3766 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); |
3767 __ movl(Address(RSP, 4), temp); | 3767 __ movl(Address(RSP, 4), temp); |
3768 __ jmp(&exitPath); | 3768 __ jmp(&exitPath); |
3769 __ Bind(&falsePath); | 3769 __ Bind(&falsePath); |
3770 __ LoadImmediate(temp, Immediate(0x0), PP); | 3770 __ LoadImmediate(temp, Immediate(0x0), PP); |
3771 __ movl(Address(RSP, 4), temp); | 3771 __ movl(Address(RSP, 4), temp); |
3772 break; | 3772 break; |
3773 case MethodRecognizer::kUint32x4WithFlagZ: | 3773 case MethodRecognizer::kInt32x4WithFlagZ: |
3774 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); | 3774 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); |
3775 __ movl(Address(RSP, 8), temp); | 3775 __ movl(Address(RSP, 8), temp); |
3776 __ jmp(&exitPath); | 3776 __ jmp(&exitPath); |
3777 __ Bind(&falsePath); | 3777 __ Bind(&falsePath); |
3778 __ LoadImmediate(temp, Immediate(0x0), PP); | 3778 __ LoadImmediate(temp, Immediate(0x0), PP); |
3779 __ movl(Address(RSP, 8), temp); | 3779 __ movl(Address(RSP, 8), temp); |
3780 break; | 3780 break; |
3781 case MethodRecognizer::kUint32x4WithFlagW: | 3781 case MethodRecognizer::kInt32x4WithFlagW: |
3782 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); | 3782 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); |
3783 __ movl(Address(RSP, 12), temp); | 3783 __ movl(Address(RSP, 12), temp); |
3784 __ jmp(&exitPath); | 3784 __ jmp(&exitPath); |
3785 __ Bind(&falsePath); | 3785 __ Bind(&falsePath); |
3786 __ LoadImmediate(temp, Immediate(0x0), PP); | 3786 __ LoadImmediate(temp, Immediate(0x0), PP); |
3787 __ movl(Address(RSP, 12), temp); | 3787 __ movl(Address(RSP, 12), temp); |
3788 break; | 3788 break; |
3789 default: UNREACHABLE(); | 3789 default: UNREACHABLE(); |
3790 } | 3790 } |
3791 __ Bind(&exitPath); | 3791 __ Bind(&exitPath); |
3792 // Copy mask back to register. | 3792 // Copy mask back to register. |
3793 __ movups(mask, Address(RSP, 0)); | 3793 __ movups(mask, Address(RSP, 0)); |
3794 __ AddImmediate(RSP, Immediate(16), PP); | 3794 __ AddImmediate(RSP, Immediate(16), PP); |
3795 } | 3795 } |
3796 | 3796 |
3797 | 3797 |
3798 LocationSummary* Uint32x4ToFloat32x4Instr::MakeLocationSummary() const { | 3798 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { |
3799 const intptr_t kNumInputs = 1; | 3799 const intptr_t kNumInputs = 1; |
3800 const intptr_t kNumTemps = 0; | 3800 const intptr_t kNumTemps = 0; |
3801 LocationSummary* summary = | 3801 LocationSummary* summary = |
3802 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3802 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3803 summary->set_in(0, Location::RequiresFpuRegister()); | 3803 summary->set_in(0, Location::RequiresFpuRegister()); |
3804 summary->set_out(Location::SameAsFirstInput()); | 3804 summary->set_out(Location::SameAsFirstInput()); |
3805 return summary; | 3805 return summary; |
3806 } | 3806 } |
3807 | 3807 |
3808 | 3808 |
3809 void Uint32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3809 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3810 // NOP. | 3810 // NOP. |
3811 } | 3811 } |
3812 | 3812 |
3813 | 3813 |
3814 LocationSummary* BinaryUint32x4OpInstr::MakeLocationSummary() const { | 3814 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { |
3815 const intptr_t kNumInputs = 2; | 3815 const intptr_t kNumInputs = 2; |
3816 const intptr_t kNumTemps = 0; | 3816 const intptr_t kNumTemps = 0; |
3817 LocationSummary* summary = | 3817 LocationSummary* summary = |
3818 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3818 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3819 summary->set_in(0, Location::RequiresFpuRegister()); | 3819 summary->set_in(0, Location::RequiresFpuRegister()); |
3820 summary->set_in(1, Location::RequiresFpuRegister()); | 3820 summary->set_in(1, Location::RequiresFpuRegister()); |
3821 summary->set_out(Location::SameAsFirstInput()); | 3821 summary->set_out(Location::SameAsFirstInput()); |
3822 return summary; | 3822 return summary; |
3823 } | 3823 } |
3824 | 3824 |
3825 | 3825 |
3826 void BinaryUint32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3826 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3827 XmmRegister left = locs()->in(0).fpu_reg(); | 3827 XmmRegister left = locs()->in(0).fpu_reg(); |
3828 XmmRegister right = locs()->in(1).fpu_reg(); | 3828 XmmRegister right = locs()->in(1).fpu_reg(); |
3829 ASSERT(left == locs()->out().fpu_reg()); | 3829 ASSERT(left == locs()->out().fpu_reg()); |
3830 switch (op_kind()) { | 3830 switch (op_kind()) { |
3831 case Token::kBIT_AND: { | 3831 case Token::kBIT_AND: { |
3832 __ andps(left, right); | 3832 __ andps(left, right); |
3833 break; | 3833 break; |
3834 } | 3834 } |
3835 case Token::kBIT_OR: { | 3835 case Token::kBIT_OR: { |
3836 __ orps(left, right); | 3836 __ orps(left, right); |
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4807 PcDescriptors::kOther, | 4807 PcDescriptors::kOther, |
4808 locs()); | 4808 locs()); |
4809 __ Drop(2); // Discard type arguments and receiver. | 4809 __ Drop(2); // Discard type arguments and receiver. |
4810 } | 4810 } |
4811 | 4811 |
4812 } // namespace dart | 4812 } // namespace dart |
4813 | 4813 |
4814 #undef __ | 4814 #undef __ |
4815 | 4815 |
4816 #endif // defined TARGET_ARCH_X64 | 4816 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |