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