Chromium Code Reviews| 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 |