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.h" | 7 #include "src/compiler/node-properties.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 case kShift64Imm: | 60 case kShift64Imm: |
61 return 0 <= value && value < 64; | 61 return 0 <= value && value < 64; |
62 case kNoImmediate: | 62 case kNoImmediate: |
63 return false; | 63 return false; |
64 } | 64 } |
65 return false; | 65 return false; |
66 } | 66 } |
67 }; | 67 }; |
68 | 68 |
69 | 69 |
70 static void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode, | 70 namespace { |
71 Node* node) { | 71 |
| 72 void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { |
72 PPCOperandGenerator g(selector); | 73 PPCOperandGenerator g(selector); |
73 selector->Emit(opcode, g.DefineAsRegister(node), | 74 selector->Emit(opcode, g.DefineAsRegister(node), |
74 g.UseRegister(node->InputAt(0))); | 75 g.UseRegister(node->InputAt(0))); |
75 } | 76 } |
76 | 77 |
77 | 78 |
78 static void VisitRRR(InstructionSelector* selector, Node* node, | 79 void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { |
79 ArchOpcode opcode) { | |
80 PPCOperandGenerator g(selector); | 80 PPCOperandGenerator g(selector); |
81 selector->Emit(opcode, g.DefineAsRegister(node), | 81 selector->Emit(opcode, g.DefineAsRegister(node), |
82 g.UseRegister(node->InputAt(0)), | 82 g.UseRegister(node->InputAt(0)), |
83 g.UseRegister(node->InputAt(1))); | |
84 } | |
85 | |
86 | |
87 static void VisitRRRFloat64(InstructionSelector* selector, Node* node, | |
88 ArchOpcode opcode) { | |
89 PPCOperandGenerator g(selector); | |
90 selector->Emit(opcode, g.DefineAsRegister(node), | |
91 g.UseRegister(node->InputAt(0)), | |
92 g.UseRegister(node->InputAt(1))); | 83 g.UseRegister(node->InputAt(1))); |
93 } | 84 } |
94 | 85 |
95 | 86 |
96 static void VisitRRO(InstructionSelector* selector, Node* node, | 87 void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node, |
97 ArchOpcode opcode, ImmediateMode operand_mode) { | 88 ImmediateMode operand_mode) { |
98 PPCOperandGenerator g(selector); | 89 PPCOperandGenerator g(selector); |
99 selector->Emit(opcode, g.DefineAsRegister(node), | 90 selector->Emit(opcode, g.DefineAsRegister(node), |
100 g.UseRegister(node->InputAt(0)), | 91 g.UseRegister(node->InputAt(0)), |
101 g.UseOperand(node->InputAt(1), operand_mode)); | 92 g.UseOperand(node->InputAt(1), operand_mode)); |
102 } | 93 } |
103 | 94 |
104 | 95 |
105 // Shared routine for multiple binary operations. | 96 // Shared routine for multiple binary operations. |
106 template <typename Matcher> | 97 template <typename Matcher> |
107 static void VisitBinop(InstructionSelector* selector, Node* node, | 98 void VisitBinop(InstructionSelector* selector, Node* node, |
108 InstructionCode opcode, ImmediateMode operand_mode, | 99 InstructionCode opcode, ImmediateMode operand_mode, |
109 FlagsContinuation* cont) { | 100 FlagsContinuation* cont) { |
110 PPCOperandGenerator g(selector); | 101 PPCOperandGenerator g(selector); |
111 Matcher m(node); | 102 Matcher m(node); |
112 InstructionOperand inputs[4]; | 103 InstructionOperand inputs[4]; |
113 size_t input_count = 0; | 104 size_t input_count = 0; |
114 InstructionOperand outputs[2]; | 105 InstructionOperand outputs[2]; |
115 size_t output_count = 0; | 106 size_t output_count = 0; |
116 | 107 |
117 inputs[input_count++] = g.UseRegister(m.left().node()); | 108 inputs[input_count++] = g.UseRegister(m.left().node()); |
118 inputs[input_count++] = g.UseOperand(m.right().node(), operand_mode); | 109 inputs[input_count++] = g.UseOperand(m.right().node(), operand_mode); |
119 | 110 |
(...skipping 12 matching lines...) Expand all Loading... |
132 DCHECK_GE(arraysize(inputs), input_count); | 123 DCHECK_GE(arraysize(inputs), input_count); |
133 DCHECK_GE(arraysize(outputs), output_count); | 124 DCHECK_GE(arraysize(outputs), output_count); |
134 | 125 |
135 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, | 126 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, |
136 inputs); | 127 inputs); |
137 } | 128 } |
138 | 129 |
139 | 130 |
140 // Shared routine for multiple binary operations. | 131 // Shared routine for multiple binary operations. |
141 template <typename Matcher> | 132 template <typename Matcher> |
142 static void VisitBinop(InstructionSelector* selector, Node* node, | 133 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, |
143 ArchOpcode opcode, ImmediateMode operand_mode) { | 134 ImmediateMode operand_mode) { |
144 FlagsContinuation cont; | 135 FlagsContinuation cont; |
145 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); | 136 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); |
146 } | 137 } |
147 | 138 |
| 139 } // namespace |
| 140 |
148 | 141 |
149 void InstructionSelector::VisitLoad(Node* node) { | 142 void InstructionSelector::VisitLoad(Node* node) { |
150 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 143 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); |
151 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | 144 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |
152 PPCOperandGenerator g(this); | 145 PPCOperandGenerator g(this); |
153 Node* base = node->InputAt(0); | 146 Node* base = node->InputAt(0); |
154 Node* offset = node->InputAt(1); | 147 Node* offset = node->InputAt(1); |
155 | 148 |
156 ArchOpcode opcode; | 149 ArchOpcode opcode; |
157 ImmediateMode mode = kInt16Imm; | 150 ImmediateMode mode = kInt16Imm; |
158 switch (rep) { | 151 switch (rep) { |
159 case kRepFloat32: | 152 case kRepFloat32: |
160 opcode = kPPC_LoadFloat32; | 153 opcode = kPPC_LoadFloat32; |
161 break; | 154 break; |
162 case kRepFloat64: | 155 case kRepFloat64: |
163 opcode = kPPC_LoadFloat64; | 156 opcode = kPPC_LoadDouble; |
164 break; | 157 break; |
165 case kRepBit: // Fall through. | 158 case kRepBit: // Fall through. |
166 case kRepWord8: | 159 case kRepWord8: |
167 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS8 : kPPC_LoadWordU8; | 160 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS8 : kPPC_LoadWordU8; |
168 break; | 161 break; |
169 case kRepWord16: | 162 case kRepWord16: |
170 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS16 : kPPC_LoadWordU16; | 163 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS16 : kPPC_LoadWordU16; |
171 break; | 164 break; |
172 #if !V8_TARGET_ARCH_PPC64 | 165 #if !V8_TARGET_ARCH_PPC64 |
173 case kRepTagged: // Fall through. | 166 case kRepTagged: // Fall through. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 return; | 216 return; |
224 } | 217 } |
225 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); | 218 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); |
226 ArchOpcode opcode; | 219 ArchOpcode opcode; |
227 ImmediateMode mode = kInt16Imm; | 220 ImmediateMode mode = kInt16Imm; |
228 switch (rep) { | 221 switch (rep) { |
229 case kRepFloat32: | 222 case kRepFloat32: |
230 opcode = kPPC_StoreFloat32; | 223 opcode = kPPC_StoreFloat32; |
231 break; | 224 break; |
232 case kRepFloat64: | 225 case kRepFloat64: |
233 opcode = kPPC_StoreFloat64; | 226 opcode = kPPC_StoreDouble; |
234 break; | 227 break; |
235 case kRepBit: // Fall through. | 228 case kRepBit: // Fall through. |
236 case kRepWord8: | 229 case kRepWord8: |
237 opcode = kPPC_StoreWord8; | 230 opcode = kPPC_StoreWord8; |
238 break; | 231 break; |
239 case kRepWord16: | 232 case kRepWord16: |
240 opcode = kPPC_StoreWord16; | 233 opcode = kPPC_StoreWord16; |
241 break; | 234 break; |
242 #if !V8_TARGET_ARCH_PPC64 | 235 #if !V8_TARGET_ARCH_PPC64 |
243 case kRepTagged: // Fall through. | 236 case kRepTagged: // Fall through. |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 | 334 |
342 template <typename Matcher> | 335 template <typename Matcher> |
343 static void VisitLogical(InstructionSelector* selector, Node* node, Matcher* m, | 336 static void VisitLogical(InstructionSelector* selector, Node* node, Matcher* m, |
344 ArchOpcode opcode, bool left_can_cover, | 337 ArchOpcode opcode, bool left_can_cover, |
345 bool right_can_cover, ImmediateMode imm_mode) { | 338 bool right_can_cover, ImmediateMode imm_mode) { |
346 PPCOperandGenerator g(selector); | 339 PPCOperandGenerator g(selector); |
347 | 340 |
348 // Map instruction to equivalent operation with inverted right input. | 341 // Map instruction to equivalent operation with inverted right input. |
349 ArchOpcode inv_opcode = opcode; | 342 ArchOpcode inv_opcode = opcode; |
350 switch (opcode) { | 343 switch (opcode) { |
351 case kPPC_And32: | 344 case kPPC_And: |
352 inv_opcode = kPPC_AndComplement32; | 345 inv_opcode = kPPC_AndComplement; |
353 break; | 346 break; |
354 case kPPC_And64: | 347 case kPPC_Or: |
355 inv_opcode = kPPC_AndComplement64; | 348 inv_opcode = kPPC_OrComplement; |
356 break; | |
357 case kPPC_Or32: | |
358 inv_opcode = kPPC_OrComplement32; | |
359 break; | |
360 case kPPC_Or64: | |
361 inv_opcode = kPPC_OrComplement64; | |
362 break; | 349 break; |
363 default: | 350 default: |
364 UNREACHABLE(); | 351 UNREACHABLE(); |
365 } | 352 } |
366 | 353 |
367 // Select Logical(y, ~x) for Logical(Xor(x, -1), y). | 354 // Select Logical(y, ~x) for Logical(Xor(x, -1), y). |
368 if ((m->left().IsWord32Xor() || m->left().IsWord64Xor()) && left_can_cover) { | 355 if ((m->left().IsWord32Xor() || m->left().IsWord64Xor()) && left_can_cover) { |
369 Matcher mleft(m->left().node()); | 356 Matcher mleft(m->left().node()); |
370 if (mleft.right().Is(-1)) { | 357 if (mleft.right().Is(-1)) { |
371 selector->Emit(inv_opcode, g.DefineAsRegister(node), | 358 selector->Emit(inv_opcode, g.DefineAsRegister(node), |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 } | 431 } |
445 } | 432 } |
446 } | 433 } |
447 if (mb >= me) { | 434 if (mb >= me) { |
448 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), g.UseRegister(left), | 435 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), g.UseRegister(left), |
449 g.TempImmediate(sh), g.TempImmediate(mb), g.TempImmediate(me)); | 436 g.TempImmediate(sh), g.TempImmediate(mb), g.TempImmediate(me)); |
450 return; | 437 return; |
451 } | 438 } |
452 } | 439 } |
453 VisitLogical<Int32BinopMatcher>( | 440 VisitLogical<Int32BinopMatcher>( |
454 this, node, &m, kPPC_And32, CanCover(node, m.left().node()), | 441 this, node, &m, kPPC_And, CanCover(node, m.left().node()), |
455 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | 442 CanCover(node, m.right().node()), kInt16Imm_Unsigned); |
456 } | 443 } |
457 | 444 |
458 | 445 |
459 #if V8_TARGET_ARCH_PPC64 | 446 #if V8_TARGET_ARCH_PPC64 |
460 // TODO(mbrandy): Absorb rotate-right into rldic? | 447 // TODO(mbrandy): Absorb rotate-right into rldic? |
461 void InstructionSelector::VisitWord64And(Node* node) { | 448 void InstructionSelector::VisitWord64And(Node* node) { |
462 PPCOperandGenerator g(this); | 449 PPCOperandGenerator g(this); |
463 Int64BinopMatcher m(node); | 450 Int64BinopMatcher m(node); |
464 int mb; | 451 int mb; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 mask = mb; | 488 mask = mb; |
502 } | 489 } |
503 if (match) { | 490 if (match) { |
504 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), | 491 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), |
505 g.TempImmediate(sh), g.TempImmediate(mask)); | 492 g.TempImmediate(sh), g.TempImmediate(mask)); |
506 return; | 493 return; |
507 } | 494 } |
508 } | 495 } |
509 } | 496 } |
510 VisitLogical<Int64BinopMatcher>( | 497 VisitLogical<Int64BinopMatcher>( |
511 this, node, &m, kPPC_And64, CanCover(node, m.left().node()), | 498 this, node, &m, kPPC_And, CanCover(node, m.left().node()), |
512 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | 499 CanCover(node, m.right().node()), kInt16Imm_Unsigned); |
513 } | 500 } |
514 #endif | 501 #endif |
515 | 502 |
516 | 503 |
517 void InstructionSelector::VisitWord32Or(Node* node) { | 504 void InstructionSelector::VisitWord32Or(Node* node) { |
518 Int32BinopMatcher m(node); | 505 Int32BinopMatcher m(node); |
519 VisitLogical<Int32BinopMatcher>( | 506 VisitLogical<Int32BinopMatcher>( |
520 this, node, &m, kPPC_Or32, CanCover(node, m.left().node()), | 507 this, node, &m, kPPC_Or, CanCover(node, m.left().node()), |
521 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | 508 CanCover(node, m.right().node()), kInt16Imm_Unsigned); |
522 } | 509 } |
523 | 510 |
524 | 511 |
525 #if V8_TARGET_ARCH_PPC64 | 512 #if V8_TARGET_ARCH_PPC64 |
526 void InstructionSelector::VisitWord64Or(Node* node) { | 513 void InstructionSelector::VisitWord64Or(Node* node) { |
527 Int64BinopMatcher m(node); | 514 Int64BinopMatcher m(node); |
528 VisitLogical<Int64BinopMatcher>( | 515 VisitLogical<Int64BinopMatcher>( |
529 this, node, &m, kPPC_Or64, CanCover(node, m.left().node()), | 516 this, node, &m, kPPC_Or, CanCover(node, m.left().node()), |
530 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | 517 CanCover(node, m.right().node()), kInt16Imm_Unsigned); |
531 } | 518 } |
532 #endif | 519 #endif |
533 | 520 |
534 | 521 |
535 void InstructionSelector::VisitWord32Xor(Node* node) { | 522 void InstructionSelector::VisitWord32Xor(Node* node) { |
536 PPCOperandGenerator g(this); | 523 PPCOperandGenerator g(this); |
537 Int32BinopMatcher m(node); | 524 Int32BinopMatcher m(node); |
538 if (m.right().Is(-1)) { | 525 if (m.right().Is(-1)) { |
539 Emit(kPPC_Not32, g.DefineAsRegister(node), g.UseRegister(m.left().node())); | 526 Emit(kPPC_Not, g.DefineAsRegister(node), g.UseRegister(m.left().node())); |
540 } else { | 527 } else { |
541 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Xor32, kInt16Imm_Unsigned); | 528 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Xor, kInt16Imm_Unsigned); |
542 } | 529 } |
543 } | 530 } |
544 | 531 |
545 | 532 |
546 #if V8_TARGET_ARCH_PPC64 | 533 #if V8_TARGET_ARCH_PPC64 |
547 void InstructionSelector::VisitWord64Xor(Node* node) { | 534 void InstructionSelector::VisitWord64Xor(Node* node) { |
548 PPCOperandGenerator g(this); | 535 PPCOperandGenerator g(this); |
549 Int64BinopMatcher m(node); | 536 Int64BinopMatcher m(node); |
550 if (m.right().Is(-1)) { | 537 if (m.right().Is(-1)) { |
551 Emit(kPPC_Not64, g.DefineAsRegister(node), g.UseRegister(m.left().node())); | 538 Emit(kPPC_Not, g.DefineAsRegister(node), g.UseRegister(m.left().node())); |
552 } else { | 539 } else { |
553 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Xor64, kInt16Imm_Unsigned); | 540 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Xor, kInt16Imm_Unsigned); |
554 } | 541 } |
555 } | 542 } |
556 #endif | 543 #endif |
557 | 544 |
558 | 545 |
559 void InstructionSelector::VisitWord32Shl(Node* node) { | 546 void InstructionSelector::VisitWord32Shl(Node* node) { |
560 PPCOperandGenerator g(this); | 547 PPCOperandGenerator g(this); |
561 Int32BinopMatcher m(node); | 548 Int32BinopMatcher m(node); |
562 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) { | 549 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) { |
563 // Try to absorb logical-and into rlwinm | 550 // Try to absorb logical-and into rlwinm |
564 Int32BinopMatcher mleft(m.left().node()); | 551 Int32BinopMatcher mleft(m.left().node()); |
565 int sh = m.right().Value(); | 552 int sh = m.right().Value(); |
566 int mb; | 553 int mb; |
567 int me; | 554 int me; |
568 if (mleft.right().HasValue() && | 555 if (mleft.right().HasValue() && |
569 IsContiguousMask32(mleft.right().Value() << sh, &mb, &me)) { | 556 IsContiguousMask32(mleft.right().Value() << sh, &mb, &me)) { |
570 // Adjust the mask such that it doesn't include any rotated bits. | 557 // Adjust the mask such that it doesn't include any rotated bits. |
571 if (me < sh) me = sh; | 558 if (me < sh) me = sh; |
572 if (mb >= me) { | 559 if (mb >= me) { |
573 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), | 560 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), |
574 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), | 561 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), |
575 g.TempImmediate(mb), g.TempImmediate(me)); | 562 g.TempImmediate(mb), g.TempImmediate(me)); |
576 return; | 563 return; |
577 } | 564 } |
578 } | 565 } |
579 } | 566 } |
580 VisitRRO(this, node, kPPC_ShiftLeft32, kShift32Imm); | 567 VisitRRO(this, kPPC_ShiftLeft32, node, kShift32Imm); |
581 } | 568 } |
582 | 569 |
583 | 570 |
584 #if V8_TARGET_ARCH_PPC64 | 571 #if V8_TARGET_ARCH_PPC64 |
585 void InstructionSelector::VisitWord64Shl(Node* node) { | 572 void InstructionSelector::VisitWord64Shl(Node* node) { |
586 PPCOperandGenerator g(this); | 573 PPCOperandGenerator g(this); |
587 Int64BinopMatcher m(node); | 574 Int64BinopMatcher m(node); |
588 // TODO(mbrandy): eliminate left sign extension if right >= 32 | 575 // TODO(mbrandy): eliminate left sign extension if right >= 32 |
589 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { | 576 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { |
590 // Try to absorb logical-and into rldic | 577 // Try to absorb logical-and into rldic |
(...skipping 24 matching lines...) Expand all Loading... |
615 } | 602 } |
616 if (match) { | 603 if (match) { |
617 Emit(opcode, g.DefineAsRegister(node), | 604 Emit(opcode, g.DefineAsRegister(node), |
618 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), | 605 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), |
619 g.TempImmediate(mask)); | 606 g.TempImmediate(mask)); |
620 return; | 607 return; |
621 } | 608 } |
622 } | 609 } |
623 } | 610 } |
624 } | 611 } |
625 VisitRRO(this, node, kPPC_ShiftLeft64, kShift64Imm); | 612 VisitRRO(this, kPPC_ShiftLeft64, node, kShift64Imm); |
626 } | 613 } |
627 #endif | 614 #endif |
628 | 615 |
629 | 616 |
630 void InstructionSelector::VisitWord32Shr(Node* node) { | 617 void InstructionSelector::VisitWord32Shr(Node* node) { |
631 PPCOperandGenerator g(this); | 618 PPCOperandGenerator g(this); |
632 Int32BinopMatcher m(node); | 619 Int32BinopMatcher m(node); |
633 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) { | 620 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) { |
634 // Try to absorb logical-and into rlwinm | 621 // Try to absorb logical-and into rlwinm |
635 Int32BinopMatcher mleft(m.left().node()); | 622 Int32BinopMatcher mleft(m.left().node()); |
636 int sh = m.right().Value(); | 623 int sh = m.right().Value(); |
637 int mb; | 624 int mb; |
638 int me; | 625 int me; |
639 if (mleft.right().HasValue() && | 626 if (mleft.right().HasValue() && |
640 IsContiguousMask32((uint32_t)(mleft.right().Value()) >> sh, &mb, &me)) { | 627 IsContiguousMask32((uint32_t)(mleft.right().Value()) >> sh, &mb, &me)) { |
641 // Adjust the mask such that it doesn't include any rotated bits. | 628 // Adjust the mask such that it doesn't include any rotated bits. |
642 if (mb > 31 - sh) mb = 31 - sh; | 629 if (mb > 31 - sh) mb = 31 - sh; |
643 sh = (32 - sh) & 0x1f; | 630 sh = (32 - sh) & 0x1f; |
644 if (mb >= me) { | 631 if (mb >= me) { |
645 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), | 632 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), |
646 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), | 633 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), |
647 g.TempImmediate(mb), g.TempImmediate(me)); | 634 g.TempImmediate(mb), g.TempImmediate(me)); |
648 return; | 635 return; |
649 } | 636 } |
650 } | 637 } |
651 } | 638 } |
652 VisitRRO(this, node, kPPC_ShiftRight32, kShift32Imm); | 639 VisitRRO(this, kPPC_ShiftRight32, node, kShift32Imm); |
653 } | 640 } |
654 | 641 |
655 | 642 |
656 #if V8_TARGET_ARCH_PPC64 | 643 #if V8_TARGET_ARCH_PPC64 |
657 void InstructionSelector::VisitWord64Shr(Node* node) { | 644 void InstructionSelector::VisitWord64Shr(Node* node) { |
658 PPCOperandGenerator g(this); | 645 PPCOperandGenerator g(this); |
659 Int64BinopMatcher m(node); | 646 Int64BinopMatcher m(node); |
660 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { | 647 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { |
661 // Try to absorb logical-and into rldic | 648 // Try to absorb logical-and into rldic |
662 Int64BinopMatcher mleft(m.left().node()); | 649 Int64BinopMatcher mleft(m.left().node()); |
(...skipping 20 matching lines...) Expand all Loading... |
683 } | 670 } |
684 if (match) { | 671 if (match) { |
685 Emit(opcode, g.DefineAsRegister(node), | 672 Emit(opcode, g.DefineAsRegister(node), |
686 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), | 673 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), |
687 g.TempImmediate(mask)); | 674 g.TempImmediate(mask)); |
688 return; | 675 return; |
689 } | 676 } |
690 } | 677 } |
691 } | 678 } |
692 } | 679 } |
693 VisitRRO(this, node, kPPC_ShiftRight64, kShift64Imm); | 680 VisitRRO(this, kPPC_ShiftRight64, node, kShift64Imm); |
694 } | 681 } |
695 #endif | 682 #endif |
696 | 683 |
697 | 684 |
698 void InstructionSelector::VisitWord32Sar(Node* node) { | 685 void InstructionSelector::VisitWord32Sar(Node* node) { |
699 PPCOperandGenerator g(this); | 686 PPCOperandGenerator g(this); |
700 Int32BinopMatcher m(node); | 687 Int32BinopMatcher m(node); |
701 // Replace with sign extension for (x << K) >> K where K is 16 or 24. | 688 // Replace with sign extension for (x << K) >> K where K is 16 or 24. |
702 if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) { | 689 if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) { |
703 Int32BinopMatcher mleft(m.left().node()); | 690 Int32BinopMatcher mleft(m.left().node()); |
704 if (mleft.right().Is(16) && m.right().Is(16)) { | 691 if (mleft.right().Is(16) && m.right().Is(16)) { |
705 Emit(kPPC_ExtendSignWord16, g.DefineAsRegister(node), | 692 Emit(kPPC_ExtendSignWord16, g.DefineAsRegister(node), |
706 g.UseRegister(mleft.left().node())); | 693 g.UseRegister(mleft.left().node())); |
707 return; | 694 return; |
708 } else if (mleft.right().Is(24) && m.right().Is(24)) { | 695 } else if (mleft.right().Is(24) && m.right().Is(24)) { |
709 Emit(kPPC_ExtendSignWord8, g.DefineAsRegister(node), | 696 Emit(kPPC_ExtendSignWord8, g.DefineAsRegister(node), |
710 g.UseRegister(mleft.left().node())); | 697 g.UseRegister(mleft.left().node())); |
711 return; | 698 return; |
712 } | 699 } |
713 } | 700 } |
714 VisitRRO(this, node, kPPC_ShiftRightAlg32, kShift32Imm); | 701 VisitRRO(this, kPPC_ShiftRightAlg32, node, kShift32Imm); |
715 } | 702 } |
716 | 703 |
717 | 704 |
718 #if V8_TARGET_ARCH_PPC64 | 705 #if V8_TARGET_ARCH_PPC64 |
719 void InstructionSelector::VisitWord64Sar(Node* node) { | 706 void InstructionSelector::VisitWord64Sar(Node* node) { |
720 VisitRRO(this, node, kPPC_ShiftRightAlg64, kShift64Imm); | 707 VisitRRO(this, kPPC_ShiftRightAlg64, node, kShift64Imm); |
721 } | 708 } |
722 #endif | 709 #endif |
723 | 710 |
724 | 711 |
725 // TODO(mbrandy): Absorb logical-and into rlwinm? | 712 // TODO(mbrandy): Absorb logical-and into rlwinm? |
726 void InstructionSelector::VisitWord32Ror(Node* node) { | 713 void InstructionSelector::VisitWord32Ror(Node* node) { |
727 VisitRRO(this, node, kPPC_RotRight32, kShift32Imm); | 714 VisitRRO(this, kPPC_RotRight32, node, kShift32Imm); |
728 } | 715 } |
729 | 716 |
730 | 717 |
731 #if V8_TARGET_ARCH_PPC64 | 718 #if V8_TARGET_ARCH_PPC64 |
732 // TODO(mbrandy): Absorb logical-and into rldic? | 719 // TODO(mbrandy): Absorb logical-and into rldic? |
733 void InstructionSelector::VisitWord64Ror(Node* node) { | 720 void InstructionSelector::VisitWord64Ror(Node* node) { |
734 VisitRRO(this, node, kPPC_RotRight64, kShift64Imm); | 721 VisitRRO(this, kPPC_RotRight64, node, kShift64Imm); |
735 } | 722 } |
736 #endif | 723 #endif |
737 | 724 |
738 | 725 |
739 void InstructionSelector::VisitWord32Clz(Node* node) { | 726 void InstructionSelector::VisitWord32Clz(Node* node) { |
740 PPCOperandGenerator g(this); | 727 PPCOperandGenerator g(this); |
741 Emit(kPPC_Cntlz32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); | 728 Emit(kPPC_Cntlz32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); |
742 } | 729 } |
743 | 730 |
744 | 731 |
745 void InstructionSelector::VisitInt32Add(Node* node) { | 732 void InstructionSelector::VisitInt32Add(Node* node) { |
746 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Add32, kInt16Imm); | 733 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Add, kInt16Imm); |
747 } | 734 } |
748 | 735 |
749 | 736 |
750 #if V8_TARGET_ARCH_PPC64 | 737 #if V8_TARGET_ARCH_PPC64 |
751 void InstructionSelector::VisitInt64Add(Node* node) { | 738 void InstructionSelector::VisitInt64Add(Node* node) { |
752 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add64, kInt16Imm); | 739 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add, kInt16Imm); |
753 } | 740 } |
754 #endif | 741 #endif |
755 | 742 |
756 | 743 |
757 void InstructionSelector::VisitInt32Sub(Node* node) { | 744 void InstructionSelector::VisitInt32Sub(Node* node) { |
758 PPCOperandGenerator g(this); | 745 PPCOperandGenerator g(this); |
759 Int32BinopMatcher m(node); | 746 Int32BinopMatcher m(node); |
760 if (m.left().Is(0)) { | 747 if (m.left().Is(0)) { |
761 Emit(kPPC_Neg32, g.DefineAsRegister(node), g.UseRegister(m.right().node())); | 748 Emit(kPPC_Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node())); |
762 } else { | 749 } else { |
763 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Sub32, kInt16Imm_Negate); | 750 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate); |
764 } | 751 } |
765 } | 752 } |
766 | 753 |
767 | 754 |
768 #if V8_TARGET_ARCH_PPC64 | 755 #if V8_TARGET_ARCH_PPC64 |
769 void InstructionSelector::VisitInt64Sub(Node* node) { | 756 void InstructionSelector::VisitInt64Sub(Node* node) { |
770 PPCOperandGenerator g(this); | 757 PPCOperandGenerator g(this); |
771 Int64BinopMatcher m(node); | 758 Int64BinopMatcher m(node); |
772 if (m.left().Is(0)) { | 759 if (m.left().Is(0)) { |
773 Emit(kPPC_Neg64, g.DefineAsRegister(node), g.UseRegister(m.right().node())); | 760 Emit(kPPC_Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node())); |
774 } else { | 761 } else { |
775 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub64, kInt16Imm_Negate); | 762 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate); |
776 } | 763 } |
777 } | 764 } |
778 #endif | 765 #endif |
779 | 766 |
780 | 767 |
781 void InstructionSelector::VisitInt32Mul(Node* node) { | 768 void InstructionSelector::VisitInt32Mul(Node* node) { |
782 VisitRRR(this, node, kPPC_Mul32); | 769 VisitRRR(this, kPPC_Mul32, node); |
783 } | 770 } |
784 | 771 |
785 | 772 |
786 #if V8_TARGET_ARCH_PPC64 | 773 #if V8_TARGET_ARCH_PPC64 |
787 void InstructionSelector::VisitInt64Mul(Node* node) { | 774 void InstructionSelector::VisitInt64Mul(Node* node) { |
788 VisitRRR(this, node, kPPC_Mul64); | 775 VisitRRR(this, kPPC_Mul64, node); |
789 } | 776 } |
790 #endif | 777 #endif |
791 | 778 |
792 | 779 |
793 void InstructionSelector::VisitInt32MulHigh(Node* node) { | 780 void InstructionSelector::VisitInt32MulHigh(Node* node) { |
794 PPCOperandGenerator g(this); | 781 PPCOperandGenerator g(this); |
795 Emit(kPPC_MulHigh32, g.DefineAsRegister(node), | 782 Emit(kPPC_MulHigh32, g.DefineAsRegister(node), |
796 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); | 783 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); |
797 } | 784 } |
798 | 785 |
799 | 786 |
800 void InstructionSelector::VisitUint32MulHigh(Node* node) { | 787 void InstructionSelector::VisitUint32MulHigh(Node* node) { |
801 PPCOperandGenerator g(this); | 788 PPCOperandGenerator g(this); |
802 Emit(kPPC_MulHighU32, g.DefineAsRegister(node), | 789 Emit(kPPC_MulHighU32, g.DefineAsRegister(node), |
803 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); | 790 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); |
804 } | 791 } |
805 | 792 |
806 | 793 |
807 void InstructionSelector::VisitInt32Div(Node* node) { | 794 void InstructionSelector::VisitInt32Div(Node* node) { |
808 VisitRRR(this, node, kPPC_Div32); | 795 VisitRRR(this, kPPC_Div32, node); |
809 } | 796 } |
810 | 797 |
811 | 798 |
812 #if V8_TARGET_ARCH_PPC64 | 799 #if V8_TARGET_ARCH_PPC64 |
813 void InstructionSelector::VisitInt64Div(Node* node) { | 800 void InstructionSelector::VisitInt64Div(Node* node) { |
814 VisitRRR(this, node, kPPC_Div64); | 801 VisitRRR(this, kPPC_Div64, node); |
815 } | 802 } |
816 #endif | 803 #endif |
817 | 804 |
818 | 805 |
819 void InstructionSelector::VisitUint32Div(Node* node) { | 806 void InstructionSelector::VisitUint32Div(Node* node) { |
820 VisitRRR(this, node, kPPC_DivU32); | 807 VisitRRR(this, kPPC_DivU32, node); |
821 } | 808 } |
822 | 809 |
823 | 810 |
824 #if V8_TARGET_ARCH_PPC64 | 811 #if V8_TARGET_ARCH_PPC64 |
825 void InstructionSelector::VisitUint64Div(Node* node) { | 812 void InstructionSelector::VisitUint64Div(Node* node) { |
826 VisitRRR(this, node, kPPC_DivU64); | 813 VisitRRR(this, kPPC_DivU64, node); |
827 } | 814 } |
828 #endif | 815 #endif |
829 | 816 |
830 | 817 |
831 void InstructionSelector::VisitInt32Mod(Node* node) { | 818 void InstructionSelector::VisitInt32Mod(Node* node) { |
832 VisitRRR(this, node, kPPC_Mod32); | 819 VisitRRR(this, kPPC_Mod32, node); |
833 } | 820 } |
834 | 821 |
835 | 822 |
836 #if V8_TARGET_ARCH_PPC64 | 823 #if V8_TARGET_ARCH_PPC64 |
837 void InstructionSelector::VisitInt64Mod(Node* node) { | 824 void InstructionSelector::VisitInt64Mod(Node* node) { |
838 VisitRRR(this, node, kPPC_Mod64); | 825 VisitRRR(this, kPPC_Mod64, node); |
839 } | 826 } |
840 #endif | 827 #endif |
841 | 828 |
842 | 829 |
843 void InstructionSelector::VisitUint32Mod(Node* node) { | 830 void InstructionSelector::VisitUint32Mod(Node* node) { |
844 VisitRRR(this, node, kPPC_ModU32); | 831 VisitRRR(this, kPPC_ModU32, node); |
845 } | 832 } |
846 | 833 |
847 | 834 |
848 #if V8_TARGET_ARCH_PPC64 | 835 #if V8_TARGET_ARCH_PPC64 |
849 void InstructionSelector::VisitUint64Mod(Node* node) { | 836 void InstructionSelector::VisitUint64Mod(Node* node) { |
850 VisitRRR(this, node, kPPC_ModU64); | 837 VisitRRR(this, kPPC_ModU64, node); |
851 } | 838 } |
852 #endif | 839 #endif |
853 | 840 |
854 | 841 |
855 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { | 842 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { |
856 PPCOperandGenerator g(this); | 843 VisitRR(this, kPPC_Float32ToDouble, node); |
857 Emit(kPPC_Float32ToFloat64, g.DefineAsRegister(node), | |
858 g.UseRegister(node->InputAt(0))); | |
859 } | 844 } |
860 | 845 |
861 | 846 |
862 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { | 847 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { |
863 PPCOperandGenerator g(this); | 848 VisitRR(this, kPPC_Int32ToDouble, node); |
864 Emit(kPPC_Int32ToFloat64, g.DefineAsRegister(node), | |
865 g.UseRegister(node->InputAt(0))); | |
866 } | 849 } |
867 | 850 |
868 | 851 |
869 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { | 852 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { |
870 PPCOperandGenerator g(this); | 853 VisitRR(this, kPPC_Uint32ToDouble, node); |
871 Emit(kPPC_Uint32ToFloat64, g.DefineAsRegister(node), | |
872 g.UseRegister(node->InputAt(0))); | |
873 } | 854 } |
874 | 855 |
875 | 856 |
876 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { | 857 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { |
877 PPCOperandGenerator g(this); | 858 VisitRR(this, kPPC_DoubleToInt32, node); |
878 Emit(kPPC_Float64ToInt32, g.DefineAsRegister(node), | |
879 g.UseRegister(node->InputAt(0))); | |
880 } | 859 } |
881 | 860 |
882 | 861 |
883 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { | 862 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { |
884 PPCOperandGenerator g(this); | 863 VisitRR(this, kPPC_DoubleToUint32, node); |
885 Emit(kPPC_Float64ToUint32, g.DefineAsRegister(node), | |
886 g.UseRegister(node->InputAt(0))); | |
887 } | 864 } |
888 | 865 |
889 | 866 |
890 #if V8_TARGET_ARCH_PPC64 | 867 #if V8_TARGET_ARCH_PPC64 |
891 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) { | 868 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) { |
892 // TODO(mbrandy): inspect input to see if nop is appropriate. | 869 // TODO(mbrandy): inspect input to see if nop is appropriate. |
893 PPCOperandGenerator g(this); | 870 VisitRR(this, kPPC_ExtendSignWord32, node); |
894 Emit(kPPC_ExtendSignWord32, g.DefineAsRegister(node), | |
895 g.UseRegister(node->InputAt(0))); | |
896 } | 871 } |
897 | 872 |
898 | 873 |
899 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) { | 874 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) { |
900 // TODO(mbrandy): inspect input to see if nop is appropriate. | 875 // TODO(mbrandy): inspect input to see if nop is appropriate. |
901 PPCOperandGenerator g(this); | 876 PPCOperandGenerator g(this); |
902 Emit(kPPC_Uint32ToUint64, g.DefineAsRegister(node), | 877 Emit(kPPC_Uint32ToUint64, g.DefineAsRegister(node), |
903 g.UseRegister(node->InputAt(0))); | 878 g.UseRegister(node->InputAt(0))); |
904 } | 879 } |
905 #endif | 880 #endif |
906 | 881 |
907 | 882 |
908 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { | 883 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { |
909 PPCOperandGenerator g(this); | 884 PPCOperandGenerator g(this); |
910 Emit(kPPC_Float64ToFloat32, g.DefineAsRegister(node), | 885 Emit(kPPC_DoubleToFloat32, g.DefineAsRegister(node), |
911 g.UseRegister(node->InputAt(0))); | 886 g.UseRegister(node->InputAt(0))); |
912 } | 887 } |
913 | 888 |
914 | 889 |
915 #if V8_TARGET_ARCH_PPC64 | 890 #if V8_TARGET_ARCH_PPC64 |
916 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { | 891 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { |
917 PPCOperandGenerator g(this); | 892 PPCOperandGenerator g(this); |
918 // TODO(mbrandy): inspect input to see if nop is appropriate. | 893 // TODO(mbrandy): inspect input to see if nop is appropriate. |
919 Emit(kPPC_Int64ToInt32, g.DefineAsRegister(node), | 894 Emit(kPPC_Int64ToInt32, g.DefineAsRegister(node), |
920 g.UseRegister(node->InputAt(0))); | 895 g.UseRegister(node->InputAt(0))); |
921 } | 896 } |
922 #endif | 897 #endif |
923 | 898 |
924 | 899 |
| 900 void InstructionSelector::VisitFloat32Add(Node* node) { |
| 901 VisitRRR(this, kPPC_AddDouble, node); |
| 902 } |
| 903 |
| 904 |
925 void InstructionSelector::VisitFloat64Add(Node* node) { | 905 void InstructionSelector::VisitFloat64Add(Node* node) { |
926 // TODO(mbrandy): detect multiply-add | 906 // TODO(mbrandy): detect multiply-add |
927 VisitRRRFloat64(this, node, kPPC_AddFloat64); | 907 VisitRRR(this, kPPC_AddDouble, node); |
928 } | 908 } |
929 | 909 |
930 | 910 |
| 911 void InstructionSelector::VisitFloat32Sub(Node* node) { |
| 912 VisitRRR(this, kPPC_SubDouble, node); |
| 913 } |
| 914 |
| 915 |
931 void InstructionSelector::VisitFloat64Sub(Node* node) { | 916 void InstructionSelector::VisitFloat64Sub(Node* node) { |
932 // TODO(mbrandy): detect multiply-subtract | 917 // TODO(mbrandy): detect multiply-subtract |
933 PPCOperandGenerator g(this); | 918 PPCOperandGenerator g(this); |
934 Float64BinopMatcher m(node); | 919 Float64BinopMatcher m(node); |
935 if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() && | 920 if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() && |
936 CanCover(m.node(), m.right().node())) { | 921 CanCover(m.node(), m.right().node())) { |
937 if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub && | 922 if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub && |
938 CanCover(m.right().node(), m.right().InputAt(0))) { | 923 CanCover(m.right().node(), m.right().InputAt(0))) { |
939 Float64BinopMatcher mright0(m.right().InputAt(0)); | 924 Float64BinopMatcher mright0(m.right().InputAt(0)); |
940 if (mright0.left().IsMinusZero()) { | 925 if (mright0.left().IsMinusZero()) { |
941 // -floor(-x) = ceil(x) | 926 // -floor(-x) = ceil(x) |
942 Emit(kPPC_CeilFloat64, g.DefineAsRegister(node), | 927 Emit(kPPC_CeilDouble, g.DefineAsRegister(node), |
943 g.UseRegister(mright0.right().node())); | 928 g.UseRegister(mright0.right().node())); |
944 return; | 929 return; |
945 } | 930 } |
946 } | 931 } |
947 } | 932 } |
948 VisitRRRFloat64(this, node, kPPC_SubFloat64); | 933 VisitRRR(this, kPPC_SubDouble, node); |
| 934 } |
| 935 |
| 936 |
| 937 void InstructionSelector::VisitFloat32Mul(Node* node) { |
| 938 VisitRRR(this, kPPC_MulDouble, node); |
949 } | 939 } |
950 | 940 |
951 | 941 |
952 void InstructionSelector::VisitFloat64Mul(Node* node) { | 942 void InstructionSelector::VisitFloat64Mul(Node* node) { |
953 // TODO(mbrandy): detect negate | 943 // TODO(mbrandy): detect negate |
954 VisitRRRFloat64(this, node, kPPC_MulFloat64); | 944 VisitRRR(this, kPPC_MulDouble, node); |
| 945 } |
| 946 |
| 947 |
| 948 void InstructionSelector::VisitFloat32Div(Node* node) { |
| 949 VisitRRR(this, kPPC_DivDouble, node); |
955 } | 950 } |
956 | 951 |
957 | 952 |
958 void InstructionSelector::VisitFloat64Div(Node* node) { | 953 void InstructionSelector::VisitFloat64Div(Node* node) { |
959 VisitRRRFloat64(this, node, kPPC_DivFloat64); | 954 VisitRRR(this, kPPC_DivDouble, node); |
960 } | 955 } |
961 | 956 |
962 | 957 |
963 void InstructionSelector::VisitFloat64Mod(Node* node) { | 958 void InstructionSelector::VisitFloat64Mod(Node* node) { |
964 PPCOperandGenerator g(this); | 959 PPCOperandGenerator g(this); |
965 Emit(kPPC_ModFloat64, g.DefineAsFixed(node, d1), | 960 Emit(kPPC_ModDouble, g.DefineAsFixed(node, d1), |
966 g.UseFixed(node->InputAt(0), d1), | 961 g.UseFixed(node->InputAt(0), d1), |
967 g.UseFixed(node->InputAt(1), d2))->MarkAsCall(); | 962 g.UseFixed(node->InputAt(1), d2))->MarkAsCall(); |
968 } | 963 } |
969 | 964 |
970 | 965 |
| 966 void InstructionSelector::VisitFloat32Max(Node* node) { |
| 967 VisitRRR(this, kPPC_MaxDouble, node); |
| 968 } |
| 969 |
| 970 |
971 void InstructionSelector::VisitFloat64Max(Node* node) { | 971 void InstructionSelector::VisitFloat64Max(Node* node) { |
972 VisitRRRFloat64(this, node, kPPC_MaxFloat64); | 972 VisitRRR(this, kPPC_MaxDouble, node); |
| 973 } |
| 974 |
| 975 |
| 976 void InstructionSelector::VisitFloat32Min(Node* node) { |
| 977 VisitRRR(this, kPPC_MinDouble, node); |
973 } | 978 } |
974 | 979 |
975 | 980 |
976 void InstructionSelector::VisitFloat64Min(Node* node) { | 981 void InstructionSelector::VisitFloat64Min(Node* node) { |
977 VisitRRRFloat64(this, node, kPPC_MinFloat64); | 982 VisitRRR(this, kPPC_MinDouble, node); |
| 983 } |
| 984 |
| 985 |
| 986 void InstructionSelector::VisitFloat32Sqrt(Node* node) { |
| 987 VisitRR(this, kPPC_SqrtDouble, node); |
978 } | 988 } |
979 | 989 |
980 | 990 |
981 void InstructionSelector::VisitFloat64Sqrt(Node* node) { | 991 void InstructionSelector::VisitFloat64Sqrt(Node* node) { |
982 VisitRRFloat64(this, kPPC_SqrtFloat64, node); | 992 VisitRR(this, kPPC_SqrtDouble, node); |
983 } | 993 } |
984 | 994 |
985 | 995 |
986 void InstructionSelector::VisitFloat64RoundDown(Node* node) { | 996 void InstructionSelector::VisitFloat64RoundDown(Node* node) { |
987 VisitRRFloat64(this, kPPC_FloorFloat64, node); | 997 VisitRR(this, kPPC_FloorDouble, node); |
988 } | 998 } |
989 | 999 |
990 | 1000 |
991 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 1001 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
992 VisitRRFloat64(this, kPPC_TruncateFloat64, node); | 1002 VisitRR(this, kPPC_TruncateDouble, node); |
993 } | 1003 } |
994 | 1004 |
995 | 1005 |
996 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 1006 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
997 VisitRRFloat64(this, kPPC_RoundFloat64, node); | 1007 VisitRR(this, kPPC_RoundDouble, node); |
998 } | 1008 } |
999 | 1009 |
1000 | 1010 |
1001 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { | 1011 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
1002 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 1012 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
1003 FlagsContinuation cont(kOverflow, ovf); | 1013 FlagsContinuation cont(kOverflow, ovf); |
1004 return VisitBinop<Int32BinopMatcher>(this, node, kPPC_AddWithOverflow32, | 1014 return VisitBinop<Int32BinopMatcher>(this, node, kPPC_AddWithOverflow32, |
1005 kInt16Imm, &cont); | 1015 kInt16Imm, &cont); |
1006 } | 1016 } |
1007 FlagsContinuation cont; | 1017 FlagsContinuation cont; |
(...skipping 22 matching lines...) Expand all Loading... |
1030 case kUnsignedGreaterThan: | 1040 case kUnsignedGreaterThan: |
1031 return true; | 1041 return true; |
1032 default: | 1042 default: |
1033 return false; | 1043 return false; |
1034 } | 1044 } |
1035 UNREACHABLE(); | 1045 UNREACHABLE(); |
1036 return false; | 1046 return false; |
1037 } | 1047 } |
1038 | 1048 |
1039 | 1049 |
| 1050 namespace { |
| 1051 |
1040 // Shared routine for multiple compare operations. | 1052 // Shared routine for multiple compare operations. |
1041 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 1053 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
1042 InstructionOperand left, InstructionOperand right, | 1054 InstructionOperand left, InstructionOperand right, |
1043 FlagsContinuation* cont) { | 1055 FlagsContinuation* cont) { |
1044 PPCOperandGenerator g(selector); | 1056 PPCOperandGenerator g(selector); |
1045 opcode = cont->Encode(opcode); | 1057 opcode = cont->Encode(opcode); |
1046 if (cont->IsBranch()) { | 1058 if (cont->IsBranch()) { |
1047 selector->Emit(opcode, g.NoOutput(), left, right, | 1059 selector->Emit(opcode, g.NoOutput(), left, right, |
1048 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1060 g.Label(cont->true_block()), g.Label(cont->false_block())); |
1049 } else { | 1061 } else { |
1050 DCHECK(cont->IsSet()); | 1062 DCHECK(cont->IsSet()); |
1051 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); | 1063 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
1052 } | 1064 } |
1053 } | 1065 } |
1054 | 1066 |
1055 | 1067 |
1056 // Shared routine for multiple word compare operations. | 1068 // Shared routine for multiple word compare operations. |
1057 static void VisitWordCompare(InstructionSelector* selector, Node* node, | 1069 void VisitWordCompare(InstructionSelector* selector, Node* node, |
1058 InstructionCode opcode, FlagsContinuation* cont, | 1070 InstructionCode opcode, FlagsContinuation* cont, |
1059 bool commutative, ImmediateMode immediate_mode) { | 1071 bool commutative, ImmediateMode immediate_mode) { |
1060 PPCOperandGenerator g(selector); | 1072 PPCOperandGenerator g(selector); |
1061 Node* left = node->InputAt(0); | 1073 Node* left = node->InputAt(0); |
1062 Node* right = node->InputAt(1); | 1074 Node* right = node->InputAt(1); |
1063 | 1075 |
1064 // Match immediates on left or right side of comparison. | 1076 // Match immediates on left or right side of comparison. |
1065 if (g.CanBeImmediate(right, immediate_mode)) { | 1077 if (g.CanBeImmediate(right, immediate_mode)) { |
1066 VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), | 1078 VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), |
1067 cont); | 1079 cont); |
1068 } else if (g.CanBeImmediate(left, immediate_mode)) { | 1080 } else if (g.CanBeImmediate(left, immediate_mode)) { |
1069 if (!commutative) cont->Commute(); | 1081 if (!commutative) cont->Commute(); |
1070 VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left), | 1082 VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left), |
1071 cont); | 1083 cont); |
1072 } else { | 1084 } else { |
1073 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), | 1085 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), |
1074 cont); | 1086 cont); |
1075 } | 1087 } |
1076 } | 1088 } |
1077 | 1089 |
1078 | 1090 |
1079 static void VisitWord32Compare(InstructionSelector* selector, Node* node, | 1091 void VisitWord32Compare(InstructionSelector* selector, Node* node, |
1080 FlagsContinuation* cont) { | 1092 FlagsContinuation* cont) { |
1081 ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm); | 1093 ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm); |
1082 VisitWordCompare(selector, node, kPPC_Cmp32, cont, false, mode); | 1094 VisitWordCompare(selector, node, kPPC_Cmp32, cont, false, mode); |
1083 } | 1095 } |
1084 | 1096 |
1085 | 1097 |
1086 #if V8_TARGET_ARCH_PPC64 | 1098 #if V8_TARGET_ARCH_PPC64 |
1087 static void VisitWord64Compare(InstructionSelector* selector, Node* node, | 1099 void VisitWord64Compare(InstructionSelector* selector, Node* node, |
1088 FlagsContinuation* cont) { | 1100 FlagsContinuation* cont) { |
1089 ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm); | 1101 ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm); |
1090 VisitWordCompare(selector, node, kPPC_Cmp64, cont, false, mode); | 1102 VisitWordCompare(selector, node, kPPC_Cmp64, cont, false, mode); |
1091 } | 1103 } |
1092 #endif | 1104 #endif |
1093 | 1105 |
1094 | 1106 |
1095 // Shared routine for multiple float compare operations. | 1107 // Shared routine for multiple float32 compare operations. |
1096 static void VisitFloat64Compare(InstructionSelector* selector, Node* node, | 1108 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
1097 FlagsContinuation* cont) { | 1109 FlagsContinuation* cont) { |
1098 PPCOperandGenerator g(selector); | 1110 PPCOperandGenerator g(selector); |
1099 Node* left = node->InputAt(0); | 1111 Node* left = node->InputAt(0); |
1100 Node* right = node->InputAt(1); | 1112 Node* right = node->InputAt(1); |
1101 VisitCompare(selector, kPPC_CmpFloat64, g.UseRegister(left), | 1113 VisitCompare(selector, kPPC_CmpDouble, g.UseRegister(left), |
| 1114 g.UseRegister(right), cont); |
| 1115 } |
| 1116 |
| 1117 |
| 1118 // Shared routine for multiple float64 compare operations. |
| 1119 void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
| 1120 FlagsContinuation* cont) { |
| 1121 PPCOperandGenerator g(selector); |
| 1122 Node* left = node->InputAt(0); |
| 1123 Node* right = node->InputAt(1); |
| 1124 VisitCompare(selector, kPPC_CmpDouble, g.UseRegister(left), |
1102 g.UseRegister(right), cont); | 1125 g.UseRegister(right), cont); |
1103 } | 1126 } |
1104 | 1127 |
1105 | 1128 |
1106 // Shared routine for word comparisons against zero. | 1129 // Shared routine for word comparisons against zero. |
1107 static void VisitWordCompareZero(InstructionSelector* selector, Node* user, | 1130 void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
1108 Node* value, InstructionCode opcode, | 1131 Node* value, InstructionCode opcode, |
1109 FlagsContinuation* cont) { | 1132 FlagsContinuation* cont) { |
1110 while (selector->CanCover(user, value)) { | 1133 while (selector->CanCover(user, value)) { |
1111 switch (value->opcode()) { | 1134 switch (value->opcode()) { |
1112 case IrOpcode::kWord32Equal: { | 1135 case IrOpcode::kWord32Equal: { |
1113 // Combine with comparisons against 0 by simply inverting the | 1136 // Combine with comparisons against 0 by simply inverting the |
1114 // continuation. | 1137 // continuation. |
1115 Int32BinopMatcher m(value); | 1138 Int32BinopMatcher m(value); |
1116 if (m.right().Is(0)) { | 1139 if (m.right().Is(0)) { |
1117 user = value; | 1140 user = value; |
1118 value = m.left().node(); | 1141 value = m.left().node(); |
1119 cont->Negate(); | 1142 cont->Negate(); |
(...skipping 21 matching lines...) Expand all Loading... |
1141 case IrOpcode::kInt64LessThan: | 1164 case IrOpcode::kInt64LessThan: |
1142 cont->OverwriteAndNegateIfEqual(kSignedLessThan); | 1165 cont->OverwriteAndNegateIfEqual(kSignedLessThan); |
1143 return VisitWord64Compare(selector, value, cont); | 1166 return VisitWord64Compare(selector, value, cont); |
1144 case IrOpcode::kInt64LessThanOrEqual: | 1167 case IrOpcode::kInt64LessThanOrEqual: |
1145 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); | 1168 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); |
1146 return VisitWord64Compare(selector, value, cont); | 1169 return VisitWord64Compare(selector, value, cont); |
1147 case IrOpcode::kUint64LessThan: | 1170 case IrOpcode::kUint64LessThan: |
1148 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1171 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
1149 return VisitWord64Compare(selector, value, cont); | 1172 return VisitWord64Compare(selector, value, cont); |
1150 #endif | 1173 #endif |
| 1174 case IrOpcode::kFloat32Equal: |
| 1175 cont->OverwriteAndNegateIfEqual(kEqual); |
| 1176 return VisitFloat32Compare(selector, value, cont); |
| 1177 case IrOpcode::kFloat32LessThan: |
| 1178 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1179 return VisitFloat32Compare(selector, value, cont); |
| 1180 case IrOpcode::kFloat32LessThanOrEqual: |
| 1181 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
| 1182 return VisitFloat32Compare(selector, value, cont); |
1151 case IrOpcode::kFloat64Equal: | 1183 case IrOpcode::kFloat64Equal: |
1152 cont->OverwriteAndNegateIfEqual(kEqual); | 1184 cont->OverwriteAndNegateIfEqual(kEqual); |
1153 return VisitFloat64Compare(selector, value, cont); | 1185 return VisitFloat64Compare(selector, value, cont); |
1154 case IrOpcode::kFloat64LessThan: | 1186 case IrOpcode::kFloat64LessThan: |
1155 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1187 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
1156 return VisitFloat64Compare(selector, value, cont); | 1188 return VisitFloat64Compare(selector, value, cont); |
1157 case IrOpcode::kFloat64LessThanOrEqual: | 1189 case IrOpcode::kFloat64LessThanOrEqual: |
1158 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); | 1190 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
1159 return VisitFloat64Compare(selector, value, cont); | 1191 return VisitFloat64Compare(selector, value, cont); |
1160 case IrOpcode::kProjection: | 1192 case IrOpcode::kProjection: |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1221 break; | 1253 break; |
1222 } | 1254 } |
1223 | 1255 |
1224 // Branch could not be combined with a compare, emit compare against 0. | 1256 // Branch could not be combined with a compare, emit compare against 0. |
1225 PPCOperandGenerator g(selector); | 1257 PPCOperandGenerator g(selector); |
1226 VisitCompare(selector, opcode, g.UseRegister(value), g.TempImmediate(0), | 1258 VisitCompare(selector, opcode, g.UseRegister(value), g.TempImmediate(0), |
1227 cont); | 1259 cont); |
1228 } | 1260 } |
1229 | 1261 |
1230 | 1262 |
1231 static void VisitWord32CompareZero(InstructionSelector* selector, Node* user, | 1263 void VisitWord32CompareZero(InstructionSelector* selector, Node* user, |
1232 Node* value, FlagsContinuation* cont) { | 1264 Node* value, FlagsContinuation* cont) { |
1233 VisitWordCompareZero(selector, user, value, kPPC_Cmp32, cont); | 1265 VisitWordCompareZero(selector, user, value, kPPC_Cmp32, cont); |
1234 } | 1266 } |
1235 | 1267 |
1236 | 1268 |
1237 #if V8_TARGET_ARCH_PPC64 | 1269 #if V8_TARGET_ARCH_PPC64 |
1238 static void VisitWord64CompareZero(InstructionSelector* selector, Node* user, | 1270 void VisitWord64CompareZero(InstructionSelector* selector, Node* user, |
1239 Node* value, FlagsContinuation* cont) { | 1271 Node* value, FlagsContinuation* cont) { |
1240 VisitWordCompareZero(selector, user, value, kPPC_Cmp64, cont); | 1272 VisitWordCompareZero(selector, user, value, kPPC_Cmp64, cont); |
1241 } | 1273 } |
1242 #endif | 1274 #endif |
1243 | 1275 |
| 1276 } // namespace |
| 1277 |
1244 | 1278 |
1245 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 1279 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
1246 BasicBlock* fbranch) { | 1280 BasicBlock* fbranch) { |
1247 FlagsContinuation cont(kNotEqual, tbranch, fbranch); | 1281 FlagsContinuation cont(kNotEqual, tbranch, fbranch); |
1248 VisitWord32CompareZero(this, branch, branch->InputAt(0), &cont); | 1282 VisitWord32CompareZero(this, branch, branch->InputAt(0), &cont); |
1249 } | 1283 } |
1250 | 1284 |
1251 | 1285 |
1252 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { | 1286 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { |
1253 PPCOperandGenerator g(this); | 1287 PPCOperandGenerator g(this); |
1254 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); | 1288 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); |
1255 | 1289 |
1256 // Emit either ArchTableSwitch or ArchLookupSwitch. | 1290 // Emit either ArchTableSwitch or ArchLookupSwitch. |
1257 size_t table_space_cost = 4 + sw.value_range; | 1291 size_t table_space_cost = 4 + sw.value_range; |
1258 size_t table_time_cost = 3; | 1292 size_t table_time_cost = 3; |
1259 size_t lookup_space_cost = 3 + 2 * sw.case_count; | 1293 size_t lookup_space_cost = 3 + 2 * sw.case_count; |
1260 size_t lookup_time_cost = sw.case_count; | 1294 size_t lookup_time_cost = sw.case_count; |
1261 if (sw.case_count > 0 && | 1295 if (sw.case_count > 0 && |
1262 table_space_cost + 3 * table_time_cost <= | 1296 table_space_cost + 3 * table_time_cost <= |
1263 lookup_space_cost + 3 * lookup_time_cost && | 1297 lookup_space_cost + 3 * lookup_time_cost && |
1264 sw.min_value > std::numeric_limits<int32_t>::min()) { | 1298 sw.min_value > std::numeric_limits<int32_t>::min()) { |
1265 InstructionOperand index_operand = value_operand; | 1299 InstructionOperand index_operand = value_operand; |
1266 if (sw.min_value) { | 1300 if (sw.min_value) { |
1267 index_operand = g.TempRegister(); | 1301 index_operand = g.TempRegister(); |
1268 Emit(kPPC_Sub32, index_operand, value_operand, | 1302 Emit(kPPC_Sub, index_operand, value_operand, |
1269 g.TempImmediate(sw.min_value)); | 1303 g.TempImmediate(sw.min_value)); |
1270 } | 1304 } |
1271 // Generate a table lookup. | 1305 // Generate a table lookup. |
1272 return EmitTableSwitch(sw, index_operand); | 1306 return EmitTableSwitch(sw, index_operand); |
1273 } | 1307 } |
1274 | 1308 |
1275 // Generate a sequence of conditional jumps. | 1309 // Generate a sequence of conditional jumps. |
1276 return EmitLookupSwitch(sw, value_operand); | 1310 return EmitLookupSwitch(sw, value_operand); |
1277 } | 1311 } |
1278 | 1312 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 } | 1368 } |
1335 | 1369 |
1336 | 1370 |
1337 void InstructionSelector::VisitUint64LessThan(Node* node) { | 1371 void InstructionSelector::VisitUint64LessThan(Node* node) { |
1338 FlagsContinuation cont(kUnsignedLessThan, node); | 1372 FlagsContinuation cont(kUnsignedLessThan, node); |
1339 VisitWord64Compare(this, node, &cont); | 1373 VisitWord64Compare(this, node, &cont); |
1340 } | 1374 } |
1341 #endif | 1375 #endif |
1342 | 1376 |
1343 | 1377 |
| 1378 void InstructionSelector::VisitFloat32Equal(Node* node) { |
| 1379 FlagsContinuation cont(kEqual, node); |
| 1380 VisitFloat32Compare(this, node, &cont); |
| 1381 } |
| 1382 |
| 1383 |
| 1384 void InstructionSelector::VisitFloat32LessThan(Node* node) { |
| 1385 FlagsContinuation cont(kUnsignedLessThan, node); |
| 1386 VisitFloat32Compare(this, node, &cont); |
| 1387 } |
| 1388 |
| 1389 |
| 1390 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { |
| 1391 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); |
| 1392 VisitFloat32Compare(this, node, &cont); |
| 1393 } |
| 1394 |
| 1395 |
1344 void InstructionSelector::VisitFloat64Equal(Node* node) { | 1396 void InstructionSelector::VisitFloat64Equal(Node* node) { |
1345 FlagsContinuation cont(kEqual, node); | 1397 FlagsContinuation cont(kEqual, node); |
1346 VisitFloat64Compare(this, node, &cont); | 1398 VisitFloat64Compare(this, node, &cont); |
1347 } | 1399 } |
1348 | 1400 |
1349 | 1401 |
1350 void InstructionSelector::VisitFloat64LessThan(Node* node) { | 1402 void InstructionSelector::VisitFloat64LessThan(Node* node) { |
1351 FlagsContinuation cont(kUnsignedLessThan, node); | 1403 FlagsContinuation cont(kUnsignedLessThan, node); |
1352 VisitFloat64Compare(this, node, &cont); | 1404 VisitFloat64Compare(this, node, &cont); |
1353 } | 1405 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1412 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; | 1464 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; |
1413 Instruction* call_instr = | 1465 Instruction* call_instr = |
1414 Emit(opcode, buffer.outputs.size(), first_output, | 1466 Emit(opcode, buffer.outputs.size(), first_output, |
1415 buffer.instruction_args.size(), &buffer.instruction_args.front()); | 1467 buffer.instruction_args.size(), &buffer.instruction_args.front()); |
1416 call_instr->MarkAsCall(); | 1468 call_instr->MarkAsCall(); |
1417 } | 1469 } |
1418 | 1470 |
1419 | 1471 |
1420 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { | 1472 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { |
1421 PPCOperandGenerator g(this); | 1473 PPCOperandGenerator g(this); |
1422 Emit(kPPC_Float64ExtractLowWord32, g.DefineAsRegister(node), | 1474 Emit(kPPC_DoubleExtractLowWord32, g.DefineAsRegister(node), |
1423 g.UseRegister(node->InputAt(0))); | 1475 g.UseRegister(node->InputAt(0))); |
1424 } | 1476 } |
1425 | 1477 |
1426 | 1478 |
1427 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { | 1479 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { |
1428 PPCOperandGenerator g(this); | 1480 PPCOperandGenerator g(this); |
1429 Emit(kPPC_Float64ExtractHighWord32, g.DefineAsRegister(node), | 1481 Emit(kPPC_DoubleExtractHighWord32, g.DefineAsRegister(node), |
1430 g.UseRegister(node->InputAt(0))); | 1482 g.UseRegister(node->InputAt(0))); |
1431 } | 1483 } |
1432 | 1484 |
1433 | 1485 |
1434 void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) { | 1486 void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) { |
1435 PPCOperandGenerator g(this); | 1487 PPCOperandGenerator g(this); |
1436 Node* left = node->InputAt(0); | 1488 Node* left = node->InputAt(0); |
1437 Node* right = node->InputAt(1); | 1489 Node* right = node->InputAt(1); |
1438 if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 && | 1490 if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 && |
1439 CanCover(node, left)) { | 1491 CanCover(node, left)) { |
1440 left = left->InputAt(1); | 1492 left = left->InputAt(1); |
1441 Emit(kPPC_Float64Construct, g.DefineAsRegister(node), g.UseRegister(left), | 1493 Emit(kPPC_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(left), |
1442 g.UseRegister(right)); | 1494 g.UseRegister(right)); |
1443 return; | 1495 return; |
1444 } | 1496 } |
1445 Emit(kPPC_Float64InsertLowWord32, g.DefineSameAsFirst(node), | 1497 Emit(kPPC_DoubleInsertLowWord32, g.DefineSameAsFirst(node), |
1446 g.UseRegister(left), g.UseRegister(right)); | 1498 g.UseRegister(left), g.UseRegister(right)); |
1447 } | 1499 } |
1448 | 1500 |
1449 | 1501 |
1450 void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { | 1502 void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { |
1451 PPCOperandGenerator g(this); | 1503 PPCOperandGenerator g(this); |
1452 Node* left = node->InputAt(0); | 1504 Node* left = node->InputAt(0); |
1453 Node* right = node->InputAt(1); | 1505 Node* right = node->InputAt(1); |
1454 if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 && | 1506 if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 && |
1455 CanCover(node, left)) { | 1507 CanCover(node, left)) { |
1456 left = left->InputAt(1); | 1508 left = left->InputAt(1); |
1457 Emit(kPPC_Float64Construct, g.DefineAsRegister(node), g.UseRegister(right), | 1509 Emit(kPPC_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(right), |
1458 g.UseRegister(left)); | 1510 g.UseRegister(left)); |
1459 return; | 1511 return; |
1460 } | 1512 } |
1461 Emit(kPPC_Float64InsertHighWord32, g.DefineSameAsFirst(node), | 1513 Emit(kPPC_DoubleInsertHighWord32, g.DefineSameAsFirst(node), |
1462 g.UseRegister(left), g.UseRegister(right)); | 1514 g.UseRegister(left), g.UseRegister(right)); |
1463 } | 1515 } |
1464 | 1516 |
1465 | 1517 |
1466 // static | 1518 // static |
1467 MachineOperatorBuilder::Flags | 1519 MachineOperatorBuilder::Flags |
1468 InstructionSelector::SupportedMachineOperatorFlags() { | 1520 InstructionSelector::SupportedMachineOperatorFlags() { |
1469 return MachineOperatorBuilder::kFloat64Max | | 1521 return MachineOperatorBuilder::kFloat32Max | |
| 1522 MachineOperatorBuilder::kFloat32Min | |
| 1523 MachineOperatorBuilder::kFloat64Max | |
1470 MachineOperatorBuilder::kFloat64Min | | 1524 MachineOperatorBuilder::kFloat64Min | |
1471 MachineOperatorBuilder::kFloat64RoundDown | | 1525 MachineOperatorBuilder::kFloat64RoundDown | |
1472 MachineOperatorBuilder::kFloat64RoundTruncate | | 1526 MachineOperatorBuilder::kFloat64RoundTruncate | |
1473 MachineOperatorBuilder::kFloat64RoundTiesAway; | 1527 MachineOperatorBuilder::kFloat64RoundTiesAway; |
1474 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. | 1528 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. |
1475 } | 1529 } |
1476 | 1530 |
1477 } // namespace compiler | 1531 } // namespace compiler |
1478 } // namespace internal | 1532 } // namespace internal |
1479 } // namespace v8 | 1533 } // namespace v8 |
OLD | NEW |