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