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 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 } | 386 } |
387 | 387 |
388 | 388 |
389 void InstructionSelector::VisitStore(Node* node) { | 389 void InstructionSelector::VisitStore(Node* node) { |
390 Arm64OperandGenerator g(this); | 390 Arm64OperandGenerator g(this); |
391 Node* base = node->InputAt(0); | 391 Node* base = node->InputAt(0); |
392 Node* index = node->InputAt(1); | 392 Node* index = node->InputAt(1); |
393 Node* value = node->InputAt(2); | 393 Node* value = node->InputAt(2); |
394 | 394 |
395 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 395 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 396 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
396 MachineType rep = RepresentationOf(store_rep.machine_type()); | 397 MachineType rep = RepresentationOf(store_rep.machine_type()); |
397 if (store_rep.write_barrier_kind() == kFullWriteBarrier) { | 398 |
398 DCHECK(rep == kRepTagged); | 399 // TODO(arm64): I guess this could be done in a better way. |
399 // TODO(dcarney): refactor RecordWrite function to take temp registers | 400 if (write_barrier_kind != kNoWriteBarrier) { |
400 // and pass them here instead of using fixed regs | 401 DCHECK_EQ(kRepTagged, rep); |
401 // TODO(dcarney): handle immediate indices. | 402 InstructionOperand inputs[3]; |
402 InstructionOperand temps[] = {g.TempRegister(x11), g.TempRegister(x12)}; | 403 size_t input_count = 0; |
403 Emit(kArm64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, x10), | 404 inputs[input_count++] = g.UseUniqueRegister(base); |
404 g.UseFixed(index, x11), g.UseFixed(value, x12), arraysize(temps), | 405 inputs[input_count++] = g.UseUniqueRegister(index); |
405 temps); | 406 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
406 return; | 407 ? g.UseRegister(value) |
407 } | 408 : g.UseUniqueRegister(value); |
408 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); | 409 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; |
409 ArchOpcode opcode; | 410 switch (write_barrier_kind) { |
410 ImmediateMode immediate_mode = kNoImmediate; | 411 case kNoWriteBarrier: |
411 switch (rep) { | 412 UNREACHABLE(); |
412 case kRepFloat32: | 413 break; |
413 opcode = kArm64StrS; | 414 case kMapWriteBarrier: |
414 immediate_mode = kLoadStoreImm32; | 415 record_write_mode = RecordWriteMode::kValueIsMap; |
415 break; | 416 break; |
416 case kRepFloat64: | 417 case kPointerWriteBarrier: |
417 opcode = kArm64StrD; | 418 record_write_mode = RecordWriteMode::kValueIsPointer; |
418 immediate_mode = kLoadStoreImm64; | 419 break; |
419 break; | 420 case kFullWriteBarrier: |
420 case kRepBit: // Fall through. | 421 record_write_mode = RecordWriteMode::kValueIsAny; |
421 case kRepWord8: | 422 break; |
422 opcode = kArm64Strb; | 423 } |
423 immediate_mode = kLoadStoreImm8; | 424 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
424 break; | 425 size_t const temp_count = arraysize(temps); |
425 case kRepWord16: | 426 InstructionCode code = kArchStoreWithWriteBarrier; |
426 opcode = kArm64Strh; | 427 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
427 immediate_mode = kLoadStoreImm16; | 428 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
428 break; | |
429 case kRepWord32: | |
430 opcode = kArm64StrW; | |
431 immediate_mode = kLoadStoreImm32; | |
432 break; | |
433 case kRepTagged: // Fall through. | |
434 case kRepWord64: | |
435 opcode = kArm64Str; | |
436 immediate_mode = kLoadStoreImm64; | |
437 break; | |
438 default: | |
439 UNREACHABLE(); | |
440 return; | |
441 } | |
442 if (g.CanBeImmediate(index, immediate_mode)) { | |
443 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | |
444 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | |
445 } else { | 429 } else { |
446 Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(), | 430 ArchOpcode opcode; |
447 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); | 431 ImmediateMode immediate_mode = kNoImmediate; |
| 432 switch (rep) { |
| 433 case kRepFloat32: |
| 434 opcode = kArm64StrS; |
| 435 immediate_mode = kLoadStoreImm32; |
| 436 break; |
| 437 case kRepFloat64: |
| 438 opcode = kArm64StrD; |
| 439 immediate_mode = kLoadStoreImm64; |
| 440 break; |
| 441 case kRepBit: // Fall through. |
| 442 case kRepWord8: |
| 443 opcode = kArm64Strb; |
| 444 immediate_mode = kLoadStoreImm8; |
| 445 break; |
| 446 case kRepWord16: |
| 447 opcode = kArm64Strh; |
| 448 immediate_mode = kLoadStoreImm16; |
| 449 break; |
| 450 case kRepWord32: |
| 451 opcode = kArm64StrW; |
| 452 immediate_mode = kLoadStoreImm32; |
| 453 break; |
| 454 case kRepTagged: // Fall through. |
| 455 case kRepWord64: |
| 456 opcode = kArm64Str; |
| 457 immediate_mode = kLoadStoreImm64; |
| 458 break; |
| 459 default: |
| 460 UNREACHABLE(); |
| 461 return; |
| 462 } |
| 463 if (g.CanBeImmediate(index, immediate_mode)) { |
| 464 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
| 465 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
| 466 } else { |
| 467 Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(), |
| 468 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); |
| 469 } |
448 } | 470 } |
449 } | 471 } |
450 | 472 |
451 | 473 |
452 void InstructionSelector::VisitCheckedLoad(Node* node) { | 474 void InstructionSelector::VisitCheckedLoad(Node* node) { |
453 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 475 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
454 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | 476 MachineType typ = TypeOf(OpParameter<MachineType>(node)); |
455 Arm64OperandGenerator g(this); | 477 Arm64OperandGenerator g(this); |
456 Node* const buffer = node->InputAt(0); | 478 Node* const buffer = node->InputAt(0); |
457 Node* const offset = node->InputAt(1); | 479 Node* const offset = node->InputAt(1); |
(...skipping 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2006 MachineOperatorBuilder::kFloat64RoundTruncate | | 2028 MachineOperatorBuilder::kFloat64RoundTruncate | |
2007 MachineOperatorBuilder::kFloat64RoundTiesAway | | 2029 MachineOperatorBuilder::kFloat64RoundTiesAway | |
2008 MachineOperatorBuilder::kWord32ShiftIsSafe | | 2030 MachineOperatorBuilder::kWord32ShiftIsSafe | |
2009 MachineOperatorBuilder::kInt32DivIsSafe | | 2031 MachineOperatorBuilder::kInt32DivIsSafe | |
2010 MachineOperatorBuilder::kUint32DivIsSafe; | 2032 MachineOperatorBuilder::kUint32DivIsSafe; |
2011 } | 2033 } |
2012 | 2034 |
2013 } // namespace compiler | 2035 } // namespace compiler |
2014 } // namespace internal | 2036 } // namespace internal |
2015 } // namespace v8 | 2037 } // namespace v8 |
OLD | NEW |