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 if (write_barrier_kind != kNoWriteBarrier) { |
368 switch (rep) { | 357 DCHECK_EQ(kRepTagged, rep); |
369 case kRepFloat32: | 358 InstructionOperand inputs[3]; |
370 opcode = kArmVstrF32; | 359 size_t input_count = 0; |
371 break; | 360 inputs[input_count++] = g.UseUniqueRegister(base); |
372 case kRepFloat64: | 361 inputs[input_count++] = g.UseUniqueRegister(index); |
373 opcode = kArmVstrF64; | 362 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
374 break; | 363 ? g.UseRegister(value) |
375 case kRepBit: // Fall through. | 364 : g.UseUniqueRegister(value); |
376 case kRepWord8: | 365 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; |
377 opcode = kArmStrb; | 366 switch (write_barrier_kind) { |
378 break; | 367 case kNoWriteBarrier: |
379 case kRepWord16: | 368 UNREACHABLE(); |
380 opcode = kArmStrh; | 369 break; |
381 break; | 370 case kMapWriteBarrier: |
382 case kRepTagged: // Fall through. | 371 record_write_mode = RecordWriteMode::kValueIsMap; |
383 case kRepWord32: | 372 break; |
384 opcode = kArmStr; | 373 case kPointerWriteBarrier: |
385 break; | 374 record_write_mode = RecordWriteMode::kValueIsPointer; |
386 default: | 375 break; |
387 UNREACHABLE(); | 376 case kFullWriteBarrier: |
388 return; | 377 record_write_mode = RecordWriteMode::kValueIsAny; |
389 } | 378 break; |
| 379 } |
| 380 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
| 381 size_t const temp_count = arraysize(temps); |
| 382 InstructionCode code = kArchStoreWithWriteBarrier; |
| 383 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
| 384 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
| 385 } else { |
| 386 ArchOpcode opcode; |
| 387 switch (rep) { |
| 388 case kRepFloat32: |
| 389 opcode = kArmVstrF32; |
| 390 break; |
| 391 case kRepFloat64: |
| 392 opcode = kArmVstrF64; |
| 393 break; |
| 394 case kRepBit: // Fall through. |
| 395 case kRepWord8: |
| 396 opcode = kArmStrb; |
| 397 break; |
| 398 case kRepWord16: |
| 399 opcode = kArmStrh; |
| 400 break; |
| 401 case kRepTagged: // Fall through. |
| 402 case kRepWord32: |
| 403 opcode = kArmStr; |
| 404 break; |
| 405 default: |
| 406 UNREACHABLE(); |
| 407 return; |
| 408 } |
390 | 409 |
391 if (g.CanBeImmediate(index, opcode)) { | 410 if (g.CanBeImmediate(index, opcode)) { |
392 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(), | 411 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(), |
393 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 412 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
394 } else { | 413 } else { |
395 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), | 414 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), |
396 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); | 415 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); |
| 416 } |
397 } | 417 } |
398 } | 418 } |
399 | 419 |
400 | 420 |
401 void InstructionSelector::VisitCheckedLoad(Node* node) { | 421 void InstructionSelector::VisitCheckedLoad(Node* node) { |
402 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 422 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
403 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | 423 MachineType typ = TypeOf(OpParameter<MachineType>(node)); |
404 ArmOperandGenerator g(this); | 424 ArmOperandGenerator g(this); |
405 Node* const buffer = node->InputAt(0); | 425 Node* const buffer = node->InputAt(0); |
406 Node* const offset = node->InputAt(1); | 426 Node* const offset = node->InputAt(1); |
(...skipping 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1538 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1558 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
1539 MachineOperatorBuilder::kFloat64RoundTruncate | | 1559 MachineOperatorBuilder::kFloat64RoundTruncate | |
1540 MachineOperatorBuilder::kFloat64RoundTiesAway; | 1560 MachineOperatorBuilder::kFloat64RoundTiesAway; |
1541 } | 1561 } |
1542 return flags; | 1562 return flags; |
1543 } | 1563 } |
1544 | 1564 |
1545 } // namespace compiler | 1565 } // namespace compiler |
1546 } // namespace internal | 1566 } // namespace internal |
1547 } // namespace v8 | 1567 } // namespace v8 |
OLD | NEW |