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 |