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 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
984 } | 984 } |
985 } | 985 } |
986 } | 986 } |
987 } | 987 } |
988 | 988 |
989 | 989 |
990 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } | 990 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } |
991 | 991 |
992 int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } | 992 int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } |
993 | 993 |
994 void InstructionSelector::VisitUnalignedLoad(Node* node) { | |
995 UnalignedLoadRepresentation load_rep = | |
996 UnalignedLoadRepresentationOf(node->op()); | |
997 MipsOperandGenerator g(this); | |
998 Node* base = node->InputAt(0); | |
999 Node* index = node->InputAt(1); | |
1000 | |
1001 ArchOpcode opcode = kArchNop; | |
1002 switch (load_rep.representation()) { | |
1003 case MachineRepresentation::kBit: // Fall through. | |
1004 case MachineRepresentation::kWord8: | |
martyn.capewell
2016/07/07 16:35:46
Can 8-bit accesses ever be unaligned? If not, thes
ivica.bogosavljevic
2016/07/08 13:58:43
Acknowledged.
| |
1005 opcode = load_rep.IsUnsigned() ? kMipsLbu : kMipsLb; | |
1006 break; | |
1007 case MachineRepresentation::kWord16: | |
1008 opcode = load_rep.IsUnsigned() ? kMipsUlhu : kMipsUlh; | |
1009 break; | |
1010 case MachineRepresentation::kTagged: // Fall through. | |
1011 case MachineRepresentation::kWord32: | |
1012 opcode = kMipsUlw; | |
1013 break; | |
1014 case MachineRepresentation::kFloat32: | |
1015 opcode = kMipsUlwc1; | |
1016 break; | |
1017 case MachineRepresentation::kFloat64: | |
1018 opcode = kMipsUldc1; | |
1019 break; | |
1020 case MachineRepresentation::kWord64: // Fall through. | |
1021 case MachineRepresentation::kSimd128: // Fall through. | |
1022 case MachineRepresentation::kNone: | |
1023 UNREACHABLE(); | |
1024 return; | |
1025 } | |
1026 | |
1027 if (g.CanBeImmediate(index, opcode)) { | |
1028 Emit(opcode | AddressingModeField::encode(kMode_MRI), | |
1029 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); | |
1030 } else { | |
1031 InstructionOperand addr_reg = g.TempRegister(); | |
1032 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, | |
1033 g.UseRegister(index), g.UseRegister(base)); | |
1034 // Emit desired load opcode, using temp addr_reg. | |
1035 Emit(opcode | AddressingModeField::encode(kMode_MRI), | |
1036 g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); | |
1037 } | |
1038 } | |
1039 | |
1040 void InstructionSelector::VisitUnalignedStore(Node* node) { | |
1041 MipsOperandGenerator g(this); | |
1042 Node* base = node->InputAt(0); | |
1043 Node* index = node->InputAt(1); | |
1044 Node* value = node->InputAt(2); | |
1045 | |
1046 UnalignedStoreRepresentation rep = UnalignedStoreRepresentationOf(node->op()); | |
1047 | |
1048 // TODO(mips): I guess this could be done in a better way. | |
1049 ArchOpcode opcode = kArchNop; | |
1050 switch (rep) { | |
1051 case MachineRepresentation::kFloat32: | |
1052 opcode = kMipsUswc1; | |
1053 break; | |
1054 case MachineRepresentation::kFloat64: | |
1055 opcode = kMipsUsdc1; | |
1056 break; | |
1057 case MachineRepresentation::kBit: // Fall through. | |
1058 case MachineRepresentation::kWord8: | |
1059 opcode = kMipsSb; | |
1060 break; | |
1061 case MachineRepresentation::kWord16: | |
1062 opcode = kMipsUsh; | |
1063 break; | |
1064 case MachineRepresentation::kTagged: // Fall through. | |
1065 case MachineRepresentation::kWord32: | |
1066 opcode = kMipsUsw; | |
1067 break; | |
1068 case MachineRepresentation::kWord64: // Fall through. | |
1069 case MachineRepresentation::kSimd128: // Fall through. | |
1070 case MachineRepresentation::kNone: | |
1071 UNREACHABLE(); | |
1072 return; | |
1073 } | |
1074 | |
1075 if (g.CanBeImmediate(index, opcode)) { | |
1076 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | |
1077 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | |
1078 } else { | |
1079 InstructionOperand addr_reg = g.TempRegister(); | |
1080 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, | |
1081 g.UseRegister(index), g.UseRegister(base)); | |
1082 // Emit desired store opcode, using temp addr_reg. | |
1083 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | |
1084 addr_reg, g.TempImmediate(0), g.UseRegister(value)); | |
1085 } | |
1086 } | |
1087 | |
994 void InstructionSelector::VisitCheckedLoad(Node* node) { | 1088 void InstructionSelector::VisitCheckedLoad(Node* node) { |
995 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); | 1089 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
996 MipsOperandGenerator g(this); | 1090 MipsOperandGenerator g(this); |
997 Node* const buffer = node->InputAt(0); | 1091 Node* const buffer = node->InputAt(0); |
998 Node* const offset = node->InputAt(1); | 1092 Node* const offset = node->InputAt(1); |
999 Node* const length = node->InputAt(2); | 1093 Node* const length = node->InputAt(2); |
1000 ArchOpcode opcode = kArchNop; | 1094 ArchOpcode opcode = kArchNop; |
1001 switch (load_rep.representation()) { | 1095 switch (load_rep.representation()) { |
1002 case MachineRepresentation::kWord8: | 1096 case MachineRepresentation::kWord8: |
1003 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; | 1097 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1551 MachineOperatorBuilder::Flags | 1645 MachineOperatorBuilder::Flags |
1552 InstructionSelector::SupportedMachineOperatorFlags() { | 1646 InstructionSelector::SupportedMachineOperatorFlags() { |
1553 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags; | 1647 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags; |
1554 if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && | 1648 if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && |
1555 IsFp64Mode()) { | 1649 IsFp64Mode()) { |
1556 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1650 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
1557 MachineOperatorBuilder::kFloat64RoundUp | | 1651 MachineOperatorBuilder::kFloat64RoundUp | |
1558 MachineOperatorBuilder::kFloat64RoundTruncate | | 1652 MachineOperatorBuilder::kFloat64RoundTruncate | |
1559 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1653 MachineOperatorBuilder::kFloat64RoundTiesEven; |
1560 } | 1654 } |
1655 | |
1656 if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1)) || | |
1657 IsMipsArchVariant(kLoongson)) { | |
1658 flags |= MachineOperatorBuilder::kUnalignedLoad | | |
1659 MachineOperatorBuilder::kUnalignedStore; | |
1660 } | |
1661 | |
1561 return flags | MachineOperatorBuilder::kWord32Ctz | | 1662 return flags | MachineOperatorBuilder::kWord32Ctz | |
1562 MachineOperatorBuilder::kWord32Popcnt | | 1663 MachineOperatorBuilder::kWord32Popcnt | |
1563 MachineOperatorBuilder::kInt32DivIsSafe | | 1664 MachineOperatorBuilder::kInt32DivIsSafe | |
1564 MachineOperatorBuilder::kUint32DivIsSafe | | 1665 MachineOperatorBuilder::kUint32DivIsSafe | |
1565 MachineOperatorBuilder::kWord32ShiftIsSafe | | 1666 MachineOperatorBuilder::kWord32ShiftIsSafe | |
1566 MachineOperatorBuilder::kFloat64Min | | 1667 MachineOperatorBuilder::kFloat64Min | |
1567 MachineOperatorBuilder::kFloat64Max | | 1668 MachineOperatorBuilder::kFloat64Max | |
1568 MachineOperatorBuilder::kFloat32Min | | 1669 MachineOperatorBuilder::kFloat32Min | |
1569 MachineOperatorBuilder::kFloat32Max | | 1670 MachineOperatorBuilder::kFloat32Max | |
1570 MachineOperatorBuilder::kFloat32RoundDown | | 1671 MachineOperatorBuilder::kFloat32RoundDown | |
(...skipping 12 matching lines...) Expand all Loading... | |
1583 DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) || | 1684 DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) || |
1584 IsMipsArchVariant(kMips32r2)); | 1685 IsMipsArchVariant(kMips32r2)); |
1585 return MachineOperatorBuilder::AlignmentRequirements:: | 1686 return MachineOperatorBuilder::AlignmentRequirements:: |
1586 NoUnalignedAccessSupport(); | 1687 NoUnalignedAccessSupport(); |
1587 } | 1688 } |
1588 } | 1689 } |
1589 | 1690 |
1590 } // namespace compiler | 1691 } // namespace compiler |
1591 } // namespace internal | 1692 } // namespace internal |
1592 } // namespace v8 | 1693 } // namespace v8 |
OLD | NEW |