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 "src/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 1376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1387 } | 1387 } |
1388 } | 1388 } |
1389 } | 1389 } |
1390 } | 1390 } |
1391 | 1391 |
1392 | 1392 |
1393 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } | 1393 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } |
1394 | 1394 |
1395 int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } | 1395 int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } |
1396 | 1396 |
| 1397 void InstructionSelector::VisitUnalignedLoad(Node* node) { |
| 1398 UnalignedLoadRepresentation load_rep = |
| 1399 UnalignedLoadRepresentationOf(node->op()); |
| 1400 Mips64OperandGenerator g(this); |
| 1401 Node* base = node->InputAt(0); |
| 1402 Node* index = node->InputAt(1); |
| 1403 |
| 1404 ArchOpcode opcode = kArchNop; |
| 1405 switch (load_rep.representation()) { |
| 1406 case MachineRepresentation::kFloat32: |
| 1407 opcode = kMips64Ulwc1; |
| 1408 break; |
| 1409 case MachineRepresentation::kFloat64: |
| 1410 opcode = kMips64Uldc1; |
| 1411 break; |
| 1412 case MachineRepresentation::kBit: // Fall through. |
| 1413 case MachineRepresentation::kWord8: |
| 1414 opcode = load_rep.IsUnsigned() ? kMips64Lbu : kMips64Lb; |
| 1415 break; |
| 1416 case MachineRepresentation::kWord16: |
| 1417 opcode = load_rep.IsUnsigned() ? kMips64Ulhu : kMips64Ulh; |
| 1418 break; |
| 1419 case MachineRepresentation::kWord32: |
| 1420 opcode = kMips64Ulw; |
| 1421 break; |
| 1422 case MachineRepresentation::kTagged: // Fall through. |
| 1423 case MachineRepresentation::kWord64: |
| 1424 opcode = kMips64Uld; |
| 1425 break; |
| 1426 case MachineRepresentation::kSimd128: // Fall through. |
| 1427 case MachineRepresentation::kNone: |
| 1428 UNREACHABLE(); |
| 1429 return; |
| 1430 } |
| 1431 |
| 1432 if (g.CanBeImmediate(index, opcode)) { |
| 1433 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 1434 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); |
| 1435 } else { |
| 1436 InstructionOperand addr_reg = g.TempRegister(); |
| 1437 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, |
| 1438 g.UseRegister(index), g.UseRegister(base)); |
| 1439 // Emit desired load opcode, using temp addr_reg. |
| 1440 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 1441 g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); |
| 1442 } |
| 1443 } |
| 1444 |
| 1445 void InstructionSelector::VisitUnalignedStore(Node* node) { |
| 1446 Mips64OperandGenerator g(this); |
| 1447 Node* base = node->InputAt(0); |
| 1448 Node* index = node->InputAt(1); |
| 1449 Node* value = node->InputAt(2); |
| 1450 |
| 1451 UnalignedStoreRepresentation rep = UnalignedStoreRepresentationOf(node->op()); |
| 1452 ArchOpcode opcode = kArchNop; |
| 1453 switch (rep) { |
| 1454 case MachineRepresentation::kFloat32: |
| 1455 opcode = kMips64Uswc1; |
| 1456 break; |
| 1457 case MachineRepresentation::kFloat64: |
| 1458 opcode = kMips64Usdc1; |
| 1459 break; |
| 1460 case MachineRepresentation::kBit: // Fall through. |
| 1461 case MachineRepresentation::kWord8: |
| 1462 opcode = kMips64Sb; |
| 1463 break; |
| 1464 case MachineRepresentation::kWord16: |
| 1465 opcode = kMips64Ush; |
| 1466 break; |
| 1467 case MachineRepresentation::kWord32: |
| 1468 opcode = kMips64Usw; |
| 1469 break; |
| 1470 case MachineRepresentation::kTagged: // Fall through. |
| 1471 case MachineRepresentation::kWord64: |
| 1472 opcode = kMips64Usd; |
| 1473 break; |
| 1474 case MachineRepresentation::kSimd128: // Fall through. |
| 1475 case MachineRepresentation::kNone: |
| 1476 UNREACHABLE(); |
| 1477 return; |
| 1478 } |
| 1479 |
| 1480 if (g.CanBeImmediate(index, opcode)) { |
| 1481 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
| 1482 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
| 1483 } else { |
| 1484 InstructionOperand addr_reg = g.TempRegister(); |
| 1485 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, |
| 1486 g.UseRegister(index), g.UseRegister(base)); |
| 1487 // Emit desired store opcode, using temp addr_reg. |
| 1488 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
| 1489 addr_reg, g.TempImmediate(0), g.UseRegister(value)); |
| 1490 } |
| 1491 } |
| 1492 |
1397 void InstructionSelector::VisitCheckedLoad(Node* node) { | 1493 void InstructionSelector::VisitCheckedLoad(Node* node) { |
1398 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); | 1494 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
1399 Mips64OperandGenerator g(this); | 1495 Mips64OperandGenerator g(this); |
1400 Node* const buffer = node->InputAt(0); | 1496 Node* const buffer = node->InputAt(0); |
1401 Node* const offset = node->InputAt(1); | 1497 Node* const offset = node->InputAt(1); |
1402 Node* const length = node->InputAt(2); | 1498 Node* const length = node->InputAt(2); |
1403 ArchOpcode opcode = kArchNop; | 1499 ArchOpcode opcode = kArchNop; |
1404 switch (load_rep.representation()) { | 1500 switch (load_rep.representation()) { |
1405 case MachineRepresentation::kWord8: | 1501 case MachineRepresentation::kWord8: |
1406 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; | 1502 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2049 g.UseRegister(index), g.UseRegister(base)); | 2145 g.UseRegister(index), g.UseRegister(base)); |
2050 // Emit desired store opcode, using temp addr_reg. | 2146 // Emit desired store opcode, using temp addr_reg. |
2051 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 2147 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
2052 addr_reg, g.TempImmediate(0), g.UseRegister(value)); | 2148 addr_reg, g.TempImmediate(0), g.UseRegister(value)); |
2053 } | 2149 } |
2054 } | 2150 } |
2055 | 2151 |
2056 // static | 2152 // static |
2057 MachineOperatorBuilder::Flags | 2153 MachineOperatorBuilder::Flags |
2058 InstructionSelector::SupportedMachineOperatorFlags() { | 2154 InstructionSelector::SupportedMachineOperatorFlags() { |
2059 return MachineOperatorBuilder::kWord32Ctz | | 2155 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags; |
| 2156 if (kArchVariant == kMips64r2) { |
| 2157 flags |= MachineOperatorBuilder::kUnalignedLoad | |
| 2158 MachineOperatorBuilder::kUnalignedStore; |
| 2159 } |
| 2160 return flags | MachineOperatorBuilder::kWord32Ctz | |
2060 MachineOperatorBuilder::kWord64Ctz | | 2161 MachineOperatorBuilder::kWord64Ctz | |
2061 MachineOperatorBuilder::kWord32Popcnt | | 2162 MachineOperatorBuilder::kWord32Popcnt | |
2062 MachineOperatorBuilder::kWord64Popcnt | | 2163 MachineOperatorBuilder::kWord64Popcnt | |
2063 MachineOperatorBuilder::kWord32ShiftIsSafe | | 2164 MachineOperatorBuilder::kWord32ShiftIsSafe | |
2064 MachineOperatorBuilder::kInt32DivIsSafe | | 2165 MachineOperatorBuilder::kInt32DivIsSafe | |
2065 MachineOperatorBuilder::kUint32DivIsSafe | | 2166 MachineOperatorBuilder::kUint32DivIsSafe | |
2066 MachineOperatorBuilder::kFloat64Min | | 2167 MachineOperatorBuilder::kFloat64Min | |
2067 MachineOperatorBuilder::kFloat64Max | | 2168 MachineOperatorBuilder::kFloat64Max | |
2068 MachineOperatorBuilder::kFloat32Min | | 2169 MachineOperatorBuilder::kFloat32Min | |
2069 MachineOperatorBuilder::kFloat32Max | | 2170 MachineOperatorBuilder::kFloat32Max | |
(...skipping 16 matching lines...) Expand all Loading... |
2086 } else { | 2187 } else { |
2087 DCHECK(kArchVariant == kMips64r2); | 2188 DCHECK(kArchVariant == kMips64r2); |
2088 return MachineOperatorBuilder::AlignmentRequirements:: | 2189 return MachineOperatorBuilder::AlignmentRequirements:: |
2089 NoUnalignedAccessSupport(); | 2190 NoUnalignedAccessSupport(); |
2090 } | 2191 } |
2091 } | 2192 } |
2092 | 2193 |
2093 } // namespace compiler | 2194 } // namespace compiler |
2094 } // namespace internal | 2195 } // namespace internal |
2095 } // namespace v8 | 2196 } // namespace v8 |
OLD | NEW |