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 |