| 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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 | 120 |
| 121 | 121 |
| 122 static void VisitBinop(InstructionSelector* selector, Node* node, | 122 static void VisitBinop(InstructionSelector* selector, Node* node, |
| 123 InstructionCode opcode) { | 123 InstructionCode opcode) { |
| 124 FlagsContinuation cont; | 124 FlagsContinuation cont; |
| 125 VisitBinop(selector, node, opcode, &cont); | 125 VisitBinop(selector, node, opcode, &cont); |
| 126 } | 126 } |
| 127 | 127 |
| 128 | 128 |
| 129 void InstructionSelector::VisitLoad(Node* node) { | 129 void InstructionSelector::VisitLoad(Node* node) { |
| 130 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 130 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
| 131 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
| 132 MipsOperandGenerator g(this); | 131 MipsOperandGenerator g(this); |
| 133 Node* base = node->InputAt(0); | 132 Node* base = node->InputAt(0); |
| 134 Node* index = node->InputAt(1); | 133 Node* index = node->InputAt(1); |
| 135 | 134 |
| 136 ArchOpcode opcode; | 135 ArchOpcode opcode; |
| 137 switch (rep) { | 136 switch (load_rep.representation()) { |
| 138 case kRepFloat32: | 137 case MachineRepresentation::kFloat32: |
| 139 opcode = kMipsLwc1; | 138 opcode = kMipsLwc1; |
| 140 break; | 139 break; |
| 141 case kRepFloat64: | 140 case MachineRepresentation::kFloat64: |
| 142 opcode = kMipsLdc1; | 141 opcode = kMipsLdc1; |
| 143 break; | 142 break; |
| 144 case kRepBit: // Fall through. | 143 case MachineRepresentation::kBit: // Fall through. |
| 145 case kRepWord8: | 144 case MachineRepresentation::kWord8: |
| 146 opcode = typ == kTypeUint32 ? kMipsLbu : kMipsLb; | 145 opcode = load_rep.IsUnsigned() ? kMipsLbu : kMipsLb; |
| 147 break; | 146 break; |
| 148 case kRepWord16: | 147 case MachineRepresentation::kWord16: |
| 149 opcode = typ == kTypeUint32 ? kMipsLhu : kMipsLh; | 148 opcode = load_rep.IsUnsigned() ? kMipsLhu : kMipsLh; |
| 150 break; | 149 break; |
| 151 case kRepTagged: // Fall through. | 150 case MachineRepresentation::kTagged: // Fall through. |
| 152 case kRepWord32: | 151 case MachineRepresentation::kWord32: |
| 153 opcode = kMipsLw; | 152 opcode = kMipsLw; |
| 154 break; | 153 break; |
| 155 default: | 154 default: |
| 156 UNREACHABLE(); | 155 UNREACHABLE(); |
| 157 return; | 156 return; |
| 158 } | 157 } |
| 159 | 158 |
| 160 if (g.CanBeImmediate(index, opcode)) { | 159 if (g.CanBeImmediate(index, opcode)) { |
| 161 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 160 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 162 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); | 161 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); |
| 163 } else { | 162 } else { |
| 164 InstructionOperand addr_reg = g.TempRegister(); | 163 InstructionOperand addr_reg = g.TempRegister(); |
| 165 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, | 164 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, |
| 166 g.UseRegister(index), g.UseRegister(base)); | 165 g.UseRegister(index), g.UseRegister(base)); |
| 167 // Emit desired load opcode, using temp addr_reg. | 166 // Emit desired load opcode, using temp addr_reg. |
| 168 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 167 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 169 g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); | 168 g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); |
| 170 } | 169 } |
| 171 } | 170 } |
| 172 | 171 |
| 173 | 172 |
| 174 void InstructionSelector::VisitStore(Node* node) { | 173 void InstructionSelector::VisitStore(Node* node) { |
| 175 MipsOperandGenerator g(this); | 174 MipsOperandGenerator g(this); |
| 176 Node* base = node->InputAt(0); | 175 Node* base = node->InputAt(0); |
| 177 Node* index = node->InputAt(1); | 176 Node* index = node->InputAt(1); |
| 178 Node* value = node->InputAt(2); | 177 Node* value = node->InputAt(2); |
| 179 | 178 |
| 180 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 179 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 181 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 180 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
| 182 MachineType rep = RepresentationOf(store_rep.machine_type()); | 181 MachineRepresentation rep = store_rep.machine_type().representation(); |
| 183 | 182 |
| 184 // TODO(mips): I guess this could be done in a better way. | 183 // TODO(mips): I guess this could be done in a better way. |
| 185 if (write_barrier_kind != kNoWriteBarrier) { | 184 if (write_barrier_kind != kNoWriteBarrier) { |
| 186 DCHECK_EQ(kRepTagged, rep); | 185 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
| 187 InstructionOperand inputs[3]; | 186 InstructionOperand inputs[3]; |
| 188 size_t input_count = 0; | 187 size_t input_count = 0; |
| 189 inputs[input_count++] = g.UseUniqueRegister(base); | 188 inputs[input_count++] = g.UseUniqueRegister(base); |
| 190 inputs[input_count++] = g.UseUniqueRegister(index); | 189 inputs[input_count++] = g.UseUniqueRegister(index); |
| 191 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) | 190 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
| 192 ? g.UseRegister(value) | 191 ? g.UseRegister(value) |
| 193 : g.UseUniqueRegister(value); | 192 : g.UseUniqueRegister(value); |
| 194 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; | 193 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; |
| 195 switch (write_barrier_kind) { | 194 switch (write_barrier_kind) { |
| 196 case kNoWriteBarrier: | 195 case kNoWriteBarrier: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 207 break; | 206 break; |
| 208 } | 207 } |
| 209 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 208 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
| 210 size_t const temp_count = arraysize(temps); | 209 size_t const temp_count = arraysize(temps); |
| 211 InstructionCode code = kArchStoreWithWriteBarrier; | 210 InstructionCode code = kArchStoreWithWriteBarrier; |
| 212 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 211 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
| 213 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 212 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
| 214 } else { | 213 } else { |
| 215 ArchOpcode opcode; | 214 ArchOpcode opcode; |
| 216 switch (rep) { | 215 switch (rep) { |
| 217 case kRepFloat32: | 216 case MachineRepresentation::kFloat32: |
| 218 opcode = kMipsSwc1; | 217 opcode = kMipsSwc1; |
| 219 break; | 218 break; |
| 220 case kRepFloat64: | 219 case MachineRepresentation::kFloat64: |
| 221 opcode = kMipsSdc1; | 220 opcode = kMipsSdc1; |
| 222 break; | 221 break; |
| 223 case kRepBit: // Fall through. | 222 case MachineRepresentation::kBit: // Fall through. |
| 224 case kRepWord8: | 223 case MachineRepresentation::kWord8: |
| 225 opcode = kMipsSb; | 224 opcode = kMipsSb; |
| 226 break; | 225 break; |
| 227 case kRepWord16: | 226 case MachineRepresentation::kWord16: |
| 228 opcode = kMipsSh; | 227 opcode = kMipsSh; |
| 229 break; | 228 break; |
| 230 case kRepTagged: // Fall through. | 229 case MachineRepresentation::kTagged: // Fall through. |
| 231 case kRepWord32: | 230 case MachineRepresentation::kWord32: |
| 232 opcode = kMipsSw; | 231 opcode = kMipsSw; |
| 233 break; | 232 break; |
| 234 default: | 233 default: |
| 235 UNREACHABLE(); | 234 UNREACHABLE(); |
| 236 return; | 235 return; |
| 237 } | 236 } |
| 238 | 237 |
| 239 if (g.CanBeImmediate(index, opcode)) { | 238 if (g.CanBeImmediate(index, opcode)) { |
| 240 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 239 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
| 241 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 240 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 796 } | 795 } |
| 797 } | 796 } |
| 798 } | 797 } |
| 799 } | 798 } |
| 800 | 799 |
| 801 | 800 |
| 802 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } | 801 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } |
| 803 | 802 |
| 804 | 803 |
| 805 void InstructionSelector::VisitCheckedLoad(Node* node) { | 804 void InstructionSelector::VisitCheckedLoad(Node* node) { |
| 806 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 805 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
| 807 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
| 808 MipsOperandGenerator g(this); | 806 MipsOperandGenerator g(this); |
| 809 Node* const buffer = node->InputAt(0); | 807 Node* const buffer = node->InputAt(0); |
| 810 Node* const offset = node->InputAt(1); | 808 Node* const offset = node->InputAt(1); |
| 811 Node* const length = node->InputAt(2); | 809 Node* const length = node->InputAt(2); |
| 812 ArchOpcode opcode; | 810 ArchOpcode opcode; |
| 813 switch (rep) { | 811 switch (load_rep.representation()) { |
| 814 case kRepWord8: | 812 case MachineRepresentation::kWord8: |
| 815 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 813 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
| 816 break; | 814 break; |
| 817 case kRepWord16: | 815 case MachineRepresentation::kWord16: |
| 818 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 816 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
| 819 break; | 817 break; |
| 820 case kRepWord32: | 818 case MachineRepresentation::kWord32: |
| 821 opcode = kCheckedLoadWord32; | 819 opcode = kCheckedLoadWord32; |
| 822 break; | 820 break; |
| 823 case kRepFloat32: | 821 case MachineRepresentation::kFloat32: |
| 824 opcode = kCheckedLoadFloat32; | 822 opcode = kCheckedLoadFloat32; |
| 825 break; | 823 break; |
| 826 case kRepFloat64: | 824 case MachineRepresentation::kFloat64: |
| 827 opcode = kCheckedLoadFloat64; | 825 opcode = kCheckedLoadFloat64; |
| 828 break; | 826 break; |
| 829 default: | 827 default: |
| 830 UNREACHABLE(); | 828 UNREACHABLE(); |
| 831 return; | 829 return; |
| 832 } | 830 } |
| 833 InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) | 831 InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) |
| 834 ? g.UseImmediate(offset) | 832 ? g.UseImmediate(offset) |
| 835 : g.UseRegister(offset); | 833 : g.UseRegister(offset); |
| 836 | 834 |
| 837 InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) | 835 InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) |
| 838 ? g.CanBeImmediate(length, opcode) | 836 ? g.CanBeImmediate(length, opcode) |
| 839 ? g.UseImmediate(length) | 837 ? g.UseImmediate(length) |
| 840 : g.UseRegister(length) | 838 : g.UseRegister(length) |
| 841 : g.UseRegister(length); | 839 : g.UseRegister(length); |
| 842 | 840 |
| 843 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 841 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 844 g.DefineAsRegister(node), offset_operand, length_operand, | 842 g.DefineAsRegister(node), offset_operand, length_operand, |
| 845 g.UseRegister(buffer)); | 843 g.UseRegister(buffer)); |
| 846 } | 844 } |
| 847 | 845 |
| 848 | 846 |
| 849 void InstructionSelector::VisitCheckedStore(Node* node) { | 847 void InstructionSelector::VisitCheckedStore(Node* node) { |
| 850 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 848 MachineRepresentation rep = |
| 849 CheckedStoreRepresentationOf(node->op()).representation(); |
| 851 MipsOperandGenerator g(this); | 850 MipsOperandGenerator g(this); |
| 852 Node* const buffer = node->InputAt(0); | 851 Node* const buffer = node->InputAt(0); |
| 853 Node* const offset = node->InputAt(1); | 852 Node* const offset = node->InputAt(1); |
| 854 Node* const length = node->InputAt(2); | 853 Node* const length = node->InputAt(2); |
| 855 Node* const value = node->InputAt(3); | 854 Node* const value = node->InputAt(3); |
| 856 ArchOpcode opcode; | 855 ArchOpcode opcode; |
| 857 switch (rep) { | 856 switch (rep) { |
| 858 case kRepWord8: | 857 case MachineRepresentation::kWord8: |
| 859 opcode = kCheckedStoreWord8; | 858 opcode = kCheckedStoreWord8; |
| 860 break; | 859 break; |
| 861 case kRepWord16: | 860 case MachineRepresentation::kWord16: |
| 862 opcode = kCheckedStoreWord16; | 861 opcode = kCheckedStoreWord16; |
| 863 break; | 862 break; |
| 864 case kRepWord32: | 863 case MachineRepresentation::kWord32: |
| 865 opcode = kCheckedStoreWord32; | 864 opcode = kCheckedStoreWord32; |
| 866 break; | 865 break; |
| 867 case kRepFloat32: | 866 case MachineRepresentation::kFloat32: |
| 868 opcode = kCheckedStoreFloat32; | 867 opcode = kCheckedStoreFloat32; |
| 869 break; | 868 break; |
| 870 case kRepFloat64: | 869 case MachineRepresentation::kFloat64: |
| 871 opcode = kCheckedStoreFloat64; | 870 opcode = kCheckedStoreFloat64; |
| 872 break; | 871 break; |
| 873 default: | 872 default: |
| 874 UNREACHABLE(); | 873 UNREACHABLE(); |
| 875 return; | 874 return; |
| 876 } | 875 } |
| 877 InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) | 876 InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) |
| 878 ? g.UseImmediate(offset) | 877 ? g.UseImmediate(offset) |
| 879 : g.UseRegister(offset); | 878 : g.UseRegister(offset); |
| 880 | 879 |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1281 MachineOperatorBuilder::kFloat32Max | | 1280 MachineOperatorBuilder::kFloat32Max | |
| 1282 MachineOperatorBuilder::kFloat32RoundDown | | 1281 MachineOperatorBuilder::kFloat32RoundDown | |
| 1283 MachineOperatorBuilder::kFloat32RoundUp | | 1282 MachineOperatorBuilder::kFloat32RoundUp | |
| 1284 MachineOperatorBuilder::kFloat32RoundTruncate | | 1283 MachineOperatorBuilder::kFloat32RoundTruncate | |
| 1285 MachineOperatorBuilder::kFloat32RoundTiesEven; | 1284 MachineOperatorBuilder::kFloat32RoundTiesEven; |
| 1286 } | 1285 } |
| 1287 | 1286 |
| 1288 } // namespace compiler | 1287 } // namespace compiler |
| 1289 } // namespace internal | 1288 } // namespace internal |
| 1290 } // namespace v8 | 1289 } // namespace v8 |
| OLD | NEW |