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/compiler/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 return WhichPowerOf2_64(value_minus_one); | 331 return WhichPowerOf2_64(value_minus_one); |
332 } | 332 } |
333 } | 333 } |
334 return 0; | 334 return 0; |
335 } | 335 } |
336 | 336 |
337 } // namespace | 337 } // namespace |
338 | 338 |
339 | 339 |
340 void InstructionSelector::VisitLoad(Node* node) { | 340 void InstructionSelector::VisitLoad(Node* node) { |
341 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 341 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
342 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
343 Arm64OperandGenerator g(this); | 342 Arm64OperandGenerator g(this); |
344 Node* base = node->InputAt(0); | 343 Node* base = node->InputAt(0); |
345 Node* index = node->InputAt(1); | 344 Node* index = node->InputAt(1); |
346 ArchOpcode opcode; | 345 ArchOpcode opcode; |
347 ImmediateMode immediate_mode = kNoImmediate; | 346 ImmediateMode immediate_mode = kNoImmediate; |
348 switch (rep) { | 347 switch (load_rep.representation()) { |
349 case kRepFloat32: | 348 case MachineRepresentation::kFloat32: |
350 opcode = kArm64LdrS; | 349 opcode = kArm64LdrS; |
351 immediate_mode = kLoadStoreImm32; | 350 immediate_mode = kLoadStoreImm32; |
352 break; | 351 break; |
353 case kRepFloat64: | 352 case MachineRepresentation::kFloat64: |
354 opcode = kArm64LdrD; | 353 opcode = kArm64LdrD; |
355 immediate_mode = kLoadStoreImm64; | 354 immediate_mode = kLoadStoreImm64; |
356 break; | 355 break; |
357 case kRepBit: // Fall through. | 356 case MachineRepresentation::kBit: // Fall through. |
358 case kRepWord8: | 357 case MachineRepresentation::kWord8: |
359 opcode = typ == kTypeInt32 ? kArm64Ldrsb : kArm64Ldrb; | 358 opcode = load_rep.IsSigned() ? kArm64Ldrsb : kArm64Ldrb; |
360 immediate_mode = kLoadStoreImm8; | 359 immediate_mode = kLoadStoreImm8; |
361 break; | 360 break; |
362 case kRepWord16: | 361 case MachineRepresentation::kWord16: |
363 opcode = typ == kTypeInt32 ? kArm64Ldrsh : kArm64Ldrh; | 362 opcode = load_rep.IsSigned() ? kArm64Ldrsh : kArm64Ldrh; |
364 immediate_mode = kLoadStoreImm16; | 363 immediate_mode = kLoadStoreImm16; |
365 break; | 364 break; |
366 case kRepWord32: | 365 case MachineRepresentation::kWord32: |
367 opcode = kArm64LdrW; | 366 opcode = kArm64LdrW; |
368 immediate_mode = kLoadStoreImm32; | 367 immediate_mode = kLoadStoreImm32; |
369 break; | 368 break; |
370 case kRepTagged: // Fall through. | 369 case MachineRepresentation::kTagged: // Fall through. |
371 case kRepWord64: | 370 case MachineRepresentation::kWord64: |
372 opcode = kArm64Ldr; | 371 opcode = kArm64Ldr; |
373 immediate_mode = kLoadStoreImm64; | 372 immediate_mode = kLoadStoreImm64; |
374 break; | 373 break; |
375 default: | 374 default: |
376 UNREACHABLE(); | 375 UNREACHABLE(); |
377 return; | 376 return; |
378 } | 377 } |
379 if (g.CanBeImmediate(index, immediate_mode)) { | 378 if (g.CanBeImmediate(index, immediate_mode)) { |
380 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 379 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
381 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); | 380 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); |
382 } else { | 381 } else { |
383 Emit(opcode | AddressingModeField::encode(kMode_MRR), | 382 Emit(opcode | AddressingModeField::encode(kMode_MRR), |
384 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); | 383 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); |
385 } | 384 } |
386 } | 385 } |
387 | 386 |
388 | 387 |
389 void InstructionSelector::VisitStore(Node* node) { | 388 void InstructionSelector::VisitStore(Node* node) { |
390 Arm64OperandGenerator g(this); | 389 Arm64OperandGenerator g(this); |
391 Node* base = node->InputAt(0); | 390 Node* base = node->InputAt(0); |
392 Node* index = node->InputAt(1); | 391 Node* index = node->InputAt(1); |
393 Node* value = node->InputAt(2); | 392 Node* value = node->InputAt(2); |
394 | 393 |
395 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 394 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
396 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 395 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
397 MachineType rep = RepresentationOf(store_rep.machine_type()); | 396 MachineRepresentation rep = store_rep.machine_type().representation(); |
398 | 397 |
399 // TODO(arm64): I guess this could be done in a better way. | 398 // TODO(arm64): I guess this could be done in a better way. |
400 if (write_barrier_kind != kNoWriteBarrier) { | 399 if (write_barrier_kind != kNoWriteBarrier) { |
401 DCHECK_EQ(kRepTagged, rep); | 400 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
402 InstructionOperand inputs[3]; | 401 InstructionOperand inputs[3]; |
403 size_t input_count = 0; | 402 size_t input_count = 0; |
404 inputs[input_count++] = g.UseUniqueRegister(base); | 403 inputs[input_count++] = g.UseUniqueRegister(base); |
405 inputs[input_count++] = g.UseUniqueRegister(index); | 404 inputs[input_count++] = g.UseUniqueRegister(index); |
406 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) | 405 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
407 ? g.UseRegister(value) | 406 ? g.UseRegister(value) |
408 : g.UseUniqueRegister(value); | 407 : g.UseUniqueRegister(value); |
409 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; | 408 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; |
410 switch (write_barrier_kind) { | 409 switch (write_barrier_kind) { |
411 case kNoWriteBarrier: | 410 case kNoWriteBarrier: |
(...skipping 11 matching lines...) Expand all Loading... |
423 } | 422 } |
424 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 423 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
425 size_t const temp_count = arraysize(temps); | 424 size_t const temp_count = arraysize(temps); |
426 InstructionCode code = kArchStoreWithWriteBarrier; | 425 InstructionCode code = kArchStoreWithWriteBarrier; |
427 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 426 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
428 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 427 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
429 } else { | 428 } else { |
430 ArchOpcode opcode; | 429 ArchOpcode opcode; |
431 ImmediateMode immediate_mode = kNoImmediate; | 430 ImmediateMode immediate_mode = kNoImmediate; |
432 switch (rep) { | 431 switch (rep) { |
433 case kRepFloat32: | 432 case MachineRepresentation::kFloat32: |
434 opcode = kArm64StrS; | 433 opcode = kArm64StrS; |
435 immediate_mode = kLoadStoreImm32; | 434 immediate_mode = kLoadStoreImm32; |
436 break; | 435 break; |
437 case kRepFloat64: | 436 case MachineRepresentation::kFloat64: |
438 opcode = kArm64StrD; | 437 opcode = kArm64StrD; |
439 immediate_mode = kLoadStoreImm64; | 438 immediate_mode = kLoadStoreImm64; |
440 break; | 439 break; |
441 case kRepBit: // Fall through. | 440 case MachineRepresentation::kBit: // Fall through. |
442 case kRepWord8: | 441 case MachineRepresentation::kWord8: |
443 opcode = kArm64Strb; | 442 opcode = kArm64Strb; |
444 immediate_mode = kLoadStoreImm8; | 443 immediate_mode = kLoadStoreImm8; |
445 break; | 444 break; |
446 case kRepWord16: | 445 case MachineRepresentation::kWord16: |
447 opcode = kArm64Strh; | 446 opcode = kArm64Strh; |
448 immediate_mode = kLoadStoreImm16; | 447 immediate_mode = kLoadStoreImm16; |
449 break; | 448 break; |
450 case kRepWord32: | 449 case MachineRepresentation::kWord32: |
451 opcode = kArm64StrW; | 450 opcode = kArm64StrW; |
452 immediate_mode = kLoadStoreImm32; | 451 immediate_mode = kLoadStoreImm32; |
453 break; | 452 break; |
454 case kRepTagged: // Fall through. | 453 case MachineRepresentation::kTagged: // Fall through. |
455 case kRepWord64: | 454 case MachineRepresentation::kWord64: |
456 opcode = kArm64Str; | 455 opcode = kArm64Str; |
457 immediate_mode = kLoadStoreImm64; | 456 immediate_mode = kLoadStoreImm64; |
458 break; | 457 break; |
459 default: | 458 default: |
460 UNREACHABLE(); | 459 UNREACHABLE(); |
461 return; | 460 return; |
462 } | 461 } |
463 if (g.CanBeImmediate(index, immediate_mode)) { | 462 if (g.CanBeImmediate(index, immediate_mode)) { |
464 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 463 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
465 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 464 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
466 } else { | 465 } else { |
467 Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(), | 466 Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(), |
468 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); | 467 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); |
469 } | 468 } |
470 } | 469 } |
471 } | 470 } |
472 | 471 |
473 | 472 |
474 void InstructionSelector::VisitCheckedLoad(Node* node) { | 473 void InstructionSelector::VisitCheckedLoad(Node* node) { |
475 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 474 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
476 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
477 Arm64OperandGenerator g(this); | 475 Arm64OperandGenerator g(this); |
478 Node* const buffer = node->InputAt(0); | 476 Node* const buffer = node->InputAt(0); |
479 Node* const offset = node->InputAt(1); | 477 Node* const offset = node->InputAt(1); |
480 Node* const length = node->InputAt(2); | 478 Node* const length = node->InputAt(2); |
481 ArchOpcode opcode; | 479 ArchOpcode opcode; |
482 switch (rep) { | 480 switch (load_rep.representation()) { |
483 case kRepWord8: | 481 case MachineRepresentation::kWord8: |
484 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 482 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
485 break; | 483 break; |
486 case kRepWord16: | 484 case MachineRepresentation::kWord16: |
487 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 485 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
488 break; | 486 break; |
489 case kRepWord32: | 487 case MachineRepresentation::kWord32: |
490 opcode = kCheckedLoadWord32; | 488 opcode = kCheckedLoadWord32; |
491 break; | 489 break; |
492 case kRepWord64: | 490 case MachineRepresentation::kWord64: |
493 opcode = kCheckedLoadWord64; | 491 opcode = kCheckedLoadWord64; |
494 break; | 492 break; |
495 case kRepFloat32: | 493 case MachineRepresentation::kFloat32: |
496 opcode = kCheckedLoadFloat32; | 494 opcode = kCheckedLoadFloat32; |
497 break; | 495 break; |
498 case kRepFloat64: | 496 case MachineRepresentation::kFloat64: |
499 opcode = kCheckedLoadFloat64; | 497 opcode = kCheckedLoadFloat64; |
500 break; | 498 break; |
501 default: | 499 default: |
502 UNREACHABLE(); | 500 UNREACHABLE(); |
503 return; | 501 return; |
504 } | 502 } |
505 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), | 503 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), |
506 g.UseRegister(offset), g.UseOperand(length, kArithmeticImm)); | 504 g.UseRegister(offset), g.UseOperand(length, kArithmeticImm)); |
507 } | 505 } |
508 | 506 |
509 | 507 |
510 void InstructionSelector::VisitCheckedStore(Node* node) { | 508 void InstructionSelector::VisitCheckedStore(Node* node) { |
511 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 509 MachineRepresentation rep = |
| 510 CheckedStoreRepresentationOf(node->op()).representation(); |
512 Arm64OperandGenerator g(this); | 511 Arm64OperandGenerator g(this); |
513 Node* const buffer = node->InputAt(0); | 512 Node* const buffer = node->InputAt(0); |
514 Node* const offset = node->InputAt(1); | 513 Node* const offset = node->InputAt(1); |
515 Node* const length = node->InputAt(2); | 514 Node* const length = node->InputAt(2); |
516 Node* const value = node->InputAt(3); | 515 Node* const value = node->InputAt(3); |
517 ArchOpcode opcode; | 516 ArchOpcode opcode; |
518 switch (rep) { | 517 switch (rep) { |
519 case kRepWord8: | 518 case MachineRepresentation::kWord8: |
520 opcode = kCheckedStoreWord8; | 519 opcode = kCheckedStoreWord8; |
521 break; | 520 break; |
522 case kRepWord16: | 521 case MachineRepresentation::kWord16: |
523 opcode = kCheckedStoreWord16; | 522 opcode = kCheckedStoreWord16; |
524 break; | 523 break; |
525 case kRepWord32: | 524 case MachineRepresentation::kWord32: |
526 opcode = kCheckedStoreWord32; | 525 opcode = kCheckedStoreWord32; |
527 break; | 526 break; |
528 case kRepWord64: | 527 case MachineRepresentation::kWord64: |
529 opcode = kCheckedStoreWord64; | 528 opcode = kCheckedStoreWord64; |
530 break; | 529 break; |
531 case kRepFloat32: | 530 case MachineRepresentation::kFloat32: |
532 opcode = kCheckedStoreFloat32; | 531 opcode = kCheckedStoreFloat32; |
533 break; | 532 break; |
534 case kRepFloat64: | 533 case MachineRepresentation::kFloat64: |
535 opcode = kCheckedStoreFloat64; | 534 opcode = kCheckedStoreFloat64; |
536 break; | 535 break; |
537 default: | 536 default: |
538 UNREACHABLE(); | 537 UNREACHABLE(); |
539 return; | 538 return; |
540 } | 539 } |
541 Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset), | 540 Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset), |
542 g.UseOperand(length, kArithmeticImm), g.UseRegister(value)); | 541 g.UseOperand(length, kArithmeticImm), g.UseRegister(value)); |
543 } | 542 } |
544 | 543 |
(...skipping 1601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2146 MachineOperatorBuilder::kFloat32RoundTiesEven | | 2145 MachineOperatorBuilder::kFloat32RoundTiesEven | |
2147 MachineOperatorBuilder::kFloat64RoundTiesEven | | 2146 MachineOperatorBuilder::kFloat64RoundTiesEven | |
2148 MachineOperatorBuilder::kWord32ShiftIsSafe | | 2147 MachineOperatorBuilder::kWord32ShiftIsSafe | |
2149 MachineOperatorBuilder::kInt32DivIsSafe | | 2148 MachineOperatorBuilder::kInt32DivIsSafe | |
2150 MachineOperatorBuilder::kUint32DivIsSafe; | 2149 MachineOperatorBuilder::kUint32DivIsSafe; |
2151 } | 2150 } |
2152 | 2151 |
2153 } // namespace compiler | 2152 } // namespace compiler |
2154 } // namespace internal | 2153 } // namespace internal |
2155 } // namespace v8 | 2154 } // namespace v8 |
OLD | NEW |