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