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/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 case kArmVstrF32: | 54 case kArmVstrF32: |
55 case kArmVldrF64: | 55 case kArmVldrF64: |
56 case kArmVstrF64: | 56 case kArmVstrF64: |
57 return value >= -1020 && value <= 1020 && (value % 4) == 0; | 57 return value >= -1020 && value <= 1020 && (value % 4) == 0; |
58 | 58 |
59 case kArmLdrb: | 59 case kArmLdrb: |
60 case kArmLdrsb: | 60 case kArmLdrsb: |
61 case kArmStrb: | 61 case kArmStrb: |
62 case kArmLdr: | 62 case kArmLdr: |
63 case kArmStr: | 63 case kArmStr: |
64 case kArmStoreWriteBarrier: | |
65 return value >= -4095 && value <= 4095; | 64 return value >= -4095 && value <= 4095; |
66 | 65 |
67 case kArmLdrh: | 66 case kArmLdrh: |
68 case kArmLdrsh: | 67 case kArmLdrsh: |
69 case kArmStrh: | 68 case kArmStrh: |
70 return value >= -255 && value <= 255; | 69 return value >= -255 && value <= 255; |
71 | 70 |
72 default: | 71 default: |
73 break; | 72 break; |
74 } | 73 } |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 } | 343 } |
345 | 344 |
346 | 345 |
347 void InstructionSelector::VisitStore(Node* node) { | 346 void InstructionSelector::VisitStore(Node* node) { |
348 ArmOperandGenerator g(this); | 347 ArmOperandGenerator g(this); |
349 Node* base = node->InputAt(0); | 348 Node* base = node->InputAt(0); |
350 Node* index = node->InputAt(1); | 349 Node* index = node->InputAt(1); |
351 Node* value = node->InputAt(2); | 350 Node* value = node->InputAt(2); |
352 | 351 |
353 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 352 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 353 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
354 MachineType rep = RepresentationOf(store_rep.machine_type()); | 354 MachineType rep = RepresentationOf(store_rep.machine_type()); |
355 if (store_rep.write_barrier_kind() == kFullWriteBarrier) { | |
356 DCHECK(rep == kRepTagged); | |
357 // TODO(dcarney): refactor RecordWrite function to take temp registers | |
358 // and pass them here instead of using fixed regs | |
359 // TODO(dcarney): handle immediate indices. | |
360 InstructionOperand temps[] = {g.TempRegister(r5), g.TempRegister(r6)}; | |
361 Emit(kArmStoreWriteBarrier, g.NoOutput(), g.UseFixed(base, r4), | |
362 g.UseFixed(index, r5), g.UseFixed(value, r6), arraysize(temps), temps); | |
363 return; | |
364 } | |
365 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); | |
366 | 355 |
367 ArchOpcode opcode; | 356 ArchOpcode opcode; |
368 switch (rep) { | 357 switch (rep) { |
369 case kRepFloat32: | 358 case kRepFloat32: |
370 opcode = kArmVstrF32; | 359 opcode = kArmVstrF32; |
371 break; | 360 break; |
372 case kRepFloat64: | 361 case kRepFloat64: |
373 opcode = kArmVstrF64; | 362 opcode = kArmVstrF64; |
374 break; | 363 break; |
375 case kRepBit: // Fall through. | 364 case kRepBit: // Fall through. |
(...skipping 12 matching lines...) Expand all Loading... |
388 return; | 377 return; |
389 } | 378 } |
390 | 379 |
391 if (g.CanBeImmediate(index, opcode)) { | 380 if (g.CanBeImmediate(index, opcode)) { |
392 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(), | 381 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(), |
393 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 382 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
394 } else { | 383 } else { |
395 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), | 384 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), |
396 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); | 385 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); |
397 } | 386 } |
| 387 |
| 388 if (write_barrier_kind != kNoWriteBarrier) { |
| 389 DCHECK_EQ(kRepTagged, rep); |
| 390 InstructionOperand inputs[3]; |
| 391 size_t input_count = 0; |
| 392 inputs[input_count++] = g.UseUniqueRegister(base); |
| 393 inputs[input_count++] = g.UseUniqueRegister(index); |
| 394 RecordWriteMode record_write_mode; |
| 395 switch (write_barrier_kind) { |
| 396 case kNoWriteBarrier: |
| 397 UNREACHABLE(); |
| 398 break; |
| 399 case kMapWriteBarrier: |
| 400 record_write_mode = RecordWriteMode::kValueIsMap; |
| 401 break; |
| 402 case kPointerWriteBarrier: |
| 403 inputs[input_count++] = g.UseUniqueRegister(value); |
| 404 record_write_mode = RecordWriteMode::kValueIsPointer; |
| 405 break; |
| 406 case kFullWriteBarrier: |
| 407 inputs[input_count++] = g.UseUniqueRegister(value); |
| 408 record_write_mode = RecordWriteMode::kValueIsAny; |
| 409 break; |
| 410 } |
| 411 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
| 412 size_t const temp_count = arraysize(temps); |
| 413 InstructionCode code = kArchRecordWrite; |
| 414 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
| 415 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
| 416 } |
398 } | 417 } |
399 | 418 |
400 | 419 |
401 void InstructionSelector::VisitCheckedLoad(Node* node) { | 420 void InstructionSelector::VisitCheckedLoad(Node* node) { |
402 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 421 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
403 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | 422 MachineType typ = TypeOf(OpParameter<MachineType>(node)); |
404 ArmOperandGenerator g(this); | 423 ArmOperandGenerator g(this); |
405 Node* const buffer = node->InputAt(0); | 424 Node* const buffer = node->InputAt(0); |
406 Node* const offset = node->InputAt(1); | 425 Node* const offset = node->InputAt(1); |
407 Node* const length = node->InputAt(2); | 426 Node* const length = node->InputAt(2); |
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1538 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1557 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
1539 MachineOperatorBuilder::kFloat64RoundTruncate | | 1558 MachineOperatorBuilder::kFloat64RoundTruncate | |
1540 MachineOperatorBuilder::kFloat64RoundTiesAway; | 1559 MachineOperatorBuilder::kFloat64RoundTiesAway; |
1541 } | 1560 } |
1542 return flags; | 1561 return flags; |
1543 } | 1562 } |
1544 | 1563 |
1545 } // namespace compiler | 1564 } // namespace compiler |
1546 } // namespace internal | 1565 } // namespace internal |
1547 } // namespace v8 | 1566 } // namespace v8 |
OLD | NEW |