| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 switch (class_id_) { | 1043 switch (class_id_) { |
| 1044 case kArrayCid: | 1044 case kArrayCid: |
| 1045 case kImmutableArrayCid: | 1045 case kImmutableArrayCid: |
| 1046 return CompileType::Dynamic(); | 1046 return CompileType::Dynamic(); |
| 1047 | 1047 |
| 1048 case kTypedDataFloat32ArrayCid: | 1048 case kTypedDataFloat32ArrayCid: |
| 1049 case kTypedDataFloat64ArrayCid: | 1049 case kTypedDataFloat64ArrayCid: |
| 1050 return CompileType::FromCid(kDoubleCid); | 1050 return CompileType::FromCid(kDoubleCid); |
| 1051 case kTypedDataFloat32x4ArrayCid: | 1051 case kTypedDataFloat32x4ArrayCid: |
| 1052 return CompileType::FromCid(kFloat32x4Cid); | 1052 return CompileType::FromCid(kFloat32x4Cid); |
| 1053 case kTypedDataUint32x4ArrayCid: | 1053 case kTypedDataInt32x4ArrayCid: |
| 1054 return CompileType::FromCid(kUint32x4Cid); | 1054 return CompileType::FromCid(kInt32x4Cid); |
| 1055 | 1055 |
| 1056 case kTypedDataInt8ArrayCid: | 1056 case kTypedDataInt8ArrayCid: |
| 1057 case kTypedDataUint8ArrayCid: | 1057 case kTypedDataUint8ArrayCid: |
| 1058 case kTypedDataUint8ClampedArrayCid: | 1058 case kTypedDataUint8ClampedArrayCid: |
| 1059 case kExternalTypedDataUint8ArrayCid: | 1059 case kExternalTypedDataUint8ArrayCid: |
| 1060 case kExternalTypedDataUint8ClampedArrayCid: | 1060 case kExternalTypedDataUint8ClampedArrayCid: |
| 1061 case kTypedDataInt16ArrayCid: | 1061 case kTypedDataInt16ArrayCid: |
| 1062 case kTypedDataUint16ArrayCid: | 1062 case kTypedDataUint16ArrayCid: |
| 1063 case kOneByteStringCid: | 1063 case kOneByteStringCid: |
| 1064 case kTwoByteStringCid: | 1064 case kTwoByteStringCid: |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1096 case kTypedDataInt32ArrayCid: | 1096 case kTypedDataInt32ArrayCid: |
| 1097 case kTypedDataUint32ArrayCid: | 1097 case kTypedDataUint32ArrayCid: |
| 1098 // Instruction can deoptimize if we optimistically assumed that the result | 1098 // Instruction can deoptimize if we optimistically assumed that the result |
| 1099 // fits into Smi. | 1099 // fits into Smi. |
| 1100 return CanDeoptimize() ? kTagged : kUnboxedMint; | 1100 return CanDeoptimize() ? kTagged : kUnboxedMint; |
| 1101 case kTypedDataFloat32ArrayCid: | 1101 case kTypedDataFloat32ArrayCid: |
| 1102 case kTypedDataFloat64ArrayCid: | 1102 case kTypedDataFloat64ArrayCid: |
| 1103 return kUnboxedDouble; | 1103 return kUnboxedDouble; |
| 1104 case kTypedDataFloat32x4ArrayCid: | 1104 case kTypedDataFloat32x4ArrayCid: |
| 1105 return kUnboxedFloat32x4; | 1105 return kUnboxedFloat32x4; |
| 1106 case kTypedDataUint32x4ArrayCid: | 1106 case kTypedDataInt32x4ArrayCid: |
| 1107 return kUnboxedUint32x4; | 1107 return kUnboxedInt32x4; |
| 1108 default: | 1108 default: |
| 1109 UNIMPLEMENTED(); | 1109 UNIMPLEMENTED(); |
| 1110 return kTagged; | 1110 return kTagged; |
| 1111 } | 1111 } |
| 1112 } | 1112 } |
| 1113 | 1113 |
| 1114 | 1114 |
| 1115 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1115 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 1116 const intptr_t kNumInputs = 2; | 1116 const intptr_t kNumInputs = 2; |
| 1117 const intptr_t kNumTemps = 0; | 1117 const intptr_t kNumTemps = 0; |
| 1118 LocationSummary* locs = | 1118 LocationSummary* locs = |
| 1119 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1119 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1120 locs->set_in(0, Location::RequiresRegister()); | 1120 locs->set_in(0, Location::RequiresRegister()); |
| 1121 if (CanBeImmediateIndex(index(), class_id())) { | 1121 if (CanBeImmediateIndex(index(), class_id())) { |
| 1122 // CanBeImmediateIndex must return false for unsafe smis. | 1122 // CanBeImmediateIndex must return false for unsafe smis. |
| 1123 locs->set_in(1, Location::Constant(index()->BoundConstant())); | 1123 locs->set_in(1, Location::Constant(index()->BoundConstant())); |
| 1124 } else { | 1124 } else { |
| 1125 // The index is either untagged (element size == 1) or a smi (for all | 1125 // The index is either untagged (element size == 1) or a smi (for all |
| 1126 // element sizes > 1). | 1126 // element sizes > 1). |
| 1127 locs->set_in(1, (index_scale() == 1) | 1127 locs->set_in(1, (index_scale() == 1) |
| 1128 ? Location::WritableRegister() | 1128 ? Location::WritableRegister() |
| 1129 : Location::RequiresRegister()); | 1129 : Location::RequiresRegister()); |
| 1130 } | 1130 } |
| 1131 if ((representation() == kUnboxedDouble) || | 1131 if ((representation() == kUnboxedDouble) || |
| 1132 (representation() == kUnboxedFloat32x4) || | 1132 (representation() == kUnboxedFloat32x4) || |
| 1133 (representation() == kUnboxedUint32x4)) { | 1133 (representation() == kUnboxedInt32x4)) { |
| 1134 locs->set_out(Location::RequiresFpuRegister()); | 1134 locs->set_out(Location::RequiresFpuRegister()); |
| 1135 } else { | 1135 } else { |
| 1136 locs->set_out(Location::RequiresRegister()); | 1136 locs->set_out(Location::RequiresRegister()); |
| 1137 } | 1137 } |
| 1138 return locs; | 1138 return locs; |
| 1139 } | 1139 } |
| 1140 | 1140 |
| 1141 | 1141 |
| 1142 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1142 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1143 Register array = locs()->in(0).reg(); | 1143 Register array = locs()->in(0).reg(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1156 ? FlowGraphCompiler::ElementAddressForRegIndex( | 1156 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1157 class_id(), index_scale(), array, index.reg()) | 1157 class_id(), index_scale(), array, index.reg()) |
| 1158 : FlowGraphCompiler::ElementAddressForIntIndex( | 1158 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1159 class_id(), index_scale(), array, | 1159 class_id(), index_scale(), array, |
| 1160 Smi::Cast(index.constant()).Value()); | 1160 Smi::Cast(index.constant()).Value()); |
| 1161 } | 1161 } |
| 1162 | 1162 |
| 1163 if ((representation() == kUnboxedDouble) || | 1163 if ((representation() == kUnboxedDouble) || |
| 1164 (representation() == kUnboxedMint) || | 1164 (representation() == kUnboxedMint) || |
| 1165 (representation() == kUnboxedFloat32x4) || | 1165 (representation() == kUnboxedFloat32x4) || |
| 1166 (representation() == kUnboxedUint32x4)) { | 1166 (representation() == kUnboxedInt32x4)) { |
| 1167 XmmRegister result = locs()->out().fpu_reg(); | 1167 XmmRegister result = locs()->out().fpu_reg(); |
| 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 switch (class_id()) { | 1171 switch (class_id()) { |
| 1172 case kTypedDataInt32ArrayCid: | 1172 case kTypedDataInt32ArrayCid: |
| 1173 __ movss(result, element_address); | 1173 __ movss(result, element_address); |
| 1174 __ pmovsxdq(result, result); | 1174 __ pmovsxdq(result, result); |
| 1175 break; | 1175 break; |
| 1176 case kTypedDataUint32ArrayCid: | 1176 case kTypedDataUint32ArrayCid: |
| 1177 __ xorpd(result, result); | 1177 __ xorpd(result, result); |
| 1178 __ movss(result, element_address); | 1178 __ movss(result, element_address); |
| 1179 break; | 1179 break; |
| 1180 case kTypedDataFloat32ArrayCid: | 1180 case kTypedDataFloat32ArrayCid: |
| 1181 // Load single precision float and promote to double. | 1181 // Load single precision float and promote to double. |
| 1182 __ movss(result, element_address); | 1182 __ movss(result, element_address); |
| 1183 __ cvtss2sd(result, locs()->out().fpu_reg()); | 1183 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 1184 break; | 1184 break; |
| 1185 case kTypedDataFloat64ArrayCid: | 1185 case kTypedDataFloat64ArrayCid: |
| 1186 __ movsd(result, element_address); | 1186 __ movsd(result, element_address); |
| 1187 break; | 1187 break; |
| 1188 case kTypedDataUint32x4ArrayCid: | 1188 case kTypedDataInt32x4ArrayCid: |
| 1189 case kTypedDataFloat32x4ArrayCid: | 1189 case kTypedDataFloat32x4ArrayCid: |
| 1190 __ movups(result, element_address); | 1190 __ movups(result, element_address); |
| 1191 break; | 1191 break; |
| 1192 } | 1192 } |
| 1193 return; | 1193 return; |
| 1194 } | 1194 } |
| 1195 | 1195 |
| 1196 Register result = locs()->out().reg(); | 1196 Register result = locs()->out().reg(); |
| 1197 if ((index_scale() == 1) && index.IsRegister()) { | 1197 if ((index_scale() == 1) && index.IsRegister()) { |
| 1198 __ SmiUntag(index.reg()); | 1198 __ SmiUntag(index.reg()); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1265 case kTypedDataUint16ArrayCid: | 1265 case kTypedDataUint16ArrayCid: |
| 1266 return kTagged; | 1266 return kTagged; |
| 1267 case kTypedDataInt32ArrayCid: | 1267 case kTypedDataInt32ArrayCid: |
| 1268 case kTypedDataUint32ArrayCid: | 1268 case kTypedDataUint32ArrayCid: |
| 1269 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 1269 return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
| 1270 case kTypedDataFloat32ArrayCid: | 1270 case kTypedDataFloat32ArrayCid: |
| 1271 case kTypedDataFloat64ArrayCid: | 1271 case kTypedDataFloat64ArrayCid: |
| 1272 return kUnboxedDouble; | 1272 return kUnboxedDouble; |
| 1273 case kTypedDataFloat32x4ArrayCid: | 1273 case kTypedDataFloat32x4ArrayCid: |
| 1274 return kUnboxedFloat32x4; | 1274 return kUnboxedFloat32x4; |
| 1275 case kTypedDataUint32x4ArrayCid: | 1275 case kTypedDataInt32x4ArrayCid: |
| 1276 return kUnboxedUint32x4; | 1276 return kUnboxedInt32x4; |
| 1277 default: | 1277 default: |
| 1278 UNIMPLEMENTED(); | 1278 UNIMPLEMENTED(); |
| 1279 return kTagged; | 1279 return kTagged; |
| 1280 } | 1280 } |
| 1281 } | 1281 } |
| 1282 | 1282 |
| 1283 | 1283 |
| 1284 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1284 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 1285 const intptr_t kNumInputs = 3; | 1285 const intptr_t kNumInputs = 3; |
| 1286 const intptr_t kNumTemps = 0; | 1286 const intptr_t kNumTemps = 0; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1327 : Location::RequiresFpuRegister()); | 1327 : Location::RequiresFpuRegister()); |
| 1328 break; | 1328 break; |
| 1329 case kTypedDataFloat32ArrayCid: | 1329 case kTypedDataFloat32ArrayCid: |
| 1330 // Need temp register for float-to-double conversion. | 1330 // Need temp register for float-to-double conversion. |
| 1331 locs->AddTemp(Location::RequiresFpuRegister()); | 1331 locs->AddTemp(Location::RequiresFpuRegister()); |
| 1332 // Fall through. | 1332 // Fall through. |
| 1333 case kTypedDataFloat64ArrayCid: | 1333 case kTypedDataFloat64ArrayCid: |
| 1334 // TODO(srdjan): Support Float64 constants. | 1334 // TODO(srdjan): Support Float64 constants. |
| 1335 locs->set_in(2, Location::RequiresFpuRegister()); | 1335 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1336 break; | 1336 break; |
| 1337 case kTypedDataUint32x4ArrayCid: | 1337 case kTypedDataInt32x4ArrayCid: |
| 1338 case kTypedDataFloat32x4ArrayCid: | 1338 case kTypedDataFloat32x4ArrayCid: |
| 1339 locs->set_in(2, Location::RequiresFpuRegister()); | 1339 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1340 break; | 1340 break; |
| 1341 default: | 1341 default: |
| 1342 UNREACHABLE(); | 1342 UNREACHABLE(); |
| 1343 return NULL; | 1343 return NULL; |
| 1344 } | 1344 } |
| 1345 return locs; | 1345 return locs; |
| 1346 } | 1346 } |
| 1347 | 1347 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 break; | 1448 break; |
| 1449 case kTypedDataFloat32ArrayCid: | 1449 case kTypedDataFloat32ArrayCid: |
| 1450 // Convert to single precision. | 1450 // Convert to single precision. |
| 1451 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); | 1451 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
| 1452 // Store. | 1452 // Store. |
| 1453 __ movss(element_address, locs()->temp(0).fpu_reg()); | 1453 __ movss(element_address, locs()->temp(0).fpu_reg()); |
| 1454 break; | 1454 break; |
| 1455 case kTypedDataFloat64ArrayCid: | 1455 case kTypedDataFloat64ArrayCid: |
| 1456 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1456 __ movsd(element_address, locs()->in(2).fpu_reg()); |
| 1457 break; | 1457 break; |
| 1458 case kTypedDataUint32x4ArrayCid: | 1458 case kTypedDataInt32x4ArrayCid: |
| 1459 case kTypedDataFloat32x4ArrayCid: | 1459 case kTypedDataFloat32x4ArrayCid: |
| 1460 __ movups(element_address, locs()->in(2).fpu_reg()); | 1460 __ movups(element_address, locs()->in(2).fpu_reg()); |
| 1461 break; | 1461 break; |
| 1462 default: | 1462 default: |
| 1463 UNREACHABLE(); | 1463 UNREACHABLE(); |
| 1464 } | 1464 } |
| 1465 } | 1465 } |
| 1466 | 1466 |
| 1467 | 1467 |
| 1468 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1468 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1578 // without triggering a deoptimization. | 1578 // without triggering a deoptimization. |
| 1579 Label check_array, length_compared, no_fixed_length; | 1579 Label check_array, length_compared, no_fixed_length; |
| 1580 // If length is negative the length guard is either disabled or | 1580 // If length is negative the length guard is either disabled or |
| 1581 // has not been initialized, either way it is safe to skip the | 1581 // has not been initialized, either way it is safe to skip the |
| 1582 // length check. | 1582 // length check. |
| 1583 __ cmpl(field_length_operand, Immediate(Smi::RawValue(0))); | 1583 __ cmpl(field_length_operand, Immediate(Smi::RawValue(0))); |
| 1584 __ j(LESS, &skip_length_check); | 1584 __ j(LESS, &skip_length_check); |
| 1585 __ cmpl(value_cid_reg, Immediate(kNullCid)); | 1585 __ cmpl(value_cid_reg, Immediate(kNullCid)); |
| 1586 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1586 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
| 1587 // Check for typed data array. | 1587 // Check for typed data array. |
| 1588 __ cmpl(value_cid_reg, Immediate(kTypedDataUint32x4ArrayCid)); | 1588 __ cmpl(value_cid_reg, Immediate(kTypedDataInt32x4ArrayCid)); |
| 1589 // Not a typed array or a regular array. | 1589 // Not a typed array or a regular array. |
| 1590 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); | 1590 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); |
| 1591 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); | 1591 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); |
| 1592 // Could still be a regular array. | 1592 // Could still be a regular array. |
| 1593 __ j(LESS, &check_array, Assembler::kNearJump); | 1593 __ j(LESS, &check_array, Assembler::kNearJump); |
| 1594 __ pushl(value_cid_reg); | 1594 __ pushl(value_cid_reg); |
| 1595 __ movl(value_cid_reg, | 1595 __ movl(value_cid_reg, |
| 1596 FieldAddress(value_reg, TypedData::length_offset())); | 1596 FieldAddress(value_reg, TypedData::length_offset())); |
| 1597 __ cmpl(field_length_operand, value_cid_reg); | 1597 __ cmpl(field_length_operand, value_cid_reg); |
| 1598 __ popl(value_cid_reg); | 1598 __ popl(value_cid_reg); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1665 // At this point the field guard is being initialized for the first time. | 1665 // At this point the field guard is being initialized for the first time. |
| 1666 if (value_cid == kDynamicCid) { | 1666 if (value_cid == kDynamicCid) { |
| 1667 // Do not know value's class id. | 1667 // Do not know value's class id. |
| 1668 __ movl(field_cid_operand, value_cid_reg); | 1668 __ movl(field_cid_operand, value_cid_reg); |
| 1669 __ movl(field_nullability_operand, value_cid_reg); | 1669 __ movl(field_nullability_operand, value_cid_reg); |
| 1670 if (field_has_length) { | 1670 if (field_has_length) { |
| 1671 Label check_array, length_set, no_fixed_length; | 1671 Label check_array, length_set, no_fixed_length; |
| 1672 __ cmpl(value_cid_reg, Immediate(kNullCid)); | 1672 __ cmpl(value_cid_reg, Immediate(kNullCid)); |
| 1673 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1673 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
| 1674 // Check for typed data array. | 1674 // Check for typed data array. |
| 1675 __ cmpl(value_cid_reg, Immediate(kTypedDataUint32x4ArrayCid)); | 1675 __ cmpl(value_cid_reg, Immediate(kTypedDataInt32x4ArrayCid)); |
| 1676 // Not a typed array or a regular array. | 1676 // Not a typed array or a regular array. |
| 1677 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); | 1677 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); |
| 1678 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); | 1678 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); |
| 1679 // Could still be a regular array. | 1679 // Could still be a regular array. |
| 1680 __ j(LESS, &check_array, Assembler::kNearJump); | 1680 __ j(LESS, &check_array, Assembler::kNearJump); |
| 1681 // Destroy value_cid_reg (safe because we are finished with it). | 1681 // Destroy value_cid_reg (safe because we are finished with it). |
| 1682 __ movl(value_cid_reg, | 1682 __ movl(value_cid_reg, |
| 1683 FieldAddress(value_reg, TypedData::length_offset())); | 1683 FieldAddress(value_reg, TypedData::length_offset())); |
| 1684 __ movl(field_length_operand, value_cid_reg); | 1684 __ movl(field_length_operand, value_cid_reg); |
| 1685 // Updated field length typed data array. | 1685 // Updated field length typed data array. |
| (...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2977 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 2977 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 2978 __ testl(value, Immediate(kSmiTagMask)); | 2978 __ testl(value, Immediate(kSmiTagMask)); |
| 2979 __ j(ZERO, deopt); | 2979 __ j(ZERO, deopt); |
| 2980 __ CompareClassId(value, kFloat32x4Cid, temp); | 2980 __ CompareClassId(value, kFloat32x4Cid, temp); |
| 2981 __ j(NOT_EQUAL, deopt); | 2981 __ j(NOT_EQUAL, deopt); |
| 2982 } | 2982 } |
| 2983 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | 2983 __ movups(result, FieldAddress(value, Float32x4::value_offset())); |
| 2984 } | 2984 } |
| 2985 | 2985 |
| 2986 | 2986 |
| 2987 LocationSummary* BoxUint32x4Instr::MakeLocationSummary() const { | 2987 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { |
| 2988 const intptr_t kNumInputs = 1; | 2988 const intptr_t kNumInputs = 1; |
| 2989 const intptr_t kNumTemps = 0; | 2989 const intptr_t kNumTemps = 0; |
| 2990 LocationSummary* summary = | 2990 LocationSummary* summary = |
| 2991 new LocationSummary(kNumInputs, | 2991 new LocationSummary(kNumInputs, |
| 2992 kNumTemps, | 2992 kNumTemps, |
| 2993 LocationSummary::kCallOnSlowPath); | 2993 LocationSummary::kCallOnSlowPath); |
| 2994 summary->set_in(0, Location::RequiresFpuRegister()); | 2994 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2995 summary->set_out(Location::RequiresRegister()); | 2995 summary->set_out(Location::RequiresRegister()); |
| 2996 return summary; | 2996 return summary; |
| 2997 } | 2997 } |
| 2998 | 2998 |
| 2999 | 2999 |
| 3000 class BoxUint32x4SlowPath : public SlowPathCode { | 3000 class BoxInt32x4SlowPath : public SlowPathCode { |
| 3001 public: | 3001 public: |
| 3002 explicit BoxUint32x4SlowPath(BoxUint32x4Instr* instruction) | 3002 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) |
| 3003 : instruction_(instruction) { } | 3003 : instruction_(instruction) { } |
| 3004 | 3004 |
| 3005 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 3005 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3006 __ Comment("BoxUint32x4SlowPath"); | 3006 __ Comment("BoxInt32x4SlowPath"); |
| 3007 __ Bind(entry_label()); | 3007 __ Bind(entry_label()); |
| 3008 const Class& uint32x4_class = compiler->uint32x4_class(); | 3008 const Class& int32x4_class = compiler->int32x4_class(); |
| 3009 const Code& stub = | 3009 const Code& stub = |
| 3010 Code::Handle(StubCode::GetAllocationStubForClass(uint32x4_class)); | 3010 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class)); |
| 3011 const ExternalLabel label(uint32x4_class.ToCString(), stub.EntryPoint()); | 3011 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint()); |
| 3012 | 3012 |
| 3013 LocationSummary* locs = instruction_->locs(); | 3013 LocationSummary* locs = instruction_->locs(); |
| 3014 locs->live_registers()->Remove(locs->out()); | 3014 locs->live_registers()->Remove(locs->out()); |
| 3015 | 3015 |
| 3016 compiler->SaveLiveRegisters(locs); | 3016 compiler->SaveLiveRegisters(locs); |
| 3017 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. | 3017 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 3018 &label, | 3018 &label, |
| 3019 PcDescriptors::kOther, | 3019 PcDescriptors::kOther, |
| 3020 locs); | 3020 locs); |
| 3021 __ MoveRegister(locs->out().reg(), EAX); | 3021 __ MoveRegister(locs->out().reg(), EAX); |
| 3022 compiler->RestoreLiveRegisters(locs); | 3022 compiler->RestoreLiveRegisters(locs); |
| 3023 | 3023 |
| 3024 __ jmp(exit_label()); | 3024 __ jmp(exit_label()); |
| 3025 } | 3025 } |
| 3026 | 3026 |
| 3027 private: | 3027 private: |
| 3028 BoxUint32x4Instr* instruction_; | 3028 BoxInt32x4Instr* instruction_; |
| 3029 }; | 3029 }; |
| 3030 | 3030 |
| 3031 | 3031 |
| 3032 void BoxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3032 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3033 BoxUint32x4SlowPath* slow_path = new BoxUint32x4SlowPath(this); | 3033 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); |
| 3034 compiler->AddSlowPathCode(slow_path); | 3034 compiler->AddSlowPathCode(slow_path); |
| 3035 | 3035 |
| 3036 Register out_reg = locs()->out().reg(); | 3036 Register out_reg = locs()->out().reg(); |
| 3037 XmmRegister value = locs()->in(0).fpu_reg(); | 3037 XmmRegister value = locs()->in(0).fpu_reg(); |
| 3038 | 3038 |
| 3039 __ TryAllocate(compiler->uint32x4_class(), | 3039 __ TryAllocate(compiler->int32x4_class(), |
| 3040 slow_path->entry_label(), | 3040 slow_path->entry_label(), |
| 3041 Assembler::kFarJump, | 3041 Assembler::kFarJump, |
| 3042 out_reg); | 3042 out_reg); |
| 3043 __ Bind(slow_path->exit_label()); | 3043 __ Bind(slow_path->exit_label()); |
| 3044 __ movups(FieldAddress(out_reg, Uint32x4::value_offset()), value); | 3044 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); |
| 3045 } | 3045 } |
| 3046 | 3046 |
| 3047 | 3047 |
| 3048 LocationSummary* UnboxUint32x4Instr::MakeLocationSummary() const { | 3048 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { |
| 3049 const intptr_t value_cid = value()->Type()->ToCid(); | 3049 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3050 const intptr_t kNumInputs = 1; | 3050 const intptr_t kNumInputs = 1; |
| 3051 const intptr_t kNumTemps = value_cid == kUint32x4Cid ? 0 : 1; | 3051 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; |
| 3052 LocationSummary* summary = | 3052 LocationSummary* summary = |
| 3053 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3053 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3054 summary->set_in(0, Location::RequiresRegister()); | 3054 summary->set_in(0, Location::RequiresRegister()); |
| 3055 if (kNumTemps > 0) { | 3055 if (kNumTemps > 0) { |
| 3056 ASSERT(kNumTemps == 1); | 3056 ASSERT(kNumTemps == 1); |
| 3057 summary->set_temp(0, Location::RequiresRegister()); | 3057 summary->set_temp(0, Location::RequiresRegister()); |
| 3058 } | 3058 } |
| 3059 summary->set_out(Location::RequiresFpuRegister()); | 3059 summary->set_out(Location::RequiresFpuRegister()); |
| 3060 return summary; | 3060 return summary; |
| 3061 } | 3061 } |
| 3062 | 3062 |
| 3063 | 3063 |
| 3064 void UnboxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3064 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3065 const intptr_t value_cid = value()->Type()->ToCid(); | 3065 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3066 const Register value = locs()->in(0).reg(); | 3066 const Register value = locs()->in(0).reg(); |
| 3067 const XmmRegister result = locs()->out().fpu_reg(); | 3067 const XmmRegister result = locs()->out().fpu_reg(); |
| 3068 | 3068 |
| 3069 if (value_cid != kUint32x4Cid) { | 3069 if (value_cid != kInt32x4Cid) { |
| 3070 const Register temp = locs()->temp(0).reg(); | 3070 const Register temp = locs()->temp(0).reg(); |
| 3071 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3071 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 3072 __ testl(value, Immediate(kSmiTagMask)); | 3072 __ testl(value, Immediate(kSmiTagMask)); |
| 3073 __ j(ZERO, deopt); | 3073 __ j(ZERO, deopt); |
| 3074 __ CompareClassId(value, kUint32x4Cid, temp); | 3074 __ CompareClassId(value, kInt32x4Cid, temp); |
| 3075 __ j(NOT_EQUAL, deopt); | 3075 __ j(NOT_EQUAL, deopt); |
| 3076 } | 3076 } |
| 3077 __ movups(result, FieldAddress(value, Uint32x4::value_offset())); | 3077 __ movups(result, FieldAddress(value, Int32x4::value_offset())); |
| 3078 } | 3078 } |
| 3079 | 3079 |
| 3080 | 3080 |
| 3081 | 3081 |
| 3082 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 3082 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { |
| 3083 const intptr_t kNumInputs = 2; | 3083 const intptr_t kNumInputs = 2; |
| 3084 const intptr_t kNumTemps = 0; | 3084 const intptr_t kNumTemps = 0; |
| 3085 LocationSummary* summary = | 3085 LocationSummary* summary = |
| 3086 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3086 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3087 summary->set_in(0, Location::RequiresFpuRegister()); | 3087 summary->set_in(0, Location::RequiresFpuRegister()); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3162 break; | 3162 break; |
| 3163 case MethodRecognizer::kFloat32x4ShuffleZ: | 3163 case MethodRecognizer::kFloat32x4ShuffleZ: |
| 3164 __ shufps(value, value, Immediate(0xAA)); | 3164 __ shufps(value, value, Immediate(0xAA)); |
| 3165 __ cvtss2sd(value, value); | 3165 __ cvtss2sd(value, value); |
| 3166 break; | 3166 break; |
| 3167 case MethodRecognizer::kFloat32x4ShuffleW: | 3167 case MethodRecognizer::kFloat32x4ShuffleW: |
| 3168 __ shufps(value, value, Immediate(0xFF)); | 3168 __ shufps(value, value, Immediate(0xFF)); |
| 3169 __ cvtss2sd(value, value); | 3169 __ cvtss2sd(value, value); |
| 3170 break; | 3170 break; |
| 3171 case MethodRecognizer::kFloat32x4Shuffle: | 3171 case MethodRecognizer::kFloat32x4Shuffle: |
| 3172 case MethodRecognizer::kUint32x4Shuffle: | 3172 case MethodRecognizer::kInt32x4Shuffle: |
| 3173 __ shufps(value, value, Immediate(mask_)); | 3173 __ shufps(value, value, Immediate(mask_)); |
| 3174 break; | 3174 break; |
| 3175 default: UNREACHABLE(); | 3175 default: UNREACHABLE(); |
| 3176 } | 3176 } |
| 3177 } | 3177 } |
| 3178 | 3178 |
| 3179 | 3179 |
| 3180 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { | 3180 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { |
| 3181 const intptr_t kNumInputs = 2; | 3181 const intptr_t kNumInputs = 2; |
| 3182 const intptr_t kNumTemps = 0; | 3182 const intptr_t kNumTemps = 0; |
| 3183 LocationSummary* summary = | 3183 LocationSummary* summary = |
| 3184 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3184 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3185 summary->set_in(0, Location::RequiresFpuRegister()); | 3185 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3186 summary->set_in(1, Location::RequiresFpuRegister()); | 3186 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3187 summary->set_out(Location::SameAsFirstInput()); | 3187 summary->set_out(Location::SameAsFirstInput()); |
| 3188 return summary; | 3188 return summary; |
| 3189 } | 3189 } |
| 3190 | 3190 |
| 3191 | 3191 |
| 3192 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3192 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3193 XmmRegister left = locs()->in(0).fpu_reg(); | 3193 XmmRegister left = locs()->in(0).fpu_reg(); |
| 3194 XmmRegister right = locs()->in(1).fpu_reg(); | 3194 XmmRegister right = locs()->in(1).fpu_reg(); |
| 3195 | 3195 |
| 3196 ASSERT(locs()->out().fpu_reg() == left); | 3196 ASSERT(locs()->out().fpu_reg() == left); |
| 3197 switch (op_kind()) { | 3197 switch (op_kind()) { |
| 3198 case MethodRecognizer::kFloat32x4ShuffleMix: | 3198 case MethodRecognizer::kFloat32x4ShuffleMix: |
| 3199 case MethodRecognizer::kUint32x4ShuffleMix: | 3199 case MethodRecognizer::kInt32x4ShuffleMix: |
| 3200 __ shufps(left, right, Immediate(mask_)); | 3200 __ shufps(left, right, Immediate(mask_)); |
| 3201 break; | 3201 break; |
| 3202 default: UNREACHABLE(); | 3202 default: UNREACHABLE(); |
| 3203 } | 3203 } |
| 3204 } | 3204 } |
| 3205 | 3205 |
| 3206 | 3206 |
| 3207 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { | 3207 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { |
| 3208 const intptr_t kNumInputs = 1; | 3208 const intptr_t kNumInputs = 1; |
| 3209 const intptr_t kNumTemps = 0; | 3209 const intptr_t kNumTemps = 0; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3542 __ movss(Address(ESP, 12), replacement); | 3542 __ movss(Address(ESP, 12), replacement); |
| 3543 // Move updated value into output register. | 3543 // Move updated value into output register. |
| 3544 __ movups(replacement, Address(ESP, 0)); | 3544 __ movups(replacement, Address(ESP, 0)); |
| 3545 __ addl(ESP, Immediate(16)); | 3545 __ addl(ESP, Immediate(16)); |
| 3546 break; | 3546 break; |
| 3547 default: UNREACHABLE(); | 3547 default: UNREACHABLE(); |
| 3548 } | 3548 } |
| 3549 } | 3549 } |
| 3550 | 3550 |
| 3551 | 3551 |
| 3552 LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const { | 3552 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { |
| 3553 const intptr_t kNumInputs = 1; | 3553 const intptr_t kNumInputs = 1; |
| 3554 const intptr_t kNumTemps = 0; | 3554 const intptr_t kNumTemps = 0; |
| 3555 LocationSummary* summary = | 3555 LocationSummary* summary = |
| 3556 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3556 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3557 summary->set_in(0, Location::RequiresFpuRegister()); | 3557 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3558 summary->set_out(Location::SameAsFirstInput()); | 3558 summary->set_out(Location::SameAsFirstInput()); |
| 3559 return summary; | 3559 return summary; |
| 3560 } | 3560 } |
| 3561 | 3561 |
| 3562 | 3562 |
| 3563 void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3563 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3564 // NOP. | 3564 // NOP. |
| 3565 } | 3565 } |
| 3566 | 3566 |
| 3567 | 3567 |
| 3568 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const { | 3568 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { |
| 3569 const intptr_t kNumInputs = 4; | 3569 const intptr_t kNumInputs = 4; |
| 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::RequiresRegister()); | 3573 summary->set_in(0, Location::RequiresRegister()); |
| 3574 summary->set_in(1, Location::RequiresRegister()); | 3574 summary->set_in(1, Location::RequiresRegister()); |
| 3575 summary->set_in(2, Location::RequiresRegister()); | 3575 summary->set_in(2, Location::RequiresRegister()); |
| 3576 summary->set_in(3, Location::RequiresRegister()); | 3576 summary->set_in(3, Location::RequiresRegister()); |
| 3577 summary->set_out(Location::RequiresFpuRegister()); | 3577 summary->set_out(Location::RequiresFpuRegister()); |
| 3578 return summary; | 3578 return summary; |
| 3579 } | 3579 } |
| 3580 | 3580 |
| 3581 | 3581 |
| 3582 void Uint32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3582 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3583 Register v0 = locs()->in(0).reg(); | 3583 Register v0 = locs()->in(0).reg(); |
| 3584 Register v1 = locs()->in(1).reg(); | 3584 Register v1 = locs()->in(1).reg(); |
| 3585 Register v2 = locs()->in(2).reg(); | 3585 Register v2 = locs()->in(2).reg(); |
| 3586 Register v3 = locs()->in(3).reg(); | 3586 Register v3 = locs()->in(3).reg(); |
| 3587 XmmRegister result = locs()->out().fpu_reg(); | 3587 XmmRegister result = locs()->out().fpu_reg(); |
| 3588 Label x_false, x_done; | 3588 Label x_false, x_done; |
| 3589 Label y_false, y_done; | 3589 Label y_false, y_done; |
| 3590 Label z_false, z_done; | 3590 Label z_false, z_done; |
| 3591 Label w_false, w_done; | 3591 Label w_false, w_done; |
| 3592 __ subl(ESP, Immediate(16)); | 3592 __ subl(ESP, Immediate(16)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3620 __ jmp(&w_done); | 3620 __ jmp(&w_done); |
| 3621 __ Bind(&w_false); | 3621 __ Bind(&w_false); |
| 3622 __ movl(Address(ESP, 12), Immediate(0x0)); | 3622 __ movl(Address(ESP, 12), Immediate(0x0)); |
| 3623 __ Bind(&w_done); | 3623 __ Bind(&w_done); |
| 3624 | 3624 |
| 3625 __ movups(result, Address(ESP, 0)); | 3625 __ movups(result, Address(ESP, 0)); |
| 3626 __ addl(ESP, Immediate(16)); | 3626 __ addl(ESP, Immediate(16)); |
| 3627 } | 3627 } |
| 3628 | 3628 |
| 3629 | 3629 |
| 3630 LocationSummary* Uint32x4GetFlagInstr::MakeLocationSummary() const { | 3630 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { |
| 3631 const intptr_t kNumInputs = 1; | 3631 const intptr_t kNumInputs = 1; |
| 3632 const intptr_t kNumTemps = 0; | 3632 const intptr_t kNumTemps = 0; |
| 3633 LocationSummary* summary = | 3633 LocationSummary* summary = |
| 3634 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3634 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3635 summary->set_in(0, Location::RequiresFpuRegister()); | 3635 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3636 summary->set_out(Location::RequiresRegister()); | 3636 summary->set_out(Location::RequiresRegister()); |
| 3637 return summary; | 3637 return summary; |
| 3638 } | 3638 } |
| 3639 | 3639 |
| 3640 | 3640 |
| 3641 void Uint32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3641 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3642 XmmRegister value = locs()->in(0).fpu_reg(); | 3642 XmmRegister value = locs()->in(0).fpu_reg(); |
| 3643 Register result = locs()->out().reg(); | 3643 Register result = locs()->out().reg(); |
| 3644 Label done; | 3644 Label done; |
| 3645 Label non_zero; | 3645 Label non_zero; |
| 3646 __ subl(ESP, Immediate(16)); | 3646 __ subl(ESP, Immediate(16)); |
| 3647 // Move value to stack. | 3647 // Move value to stack. |
| 3648 __ movups(Address(ESP, 0), value); | 3648 __ movups(Address(ESP, 0), value); |
| 3649 switch (op_kind()) { | 3649 switch (op_kind()) { |
| 3650 case MethodRecognizer::kUint32x4GetFlagX: | 3650 case MethodRecognizer::kInt32x4GetFlagX: |
| 3651 __ movl(result, Address(ESP, 0)); | 3651 __ movl(result, Address(ESP, 0)); |
| 3652 break; | 3652 break; |
| 3653 case MethodRecognizer::kUint32x4GetFlagY: | 3653 case MethodRecognizer::kInt32x4GetFlagY: |
| 3654 __ movl(result, Address(ESP, 4)); | 3654 __ movl(result, Address(ESP, 4)); |
| 3655 break; | 3655 break; |
| 3656 case MethodRecognizer::kUint32x4GetFlagZ: | 3656 case MethodRecognizer::kInt32x4GetFlagZ: |
| 3657 __ movl(result, Address(ESP, 8)); | 3657 __ movl(result, Address(ESP, 8)); |
| 3658 break; | 3658 break; |
| 3659 case MethodRecognizer::kUint32x4GetFlagW: | 3659 case MethodRecognizer::kInt32x4GetFlagW: |
| 3660 __ movl(result, Address(ESP, 12)); | 3660 __ movl(result, Address(ESP, 12)); |
| 3661 break; | 3661 break; |
| 3662 default: UNREACHABLE(); | 3662 default: UNREACHABLE(); |
| 3663 } | 3663 } |
| 3664 __ addl(ESP, Immediate(16)); | 3664 __ addl(ESP, Immediate(16)); |
| 3665 __ testl(result, result); | 3665 __ testl(result, result); |
| 3666 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); | 3666 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); |
| 3667 __ LoadObject(result, Bool::False()); | 3667 __ LoadObject(result, Bool::False()); |
| 3668 __ jmp(&done); | 3668 __ jmp(&done); |
| 3669 __ Bind(&non_zero); | 3669 __ Bind(&non_zero); |
| 3670 __ LoadObject(result, Bool::True()); | 3670 __ LoadObject(result, Bool::True()); |
| 3671 __ Bind(&done); | 3671 __ Bind(&done); |
| 3672 } | 3672 } |
| 3673 | 3673 |
| 3674 | 3674 |
| 3675 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const { | 3675 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { |
| 3676 const intptr_t kNumInputs = 3; | 3676 const intptr_t kNumInputs = 3; |
| 3677 const intptr_t kNumTemps = 1; | 3677 const intptr_t kNumTemps = 1; |
| 3678 LocationSummary* summary = | 3678 LocationSummary* summary = |
| 3679 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3679 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3680 summary->set_in(0, Location::RequiresFpuRegister()); | 3680 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3681 summary->set_in(1, Location::RequiresFpuRegister()); | 3681 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3682 summary->set_in(2, Location::RequiresFpuRegister()); | 3682 summary->set_in(2, Location::RequiresFpuRegister()); |
| 3683 summary->set_temp(0, Location::RequiresFpuRegister()); | 3683 summary->set_temp(0, Location::RequiresFpuRegister()); |
| 3684 summary->set_out(Location::SameAsFirstInput()); | 3684 summary->set_out(Location::SameAsFirstInput()); |
| 3685 return summary; | 3685 return summary; |
| 3686 } | 3686 } |
| 3687 | 3687 |
| 3688 | 3688 |
| 3689 void Uint32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3689 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3690 XmmRegister mask = locs()->in(0).fpu_reg(); | 3690 XmmRegister mask = locs()->in(0).fpu_reg(); |
| 3691 XmmRegister trueValue = locs()->in(1).fpu_reg(); | 3691 XmmRegister trueValue = locs()->in(1).fpu_reg(); |
| 3692 XmmRegister falseValue = locs()->in(2).fpu_reg(); | 3692 XmmRegister falseValue = locs()->in(2).fpu_reg(); |
| 3693 XmmRegister out = locs()->out().fpu_reg(); | 3693 XmmRegister out = locs()->out().fpu_reg(); |
| 3694 XmmRegister temp = locs()->temp(0).fpu_reg(); | 3694 XmmRegister temp = locs()->temp(0).fpu_reg(); |
| 3695 ASSERT(out == mask); | 3695 ASSERT(out == mask); |
| 3696 // Copy mask. | 3696 // Copy mask. |
| 3697 __ movaps(temp, mask); | 3697 __ movaps(temp, mask); |
| 3698 // Invert it. | 3698 // Invert it. |
| 3699 __ notps(temp); | 3699 __ notps(temp); |
| 3700 // mask = mask & trueValue. | 3700 // mask = mask & trueValue. |
| 3701 __ andps(mask, trueValue); | 3701 __ andps(mask, trueValue); |
| 3702 // temp = temp & falseValue. | 3702 // temp = temp & falseValue. |
| 3703 __ andps(temp, falseValue); | 3703 __ andps(temp, falseValue); |
| 3704 // out = mask | temp. | 3704 // out = mask | temp. |
| 3705 __ orps(mask, temp); | 3705 __ orps(mask, temp); |
| 3706 } | 3706 } |
| 3707 | 3707 |
| 3708 | 3708 |
| 3709 LocationSummary* Uint32x4SetFlagInstr::MakeLocationSummary() const { | 3709 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { |
| 3710 const intptr_t kNumInputs = 2; | 3710 const intptr_t kNumInputs = 2; |
| 3711 const intptr_t kNumTemps = 0; | 3711 const intptr_t kNumTemps = 0; |
| 3712 LocationSummary* summary = | 3712 LocationSummary* summary = |
| 3713 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3713 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3714 summary->set_in(0, Location::RequiresFpuRegister()); | 3714 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3715 summary->set_in(1, Location::RequiresRegister()); | 3715 summary->set_in(1, Location::RequiresRegister()); |
| 3716 summary->set_out(Location::SameAsFirstInput()); | 3716 summary->set_out(Location::SameAsFirstInput()); |
| 3717 return summary; | 3717 return summary; |
| 3718 } | 3718 } |
| 3719 | 3719 |
| 3720 | 3720 |
| 3721 void Uint32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3721 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3722 XmmRegister mask = locs()->in(0).fpu_reg(); | 3722 XmmRegister mask = locs()->in(0).fpu_reg(); |
| 3723 Register flag = locs()->in(1).reg(); | 3723 Register flag = locs()->in(1).reg(); |
| 3724 ASSERT(mask == locs()->out().fpu_reg()); | 3724 ASSERT(mask == locs()->out().fpu_reg()); |
| 3725 __ subl(ESP, Immediate(16)); | 3725 __ subl(ESP, Immediate(16)); |
| 3726 // Copy mask to stack. | 3726 // Copy mask to stack. |
| 3727 __ movups(Address(ESP, 0), mask); | 3727 __ movups(Address(ESP, 0), mask); |
| 3728 Label falsePath, exitPath; | 3728 Label falsePath, exitPath; |
| 3729 __ CompareObject(flag, Bool::True()); | 3729 __ CompareObject(flag, Bool::True()); |
| 3730 __ j(NOT_EQUAL, &falsePath); | 3730 __ j(NOT_EQUAL, &falsePath); |
| 3731 switch (op_kind()) { | 3731 switch (op_kind()) { |
| 3732 case MethodRecognizer::kUint32x4WithFlagX: | 3732 case MethodRecognizer::kInt32x4WithFlagX: |
| 3733 __ movl(Address(ESP, 0), Immediate(0xFFFFFFFF)); | 3733 __ movl(Address(ESP, 0), Immediate(0xFFFFFFFF)); |
| 3734 __ jmp(&exitPath); | 3734 __ jmp(&exitPath); |
| 3735 __ Bind(&falsePath); | 3735 __ Bind(&falsePath); |
| 3736 __ movl(Address(ESP, 0), Immediate(0x0)); | 3736 __ movl(Address(ESP, 0), Immediate(0x0)); |
| 3737 break; | 3737 break; |
| 3738 case MethodRecognizer::kUint32x4WithFlagY: | 3738 case MethodRecognizer::kInt32x4WithFlagY: |
| 3739 __ movl(Address(ESP, 4), Immediate(0xFFFFFFFF)); | 3739 __ movl(Address(ESP, 4), Immediate(0xFFFFFFFF)); |
| 3740 __ jmp(&exitPath); | 3740 __ jmp(&exitPath); |
| 3741 __ Bind(&falsePath); | 3741 __ Bind(&falsePath); |
| 3742 __ movl(Address(ESP, 4), Immediate(0x0)); | 3742 __ movl(Address(ESP, 4), Immediate(0x0)); |
| 3743 break; | 3743 break; |
| 3744 case MethodRecognizer::kUint32x4WithFlagZ: | 3744 case MethodRecognizer::kInt32x4WithFlagZ: |
| 3745 __ movl(Address(ESP, 8), Immediate(0xFFFFFFFF)); | 3745 __ movl(Address(ESP, 8), Immediate(0xFFFFFFFF)); |
| 3746 __ jmp(&exitPath); | 3746 __ jmp(&exitPath); |
| 3747 __ Bind(&falsePath); | 3747 __ Bind(&falsePath); |
| 3748 __ movl(Address(ESP, 8), Immediate(0x0)); | 3748 __ movl(Address(ESP, 8), Immediate(0x0)); |
| 3749 break; | 3749 break; |
| 3750 case MethodRecognizer::kUint32x4WithFlagW: | 3750 case MethodRecognizer::kInt32x4WithFlagW: |
| 3751 __ movl(Address(ESP, 12), Immediate(0xFFFFFFFF)); | 3751 __ movl(Address(ESP, 12), Immediate(0xFFFFFFFF)); |
| 3752 __ jmp(&exitPath); | 3752 __ jmp(&exitPath); |
| 3753 __ Bind(&falsePath); | 3753 __ Bind(&falsePath); |
| 3754 __ movl(Address(ESP, 12), Immediate(0x0)); | 3754 __ movl(Address(ESP, 12), Immediate(0x0)); |
| 3755 break; | 3755 break; |
| 3756 default: UNREACHABLE(); | 3756 default: UNREACHABLE(); |
| 3757 } | 3757 } |
| 3758 __ Bind(&exitPath); | 3758 __ Bind(&exitPath); |
| 3759 // Copy mask back to register. | 3759 // Copy mask back to register. |
| 3760 __ movups(mask, Address(ESP, 0)); | 3760 __ movups(mask, Address(ESP, 0)); |
| 3761 __ addl(ESP, Immediate(16)); | 3761 __ addl(ESP, Immediate(16)); |
| 3762 } | 3762 } |
| 3763 | 3763 |
| 3764 | 3764 |
| 3765 LocationSummary* Uint32x4ToFloat32x4Instr::MakeLocationSummary() const { | 3765 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { |
| 3766 const intptr_t kNumInputs = 1; | 3766 const intptr_t kNumInputs = 1; |
| 3767 const intptr_t kNumTemps = 0; | 3767 const intptr_t kNumTemps = 0; |
| 3768 LocationSummary* summary = | 3768 LocationSummary* summary = |
| 3769 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3769 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3770 summary->set_in(0, Location::RequiresFpuRegister()); | 3770 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3771 summary->set_out(Location::SameAsFirstInput()); | 3771 summary->set_out(Location::SameAsFirstInput()); |
| 3772 return summary; | 3772 return summary; |
| 3773 } | 3773 } |
| 3774 | 3774 |
| 3775 | 3775 |
| 3776 void Uint32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3776 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3777 // NOP. | 3777 // NOP. |
| 3778 } | 3778 } |
| 3779 | 3779 |
| 3780 | 3780 |
| 3781 LocationSummary* BinaryUint32x4OpInstr::MakeLocationSummary() const { | 3781 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { |
| 3782 const intptr_t kNumInputs = 2; | 3782 const intptr_t kNumInputs = 2; |
| 3783 const intptr_t kNumTemps = 0; | 3783 const intptr_t kNumTemps = 0; |
| 3784 LocationSummary* summary = | 3784 LocationSummary* summary = |
| 3785 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3785 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3786 summary->set_in(0, Location::RequiresFpuRegister()); | 3786 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3787 summary->set_in(1, Location::RequiresFpuRegister()); | 3787 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3788 summary->set_out(Location::SameAsFirstInput()); | 3788 summary->set_out(Location::SameAsFirstInput()); |
| 3789 return summary; | 3789 return summary; |
| 3790 } | 3790 } |
| 3791 | 3791 |
| 3792 | 3792 |
| 3793 void BinaryUint32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3793 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3794 XmmRegister left = locs()->in(0).fpu_reg(); | 3794 XmmRegister left = locs()->in(0).fpu_reg(); |
| 3795 XmmRegister right = locs()->in(1).fpu_reg(); | 3795 XmmRegister right = locs()->in(1).fpu_reg(); |
| 3796 ASSERT(left == locs()->out().fpu_reg()); | 3796 ASSERT(left == locs()->out().fpu_reg()); |
| 3797 switch (op_kind()) { | 3797 switch (op_kind()) { |
| 3798 case Token::kBIT_AND: { | 3798 case Token::kBIT_AND: { |
| 3799 __ andps(left, right); | 3799 __ andps(left, right); |
| 3800 break; | 3800 break; |
| 3801 } | 3801 } |
| 3802 case Token::kBIT_OR: { | 3802 case Token::kBIT_OR: { |
| 3803 __ orps(left, right); | 3803 __ orps(left, right); |
| (...skipping 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5174 PcDescriptors::kOther, | 5174 PcDescriptors::kOther, |
| 5175 locs()); | 5175 locs()); |
| 5176 __ Drop(2); // Discard type arguments and receiver. | 5176 __ Drop(2); // Discard type arguments and receiver. |
| 5177 } | 5177 } |
| 5178 | 5178 |
| 5179 } // namespace dart | 5179 } // namespace dart |
| 5180 | 5180 |
| 5181 #undef __ | 5181 #undef __ |
| 5182 | 5182 |
| 5183 #endif // defined TARGET_ARCH_IA32 | 5183 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |