| 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 |