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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 InstructionOperand mul_operand = g.TempRegister(); | 296 InstructionOperand mul_operand = g.TempRegister(); |
297 selector->Emit(kArmMul, mul_operand, div_operand, right_operand); | 297 selector->Emit(kArmMul, mul_operand, div_operand, right_operand); |
298 selector->Emit(kArmSub, result_operand, left_operand, mul_operand); | 298 selector->Emit(kArmSub, result_operand, left_operand, mul_operand); |
299 } | 299 } |
300 } | 300 } |
301 | 301 |
302 } // namespace | 302 } // namespace |
303 | 303 |
304 | 304 |
305 void InstructionSelector::VisitLoad(Node* node) { | 305 void InstructionSelector::VisitLoad(Node* node) { |
306 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 306 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
307 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
308 ArmOperandGenerator g(this); | 307 ArmOperandGenerator g(this); |
309 Node* base = node->InputAt(0); | 308 Node* base = node->InputAt(0); |
310 Node* index = node->InputAt(1); | 309 Node* index = node->InputAt(1); |
311 | 310 |
312 ArchOpcode opcode; | 311 ArchOpcode opcode; |
313 switch (rep) { | 312 switch (load_rep.representation()) { |
314 case kRepFloat32: | 313 case MachineRepresentation::kFloat32: |
315 opcode = kArmVldrF32; | 314 opcode = kArmVldrF32; |
316 break; | 315 break; |
317 case kRepFloat64: | 316 case MachineRepresentation::kFloat64: |
318 opcode = kArmVldrF64; | 317 opcode = kArmVldrF64; |
319 break; | 318 break; |
320 case kRepBit: // Fall through. | 319 case MachineRepresentation::kBit: // Fall through. |
321 case kRepWord8: | 320 case MachineRepresentation::kWord8: |
322 opcode = typ == kTypeUint32 ? kArmLdrb : kArmLdrsb; | 321 opcode = load_rep.IsUnsigned() ? kArmLdrb : kArmLdrsb; |
323 break; | 322 break; |
324 case kRepWord16: | 323 case MachineRepresentation::kWord16: |
325 opcode = typ == kTypeUint32 ? kArmLdrh : kArmLdrsh; | 324 opcode = load_rep.IsUnsigned() ? kArmLdrh : kArmLdrsh; |
326 break; | 325 break; |
327 case kRepTagged: // Fall through. | 326 case MachineRepresentation::kTagged: // Fall through. |
328 case kRepWord32: | 327 case MachineRepresentation::kWord32: |
329 opcode = kArmLdr; | 328 opcode = kArmLdr; |
330 break; | 329 break; |
331 default: | 330 default: |
332 UNREACHABLE(); | 331 UNREACHABLE(); |
333 return; | 332 return; |
334 } | 333 } |
335 | 334 |
336 if (g.CanBeImmediate(index, opcode)) { | 335 if (g.CanBeImmediate(index, opcode)) { |
337 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), | 336 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), |
338 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); | 337 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); |
339 } else { | 338 } else { |
340 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), | 339 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), |
341 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); | 340 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); |
342 } | 341 } |
343 } | 342 } |
344 | 343 |
345 | 344 |
346 void InstructionSelector::VisitStore(Node* node) { | 345 void InstructionSelector::VisitStore(Node* node) { |
347 ArmOperandGenerator g(this); | 346 ArmOperandGenerator g(this); |
348 Node* base = node->InputAt(0); | 347 Node* base = node->InputAt(0); |
349 Node* index = node->InputAt(1); | 348 Node* index = node->InputAt(1); |
350 Node* value = node->InputAt(2); | 349 Node* value = node->InputAt(2); |
351 | 350 |
352 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 351 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
353 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 352 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
354 MachineType rep = RepresentationOf(store_rep.machine_type()); | 353 MachineRepresentation rep = store_rep.machine_type().representation(); |
355 | 354 |
356 if (write_barrier_kind != kNoWriteBarrier) { | 355 if (write_barrier_kind != kNoWriteBarrier) { |
357 DCHECK_EQ(kRepTagged, rep); | 356 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
358 InstructionOperand inputs[3]; | 357 InstructionOperand inputs[3]; |
359 size_t input_count = 0; | 358 size_t input_count = 0; |
360 inputs[input_count++] = g.UseUniqueRegister(base); | 359 inputs[input_count++] = g.UseUniqueRegister(base); |
361 inputs[input_count++] = g.UseUniqueRegister(index); | 360 inputs[input_count++] = g.UseUniqueRegister(index); |
362 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) | 361 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
363 ? g.UseRegister(value) | 362 ? g.UseRegister(value) |
364 : g.UseUniqueRegister(value); | 363 : g.UseUniqueRegister(value); |
365 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; | 364 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; |
366 switch (write_barrier_kind) { | 365 switch (write_barrier_kind) { |
367 case kNoWriteBarrier: | 366 case kNoWriteBarrier: |
(...skipping 10 matching lines...) Expand all Loading... |
378 break; | 377 break; |
379 } | 378 } |
380 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 379 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
381 size_t const temp_count = arraysize(temps); | 380 size_t const temp_count = arraysize(temps); |
382 InstructionCode code = kArchStoreWithWriteBarrier; | 381 InstructionCode code = kArchStoreWithWriteBarrier; |
383 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 382 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
384 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 383 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
385 } else { | 384 } else { |
386 ArchOpcode opcode; | 385 ArchOpcode opcode; |
387 switch (rep) { | 386 switch (rep) { |
388 case kRepFloat32: | 387 case MachineRepresentation::kFloat32: |
389 opcode = kArmVstrF32; | 388 opcode = kArmVstrF32; |
390 break; | 389 break; |
391 case kRepFloat64: | 390 case MachineRepresentation::kFloat64: |
392 opcode = kArmVstrF64; | 391 opcode = kArmVstrF64; |
393 break; | 392 break; |
394 case kRepBit: // Fall through. | 393 case MachineRepresentation::kBit: // Fall through. |
395 case kRepWord8: | 394 case MachineRepresentation::kWord8: |
396 opcode = kArmStrb; | 395 opcode = kArmStrb; |
397 break; | 396 break; |
398 case kRepWord16: | 397 case MachineRepresentation::kWord16: |
399 opcode = kArmStrh; | 398 opcode = kArmStrh; |
400 break; | 399 break; |
401 case kRepTagged: // Fall through. | 400 case MachineRepresentation::kTagged: // Fall through. |
402 case kRepWord32: | 401 case MachineRepresentation::kWord32: |
403 opcode = kArmStr; | 402 opcode = kArmStr; |
404 break; | 403 break; |
405 default: | 404 default: |
406 UNREACHABLE(); | 405 UNREACHABLE(); |
407 return; | 406 return; |
408 } | 407 } |
409 | 408 |
410 if (g.CanBeImmediate(index, opcode)) { | 409 if (g.CanBeImmediate(index, opcode)) { |
411 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(), | 410 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(), |
412 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 411 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
413 } else { | 412 } else { |
414 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), | 413 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), |
415 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); | 414 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); |
416 } | 415 } |
417 } | 416 } |
418 } | 417 } |
419 | 418 |
420 | 419 |
421 void InstructionSelector::VisitCheckedLoad(Node* node) { | 420 void InstructionSelector::VisitCheckedLoad(Node* node) { |
422 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 421 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
423 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
424 ArmOperandGenerator g(this); | 422 ArmOperandGenerator g(this); |
425 Node* const buffer = node->InputAt(0); | 423 Node* const buffer = node->InputAt(0); |
426 Node* const offset = node->InputAt(1); | 424 Node* const offset = node->InputAt(1); |
427 Node* const length = node->InputAt(2); | 425 Node* const length = node->InputAt(2); |
428 ArchOpcode opcode; | 426 ArchOpcode opcode; |
429 switch (rep) { | 427 switch (load_rep.representation()) { |
430 case kRepWord8: | 428 case MachineRepresentation::kWord8: |
431 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 429 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
432 break; | 430 break; |
433 case kRepWord16: | 431 case MachineRepresentation::kWord16: |
434 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 432 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
435 break; | 433 break; |
436 case kRepWord32: | 434 case MachineRepresentation::kWord32: |
437 opcode = kCheckedLoadWord32; | 435 opcode = kCheckedLoadWord32; |
438 break; | 436 break; |
439 case kRepFloat32: | 437 case MachineRepresentation::kFloat32: |
440 opcode = kCheckedLoadFloat32; | 438 opcode = kCheckedLoadFloat32; |
441 break; | 439 break; |
442 case kRepFloat64: | 440 case MachineRepresentation::kFloat64: |
443 opcode = kCheckedLoadFloat64; | 441 opcode = kCheckedLoadFloat64; |
444 break; | 442 break; |
445 default: | 443 default: |
446 UNREACHABLE(); | 444 UNREACHABLE(); |
447 return; | 445 return; |
448 } | 446 } |
449 InstructionOperand offset_operand = g.UseRegister(offset); | 447 InstructionOperand offset_operand = g.UseRegister(offset); |
450 InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) | 448 InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) |
451 ? g.UseImmediate(length) | 449 ? g.UseImmediate(length) |
452 : g.UseRegister(length); | 450 : g.UseRegister(length); |
453 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), | 451 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), |
454 g.DefineAsRegister(node), offset_operand, length_operand, | 452 g.DefineAsRegister(node), offset_operand, length_operand, |
455 g.UseRegister(buffer), offset_operand); | 453 g.UseRegister(buffer), offset_operand); |
456 } | 454 } |
457 | 455 |
458 | 456 |
459 void InstructionSelector::VisitCheckedStore(Node* node) { | 457 void InstructionSelector::VisitCheckedStore(Node* node) { |
460 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 458 MachineRepresentation rep = |
| 459 CheckedStoreRepresentationOf(node->op()).representation(); |
461 ArmOperandGenerator g(this); | 460 ArmOperandGenerator g(this); |
462 Node* const buffer = node->InputAt(0); | 461 Node* const buffer = node->InputAt(0); |
463 Node* const offset = node->InputAt(1); | 462 Node* const offset = node->InputAt(1); |
464 Node* const length = node->InputAt(2); | 463 Node* const length = node->InputAt(2); |
465 Node* const value = node->InputAt(3); | 464 Node* const value = node->InputAt(3); |
466 ArchOpcode opcode; | 465 ArchOpcode opcode; |
467 switch (rep) { | 466 switch (rep) { |
468 case kRepWord8: | 467 case MachineRepresentation::kWord8: |
469 opcode = kCheckedStoreWord8; | 468 opcode = kCheckedStoreWord8; |
470 break; | 469 break; |
471 case kRepWord16: | 470 case MachineRepresentation::kWord16: |
472 opcode = kCheckedStoreWord16; | 471 opcode = kCheckedStoreWord16; |
473 break; | 472 break; |
474 case kRepWord32: | 473 case MachineRepresentation::kWord32: |
475 opcode = kCheckedStoreWord32; | 474 opcode = kCheckedStoreWord32; |
476 break; | 475 break; |
477 case kRepFloat32: | 476 case MachineRepresentation::kFloat32: |
478 opcode = kCheckedStoreFloat32; | 477 opcode = kCheckedStoreFloat32; |
479 break; | 478 break; |
480 case kRepFloat64: | 479 case MachineRepresentation::kFloat64: |
481 opcode = kCheckedStoreFloat64; | 480 opcode = kCheckedStoreFloat64; |
482 break; | 481 break; |
483 default: | 482 default: |
484 UNREACHABLE(); | 483 UNREACHABLE(); |
485 return; | 484 return; |
486 } | 485 } |
487 InstructionOperand offset_operand = g.UseRegister(offset); | 486 InstructionOperand offset_operand = g.UseRegister(offset); |
488 InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) | 487 InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) |
489 ? g.UseImmediate(length) | 488 ? g.UseImmediate(length) |
490 : g.UseRegister(length); | 489 : g.UseRegister(length); |
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1594 MachineOperatorBuilder::kFloat64RoundTiesAway | | 1593 MachineOperatorBuilder::kFloat64RoundTiesAway | |
1595 MachineOperatorBuilder::kFloat32RoundTiesEven | | 1594 MachineOperatorBuilder::kFloat32RoundTiesEven | |
1596 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1595 MachineOperatorBuilder::kFloat64RoundTiesEven; |
1597 } | 1596 } |
1598 return flags; | 1597 return flags; |
1599 } | 1598 } |
1600 | 1599 |
1601 } // namespace compiler | 1600 } // namespace compiler |
1602 } // namespace internal | 1601 } // namespace internal |
1603 } // namespace v8 | 1602 } // namespace v8 |
OLD | NEW |