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

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

Issue 2472703002: MIPS[64]: Use immediate constants in Add, And, Or and Xor instructions in turbofan (Closed)
Patch Set: Created 4 years, 1 month 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/mips/instruction-selector-mips.cc ('k') | no next file » | 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/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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 bool CanBeImmediate(int64_t value, InstructionCode opcode) { 52 bool CanBeImmediate(int64_t value, InstructionCode opcode) {
53 switch (ArchOpcodeField::decode(opcode)) { 53 switch (ArchOpcodeField::decode(opcode)) {
54 case kMips64Shl: 54 case kMips64Shl:
55 case kMips64Sar: 55 case kMips64Sar:
56 case kMips64Shr: 56 case kMips64Shr:
57 return is_uint5(value); 57 return is_uint5(value);
58 case kMips64Dshl: 58 case kMips64Dshl:
59 case kMips64Dsar: 59 case kMips64Dsar:
60 case kMips64Dshr: 60 case kMips64Dshr:
61 return is_uint6(value); 61 return is_uint6(value);
62 case kMips64Add:
63 case kMips64And32:
64 case kMips64And:
65 case kMips64Dadd:
66 case kMips64Or32:
67 case kMips64Or:
62 case kMips64Xor: 68 case kMips64Xor:
63 return is_uint16(value); 69 return is_uint16(value);
64 case kMips64Ldc1: 70 case kMips64Ldc1:
65 case kMips64Sdc1: 71 case kMips64Sdc1:
66 return is_int16(value + kIntSize); 72 return is_int16(value + kIntSize);
67 default: 73 default:
68 return is_int16(value); 74 return is_int16(value);
69 } 75 }
70 } 76 }
71 77
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 DCHECK(is_int32(m.immediate())); 172 DCHECK(is_int32(m.immediate()));
167 inputs[1] = g.TempImmediate(static_cast<int32_t>(m.immediate())); 173 inputs[1] = g.TempImmediate(static_cast<int32_t>(m.immediate()));
168 InstructionOperand outputs[] = {g.DefineAsRegister(node)}; 174 InstructionOperand outputs[] = {g.DefineAsRegister(node)};
169 selector->Emit(opcode, arraysize(outputs), outputs, arraysize(inputs), 175 selector->Emit(opcode, arraysize(outputs), outputs, arraysize(inputs),
170 inputs); 176 inputs);
171 return true; 177 return true;
172 } 178 }
173 return false; 179 return false;
174 } 180 }
175 181
182 bool TryMatchImmediate(InstructionSelector* selector,
183 InstructionCode* opcode_return, Node* node,
184 size_t* input_count_return, InstructionOperand* inputs) {
185 Mips64OperandGenerator g(selector);
186 if (g.CanBeImmediate(node, *opcode_return)) {
187 *opcode_return |= AddressingModeField::encode(kMode_MRI);
188 inputs[0] = g.UseImmediate(node);
189 *input_count_return = 1;
190 return true;
191 }
192 return false;
193 }
194
176 static void VisitBinop(InstructionSelector* selector, Node* node, 195 static void VisitBinop(InstructionSelector* selector, Node* node,
177 InstructionCode opcode, FlagsContinuation* cont) { 196 InstructionCode opcode, bool has_reverse_opcode,
197 InstructionCode reverse_opcode,
198 FlagsContinuation* cont) {
178 Mips64OperandGenerator g(selector); 199 Mips64OperandGenerator g(selector);
179 Int32BinopMatcher m(node); 200 Int32BinopMatcher m(node);
180 InstructionOperand inputs[4]; 201 InstructionOperand inputs[4];
181 size_t input_count = 0; 202 size_t input_count = 0;
182 InstructionOperand outputs[2]; 203 InstructionOperand outputs[2];
183 size_t output_count = 0; 204 size_t output_count = 0;
184 205
185 inputs[input_count++] = g.UseRegister(m.left().node()); 206 if (TryMatchImmediate(selector, &opcode, m.right().node(), &input_count,
186 inputs[input_count++] = g.UseOperand(m.right().node(), opcode); 207 &inputs[1])) {
208 inputs[0] = g.UseRegister(m.left().node());
209 input_count++;
210 }
211 if (has_reverse_opcode &&
212 TryMatchImmediate(selector, &reverse_opcode, m.left().node(),
213 &input_count, &inputs[1])) {
214 inputs[0] = g.UseRegister(m.right().node());
215 opcode = reverse_opcode;
216 input_count++;
217 } else {
218 inputs[input_count++] = g.UseRegister(m.left().node());
219 inputs[input_count++] = g.UseOperand(m.right().node(), opcode);
220 }
187 221
188 if (cont->IsBranch()) { 222 if (cont->IsBranch()) {
189 inputs[input_count++] = g.Label(cont->true_block()); 223 inputs[input_count++] = g.Label(cont->true_block());
190 inputs[input_count++] = g.Label(cont->false_block()); 224 inputs[input_count++] = g.Label(cont->false_block());
191 } 225 }
192 226
193 if (cont->IsDeoptimize()) { 227 if (cont->IsDeoptimize()) {
194 // If we can deoptimize as a result of the binop, we need to make sure that 228 // If we can deoptimize as a result of the binop, we need to make sure that
195 // the deopt inputs are not overwritten by the binop result. One way 229 // the deopt inputs are not overwritten by the binop result. One way
196 // to achieve that is to declare the output register as same-as-first. 230 // to achieve that is to declare the output register as same-as-first.
(...skipping 12 matching lines...) Expand all
209 243
210 opcode = cont->Encode(opcode); 244 opcode = cont->Encode(opcode);
211 if (cont->IsDeoptimize()) { 245 if (cont->IsDeoptimize()) {
212 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, 246 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
213 cont->reason(), cont->frame_state()); 247 cont->reason(), cont->frame_state());
214 } else { 248 } else {
215 selector->Emit(opcode, output_count, outputs, input_count, inputs); 249 selector->Emit(opcode, output_count, outputs, input_count, inputs);
216 } 250 }
217 } 251 }
218 252
253 static void VisitBinop(InstructionSelector* selector, Node* node,
254 InstructionCode opcode, bool has_reverse_opcode,
255 InstructionCode reverse_opcode) {
256 FlagsContinuation cont;
257 VisitBinop(selector, node, opcode, has_reverse_opcode, reverse_opcode, &cont);
258 }
259
260 static void VisitBinop(InstructionSelector* selector, Node* node,
261 InstructionCode opcode, FlagsContinuation* cont) {
262 VisitBinop(selector, node, opcode, false, kArchNop, cont);
263 }
219 264
220 static void VisitBinop(InstructionSelector* selector, Node* node, 265 static void VisitBinop(InstructionSelector* selector, Node* node,
221 InstructionCode opcode) { 266 InstructionCode opcode) {
222 FlagsContinuation cont; 267 VisitBinop(selector, node, opcode, false, kArchNop);
223 VisitBinop(selector, node, opcode, &cont);
224 } 268 }
225 269
226 void EmitLoad(InstructionSelector* selector, Node* node, InstructionCode opcode, 270 void EmitLoad(InstructionSelector* selector, Node* node, InstructionCode opcode,
227 Node* output = nullptr) { 271 Node* output = nullptr) {
228 Mips64OperandGenerator g(selector); 272 Mips64OperandGenerator g(selector);
229 Node* base = node->InputAt(0); 273 Node* base = node->InputAt(0);
230 Node* index = node->InputAt(1); 274 Node* index = node->InputAt(1);
231 275
232 if (g.CanBeImmediate(index, opcode)) { 276 if (g.CanBeImmediate(index, opcode)) {
233 selector->Emit(opcode | AddressingModeField::encode(kMode_MRI), 277 selector->Emit(opcode | AddressingModeField::encode(kMode_MRI),
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 uint32_t msb = base::bits::CountLeadingZeros32(~mask); 452 uint32_t msb = base::bits::CountLeadingZeros32(~mask);
409 if (shift != 0 && shift != 32 && msb + shift == 32) { 453 if (shift != 0 && shift != 32 && msb + shift == 32) {
410 // Insert zeros for (x >> K) << K => x & ~(2^K - 1) expression reduction 454 // Insert zeros for (x >> K) << K => x & ~(2^K - 1) expression reduction
411 // and remove constant loading of inverted mask. 455 // and remove constant loading of inverted mask.
412 Emit(kMips64Ins, g.DefineSameAsFirst(node), 456 Emit(kMips64Ins, g.DefineSameAsFirst(node),
413 g.UseRegister(m.left().node()), g.TempImmediate(0), 457 g.UseRegister(m.left().node()), g.TempImmediate(0),
414 g.TempImmediate(shift)); 458 g.TempImmediate(shift));
415 return; 459 return;
416 } 460 }
417 } 461 }
418 VisitBinop(this, node, kMips64And32); 462 VisitBinop(this, node, kMips64And32, true, kMips64And32);
419 } 463 }
420 464
421 465
422 void InstructionSelector::VisitWord64And(Node* node) { 466 void InstructionSelector::VisitWord64And(Node* node) {
423 Mips64OperandGenerator g(this); 467 Mips64OperandGenerator g(this);
424 Int64BinopMatcher m(node); 468 Int64BinopMatcher m(node);
425 if (m.left().IsWord64Shr() && CanCover(node, m.left().node()) && 469 if (m.left().IsWord64Shr() && CanCover(node, m.left().node()) &&
426 m.right().HasValue()) { 470 m.right().HasValue()) {
427 uint64_t mask = m.right().Value(); 471 uint64_t mask = m.right().Value();
428 uint32_t mask_width = base::bits::CountPopulation64(mask); 472 uint32_t mask_width = base::bits::CountPopulation64(mask);
(...skipping 30 matching lines...) Expand all
459 if (shift != 0 && shift < 32 && msb + shift == 64) { 503 if (shift != 0 && shift < 32 && msb + shift == 64) {
460 // Insert zeros for (x >> K) << K => x & ~(2^K - 1) expression reduction 504 // Insert zeros for (x >> K) << K => x & ~(2^K - 1) expression reduction
461 // and remove constant loading of inverted mask. Dins cannot insert bits 505 // and remove constant loading of inverted mask. Dins cannot insert bits
462 // past word size, so shifts smaller than 32 are covered. 506 // past word size, so shifts smaller than 32 are covered.
463 Emit(kMips64Dins, g.DefineSameAsFirst(node), 507 Emit(kMips64Dins, g.DefineSameAsFirst(node),
464 g.UseRegister(m.left().node()), g.TempImmediate(0), 508 g.UseRegister(m.left().node()), g.TempImmediate(0),
465 g.TempImmediate(shift)); 509 g.TempImmediate(shift));
466 return; 510 return;
467 } 511 }
468 } 512 }
469 VisitBinop(this, node, kMips64And); 513 VisitBinop(this, node, kMips64And, true, kMips64And);
470 } 514 }
471 515
472 516
473 void InstructionSelector::VisitWord32Or(Node* node) { 517 void InstructionSelector::VisitWord32Or(Node* node) {
474 VisitBinop(this, node, kMips64Or32); 518 VisitBinop(this, node, kMips64Or32, true, kMips64Or32);
475 } 519 }
476 520
477 521
478 void InstructionSelector::VisitWord64Or(Node* node) { 522 void InstructionSelector::VisitWord64Or(Node* node) {
479 VisitBinop(this, node, kMips64Or); 523 VisitBinop(this, node, kMips64Or, true, kMips64Or);
480 } 524 }
481 525
482 526
483 void InstructionSelector::VisitWord32Xor(Node* node) { 527 void InstructionSelector::VisitWord32Xor(Node* node) {
484 Int32BinopMatcher m(node); 528 Int32BinopMatcher m(node);
485 if (m.left().IsWord32Or() && CanCover(node, m.left().node()) && 529 if (m.left().IsWord32Or() && CanCover(node, m.left().node()) &&
486 m.right().Is(-1)) { 530 m.right().Is(-1)) {
487 Int32BinopMatcher mleft(m.left().node()); 531 Int32BinopMatcher mleft(m.left().node());
488 if (!mleft.right().HasValue()) { 532 if (!mleft.right().HasValue()) {
489 Mips64OperandGenerator g(this); 533 Mips64OperandGenerator g(this);
490 Emit(kMips64Nor32, g.DefineAsRegister(node), 534 Emit(kMips64Nor32, g.DefineAsRegister(node),
491 g.UseRegister(mleft.left().node()), 535 g.UseRegister(mleft.left().node()),
492 g.UseRegister(mleft.right().node())); 536 g.UseRegister(mleft.right().node()));
493 return; 537 return;
494 } 538 }
495 } 539 }
496 if (m.right().Is(-1)) { 540 if (m.right().Is(-1)) {
497 // Use Nor for bit negation and eliminate constant loading for xori. 541 // Use Nor for bit negation and eliminate constant loading for xori.
498 Mips64OperandGenerator g(this); 542 Mips64OperandGenerator g(this);
499 Emit(kMips64Nor32, g.DefineAsRegister(node), g.UseRegister(m.left().node()), 543 Emit(kMips64Nor32, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
500 g.TempImmediate(0)); 544 g.TempImmediate(0));
501 return; 545 return;
502 } 546 }
503 VisitBinop(this, node, kMips64Xor32); 547 VisitBinop(this, node, kMips64Xor32, true, kMips64Xor32);
504 } 548 }
505 549
506 550
507 void InstructionSelector::VisitWord64Xor(Node* node) { 551 void InstructionSelector::VisitWord64Xor(Node* node) {
508 Int64BinopMatcher m(node); 552 Int64BinopMatcher m(node);
509 if (m.left().IsWord64Or() && CanCover(node, m.left().node()) && 553 if (m.left().IsWord64Or() && CanCover(node, m.left().node()) &&
510 m.right().Is(-1)) { 554 m.right().Is(-1)) {
511 Int64BinopMatcher mleft(m.left().node()); 555 Int64BinopMatcher mleft(m.left().node());
512 if (!mleft.right().HasValue()) { 556 if (!mleft.right().HasValue()) {
513 Mips64OperandGenerator g(this); 557 Mips64OperandGenerator g(this);
514 Emit(kMips64Nor, g.DefineAsRegister(node), 558 Emit(kMips64Nor, g.DefineAsRegister(node),
515 g.UseRegister(mleft.left().node()), 559 g.UseRegister(mleft.left().node()),
516 g.UseRegister(mleft.right().node())); 560 g.UseRegister(mleft.right().node()));
517 return; 561 return;
518 } 562 }
519 } 563 }
520 if (m.right().Is(-1)) { 564 if (m.right().Is(-1)) {
521 // Use Nor for bit negation and eliminate constant loading for xori. 565 // Use Nor for bit negation and eliminate constant loading for xori.
522 Mips64OperandGenerator g(this); 566 Mips64OperandGenerator g(this);
523 Emit(kMips64Nor, g.DefineAsRegister(node), g.UseRegister(m.left().node()), 567 Emit(kMips64Nor, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
524 g.TempImmediate(0)); 568 g.TempImmediate(0));
525 return; 569 return;
526 } 570 }
527 VisitBinop(this, node, kMips64Xor); 571 VisitBinop(this, node, kMips64Xor, true, kMips64Xor);
528 } 572 }
529 573
530 574
531 void InstructionSelector::VisitWord32Shl(Node* node) { 575 void InstructionSelector::VisitWord32Shl(Node* node) {
532 Int32BinopMatcher m(node); 576 Int32BinopMatcher m(node);
533 if (m.left().IsWord32And() && CanCover(node, m.left().node()) && 577 if (m.left().IsWord32And() && CanCover(node, m.left().node()) &&
534 m.right().IsInRange(1, 31)) { 578 m.right().IsInRange(1, 31)) {
535 Mips64OperandGenerator g(this); 579 Mips64OperandGenerator g(this);
536 Int32BinopMatcher mleft(m.left().node()); 580 Int32BinopMatcher mleft(m.left().node());
537 // Match Word32Shl(Word32And(x, mask), imm) to Shl where the mask is 581 // Match Word32Shl(Word32And(x, mask), imm) to Shl where the mask is
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 CanCover(node, m.right().node()) && CanCover(node, m.left().node())) { 811 CanCover(node, m.right().node()) && CanCover(node, m.left().node())) {
768 Int32BinopMatcher mleft(m.left().node()); 812 Int32BinopMatcher mleft(m.left().node());
769 if (mleft.right().HasValue()) { 813 if (mleft.right().HasValue()) {
770 int32_t shift_value = static_cast<int32_t>(mleft.right().Value()); 814 int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
771 Emit(kMips64Lsa, g.DefineAsRegister(node), 815 Emit(kMips64Lsa, g.DefineAsRegister(node),
772 g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), 816 g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()),
773 g.TempImmediate(shift_value)); 817 g.TempImmediate(shift_value));
774 return; 818 return;
775 } 819 }
776 } 820 }
777 VisitBinop(this, node, kMips64Add); 821 VisitBinop(this, node, kMips64Add, true, kMips64Add);
778 } 822 }
779 823
780 824
781 void InstructionSelector::VisitInt64Add(Node* node) { 825 void InstructionSelector::VisitInt64Add(Node* node) {
782 Mips64OperandGenerator g(this); 826 Mips64OperandGenerator g(this);
783 Int64BinopMatcher m(node); 827 Int64BinopMatcher m(node);
784 828
785 // Select Dlsa for (left + (left_of_right << imm)). 829 // Select Dlsa for (left + (left_of_right << imm)).
786 if (m.right().opcode() == IrOpcode::kWord64Shl && 830 if (m.right().opcode() == IrOpcode::kWord64Shl &&
787 CanCover(node, m.left().node()) && CanCover(node, m.right().node())) { 831 CanCover(node, m.left().node()) && CanCover(node, m.right().node())) {
(...skipping 13 matching lines...) Expand all
801 Int64BinopMatcher mleft(m.left().node()); 845 Int64BinopMatcher mleft(m.left().node());
802 if (mleft.right().HasValue()) { 846 if (mleft.right().HasValue()) {
803 int32_t shift_value = static_cast<int32_t>(mleft.right().Value()); 847 int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
804 Emit(kMips64Dlsa, g.DefineAsRegister(node), 848 Emit(kMips64Dlsa, g.DefineAsRegister(node),
805 g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), 849 g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()),
806 g.TempImmediate(shift_value)); 850 g.TempImmediate(shift_value));
807 return; 851 return;
808 } 852 }
809 } 853 }
810 854
811 VisitBinop(this, node, kMips64Dadd); 855 VisitBinop(this, node, kMips64Dadd, true, kMips64Dadd);
812 } 856 }
813 857
814 858
815 void InstructionSelector::VisitInt32Sub(Node* node) { 859 void InstructionSelector::VisitInt32Sub(Node* node) {
816 VisitBinop(this, node, kMips64Sub); 860 VisitBinop(this, node, kMips64Sub);
817 } 861 }
818 862
819 863
820 void InstructionSelector::VisitInt64Sub(Node* node) { 864 void InstructionSelector::VisitInt64Sub(Node* node) {
821 VisitBinop(this, node, kMips64Dsub); 865 VisitBinop(this, node, kMips64Dsub);
(...skipping 1670 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 } else { 2536 } else {
2493 DCHECK(kArchVariant == kMips64r2); 2537 DCHECK(kArchVariant == kMips64r2);
2494 return MachineOperatorBuilder::AlignmentRequirements:: 2538 return MachineOperatorBuilder::AlignmentRequirements::
2495 NoUnalignedAccessSupport(); 2539 NoUnalignedAccessSupport();
2496 } 2540 }
2497 } 2541 }
2498 2542
2499 } // namespace compiler 2543 } // namespace compiler
2500 } // namespace internal 2544 } // namespace internal
2501 } // namespace v8 2545 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/mips/instruction-selector-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698