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 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 } | 945 } |
946 } | 946 } |
947 } | 947 } |
948 } | 948 } |
949 | 949 |
950 | 950 |
951 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } | 951 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } |
952 | 952 |
953 int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } | 953 int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } |
954 | 954 |
| 955 void InstructionSelector::VisitUnalignedLoad(Node* node) { |
| 956 UnalignedLoadRepresentation load_rep = |
| 957 UnalignedLoadRepresentationOf(node->op()); |
| 958 MipsOperandGenerator g(this); |
| 959 Node* base = node->InputAt(0); |
| 960 Node* index = node->InputAt(1); |
| 961 |
| 962 ArchOpcode opcode = kArchNop; |
| 963 switch (load_rep.representation()) { |
| 964 case MachineRepresentation::kBit: // Fall through. |
| 965 case MachineRepresentation::kWord8: |
| 966 UNREACHABLE(); |
| 967 break; |
| 968 case MachineRepresentation::kWord16: |
| 969 opcode = load_rep.IsUnsigned() ? kMipsUlhu : kMipsUlh; |
| 970 break; |
| 971 case MachineRepresentation::kTagged: // Fall through. |
| 972 case MachineRepresentation::kWord32: |
| 973 opcode = kMipsUlw; |
| 974 break; |
| 975 case MachineRepresentation::kFloat32: |
| 976 opcode = kMipsUlwc1; |
| 977 break; |
| 978 case MachineRepresentation::kFloat64: |
| 979 opcode = kMipsUldc1; |
| 980 break; |
| 981 case MachineRepresentation::kWord64: // Fall through. |
| 982 case MachineRepresentation::kSimd128: // Fall through. |
| 983 case MachineRepresentation::kNone: |
| 984 UNREACHABLE(); |
| 985 return; |
| 986 } |
| 987 |
| 988 if (g.CanBeImmediate(index, opcode)) { |
| 989 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 990 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); |
| 991 } else { |
| 992 InstructionOperand addr_reg = g.TempRegister(); |
| 993 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, |
| 994 g.UseRegister(index), g.UseRegister(base)); |
| 995 // Emit desired load opcode, using temp addr_reg. |
| 996 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 997 g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); |
| 998 } |
| 999 } |
| 1000 |
| 1001 void InstructionSelector::VisitUnalignedStore(Node* node) { |
| 1002 MipsOperandGenerator g(this); |
| 1003 Node* base = node->InputAt(0); |
| 1004 Node* index = node->InputAt(1); |
| 1005 Node* value = node->InputAt(2); |
| 1006 |
| 1007 UnalignedStoreRepresentation rep = UnalignedStoreRepresentationOf(node->op()); |
| 1008 |
| 1009 // TODO(mips): I guess this could be done in a better way. |
| 1010 ArchOpcode opcode = kArchNop; |
| 1011 switch (rep) { |
| 1012 case MachineRepresentation::kFloat32: |
| 1013 opcode = kMipsUswc1; |
| 1014 break; |
| 1015 case MachineRepresentation::kFloat64: |
| 1016 opcode = kMipsUsdc1; |
| 1017 break; |
| 1018 case MachineRepresentation::kBit: // Fall through. |
| 1019 case MachineRepresentation::kWord8: |
| 1020 UNREACHABLE(); |
| 1021 break; |
| 1022 case MachineRepresentation::kWord16: |
| 1023 opcode = kMipsUsh; |
| 1024 break; |
| 1025 case MachineRepresentation::kTagged: // Fall through. |
| 1026 case MachineRepresentation::kWord32: |
| 1027 opcode = kMipsUsw; |
| 1028 break; |
| 1029 case MachineRepresentation::kWord64: // Fall through. |
| 1030 case MachineRepresentation::kSimd128: // Fall through. |
| 1031 case MachineRepresentation::kNone: |
| 1032 UNREACHABLE(); |
| 1033 return; |
| 1034 } |
| 1035 |
| 1036 if (g.CanBeImmediate(index, opcode)) { |
| 1037 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
| 1038 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
| 1039 } else { |
| 1040 InstructionOperand addr_reg = g.TempRegister(); |
| 1041 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, |
| 1042 g.UseRegister(index), g.UseRegister(base)); |
| 1043 // Emit desired store opcode, using temp addr_reg. |
| 1044 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
| 1045 addr_reg, g.TempImmediate(0), g.UseRegister(value)); |
| 1046 } |
| 1047 } |
| 1048 |
955 void InstructionSelector::VisitCheckedLoad(Node* node) { | 1049 void InstructionSelector::VisitCheckedLoad(Node* node) { |
956 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); | 1050 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
957 MipsOperandGenerator g(this); | 1051 MipsOperandGenerator g(this); |
958 Node* const buffer = node->InputAt(0); | 1052 Node* const buffer = node->InputAt(0); |
959 Node* const offset = node->InputAt(1); | 1053 Node* const offset = node->InputAt(1); |
960 Node* const length = node->InputAt(2); | 1054 Node* const length = node->InputAt(2); |
961 ArchOpcode opcode = kArchNop; | 1055 ArchOpcode opcode = kArchNop; |
962 switch (load_rep.representation()) { | 1056 switch (load_rep.representation()) { |
963 case MachineRepresentation::kWord8: | 1057 case MachineRepresentation::kWord8: |
964 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; | 1058 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1524 MachineOperatorBuilder::Flags | 1618 MachineOperatorBuilder::Flags |
1525 InstructionSelector::SupportedMachineOperatorFlags() { | 1619 InstructionSelector::SupportedMachineOperatorFlags() { |
1526 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags; | 1620 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags; |
1527 if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && | 1621 if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && |
1528 IsFp64Mode()) { | 1622 IsFp64Mode()) { |
1529 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1623 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
1530 MachineOperatorBuilder::kFloat64RoundUp | | 1624 MachineOperatorBuilder::kFloat64RoundUp | |
1531 MachineOperatorBuilder::kFloat64RoundTruncate | | 1625 MachineOperatorBuilder::kFloat64RoundTruncate | |
1532 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1626 MachineOperatorBuilder::kFloat64RoundTiesEven; |
1533 } | 1627 } |
| 1628 |
1534 return flags | MachineOperatorBuilder::kWord32Ctz | | 1629 return flags | MachineOperatorBuilder::kWord32Ctz | |
1535 MachineOperatorBuilder::kWord32Popcnt | | 1630 MachineOperatorBuilder::kWord32Popcnt | |
1536 MachineOperatorBuilder::kInt32DivIsSafe | | 1631 MachineOperatorBuilder::kInt32DivIsSafe | |
1537 MachineOperatorBuilder::kUint32DivIsSafe | | 1632 MachineOperatorBuilder::kUint32DivIsSafe | |
1538 MachineOperatorBuilder::kWord32ShiftIsSafe | | 1633 MachineOperatorBuilder::kWord32ShiftIsSafe | |
1539 MachineOperatorBuilder::kFloat32RoundDown | | 1634 MachineOperatorBuilder::kFloat32RoundDown | |
1540 MachineOperatorBuilder::kFloat32RoundUp | | 1635 MachineOperatorBuilder::kFloat32RoundUp | |
1541 MachineOperatorBuilder::kFloat32RoundTruncate | | 1636 MachineOperatorBuilder::kFloat32RoundTruncate | |
1542 MachineOperatorBuilder::kFloat32RoundTiesEven; | 1637 MachineOperatorBuilder::kFloat32RoundTiesEven; |
1543 } | 1638 } |
1544 | 1639 |
1545 // static | 1640 // static |
1546 MachineOperatorBuilder::AlignmentRequirements | 1641 MachineOperatorBuilder::AlignmentRequirements |
1547 InstructionSelector::AlignmentRequirements() { | 1642 InstructionSelector::AlignmentRequirements() { |
1548 if (IsMipsArchVariant(kMips32r6)) { | 1643 if (IsMipsArchVariant(kMips32r6)) { |
1549 return MachineOperatorBuilder::AlignmentRequirements:: | 1644 return MachineOperatorBuilder::AlignmentRequirements:: |
1550 FullUnalignedAccessSupport(); | 1645 FullUnalignedAccessSupport(); |
1551 } else { | 1646 } else { |
1552 DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) || | 1647 DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) || |
1553 IsMipsArchVariant(kMips32r2)); | 1648 IsMipsArchVariant(kMips32r2)); |
1554 return MachineOperatorBuilder::AlignmentRequirements:: | 1649 return MachineOperatorBuilder::AlignmentRequirements:: |
1555 NoUnalignedAccessSupport(); | 1650 NoUnalignedAccessSupport(); |
1556 } | 1651 } |
1557 } | 1652 } |
1558 | 1653 |
1559 } // namespace compiler | 1654 } // namespace compiler |
1560 } // namespace internal | 1655 } // namespace internal |
1561 } // namespace v8 | 1656 } // namespace v8 |
OLD | NEW |