Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: src/compiler/ia32/instruction-selector-ia32.cc

Issue 763963002: [turbofan] Add checked load/store operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Reapply fix. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/ia32/code-generator-ia32.cc ('k') | src/compiler/instruction-codes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/ia32/code-generator-ia32.cc ('k') | src/compiler/instruction-codes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698