| 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 |