OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "src/base/adapters.h" | 7 #include "src/base/adapters.h" |
8 #include "src/compiler/instruction-selector-impl.h" | 8 #include "src/compiler/instruction-selector-impl.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 | 823 |
824 void InstructionSelector::VisitWord32Ror(Node* node) { | 824 void InstructionSelector::VisitWord32Ror(Node* node) { |
825 VisitWord32Shift(this, node, kX64Ror32); | 825 VisitWord32Shift(this, node, kX64Ror32); |
826 } | 826 } |
827 | 827 |
828 | 828 |
829 void InstructionSelector::VisitWord64Ror(Node* node) { | 829 void InstructionSelector::VisitWord64Ror(Node* node) { |
830 VisitWord64Shift(this, node, kX64Ror); | 830 VisitWord64Shift(this, node, kX64Ror); |
831 } | 831 } |
832 | 832 |
| 833 |
| 834 void InstructionSelector::VisitWord64Clz(Node* node) { |
| 835 X64OperandGenerator g(this); |
| 836 Emit(kX64Lzcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 837 } |
| 838 |
| 839 |
| 840 void InstructionSelector::VisitWord32Clz(Node* node) { |
| 841 X64OperandGenerator g(this); |
| 842 Emit(kX64Lzcnt32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 843 } |
| 844 |
| 845 |
| 846 void InstructionSelector::VisitWord64Ctz(Node* node) { |
| 847 X64OperandGenerator g(this); |
| 848 Emit(kX64Tzcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 849 } |
| 850 |
| 851 |
| 852 void InstructionSelector::VisitWord32Ctz(Node* node) { |
| 853 X64OperandGenerator g(this); |
| 854 Emit(kX64Tzcnt32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 855 } |
| 856 |
| 857 |
833 void InstructionSelector::VisitWord32ReverseBits(Node* node) { UNREACHABLE(); } | 858 void InstructionSelector::VisitWord32ReverseBits(Node* node) { UNREACHABLE(); } |
834 | 859 |
835 | 860 |
836 void InstructionSelector::VisitWord64ReverseBits(Node* node) { UNREACHABLE(); } | 861 void InstructionSelector::VisitWord64ReverseBits(Node* node) { UNREACHABLE(); } |
837 | 862 |
838 void InstructionSelector::VisitWord64ReverseBytes(Node* node) { UNREACHABLE(); } | 863 void InstructionSelector::VisitWord64ReverseBytes(Node* node) { UNREACHABLE(); } |
839 | 864 |
840 void InstructionSelector::VisitWord32ReverseBytes(Node* node) { UNREACHABLE(); } | 865 void InstructionSelector::VisitWord32ReverseBytes(Node* node) { UNREACHABLE(); } |
841 | 866 |
| 867 void InstructionSelector::VisitWord32Popcnt(Node* node) { |
| 868 X64OperandGenerator g(this); |
| 869 Emit(kX64Popcnt32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 870 } |
| 871 |
| 872 |
| 873 void InstructionSelector::VisitWord64Popcnt(Node* node) { |
| 874 X64OperandGenerator g(this); |
| 875 Emit(kX64Popcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 876 } |
| 877 |
| 878 |
842 void InstructionSelector::VisitInt32Add(Node* node) { | 879 void InstructionSelector::VisitInt32Add(Node* node) { |
843 X64OperandGenerator g(this); | 880 X64OperandGenerator g(this); |
844 | 881 |
845 // Try to match the Add to a leal pattern | 882 // Try to match the Add to a leal pattern |
846 BaseWithIndexAndDisplacement32Matcher m(node); | 883 BaseWithIndexAndDisplacement32Matcher m(node); |
847 if (m.matches() && | 884 if (m.matches() && |
848 (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) { | 885 (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) { |
849 EmitLea(this, kX64Lea32, node, m.index(), m.scale(), m.base(), | 886 EmitLea(this, kX64Lea32, node, m.index(), m.scale(), m.base(), |
850 m.displacement(), m.displacement_mode()); | 887 m.displacement(), m.displacement_mode()); |
851 return; | 888 return; |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1054 | 1091 |
1055 void InstructionSelector::VisitUint64Mod(Node* node) { | 1092 void InstructionSelector::VisitUint64Mod(Node* node) { |
1056 VisitMod(this, node, kX64Udiv); | 1093 VisitMod(this, node, kX64Udiv); |
1057 } | 1094 } |
1058 | 1095 |
1059 | 1096 |
1060 void InstructionSelector::VisitUint32MulHigh(Node* node) { | 1097 void InstructionSelector::VisitUint32MulHigh(Node* node) { |
1061 VisitMulHigh(this, node, kX64UmulHigh32); | 1098 VisitMulHigh(this, node, kX64UmulHigh32); |
1062 } | 1099 } |
1063 | 1100 |
| 1101 |
| 1102 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { |
| 1103 X64OperandGenerator g(this); |
| 1104 Emit(kSSEFloat32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1105 } |
| 1106 |
| 1107 |
| 1108 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { |
| 1109 X64OperandGenerator g(this); |
| 1110 Emit(kSSEInt32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1111 } |
| 1112 |
| 1113 |
| 1114 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { |
| 1115 X64OperandGenerator g(this); |
| 1116 Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1117 } |
| 1118 |
| 1119 |
| 1120 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { |
| 1121 X64OperandGenerator g(this); |
| 1122 Emit(kSSEFloat64ToInt32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1123 } |
| 1124 |
| 1125 |
| 1126 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { |
| 1127 X64OperandGenerator g(this); |
| 1128 Emit(kSSEFloat64ToUint32 | MiscField::encode(1), g.DefineAsRegister(node), |
| 1129 g.Use(node->InputAt(0))); |
| 1130 } |
| 1131 |
| 1132 void InstructionSelector::VisitTruncateFloat64ToUint32(Node* node) { |
| 1133 X64OperandGenerator g(this); |
| 1134 Emit(kSSEFloat64ToUint32 | MiscField::encode(0), g.DefineAsRegister(node), |
| 1135 g.Use(node->InputAt(0))); |
| 1136 } |
| 1137 |
| 1138 void InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) { |
| 1139 X64OperandGenerator g(this); |
| 1140 Emit(kSSEFloat32ToInt32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1141 } |
| 1142 |
| 1143 |
| 1144 void InstructionSelector::VisitTruncateFloat32ToUint32(Node* node) { |
| 1145 X64OperandGenerator g(this); |
| 1146 Emit(kSSEFloat32ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1147 } |
| 1148 |
| 1149 |
1064 void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) { | 1150 void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) { |
1065 X64OperandGenerator g(this); | 1151 X64OperandGenerator g(this); |
1066 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))}; | 1152 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))}; |
1067 InstructionOperand outputs[2]; | 1153 InstructionOperand outputs[2]; |
1068 size_t output_count = 0; | 1154 size_t output_count = 0; |
1069 outputs[output_count++] = g.DefineAsRegister(node); | 1155 outputs[output_count++] = g.DefineAsRegister(node); |
1070 | 1156 |
1071 Node* success_output = NodeProperties::FindProjection(node, 1); | 1157 Node* success_output = NodeProperties::FindProjection(node, 1); |
1072 if (success_output) { | 1158 if (success_output) { |
1073 outputs[output_count++] = g.DefineAsRegister(success_output); | 1159 outputs[output_count++] = g.DefineAsRegister(success_output); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1271 X64OperandGenerator g(selector); | 1357 X64OperandGenerator g(selector); |
1272 if (selector->IsSupported(AVX)) { | 1358 if (selector->IsSupported(AVX)) { |
1273 selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input)); | 1359 selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input)); |
1274 } else { | 1360 } else { |
1275 selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input)); | 1361 selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input)); |
1276 } | 1362 } |
1277 } | 1363 } |
1278 | 1364 |
1279 } // namespace | 1365 } // namespace |
1280 | 1366 |
1281 #define RO_OP_LIST(V) \ | |
1282 V(Word64Clz, kX64Lzcnt) \ | |
1283 V(Word32Clz, kX64Lzcnt32) \ | |
1284 V(Word64Ctz, kX64Tzcnt) \ | |
1285 V(Word32Ctz, kX64Tzcnt32) \ | |
1286 V(Word64Popcnt, kX64Popcnt) \ | |
1287 V(Word32Popcnt, kX64Popcnt32) \ | |
1288 V(Float64Sqrt, kSSEFloat64Sqrt) \ | |
1289 V(Float32Sqrt, kSSEFloat32Sqrt) \ | |
1290 V(ChangeFloat64ToInt32, kSSEFloat64ToInt32) \ | |
1291 V(ChangeFloat64ToUint32, kSSEFloat64ToUint32 | MiscField::encode(1)) \ | |
1292 V(TruncateFloat64ToUint32, kSSEFloat64ToUint32 | MiscField::encode(0)) \ | |
1293 V(TruncateFloat64ToFloat32, kSSEFloat64ToFloat32) \ | |
1294 V(ChangeFloat32ToFloat64, kSSEFloat32ToFloat64) \ | |
1295 V(TruncateFloat32ToInt32, kSSEFloat32ToInt32) \ | |
1296 V(TruncateFloat32ToUint32, kSSEFloat32ToUint32) \ | |
1297 V(ChangeInt32ToFloat64, kSSEInt32ToFloat64) \ | |
1298 V(ChangeUint32ToFloat64, kSSEUint32ToFloat64) \ | |
1299 V(RoundFloat64ToInt32, kSSEFloat64ToInt32) \ | |
1300 V(RoundInt32ToFloat32, kSSEInt32ToFloat32) \ | |
1301 V(RoundInt64ToFloat32, kSSEInt64ToFloat32) \ | |
1302 V(RoundInt64ToFloat64, kSSEInt64ToFloat64) \ | |
1303 V(RoundUint32ToFloat32, kSSEUint32ToFloat32) \ | |
1304 V(BitcastFloat32ToInt32, kX64BitcastFI) \ | |
1305 V(BitcastFloat64ToInt64, kX64BitcastDL) \ | |
1306 V(BitcastInt32ToFloat32, kX64BitcastIF) \ | |
1307 V(BitcastInt64ToFloat64, kX64BitcastLD) \ | |
1308 V(Float64ExtractLowWord32, kSSEFloat64ExtractLowWord32) \ | |
1309 V(Float64ExtractHighWord32, kSSEFloat64ExtractHighWord32) \ | |
1310 V(Float64SilenceNaN, kSSEFloat64SilenceNaN) | |
1311 | 1367 |
1312 #define RR_OP_LIST(V) \ | 1368 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { |
1313 V(Float32RoundDown, kSSEFloat32Round | MiscField::encode(kRoundDown)) \ | 1369 VisitRO(this, node, kSSEFloat64ToFloat32); |
1314 V(Float64RoundDown, kSSEFloat64Round | MiscField::encode(kRoundDown)) \ | 1370 } |
1315 V(Float32RoundUp, kSSEFloat32Round | MiscField::encode(kRoundUp)) \ | |
1316 V(Float64RoundUp, kSSEFloat64Round | MiscField::encode(kRoundUp)) \ | |
1317 V(Float32RoundTruncate, kSSEFloat32Round | MiscField::encode(kRoundToZero)) \ | |
1318 V(Float64RoundTruncate, kSSEFloat64Round | MiscField::encode(kRoundToZero)) \ | |
1319 V(Float32RoundTiesEven, \ | |
1320 kSSEFloat32Round | MiscField::encode(kRoundToNearest)) \ | |
1321 V(Float64RoundTiesEven, kSSEFloat64Round | MiscField::encode(kRoundToNearest)) | |
1322 | |
1323 #define RO_VISITOR(Name, opcode) \ | |
1324 void InstructionSelector::Visit##Name(Node* node) { \ | |
1325 VisitRO(this, node, opcode); \ | |
1326 } | |
1327 RO_OP_LIST(RO_VISITOR) | |
1328 #undef RO_VISITOR | |
1329 | |
1330 #define RR_VISITOR(Name, opcode) \ | |
1331 void InstructionSelector::Visit##Name(Node* node) { \ | |
1332 VisitRR(this, node, opcode); \ | |
1333 } | |
1334 RR_OP_LIST(RR_VISITOR) | |
1335 #undef RR_VISITOR | |
1336 | 1371 |
1337 void InstructionSelector::VisitTruncateFloat64ToWord32(Node* node) { | 1372 void InstructionSelector::VisitTruncateFloat64ToWord32(Node* node) { |
1338 VisitRR(this, node, kArchTruncateDoubleToI); | 1373 VisitRR(this, node, kArchTruncateDoubleToI); |
1339 } | 1374 } |
1340 | 1375 |
| 1376 |
1341 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { | 1377 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { |
1342 X64OperandGenerator g(this); | 1378 X64OperandGenerator g(this); |
1343 Node* value = node->InputAt(0); | 1379 Node* value = node->InputAt(0); |
1344 if (CanCover(node, value)) { | 1380 if (CanCover(node, value)) { |
1345 switch (value->opcode()) { | 1381 switch (value->opcode()) { |
1346 case IrOpcode::kWord64Sar: | 1382 case IrOpcode::kWord64Sar: |
1347 case IrOpcode::kWord64Shr: { | 1383 case IrOpcode::kWord64Shr: { |
1348 Int64BinopMatcher m(value); | 1384 Int64BinopMatcher m(value); |
1349 if (m.right().Is(32)) { | 1385 if (m.right().Is(32)) { |
1350 if (TryMatchLoadWord64AndShiftRight(this, value, kX64Movl)) { | 1386 if (TryMatchLoadWord64AndShiftRight(this, value, kX64Movl)) { |
1351 return EmitIdentity(node); | 1387 return EmitIdentity(node); |
1352 } | 1388 } |
1353 Emit(kX64Shr, g.DefineSameAsFirst(node), | 1389 Emit(kX64Shr, g.DefineSameAsFirst(node), |
1354 g.UseRegister(m.left().node()), g.TempImmediate(32)); | 1390 g.UseRegister(m.left().node()), g.TempImmediate(32)); |
1355 return; | 1391 return; |
1356 } | 1392 } |
1357 break; | 1393 break; |
1358 } | 1394 } |
1359 default: | 1395 default: |
1360 break; | 1396 break; |
1361 } | 1397 } |
1362 } | 1398 } |
1363 Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value)); | 1399 Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value)); |
1364 } | 1400 } |
1365 | 1401 |
| 1402 void InstructionSelector::VisitRoundFloat64ToInt32(Node* node) { |
| 1403 VisitRO(this, node, kSSEFloat64ToInt32); |
| 1404 } |
| 1405 |
| 1406 void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) { |
| 1407 X64OperandGenerator g(this); |
| 1408 Emit(kSSEInt32ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1409 } |
| 1410 |
| 1411 |
| 1412 void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) { |
| 1413 X64OperandGenerator g(this); |
| 1414 Emit(kSSEInt64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1415 } |
| 1416 |
| 1417 |
| 1418 void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) { |
| 1419 X64OperandGenerator g(this); |
| 1420 Emit(kSSEInt64ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1421 } |
| 1422 |
| 1423 |
| 1424 void InstructionSelector::VisitRoundUint32ToFloat32(Node* node) { |
| 1425 X64OperandGenerator g(this); |
| 1426 Emit(kSSEUint32ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1427 } |
| 1428 |
| 1429 |
1366 void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) { | 1430 void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) { |
1367 X64OperandGenerator g(this); | 1431 X64OperandGenerator g(this); |
1368 InstructionOperand temps[] = {g.TempRegister()}; | 1432 InstructionOperand temps[] = {g.TempRegister()}; |
1369 Emit(kSSEUint64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0)), | 1433 Emit(kSSEUint64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0)), |
1370 arraysize(temps), temps); | 1434 arraysize(temps), temps); |
1371 } | 1435 } |
1372 | 1436 |
1373 | 1437 |
1374 void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) { | 1438 void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) { |
1375 X64OperandGenerator g(this); | 1439 X64OperandGenerator g(this); |
1376 InstructionOperand temps[] = {g.TempRegister()}; | 1440 InstructionOperand temps[] = {g.TempRegister()}; |
1377 Emit(kSSEUint64ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)), | 1441 Emit(kSSEUint64ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)), |
1378 arraysize(temps), temps); | 1442 arraysize(temps), temps); |
1379 } | 1443 } |
1380 | 1444 |
| 1445 |
| 1446 void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) { |
| 1447 X64OperandGenerator g(this); |
| 1448 Emit(kX64BitcastFI, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1449 } |
| 1450 |
| 1451 |
| 1452 void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) { |
| 1453 X64OperandGenerator g(this); |
| 1454 Emit(kX64BitcastDL, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1455 } |
| 1456 |
| 1457 |
| 1458 void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) { |
| 1459 X64OperandGenerator g(this); |
| 1460 Emit(kX64BitcastIF, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1461 } |
| 1462 |
| 1463 |
| 1464 void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) { |
| 1465 X64OperandGenerator g(this); |
| 1466 Emit(kX64BitcastLD, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 1467 } |
| 1468 |
| 1469 |
1381 void InstructionSelector::VisitFloat32Add(Node* node) { | 1470 void InstructionSelector::VisitFloat32Add(Node* node) { |
1382 VisitFloatBinop(this, node, kAVXFloat32Add, kSSEFloat32Add); | 1471 VisitFloatBinop(this, node, kAVXFloat32Add, kSSEFloat32Add); |
1383 } | 1472 } |
1384 | 1473 |
1385 | 1474 |
1386 void InstructionSelector::VisitFloat32Sub(Node* node) { | 1475 void InstructionSelector::VisitFloat32Sub(Node* node) { |
1387 VisitFloatBinop(this, node, kAVXFloat32Sub, kSSEFloat32Sub); | 1476 VisitFloatBinop(this, node, kAVXFloat32Sub, kSSEFloat32Sub); |
1388 } | 1477 } |
1389 | 1478 |
1390 void InstructionSelector::VisitFloat32Mul(Node* node) { | 1479 void InstructionSelector::VisitFloat32Mul(Node* node) { |
1391 VisitFloatBinop(this, node, kAVXFloat32Mul, kSSEFloat32Mul); | 1480 VisitFloatBinop(this, node, kAVXFloat32Mul, kSSEFloat32Mul); |
1392 } | 1481 } |
1393 | 1482 |
1394 | 1483 |
1395 void InstructionSelector::VisitFloat32Div(Node* node) { | 1484 void InstructionSelector::VisitFloat32Div(Node* node) { |
1396 VisitFloatBinop(this, node, kAVXFloat32Div, kSSEFloat32Div); | 1485 VisitFloatBinop(this, node, kAVXFloat32Div, kSSEFloat32Div); |
1397 } | 1486 } |
1398 | 1487 |
1399 | 1488 |
1400 void InstructionSelector::VisitFloat32Abs(Node* node) { | 1489 void InstructionSelector::VisitFloat32Abs(Node* node) { |
1401 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Abs, kSSEFloat32Abs); | 1490 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Abs, kSSEFloat32Abs); |
1402 } | 1491 } |
1403 | 1492 |
1404 | 1493 |
| 1494 void InstructionSelector::VisitFloat32Sqrt(Node* node) { |
| 1495 VisitRO(this, node, kSSEFloat32Sqrt); |
| 1496 } |
| 1497 |
1405 void InstructionSelector::VisitFloat32Max(Node* node) { | 1498 void InstructionSelector::VisitFloat32Max(Node* node) { |
1406 VisitRRO(this, node, kSSEFloat32Max); | 1499 VisitRRO(this, node, kSSEFloat32Max); |
1407 } | 1500 } |
1408 | 1501 |
1409 void InstructionSelector::VisitFloat32Min(Node* node) { | 1502 void InstructionSelector::VisitFloat32Min(Node* node) { |
1410 VisitRRO(this, node, kSSEFloat32Min); | 1503 VisitRRO(this, node, kSSEFloat32Min); |
1411 } | 1504 } |
1412 | 1505 |
1413 void InstructionSelector::VisitFloat64Add(Node* node) { | 1506 void InstructionSelector::VisitFloat64Add(Node* node) { |
1414 VisitFloatBinop(this, node, kAVXFloat64Add, kSSEFloat64Add); | 1507 VisitFloatBinop(this, node, kAVXFloat64Add, kSSEFloat64Add); |
(...skipping 30 matching lines...) Expand all Loading... |
1445 | 1538 |
1446 void InstructionSelector::VisitFloat64Min(Node* node) { | 1539 void InstructionSelector::VisitFloat64Min(Node* node) { |
1447 VisitRRO(this, node, kSSEFloat64Min); | 1540 VisitRRO(this, node, kSSEFloat64Min); |
1448 } | 1541 } |
1449 | 1542 |
1450 | 1543 |
1451 void InstructionSelector::VisitFloat64Abs(Node* node) { | 1544 void InstructionSelector::VisitFloat64Abs(Node* node) { |
1452 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Abs, kSSEFloat64Abs); | 1545 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Abs, kSSEFloat64Abs); |
1453 } | 1546 } |
1454 | 1547 |
| 1548 void InstructionSelector::VisitFloat64Sqrt(Node* node) { |
| 1549 VisitRO(this, node, kSSEFloat64Sqrt); |
| 1550 } |
| 1551 |
| 1552 |
| 1553 void InstructionSelector::VisitFloat32RoundDown(Node* node) { |
| 1554 VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundDown)); |
| 1555 } |
| 1556 |
| 1557 |
| 1558 void InstructionSelector::VisitFloat64RoundDown(Node* node) { |
| 1559 VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundDown)); |
| 1560 } |
| 1561 |
| 1562 |
| 1563 void InstructionSelector::VisitFloat32RoundUp(Node* node) { |
| 1564 VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundUp)); |
| 1565 } |
| 1566 |
| 1567 |
| 1568 void InstructionSelector::VisitFloat64RoundUp(Node* node) { |
| 1569 VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundUp)); |
| 1570 } |
| 1571 |
| 1572 |
| 1573 void InstructionSelector::VisitFloat32RoundTruncate(Node* node) { |
| 1574 VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundToZero)); |
| 1575 } |
| 1576 |
| 1577 |
| 1578 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
| 1579 VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero)); |
| 1580 } |
| 1581 |
1455 | 1582 |
1456 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 1583 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
1457 UNREACHABLE(); | 1584 UNREACHABLE(); |
1458 } | 1585 } |
1459 | 1586 |
1460 | 1587 |
| 1588 void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) { |
| 1589 VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundToNearest)); |
| 1590 } |
| 1591 |
| 1592 |
| 1593 void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) { |
| 1594 VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToNearest)); |
| 1595 } |
| 1596 |
1461 void InstructionSelector::VisitFloat32Neg(Node* node) { | 1597 void InstructionSelector::VisitFloat32Neg(Node* node) { |
1462 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Neg, kSSEFloat32Neg); | 1598 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Neg, kSSEFloat32Neg); |
1463 } | 1599 } |
1464 | 1600 |
1465 void InstructionSelector::VisitFloat64Neg(Node* node) { | 1601 void InstructionSelector::VisitFloat64Neg(Node* node) { |
1466 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Neg, kSSEFloat64Neg); | 1602 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Neg, kSSEFloat64Neg); |
1467 } | 1603 } |
1468 | 1604 |
1469 void InstructionSelector::VisitFloat64Ieee754Binop(Node* node, | 1605 void InstructionSelector::VisitFloat64Ieee754Binop(Node* node, |
1470 InstructionCode opcode) { | 1606 InstructionCode opcode) { |
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2190 FlagsContinuation::ForSet(kUnsignedGreaterThan, node); | 2326 FlagsContinuation::ForSet(kUnsignedGreaterThan, node); |
2191 VisitFloat64Compare(this, node, &cont); | 2327 VisitFloat64Compare(this, node, &cont); |
2192 } | 2328 } |
2193 | 2329 |
2194 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { | 2330 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { |
2195 FlagsContinuation cont = | 2331 FlagsContinuation cont = |
2196 FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node); | 2332 FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node); |
2197 VisitFloat64Compare(this, node, &cont); | 2333 VisitFloat64Compare(this, node, &cont); |
2198 } | 2334 } |
2199 | 2335 |
| 2336 |
| 2337 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { |
| 2338 X64OperandGenerator g(this); |
| 2339 Emit(kSSEFloat64ExtractLowWord32, g.DefineAsRegister(node), |
| 2340 g.Use(node->InputAt(0))); |
| 2341 } |
| 2342 |
| 2343 |
| 2344 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { |
| 2345 X64OperandGenerator g(this); |
| 2346 Emit(kSSEFloat64ExtractHighWord32, g.DefineAsRegister(node), |
| 2347 g.Use(node->InputAt(0))); |
| 2348 } |
| 2349 |
| 2350 |
2200 void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) { | 2351 void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) { |
2201 X64OperandGenerator g(this); | 2352 X64OperandGenerator g(this); |
2202 Node* left = node->InputAt(0); | 2353 Node* left = node->InputAt(0); |
2203 Node* right = node->InputAt(1); | 2354 Node* right = node->InputAt(1); |
2204 Float64Matcher mleft(left); | 2355 Float64Matcher mleft(left); |
2205 if (mleft.HasValue() && (bit_cast<uint64_t>(mleft.Value()) >> 32) == 0u) { | 2356 if (mleft.HasValue() && (bit_cast<uint64_t>(mleft.Value()) >> 32) == 0u) { |
2206 Emit(kSSEFloat64LoadLowWord32, g.DefineAsRegister(node), g.Use(right)); | 2357 Emit(kSSEFloat64LoadLowWord32, g.DefineAsRegister(node), g.Use(right)); |
2207 return; | 2358 return; |
2208 } | 2359 } |
2209 Emit(kSSEFloat64InsertLowWord32, g.DefineSameAsFirst(node), | 2360 Emit(kSSEFloat64InsertLowWord32, g.DefineSameAsFirst(node), |
2210 g.UseRegister(left), g.Use(right)); | 2361 g.UseRegister(left), g.Use(right)); |
2211 } | 2362 } |
2212 | 2363 |
2213 | 2364 |
2214 void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { | 2365 void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { |
2215 X64OperandGenerator g(this); | 2366 X64OperandGenerator g(this); |
2216 Node* left = node->InputAt(0); | 2367 Node* left = node->InputAt(0); |
2217 Node* right = node->InputAt(1); | 2368 Node* right = node->InputAt(1); |
2218 Emit(kSSEFloat64InsertHighWord32, g.DefineSameAsFirst(node), | 2369 Emit(kSSEFloat64InsertHighWord32, g.DefineSameAsFirst(node), |
2219 g.UseRegister(left), g.Use(right)); | 2370 g.UseRegister(left), g.Use(right)); |
2220 } | 2371 } |
2221 | 2372 |
| 2373 void InstructionSelector::VisitFloat64SilenceNaN(Node* node) { |
| 2374 X64OperandGenerator g(this); |
| 2375 Emit(kSSEFloat64SilenceNaN, g.DefineSameAsFirst(node), |
| 2376 g.UseRegister(node->InputAt(0))); |
| 2377 } |
| 2378 |
2222 void InstructionSelector::VisitAtomicLoad(Node* node) { | 2379 void InstructionSelector::VisitAtomicLoad(Node* node) { |
2223 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); | 2380 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
2224 DCHECK(load_rep.representation() == MachineRepresentation::kWord8 || | 2381 DCHECK(load_rep.representation() == MachineRepresentation::kWord8 || |
2225 load_rep.representation() == MachineRepresentation::kWord16 || | 2382 load_rep.representation() == MachineRepresentation::kWord16 || |
2226 load_rep.representation() == MachineRepresentation::kWord32); | 2383 load_rep.representation() == MachineRepresentation::kWord32); |
2227 USE(load_rep); | 2384 USE(load_rep); |
2228 VisitLoad(node); | 2385 VisitLoad(node); |
2229 } | 2386 } |
2230 | 2387 |
2231 void InstructionSelector::VisitAtomicStore(Node* node) { | 2388 void InstructionSelector::VisitAtomicStore(Node* node) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2324 // static | 2481 // static |
2325 MachineOperatorBuilder::AlignmentRequirements | 2482 MachineOperatorBuilder::AlignmentRequirements |
2326 InstructionSelector::AlignmentRequirements() { | 2483 InstructionSelector::AlignmentRequirements() { |
2327 return MachineOperatorBuilder::AlignmentRequirements:: | 2484 return MachineOperatorBuilder::AlignmentRequirements:: |
2328 FullUnalignedAccessSupport(); | 2485 FullUnalignedAccessSupport(); |
2329 } | 2486 } |
2330 | 2487 |
2331 } // namespace compiler | 2488 } // namespace compiler |
2332 } // namespace internal | 2489 } // namespace internal |
2333 } // namespace v8 | 2490 } // namespace v8 |
OLD | NEW |