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/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 } else { | 162 } else { |
163 selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input)); | 163 selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input)); |
164 } | 164 } |
165 } | 165 } |
166 | 166 |
167 | 167 |
168 } // namespace | 168 } // namespace |
169 | 169 |
170 | 170 |
171 void InstructionSelector::VisitLoad(Node* node) { | 171 void InstructionSelector::VisitLoad(Node* node) { |
172 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 172 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
173 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
174 | 173 |
175 ArchOpcode opcode; | 174 ArchOpcode opcode; |
176 switch (rep) { | 175 switch (load_rep.representation()) { |
177 case kRepFloat32: | 176 case MachineRepresentation::kFloat32: |
178 opcode = kIA32Movss; | 177 opcode = kIA32Movss; |
179 break; | 178 break; |
180 case kRepFloat64: | 179 case MachineRepresentation::kFloat64: |
181 opcode = kIA32Movsd; | 180 opcode = kIA32Movsd; |
182 break; | 181 break; |
183 case kRepBit: // Fall through. | 182 case MachineRepresentation::kBit: // Fall through. |
184 case kRepWord8: | 183 case MachineRepresentation::kWord8: |
185 opcode = typ == kTypeInt32 ? kIA32Movsxbl : kIA32Movzxbl; | 184 opcode = load_rep.IsSigned() ? kIA32Movsxbl : kIA32Movzxbl; |
186 break; | 185 break; |
187 case kRepWord16: | 186 case MachineRepresentation::kWord16: |
188 opcode = typ == kTypeInt32 ? kIA32Movsxwl : kIA32Movzxwl; | 187 opcode = load_rep.IsSigned() ? kIA32Movsxwl : kIA32Movzxwl; |
189 break; | 188 break; |
190 case kRepTagged: // Fall through. | 189 case MachineRepresentation::kTagged: // Fall through. |
191 case kRepWord32: | 190 case MachineRepresentation::kWord32: |
192 opcode = kIA32Movl; | 191 opcode = kIA32Movl; |
193 break; | 192 break; |
194 default: | 193 default: |
195 UNREACHABLE(); | 194 UNREACHABLE(); |
196 return; | 195 return; |
197 } | 196 } |
198 | 197 |
199 IA32OperandGenerator g(this); | 198 IA32OperandGenerator g(this); |
200 InstructionOperand outputs[1]; | 199 InstructionOperand outputs[1]; |
201 outputs[0] = g.DefineAsRegister(node); | 200 outputs[0] = g.DefineAsRegister(node); |
202 InstructionOperand inputs[3]; | 201 InstructionOperand inputs[3]; |
203 size_t input_count = 0; | 202 size_t input_count = 0; |
204 AddressingMode mode = | 203 AddressingMode mode = |
205 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 204 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
206 InstructionCode code = opcode | AddressingModeField::encode(mode); | 205 InstructionCode code = opcode | AddressingModeField::encode(mode); |
207 Emit(code, 1, outputs, input_count, inputs); | 206 Emit(code, 1, outputs, input_count, inputs); |
208 } | 207 } |
209 | 208 |
210 | 209 |
211 void InstructionSelector::VisitStore(Node* node) { | 210 void InstructionSelector::VisitStore(Node* node) { |
212 IA32OperandGenerator g(this); | 211 IA32OperandGenerator g(this); |
213 Node* base = node->InputAt(0); | 212 Node* base = node->InputAt(0); |
214 Node* index = node->InputAt(1); | 213 Node* index = node->InputAt(1); |
215 Node* value = node->InputAt(2); | 214 Node* value = node->InputAt(2); |
216 | 215 |
217 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 216 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
218 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 217 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
219 MachineType rep = RepresentationOf(store_rep.machine_type()); | 218 MachineRepresentation rep = store_rep.machine_type().representation(); |
220 | 219 |
221 if (write_barrier_kind != kNoWriteBarrier) { | 220 if (write_barrier_kind != kNoWriteBarrier) { |
222 DCHECK_EQ(kRepTagged, rep); | 221 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
223 AddressingMode addressing_mode; | 222 AddressingMode addressing_mode; |
224 InstructionOperand inputs[3]; | 223 InstructionOperand inputs[3]; |
225 size_t input_count = 0; | 224 size_t input_count = 0; |
226 inputs[input_count++] = g.UseUniqueRegister(base); | 225 inputs[input_count++] = g.UseUniqueRegister(base); |
227 if (g.CanBeImmediate(index)) { | 226 if (g.CanBeImmediate(index)) { |
228 inputs[input_count++] = g.UseImmediate(index); | 227 inputs[input_count++] = g.UseImmediate(index); |
229 addressing_mode = kMode_MRI; | 228 addressing_mode = kMode_MRI; |
230 } else { | 229 } else { |
231 inputs[input_count++] = g.UseUniqueRegister(index); | 230 inputs[input_count++] = g.UseUniqueRegister(index); |
232 addressing_mode = kMode_MR1; | 231 addressing_mode = kMode_MR1; |
(...skipping 18 matching lines...) Expand all Loading... |
251 } | 250 } |
252 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 251 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
253 size_t const temp_count = arraysize(temps); | 252 size_t const temp_count = arraysize(temps); |
254 InstructionCode code = kArchStoreWithWriteBarrier; | 253 InstructionCode code = kArchStoreWithWriteBarrier; |
255 code |= AddressingModeField::encode(addressing_mode); | 254 code |= AddressingModeField::encode(addressing_mode); |
256 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 255 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
257 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 256 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
258 } else { | 257 } else { |
259 ArchOpcode opcode; | 258 ArchOpcode opcode; |
260 switch (rep) { | 259 switch (rep) { |
261 case kRepFloat32: | 260 case MachineRepresentation::kFloat32: |
262 opcode = kIA32Movss; | 261 opcode = kIA32Movss; |
263 break; | 262 break; |
264 case kRepFloat64: | 263 case MachineRepresentation::kFloat64: |
265 opcode = kIA32Movsd; | 264 opcode = kIA32Movsd; |
266 break; | 265 break; |
267 case kRepBit: // Fall through. | 266 case MachineRepresentation::kBit: // Fall through. |
268 case kRepWord8: | 267 case MachineRepresentation::kWord8: |
269 opcode = kIA32Movb; | 268 opcode = kIA32Movb; |
270 break; | 269 break; |
271 case kRepWord16: | 270 case MachineRepresentation::kWord16: |
272 opcode = kIA32Movw; | 271 opcode = kIA32Movw; |
273 break; | 272 break; |
274 case kRepTagged: // Fall through. | 273 case MachineRepresentation::kTagged: // Fall through. |
275 case kRepWord32: | 274 case MachineRepresentation::kWord32: |
276 opcode = kIA32Movl; | 275 opcode = kIA32Movl; |
277 break; | 276 break; |
278 default: | 277 default: |
279 UNREACHABLE(); | 278 UNREACHABLE(); |
280 return; | 279 return; |
281 } | 280 } |
282 | 281 |
283 InstructionOperand val; | 282 InstructionOperand val; |
284 if (g.CanBeImmediate(value)) { | 283 if (g.CanBeImmediate(value)) { |
285 val = g.UseImmediate(value); | 284 val = g.UseImmediate(value); |
286 } else if (rep == kRepWord8 || rep == kRepBit) { | 285 } else if (rep == MachineRepresentation::kWord8 || |
| 286 rep == MachineRepresentation::kBit) { |
287 val = g.UseByteRegister(value); | 287 val = g.UseByteRegister(value); |
288 } else { | 288 } else { |
289 val = g.UseRegister(value); | 289 val = g.UseRegister(value); |
290 } | 290 } |
291 | 291 |
292 InstructionOperand inputs[4]; | 292 InstructionOperand inputs[4]; |
293 size_t input_count = 0; | 293 size_t input_count = 0; |
294 AddressingMode addressing_mode = | 294 AddressingMode addressing_mode = |
295 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 295 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
296 InstructionCode code = | 296 InstructionCode code = |
297 opcode | AddressingModeField::encode(addressing_mode); | 297 opcode | AddressingModeField::encode(addressing_mode); |
298 inputs[input_count++] = val; | 298 inputs[input_count++] = val; |
299 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); | 299 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); |
300 } | 300 } |
301 } | 301 } |
302 | 302 |
303 | 303 |
304 void InstructionSelector::VisitCheckedLoad(Node* node) { | 304 void InstructionSelector::VisitCheckedLoad(Node* node) { |
305 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 305 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
306 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
307 IA32OperandGenerator g(this); | 306 IA32OperandGenerator g(this); |
308 Node* const buffer = node->InputAt(0); | 307 Node* const buffer = node->InputAt(0); |
309 Node* const offset = node->InputAt(1); | 308 Node* const offset = node->InputAt(1); |
310 Node* const length = node->InputAt(2); | 309 Node* const length = node->InputAt(2); |
311 ArchOpcode opcode; | 310 ArchOpcode opcode; |
312 switch (rep) { | 311 switch (load_rep.representation()) { |
313 case kRepWord8: | 312 case MachineRepresentation::kWord8: |
314 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 313 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
315 break; | 314 break; |
316 case kRepWord16: | 315 case MachineRepresentation::kWord16: |
317 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 316 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
318 break; | 317 break; |
319 case kRepWord32: | 318 case MachineRepresentation::kWord32: |
320 opcode = kCheckedLoadWord32; | 319 opcode = kCheckedLoadWord32; |
321 break; | 320 break; |
322 case kRepFloat32: | 321 case MachineRepresentation::kFloat32: |
323 opcode = kCheckedLoadFloat32; | 322 opcode = kCheckedLoadFloat32; |
324 break; | 323 break; |
325 case kRepFloat64: | 324 case MachineRepresentation::kFloat64: |
326 opcode = kCheckedLoadFloat64; | 325 opcode = kCheckedLoadFloat64; |
327 break; | 326 break; |
328 default: | 327 default: |
329 UNREACHABLE(); | 328 UNREACHABLE(); |
330 return; | 329 return; |
331 } | 330 } |
332 InstructionOperand offset_operand = g.UseRegister(offset); | 331 InstructionOperand offset_operand = g.UseRegister(offset); |
333 InstructionOperand length_operand = | 332 InstructionOperand length_operand = |
334 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); | 333 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
335 if (g.CanBeImmediate(buffer)) { | 334 if (g.CanBeImmediate(buffer)) { |
336 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 335 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
337 g.DefineAsRegister(node), offset_operand, length_operand, | 336 g.DefineAsRegister(node), offset_operand, length_operand, |
338 offset_operand, g.UseImmediate(buffer)); | 337 offset_operand, g.UseImmediate(buffer)); |
339 } else { | 338 } else { |
340 Emit(opcode | AddressingModeField::encode(kMode_MR1), | 339 Emit(opcode | AddressingModeField::encode(kMode_MR1), |
341 g.DefineAsRegister(node), offset_operand, length_operand, | 340 g.DefineAsRegister(node), offset_operand, length_operand, |
342 g.UseRegister(buffer), offset_operand); | 341 g.UseRegister(buffer), offset_operand); |
343 } | 342 } |
344 } | 343 } |
345 | 344 |
346 | 345 |
347 void InstructionSelector::VisitCheckedStore(Node* node) { | 346 void InstructionSelector::VisitCheckedStore(Node* node) { |
348 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 347 MachineRepresentation rep = |
| 348 CheckedStoreRepresentationOf(node->op()).representation(); |
349 IA32OperandGenerator g(this); | 349 IA32OperandGenerator g(this); |
350 Node* const buffer = node->InputAt(0); | 350 Node* const buffer = node->InputAt(0); |
351 Node* const offset = node->InputAt(1); | 351 Node* const offset = node->InputAt(1); |
352 Node* const length = node->InputAt(2); | 352 Node* const length = node->InputAt(2); |
353 Node* const value = node->InputAt(3); | 353 Node* const value = node->InputAt(3); |
354 ArchOpcode opcode; | 354 ArchOpcode opcode; |
355 switch (rep) { | 355 switch (rep) { |
356 case kRepWord8: | 356 case MachineRepresentation::kWord8: |
357 opcode = kCheckedStoreWord8; | 357 opcode = kCheckedStoreWord8; |
358 break; | 358 break; |
359 case kRepWord16: | 359 case MachineRepresentation::kWord16: |
360 opcode = kCheckedStoreWord16; | 360 opcode = kCheckedStoreWord16; |
361 break; | 361 break; |
362 case kRepWord32: | 362 case MachineRepresentation::kWord32: |
363 opcode = kCheckedStoreWord32; | 363 opcode = kCheckedStoreWord32; |
364 break; | 364 break; |
365 case kRepFloat32: | 365 case MachineRepresentation::kFloat32: |
366 opcode = kCheckedStoreFloat32; | 366 opcode = kCheckedStoreFloat32; |
367 break; | 367 break; |
368 case kRepFloat64: | 368 case MachineRepresentation::kFloat64: |
369 opcode = kCheckedStoreFloat64; | 369 opcode = kCheckedStoreFloat64; |
370 break; | 370 break; |
371 default: | 371 default: |
372 UNREACHABLE(); | 372 UNREACHABLE(); |
373 return; | 373 return; |
374 } | 374 } |
375 InstructionOperand value_operand = | 375 InstructionOperand value_operand = |
376 g.CanBeImmediate(value) | 376 g.CanBeImmediate(value) ? g.UseImmediate(value) |
377 ? g.UseImmediate(value) | 377 : ((rep == MachineRepresentation::kWord8 || |
378 : ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value) | 378 rep == MachineRepresentation::kBit) |
379 : g.UseRegister(value)); | 379 ? g.UseByteRegister(value) |
| 380 : g.UseRegister(value)); |
380 InstructionOperand offset_operand = g.UseRegister(offset); | 381 InstructionOperand offset_operand = g.UseRegister(offset); |
381 InstructionOperand length_operand = | 382 InstructionOperand length_operand = |
382 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); | 383 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
383 if (g.CanBeImmediate(buffer)) { | 384 if (g.CanBeImmediate(buffer)) { |
384 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 385 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
385 offset_operand, length_operand, value_operand, offset_operand, | 386 offset_operand, length_operand, value_operand, offset_operand, |
386 g.UseImmediate(buffer)); | 387 g.UseImmediate(buffer)); |
387 } else { | 388 } else { |
388 Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(), | 389 Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(), |
389 offset_operand, length_operand, value_operand, g.UseRegister(buffer), | 390 offset_operand, length_operand, value_operand, g.UseRegister(buffer), |
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1312 MachineOperatorBuilder::kFloat64RoundTruncate | | 1313 MachineOperatorBuilder::kFloat64RoundTruncate | |
1313 MachineOperatorBuilder::kFloat32RoundTiesEven | | 1314 MachineOperatorBuilder::kFloat32RoundTiesEven | |
1314 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1315 MachineOperatorBuilder::kFloat64RoundTiesEven; |
1315 } | 1316 } |
1316 return flags; | 1317 return flags; |
1317 } | 1318 } |
1318 | 1319 |
1319 } // namespace compiler | 1320 } // namespace compiler |
1320 } // namespace internal | 1321 } // namespace internal |
1321 } // namespace v8 | 1322 } // namespace v8 |
OLD | NEW |