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-inl.h" | 7 #include "src/compiler/node-properties-inl.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 | 419 |
420 AddressingModeMatcher matcher(&g, base, index); | 420 AddressingModeMatcher matcher(&g, base, index); |
421 InstructionCode code = opcode | AddressingModeField::encode(matcher.mode_); | 421 InstructionCode code = opcode | AddressingModeField::encode(matcher.mode_); |
422 InstructionOperand* inputs[AddressingModeMatcher::kMaxInputCount + 1]; | 422 InstructionOperand* inputs[AddressingModeMatcher::kMaxInputCount + 1]; |
423 size_t input_count = matcher.SetInputs(inputs); | 423 size_t input_count = matcher.SetInputs(inputs); |
424 inputs[input_count++] = val; | 424 inputs[input_count++] = val; |
425 Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs); | 425 Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs); |
426 } | 426 } |
427 | 427 |
428 | 428 |
| 429 void InstructionSelector::VisitCheckedLoad(Node* node) { |
| 430 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
| 431 MachineType typ = TypeOf(OpParameter<MachineType>(node)); |
| 432 IA32OperandGenerator g(this); |
| 433 Node* const buffer = node->InputAt(0); |
| 434 Node* const offset = node->InputAt(1); |
| 435 Node* const length = node->InputAt(2); |
| 436 ArchOpcode opcode; |
| 437 switch (rep) { |
| 438 case kRepWord8: |
| 439 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; |
| 440 break; |
| 441 case kRepWord16: |
| 442 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; |
| 443 break; |
| 444 case kRepWord32: |
| 445 opcode = kCheckedLoadWord32; |
| 446 break; |
| 447 case kRepFloat32: |
| 448 opcode = kCheckedLoadFloat32; |
| 449 break; |
| 450 case kRepFloat64: |
| 451 opcode = kCheckedLoadFloat64; |
| 452 break; |
| 453 default: |
| 454 UNREACHABLE(); |
| 455 return; |
| 456 } |
| 457 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { |
| 458 Int32Matcher mlength(length); |
| 459 Int32BinopMatcher moffset(offset); |
| 460 if (mlength.HasValue() && moffset.right().HasValue() && |
| 461 mlength.Value() > moffset.right().Value()) { |
| 462 Int32Matcher mbuffer(buffer); |
| 463 InstructionOperand* offset_operand = g.UseRegister(moffset.left().node()); |
| 464 InstructionOperand* length_operand = |
| 465 g.TempImmediate(mlength.Value() - moffset.right().Value()); |
| 466 if (mbuffer.HasValue()) { |
| 467 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 468 g.DefineAsRegister(node), offset_operand, length_operand, |
| 469 offset_operand, |
| 470 g.TempImmediate(mbuffer.Value() + moffset.right().Value())); |
| 471 } else { |
| 472 Emit(opcode | AddressingModeField::encode(kMode_MR1I), |
| 473 g.DefineAsRegister(node), offset_operand, length_operand, |
| 474 g.UseRegister(buffer), offset_operand, |
| 475 g.UseImmediate(moffset.right().node())); |
| 476 } |
| 477 return; |
| 478 } |
| 479 } |
| 480 InstructionOperand* offset_operand = g.UseRegister(offset); |
| 481 InstructionOperand* length_operand = |
| 482 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
| 483 if (g.CanBeImmediate(buffer)) { |
| 484 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 485 g.DefineAsRegister(node), offset_operand, length_operand, |
| 486 offset_operand, g.UseImmediate(buffer)); |
| 487 } else { |
| 488 Emit(opcode | AddressingModeField::encode(kMode_MR1), |
| 489 g.DefineAsRegister(node), offset_operand, length_operand, |
| 490 g.UseRegister(buffer), offset_operand); |
| 491 } |
| 492 } |
| 493 |
| 494 |
| 495 void InstructionSelector::VisitCheckedStore(Node* node) { |
| 496 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
| 497 IA32OperandGenerator g(this); |
| 498 Node* const buffer = node->InputAt(0); |
| 499 Node* const offset = node->InputAt(1); |
| 500 Node* const length = node->InputAt(2); |
| 501 Node* const value = node->InputAt(3); |
| 502 ArchOpcode opcode; |
| 503 switch (rep) { |
| 504 case kRepWord8: |
| 505 opcode = kCheckedStoreWord8; |
| 506 break; |
| 507 case kRepWord16: |
| 508 opcode = kCheckedStoreWord16; |
| 509 break; |
| 510 case kRepWord32: |
| 511 opcode = kCheckedStoreWord32; |
| 512 break; |
| 513 case kRepFloat32: |
| 514 opcode = kCheckedStoreFloat32; |
| 515 break; |
| 516 case kRepFloat64: |
| 517 opcode = kCheckedStoreFloat64; |
| 518 break; |
| 519 default: |
| 520 UNREACHABLE(); |
| 521 return; |
| 522 } |
| 523 InstructionOperand* value_operand = |
| 524 g.CanBeImmediate(value) |
| 525 ? g.UseImmediate(value) |
| 526 : ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value) |
| 527 : g.UseRegister(value)); |
| 528 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { |
| 529 Int32Matcher mbuffer(buffer); |
| 530 Int32Matcher mlength(length); |
| 531 Int32BinopMatcher moffset(offset); |
| 532 if (mlength.HasValue() && moffset.right().HasValue() && |
| 533 mlength.Value() > moffset.right().Value()) { |
| 534 InstructionOperand* offset_operand = g.UseRegister(moffset.left().node()); |
| 535 InstructionOperand* length_operand = |
| 536 g.TempImmediate(mlength.Value() - moffset.right().Value()); |
| 537 if (mbuffer.HasValue()) { |
| 538 Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, |
| 539 offset_operand, length_operand, value_operand, offset_operand, |
| 540 g.TempImmediate(mbuffer.Value() + moffset.right().Value())); |
| 541 } else { |
| 542 Emit(opcode | AddressingModeField::encode(kMode_MR1I), nullptr, |
| 543 offset_operand, length_operand, value_operand, |
| 544 g.UseRegister(buffer), offset_operand, |
| 545 g.UseImmediate(moffset.right().node())); |
| 546 } |
| 547 return; |
| 548 } |
| 549 } |
| 550 InstructionOperand* offset_operand = g.UseRegister(offset); |
| 551 InstructionOperand* length_operand = |
| 552 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
| 553 if (g.CanBeImmediate(buffer)) { |
| 554 Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, |
| 555 offset_operand, length_operand, value_operand, offset_operand, |
| 556 g.UseImmediate(buffer)); |
| 557 } else { |
| 558 Emit(opcode | AddressingModeField::encode(kMode_MR1), nullptr, |
| 559 offset_operand, length_operand, value_operand, g.UseRegister(buffer), |
| 560 offset_operand); |
| 561 } |
| 562 } |
| 563 |
| 564 |
429 // Shared routine for multiple binary operations. | 565 // Shared routine for multiple binary operations. |
430 static void VisitBinop(InstructionSelector* selector, Node* node, | 566 static void VisitBinop(InstructionSelector* selector, Node* node, |
431 InstructionCode opcode, FlagsContinuation* cont) { | 567 InstructionCode opcode, FlagsContinuation* cont) { |
432 IA32OperandGenerator g(selector); | 568 IA32OperandGenerator g(selector); |
433 Int32BinopMatcher m(node); | 569 Int32BinopMatcher m(node); |
434 Node* left = m.left().node(); | 570 Node* left = m.left().node(); |
435 Node* right = m.right().node(); | 571 Node* right = m.right().node(); |
436 InstructionOperand* inputs[4]; | 572 InstructionOperand* inputs[4]; |
437 size_t input_count = 0; | 573 size_t input_count = 0; |
438 InstructionOperand* outputs[2]; | 574 InstructionOperand* outputs[2]; |
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 return MachineOperatorBuilder::kFloat64Floor | | 1222 return MachineOperatorBuilder::kFloat64Floor | |
1087 MachineOperatorBuilder::kFloat64Ceil | | 1223 MachineOperatorBuilder::kFloat64Ceil | |
1088 MachineOperatorBuilder::kFloat64RoundTruncate | | 1224 MachineOperatorBuilder::kFloat64RoundTruncate | |
1089 MachineOperatorBuilder::kWord32ShiftIsSafe; | 1225 MachineOperatorBuilder::kWord32ShiftIsSafe; |
1090 } | 1226 } |
1091 return MachineOperatorBuilder::Flag::kNoFlags; | 1227 return MachineOperatorBuilder::Flag::kNoFlags; |
1092 } | 1228 } |
1093 } // namespace compiler | 1229 } // namespace compiler |
1094 } // namespace internal | 1230 } // namespace internal |
1095 } // namespace v8 | 1231 } // namespace v8 |
OLD | NEW |