5 #include "src/base/adapters.h" 6 #include "src/compiler/backend/instruction-selector-impl.h" 7 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-properties.h" 9 #include "src/ppc/frame-constants-ppc.h" 19 kInt16Imm_4ByteAligned,
32 if (CanBeImmediate(node, mode)) {
33 return UseImmediate(node);
35 return UseRegister(node);
38 bool CanBeImmediate(
Node* node, ImmediateMode mode) {
40 if (node->opcode() == IrOpcode::kInt32Constant)
41 value = OpParameter<int32_t>(node->op());
42 else if (node->opcode() == IrOpcode::kInt64Constant)
43 value = OpParameter<int64_t>(node->op());
46 return CanBeImmediate(value, mode);
49 bool CanBeImmediate(
int64_t value, ImmediateMode mode) {
52 return is_int16(value);
53 case kInt16Imm_Unsigned:
54 return is_uint16(value);
55 case kInt16Imm_Negate:
56 return is_int16(-value);
57 case kInt16Imm_4ByteAligned:
58 return is_int16(value) && !(value & 3);
60 return 0 <= value && value < 32;
62 return 0 <= value && value < 64;
72 if (node->opcode() == IrOpcode::kLoadStackPointer) {
74 LocationOperand::REGISTER,
75 MachineRepresentation::kWord32, sp.code());
77 return UseRegister(node);
86 selector->Emit(opcode, g.DefineAsRegister(node),
87 g.UseRegister(node->InputAt(0)));
90 void VisitRRR(InstructionSelector* selector, InstructionCode opcode,
92 PPCOperandGenerator g(selector);
93 selector->Emit(opcode, g.DefineAsRegister(node),
94 g.UseRegister(node->InputAt(0)),
95 g.UseRegister(node->InputAt(1)));
98 void VisitRRO(InstructionSelector* selector, InstructionCode opcode, Node* node,
99 ImmediateMode operand_mode) {
100 PPCOperandGenerator g(selector);
101 selector->Emit(opcode, g.DefineAsRegister(node),
102 g.UseRegister(node->InputAt(0)),
103 g.UseOperand(node->InputAt(1), operand_mode));
106 #if V8_TARGET_ARCH_PPC64 107 void VisitTryTruncateDouble(InstructionSelector* selector,
108 InstructionCode opcode, Node* node) {
109 PPCOperandGenerator g(selector);
110 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
111 InstructionOperand outputs[2];
112 size_t output_count = 0;
113 outputs[output_count++] = g.DefineAsRegister(node);
115 Node* success_output = NodeProperties::FindProjection(node, 1);
116 if (success_output) {
117 outputs[output_count++] = g.DefineAsRegister(success_output);
120 selector->Emit(opcode, output_count, outputs, 1, inputs);
125 template <
typename Matcher>
126 void VisitBinop(InstructionSelector* selector, Node* node,
127 InstructionCode opcode, ImmediateMode operand_mode,
128 FlagsContinuation* cont) {
129 PPCOperandGenerator g(selector);
131 InstructionOperand inputs[4];
132 size_t input_count = 0;
133 InstructionOperand outputs[2];
134 size_t output_count = 0;
136 inputs[input_count++] = g.UseRegister(m.left().node());
137 inputs[input_count++] = g.UseOperand(m.right().node(), operand_mode);
139 if (cont->IsDeoptimize()) {
143 outputs[output_count++] = g.DefineSameAsFirst(node);
145 outputs[output_count++] = g.DefineAsRegister(node);
148 DCHECK_NE(0u, input_count);
149 DCHECK_NE(0u, output_count);
150 DCHECK_GE(arraysize(inputs), input_count);
151 DCHECK_GE(arraysize(outputs), output_count);
153 selector->EmitWithContinuation(opcode, output_count, outputs, input_count,
158 template <
typename Matcher>
159 void VisitBinop(InstructionSelector* selector, Node* node,
160 InstructionCode opcode, ImmediateMode operand_mode) {
161 FlagsContinuation cont;
162 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont);
167 void InstructionSelector::VisitStackSlot(Node* node) {
168 StackSlotRepresentation rep = StackSlotRepresentationOf(node->op());
169 int slot = frame_->AllocateSpillSlot(rep.size());
170 OperandGenerator g(
this);
172 Emit(kArchStackSlot, g.DefineAsRegister(node),
173 sequence()->AddImmediate(Constant(slot)), 0,
nullptr);
176 void InstructionSelector::VisitDebugAbort(Node* node) {
177 PPCOperandGenerator g(
this);
178 Emit(kArchDebugAbort, g.NoOutput(), g.UseFixed(node->InputAt(0), r4));
181 void InstructionSelector::VisitLoad(Node* node) {
182 LoadRepresentation load_rep = LoadRepresentationOf(node->op());
183 PPCOperandGenerator g(
this);
184 Node* base = node->InputAt(0);
185 Node* offset = node->InputAt(1);
186 InstructionCode opcode = kArchNop;
187 ImmediateMode mode = kInt16Imm;
188 switch (load_rep.representation()) {
189 case MachineRepresentation::kFloat32:
190 opcode = kPPC_LoadFloat32;
192 case MachineRepresentation::kFloat64:
193 opcode = kPPC_LoadDouble;
195 case MachineRepresentation::kBit:
196 case MachineRepresentation::kWord8:
197 opcode = load_rep.IsSigned() ? kPPC_LoadWordS8 : kPPC_LoadWordU8;
199 case MachineRepresentation::kWord16:
200 opcode = load_rep.IsSigned() ? kPPC_LoadWordS16 : kPPC_LoadWordU16;
202 case MachineRepresentation::kWord32:
203 opcode = kPPC_LoadWordU32;
205 case MachineRepresentation::kTaggedSigned:
206 case MachineRepresentation::kTaggedPointer:
207 case MachineRepresentation::kTagged:
208 case MachineRepresentation::kWord64:
209 opcode = kPPC_LoadWord64;
210 mode = kInt16Imm_4ByteAligned;
212 case MachineRepresentation::kSimd128:
213 case MachineRepresentation::kNone:
218 if (node->opcode() == IrOpcode::kPoisonedLoad &&
219 poisoning_level_ != PoisoningMitigationLevel::kDontPoison) {
220 opcode |= MiscField::encode(kMemoryAccessPoisoned);
223 bool is_atomic = (node->opcode() == IrOpcode::kWord32AtomicLoad ||
224 node->opcode() == IrOpcode::kWord64AtomicLoad);
226 if (g.CanBeImmediate(offset, mode)) {
227 Emit(opcode | AddressingModeField::encode(kMode_MRI),
228 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(offset),
229 g.UseImmediate(is_atomic));
230 }
else if (g.CanBeImmediate(base, mode)) {
231 Emit(opcode | AddressingModeField::encode(kMode_MRI),
232 g.DefineAsRegister(node), g.UseRegister(offset), g.UseImmediate(base),
233 g.UseImmediate(is_atomic));
235 Emit(opcode | AddressingModeField::encode(kMode_MRR),
236 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset),
237 g.UseImmediate(is_atomic));
241 void InstructionSelector::VisitPoisonedLoad(Node* node) { VisitLoad(node); }
243 void InstructionSelector::VisitProtectedLoad(Node* node) {
248 void InstructionSelector::VisitStore(Node* node) {
249 PPCOperandGenerator g(
this);
250 Node* base = node->InputAt(0);
251 Node* offset = node->InputAt(1);
252 Node* value = node->InputAt(2);
254 bool is_atomic = (node->opcode() == IrOpcode::kWord32AtomicStore ||
255 node->opcode() == IrOpcode::kWord64AtomicStore);
257 MachineRepresentation rep;
258 WriteBarrierKind write_barrier_kind = kNoWriteBarrier;
261 rep = AtomicStoreRepresentationOf(node->op());
263 StoreRepresentation store_rep = StoreRepresentationOf(node->op());
264 write_barrier_kind = store_rep.write_barrier_kind();
265 rep = store_rep.representation();
268 if (write_barrier_kind != kNoWriteBarrier) {
269 DCHECK(CanBeTaggedPointer(rep));
270 AddressingMode addressing_mode;
271 InstructionOperand inputs[3];
272 size_t input_count = 0;
273 inputs[input_count++] = g.UseUniqueRegister(base);
276 if (g.CanBeImmediate(offset, kInt16Imm)
277 #if V8_TARGET_ARCH_PPC64 278 && g.CanBeImmediate(offset, kInt16Imm_4ByteAligned)
281 inputs[input_count++] = g.UseImmediate(offset);
282 addressing_mode = kMode_MRI;
284 inputs[input_count++] = g.UseUniqueRegister(offset);
285 addressing_mode = kMode_MRR;
287 inputs[input_count++] = g.UseUniqueRegister(value);
288 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
289 switch (write_barrier_kind) {
290 case kNoWriteBarrier:
293 case kMapWriteBarrier:
294 record_write_mode = RecordWriteMode::kValueIsMap;
296 case kPointerWriteBarrier:
297 record_write_mode = RecordWriteMode::kValueIsPointer;
299 case kFullWriteBarrier:
300 record_write_mode = RecordWriteMode::kValueIsAny;
303 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
304 size_t const temp_count = arraysize(temps);
305 InstructionCode code = kArchStoreWithWriteBarrier;
306 code |= AddressingModeField::encode(addressing_mode);
307 code |= MiscField::encode(static_cast<int>(record_write_mode));
308 CHECK_EQ(is_atomic,
false);
309 Emit(code, 0,
nullptr, input_count, inputs, temp_count, temps);
311 ArchOpcode opcode = kArchNop;
312 ImmediateMode mode = kInt16Imm;
314 case MachineRepresentation::kFloat32:
315 opcode = kPPC_StoreFloat32;
317 case MachineRepresentation::kFloat64:
318 opcode = kPPC_StoreDouble;
320 case MachineRepresentation::kBit:
321 case MachineRepresentation::kWord8:
322 opcode = kPPC_StoreWord8;
324 case MachineRepresentation::kWord16:
325 opcode = kPPC_StoreWord16;
327 #if !V8_TARGET_ARCH_PPC64 328 case MachineRepresentation::kTaggedSigned:
329 case MachineRepresentation::kTaggedPointer:
330 case MachineRepresentation::kTagged:
332 case MachineRepresentation::kWord32:
333 opcode = kPPC_StoreWord32;
335 #if V8_TARGET_ARCH_PPC64 336 case MachineRepresentation::kTaggedSigned:
337 case MachineRepresentation::kTaggedPointer:
338 case MachineRepresentation::kTagged:
339 case MachineRepresentation::kWord64:
340 opcode = kPPC_StoreWord64;
341 mode = kInt16Imm_4ByteAligned;
344 case MachineRepresentation::kWord64:
346 case MachineRepresentation::kSimd128:
347 case MachineRepresentation::kNone:
352 if (g.CanBeImmediate(offset, mode)) {
353 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
354 g.UseRegister(base), g.UseImmediate(offset), g.UseRegister(value),
355 g.UseImmediate(is_atomic));
356 }
else if (g.CanBeImmediate(base, mode)) {
357 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
358 g.UseRegister(offset), g.UseImmediate(base), g.UseRegister(value),
359 g.UseImmediate(is_atomic));
361 Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(),
362 g.UseRegister(base), g.UseRegister(offset), g.UseRegister(value),
363 g.UseImmediate(is_atomic));
368 void InstructionSelector::VisitProtectedStore(Node* node) {
374 void InstructionSelector::VisitUnalignedLoad(Node* node) { UNREACHABLE(); }
377 void InstructionSelector::VisitUnalignedStore(Node* node) { UNREACHABLE(); }
379 template <
typename Matcher>
380 static void VisitLogical(InstructionSelector* selector, Node* node, Matcher* m,
381 ArchOpcode opcode,
bool left_can_cover,
382 bool right_can_cover, ImmediateMode imm_mode) {
383 PPCOperandGenerator g(selector);
386 ArchOpcode inv_opcode = opcode;
389 inv_opcode = kPPC_AndComplement;
392 inv_opcode = kPPC_OrComplement;
399 if ((m->left().IsWord32Xor() || m->left().IsWord64Xor()) && left_can_cover) {
400 Matcher mleft(m->left().node());
401 if (mleft.right().Is(-1)) {
402 selector->Emit(inv_opcode, g.DefineAsRegister(node),
403 g.UseRegister(m->right().node()),
404 g.UseRegister(mleft.left().node()));
410 if ((m->right().IsWord32Xor() || m->right().IsWord64Xor()) &&
412 Matcher mright(m->right().node());
413 if (mright.right().Is(-1)) {
415 selector->Emit(inv_opcode, g.DefineAsRegister(node),
416 g.UseRegister(m->left().node()),
417 g.UseRegister(mright.left().node()));
422 VisitBinop<Matcher>(selector, node, opcode, imm_mode);
425 static inline bool IsContiguousMask32(
uint32_t value,
int* mb,
int* me) {
426 int mask_width = base::bits::CountPopulation(value);
427 int mask_msb = base::bits::CountLeadingZeros32(value);
428 int mask_lsb = base::bits::CountTrailingZeros32(value);
429 if ((mask_width == 0) || (mask_msb + mask_width + mask_lsb != 32))
431 *mb = mask_lsb + mask_width - 1;
436 #if V8_TARGET_ARCH_PPC64 437 static inline bool IsContiguousMask64(uint64_t value,
int* mb,
int* me) {
438 int mask_width = base::bits::CountPopulation(value);
439 int mask_msb = base::bits::CountLeadingZeros64(value);
440 int mask_lsb = base::bits::CountTrailingZeros64(value);
441 if ((mask_width == 0) || (mask_msb + mask_width + mask_lsb != 64))
443 *mb = mask_lsb + mask_width - 1;
450 void InstructionSelector::VisitWord32And(Node* node) {
451 PPCOperandGenerator g(
this);
452 Int32BinopMatcher m(node);
455 if (m.right().HasValue() && IsContiguousMask32(m.right().Value(), &mb, &me)) {
457 Node* left = m.left().node();
458 if ((m.left().IsWord32Shr() || m.left().IsWord32Shl()) &&
459 CanCover(node, left)) {
461 Int32BinopMatcher mleft(m.left().node());
462 if (mleft.right().IsInRange(0, 31)) {
463 left = mleft.left().node();
464 sh = mleft.right().Value();
465 if (m.left().IsWord32Shr()) {
467 if (mb > 31 - sh) mb = 31 - sh;
468 sh = (32 - sh) & 0x1F;
471 if (me < sh) me = sh;
476 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), g.UseRegister(left),
477 g.TempImmediate(sh), g.TempImmediate(mb), g.TempImmediate(me));
481 VisitLogical<Int32BinopMatcher>(
482 this, node, &m, kPPC_And, CanCover(node, m.left().node()),
483 CanCover(node, m.right().node()), kInt16Imm_Unsigned);
486 #if V8_TARGET_ARCH_PPC64 488 void InstructionSelector::VisitWord64And(Node* node) {
489 PPCOperandGenerator g(
this);
490 Int64BinopMatcher m(node);
493 if (m.right().HasValue() && IsContiguousMask64(m.right().Value(), &mb, &me)) {
495 Node* left = m.left().node();
496 if ((m.left().IsWord64Shr() || m.left().IsWord64Shl()) &&
497 CanCover(node, left)) {
499 Int64BinopMatcher mleft(m.left().node());
500 if (mleft.right().IsInRange(0, 63)) {
501 left = mleft.left().node();
502 sh = mleft.right().Value();
503 if (m.left().IsWord64Shr()) {
505 if (mb > 63 - sh) mb = 63 - sh;
506 sh = (64 - sh) & 0x3F;
509 if (me < sh) me = sh;
519 opcode = kPPC_RotLeftAndClearLeft64;
521 }
else if (mb == 63) {
523 opcode = kPPC_RotLeftAndClearRight64;
525 }
else if (sh && me <= sh && m.left().IsWord64Shl()) {
527 opcode = kPPC_RotLeftAndClear64;
531 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left),
532 g.TempImmediate(sh), g.TempImmediate(mask));
537 VisitLogical<Int64BinopMatcher>(
538 this, node, &m, kPPC_And, CanCover(node, m.left().node()),
539 CanCover(node, m.right().node()), kInt16Imm_Unsigned);
543 void InstructionSelector::VisitWord32Or(Node* node) {
544 Int32BinopMatcher m(node);
545 VisitLogical<Int32BinopMatcher>(
546 this, node, &m, kPPC_Or, CanCover(node, m.left().node()),
547 CanCover(node, m.right().node()), kInt16Imm_Unsigned);
550 #if V8_TARGET_ARCH_PPC64 551 void InstructionSelector::VisitWord64Or(Node* node) {
552 Int64BinopMatcher m(node);
553 VisitLogical<Int64BinopMatcher>(
554 this, node, &m, kPPC_Or, CanCover(node, m.left().node()),
555 CanCover(node, m.right().node()), kInt16Imm_Unsigned);
559 void InstructionSelector::VisitWord32Xor(Node* node) {
560 PPCOperandGenerator g(
this);
561 Int32BinopMatcher m(node);
562 if (m.right().Is(-1)) {
563 Emit(kPPC_Not, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
565 VisitBinop<Int32BinopMatcher>(
this, node, kPPC_Xor, kInt16Imm_Unsigned);
569 #if V8_TARGET_ARCH_PPC64 570 void InstructionSelector::VisitWord64Xor(Node* node) {
571 PPCOperandGenerator g(
this);
572 Int64BinopMatcher m(node);
573 if (m.right().Is(-1)) {
574 Emit(kPPC_Not, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
576 VisitBinop<Int64BinopMatcher>(
this, node, kPPC_Xor, kInt16Imm_Unsigned);
581 void InstructionSelector::VisitWord32Shl(Node* node) {
582 PPCOperandGenerator g(
this);
583 Int32BinopMatcher m(node);
584 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) {
586 Int32BinopMatcher mleft(m.left().node());
587 int sh = m.right().Value();
590 if (mleft.right().HasValue() &&
591 IsContiguousMask32(mleft.right().Value() << sh, &mb, &me)) {
593 if (me < sh) me = sh;
595 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node),
596 g.UseRegister(mleft.left().node()), g.TempImmediate(sh),
597 g.TempImmediate(mb), g.TempImmediate(me));
602 VisitRRO(
this, kPPC_ShiftLeft32, node, kShift32Imm);
605 #if V8_TARGET_ARCH_PPC64 606 void InstructionSelector::VisitWord64Shl(Node* node) {
607 PPCOperandGenerator g(
this);
608 Int64BinopMatcher m(node);
610 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) {
612 Int64BinopMatcher mleft(m.left().node());
613 int sh = m.right().Value();
616 if (mleft.right().HasValue() &&
617 IsContiguousMask64(mleft.right().Value() << sh, &mb, &me)) {
619 if (me < sh) me = sh;
626 opcode = kPPC_RotLeftAndClearLeft64;
628 }
else if (mb == 63) {
630 opcode = kPPC_RotLeftAndClearRight64;
632 }
else if (sh && me <= sh) {
634 opcode = kPPC_RotLeftAndClear64;
638 Emit(opcode, g.DefineAsRegister(node),
639 g.UseRegister(mleft.left().node()), g.TempImmediate(sh),
640 g.TempImmediate(mask));
646 VisitRRO(
this, kPPC_ShiftLeft64, node, kShift64Imm);
650 void InstructionSelector::VisitWord32Shr(Node* node) {
651 PPCOperandGenerator g(
this);
652 Int32BinopMatcher m(node);
653 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) {
655 Int32BinopMatcher mleft(m.left().node());
656 int sh = m.right().Value();
659 if (mleft.right().HasValue() &&
660 IsContiguousMask32((
uint32_t)(mleft.right().Value()) >> sh, &mb, &me)) {
662 if (mb > 31 - sh) mb = 31 - sh;
663 sh = (32 - sh) & 0x1F;
665 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node),
666 g.UseRegister(mleft.left().node()), g.TempImmediate(sh),
667 g.TempImmediate(mb), g.TempImmediate(me));
672 VisitRRO(
this, kPPC_ShiftRight32, node, kShift32Imm);
675 #if V8_TARGET_ARCH_PPC64 676 void InstructionSelector::VisitWord64Shr(Node* node) {
677 PPCOperandGenerator g(
this);
678 Int64BinopMatcher m(node);
679 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) {
681 Int64BinopMatcher mleft(m.left().node());
682 int sh = m.right().Value();
685 if (mleft.right().HasValue() &&
686 IsContiguousMask64((uint64_t)(mleft.right().Value()) >> sh, &mb, &me)) {
688 if (mb > 63 - sh) mb = 63 - sh;
689 sh = (64 - sh) & 0x3F;
696 opcode = kPPC_RotLeftAndClearLeft64;
698 }
else if (mb == 63) {
700 opcode = kPPC_RotLeftAndClearRight64;
704 Emit(opcode, g.DefineAsRegister(node),
705 g.UseRegister(mleft.left().node()), g.TempImmediate(sh),
706 g.TempImmediate(mask));
712 VisitRRO(
this, kPPC_ShiftRight64, node, kShift64Imm);
716 void InstructionSelector::VisitWord32Sar(Node* node) {
717 PPCOperandGenerator g(
this);
718 Int32BinopMatcher m(node);
720 if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) {
721 Int32BinopMatcher mleft(m.left().node());
722 if (mleft.right().Is(16) && m.right().Is(16)) {
723 Emit(kPPC_ExtendSignWord16, g.DefineAsRegister(node),
724 g.UseRegister(mleft.left().node()));
726 }
else if (mleft.right().Is(24) && m.right().Is(24)) {
727 Emit(kPPC_ExtendSignWord8, g.DefineAsRegister(node),
728 g.UseRegister(mleft.left().node()));
732 VisitRRO(
this, kPPC_ShiftRightAlg32, node, kShift32Imm);
735 #if !V8_TARGET_ARCH_PPC64 736 void VisitPairBinop(InstructionSelector* selector, InstructionCode opcode,
737 InstructionCode opcode2, Node* node) {
738 PPCOperandGenerator g(selector);
740 Node* projection1 = NodeProperties::FindProjection(node, 1);
744 InstructionOperand inputs[] = {
745 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)),
746 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))};
748 InstructionOperand outputs[] = {
749 g.DefineAsRegister(node),
750 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))};
752 selector->Emit(opcode, 2, outputs, 4, inputs);
756 selector->Emit(opcode2, g.DefineSameAsFirst(node),
757 g.UseRegister(node->InputAt(0)),
758 g.UseRegister(node->InputAt(2)));
762 void InstructionSelector::VisitInt32PairAdd(Node* node) {
763 VisitPairBinop(
this, kPPC_AddPair, kPPC_Add32, node);
766 void InstructionSelector::VisitInt32PairSub(Node* node) {
767 VisitPairBinop(
this, kPPC_SubPair, kPPC_Sub, node);
770 void InstructionSelector::VisitInt32PairMul(Node* node) {
771 PPCOperandGenerator g(
this);
772 Node* projection1 = NodeProperties::FindProjection(node, 1);
774 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)),
775 g.UseUniqueRegister(node->InputAt(1)),
776 g.UseUniqueRegister(node->InputAt(2)),
777 g.UseUniqueRegister(node->InputAt(3))};
779 InstructionOperand outputs[] = {
780 g.DefineAsRegister(node),
781 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))};
783 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
785 Emit(kPPC_MulPair, 2, outputs, 4, inputs, 2, temps);
789 Emit(kPPC_Mul32, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)),
790 g.UseRegister(node->InputAt(2)));
796 void VisitPairShift(InstructionSelector* selector, InstructionCode opcode,
798 PPCOperandGenerator g(selector);
801 Int32Matcher m(node->InputAt(2));
802 InstructionOperand shift_operand;
804 shift_operand = g.UseImmediate(m.node());
806 shift_operand = g.UseUniqueRegister(m.node());
809 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)),
810 g.UseUniqueRegister(node->InputAt(1)),
813 Node* projection1 = NodeProperties::FindProjection(node, 1);
815 InstructionOperand outputs[2];
816 InstructionOperand temps[1];
817 int32_t output_count = 0;
818 int32_t temp_count = 0;
820 outputs[output_count++] = g.DefineAsRegister(node);
822 outputs[output_count++] = g.DefineAsRegister(projection1);
824 temps[temp_count++] = g.TempRegister();
827 selector->Emit(opcode, output_count, outputs, 3, inputs, temp_count, temps);
831 void InstructionSelector::VisitWord32PairShl(Node* node) {
832 VisitPairShift(
this, kPPC_ShiftLeftPair, node);
835 void InstructionSelector::VisitWord32PairShr(Node* node) {
836 VisitPairShift(
this, kPPC_ShiftRightPair, node);
839 void InstructionSelector::VisitWord32PairSar(Node* node) {
840 VisitPairShift(
this, kPPC_ShiftRightAlgPair, node);
844 #if V8_TARGET_ARCH_PPC64 845 void InstructionSelector::VisitWord64Sar(Node* node) {
846 PPCOperandGenerator g(
this);
847 Int64BinopMatcher m(node);
848 if (CanCover(m.node(), m.left().node()) && m.left().IsLoad() &&
852 BaseWithIndexAndDisplacement64Matcher mleft(m.left().node(),
853 AddressOption::kAllowAll);
854 if (mleft.matches() && mleft.index() ==
nullptr) {
856 Node* displacement = mleft.displacement();
857 if (displacement !=
nullptr) {
858 Int64Matcher mdisplacement(displacement);
859 DCHECK(mdisplacement.HasValue());
860 offset = mdisplacement.Value();
862 offset = SmiWordOffset(offset);
863 if (g.CanBeImmediate(offset, kInt16Imm_4ByteAligned)) {
864 Emit(kPPC_LoadWordS32 | AddressingModeField::encode(kMode_MRI),
865 g.DefineAsRegister(node), g.UseRegister(mleft.base()),
866 g.TempImmediate(offset), g.UseImmediate(0));
871 VisitRRO(
this, kPPC_ShiftRightAlg64, node, kShift64Imm);
876 void InstructionSelector::VisitWord32Ror(Node* node) {
877 VisitRRO(
this, kPPC_RotRight32, node, kShift32Imm);
880 #if V8_TARGET_ARCH_PPC64 882 void InstructionSelector::VisitWord64Ror(Node* node) {
883 VisitRRO(
this, kPPC_RotRight64, node, kShift64Imm);
887 void InstructionSelector::VisitWord32Clz(Node* node) {
888 PPCOperandGenerator g(
this);
889 Emit(kPPC_Cntlz32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
892 #if V8_TARGET_ARCH_PPC64 893 void InstructionSelector::VisitWord64Clz(Node* node) {
894 PPCOperandGenerator g(
this);
895 Emit(kPPC_Cntlz64, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
899 void InstructionSelector::VisitWord32Popcnt(Node* node) {
900 PPCOperandGenerator g(
this);
901 Emit(kPPC_Popcnt32, g.DefineAsRegister(node),
902 g.UseRegister(node->InputAt(0)));
905 #if V8_TARGET_ARCH_PPC64 906 void InstructionSelector::VisitWord64Popcnt(Node* node) {
907 PPCOperandGenerator g(
this);
908 Emit(kPPC_Popcnt64, g.DefineAsRegister(node),
909 g.UseRegister(node->InputAt(0)));
913 void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
915 #if V8_TARGET_ARCH_PPC64 916 void InstructionSelector::VisitWord64Ctz(Node* node) { UNREACHABLE(); }
919 void InstructionSelector::VisitWord32ReverseBits(Node* node) { UNREACHABLE(); }
921 #if V8_TARGET_ARCH_PPC64 922 void InstructionSelector::VisitWord64ReverseBits(Node* node) { UNREACHABLE(); }
925 void InstructionSelector::VisitWord64ReverseBytes(Node* node) {
926 PPCOperandGenerator g(
this);
927 InstructionOperand temp[] = {g.TempRegister()};
928 Emit(kPPC_ByteRev64, g.DefineAsRegister(node),
929 g.UseUniqueRegister(node->InputAt(0)), 1, temp);
932 void InstructionSelector::VisitWord32ReverseBytes(Node* node) {
933 PPCOperandGenerator g(
this);
934 Emit(kPPC_ByteRev32, g.DefineAsRegister(node),
935 g.UseRegister(node->InputAt(0)));
938 void InstructionSelector::VisitSpeculationFence(Node* node) { UNREACHABLE(); }
940 void InstructionSelector::VisitInt32Add(Node* node) {
941 VisitBinop<Int32BinopMatcher>(
this, node, kPPC_Add32, kInt16Imm);
944 #if V8_TARGET_ARCH_PPC64 945 void InstructionSelector::VisitInt64Add(Node* node) {
946 VisitBinop<Int64BinopMatcher>(
this, node, kPPC_Add64, kInt16Imm);
950 void InstructionSelector::VisitInt32Sub(Node* node) {
951 PPCOperandGenerator g(
this);
952 Int32BinopMatcher m(node);
953 if (m.left().Is(0)) {
954 Emit(kPPC_Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node()));
956 VisitBinop<Int32BinopMatcher>(
this, node, kPPC_Sub, kInt16Imm_Negate);
960 #if V8_TARGET_ARCH_PPC64 961 void InstructionSelector::VisitInt64Sub(Node* node) {
962 PPCOperandGenerator g(
this);
963 Int64BinopMatcher m(node);
964 if (m.left().Is(0)) {
965 Emit(kPPC_Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node()));
967 VisitBinop<Int64BinopMatcher>(
this, node, kPPC_Sub, kInt16Imm_Negate);
974 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
975 InstructionOperand left, InstructionOperand right,
976 FlagsContinuation* cont);
977 void EmitInt32MulWithOverflow(InstructionSelector* selector, Node* node,
978 FlagsContinuation* cont) {
979 PPCOperandGenerator g(selector);
980 Int32BinopMatcher m(node);
981 InstructionOperand result_operand = g.DefineAsRegister(node);
982 InstructionOperand high32_operand = g.TempRegister();
983 InstructionOperand temp_operand = g.TempRegister();
985 InstructionOperand outputs[] = {result_operand, high32_operand};
986 InstructionOperand inputs[] = {g.UseRegister(m.left().node()),
987 g.UseRegister(m.right().node())};
988 selector->Emit(kPPC_Mul32WithHigh32, 2, outputs, 2, inputs);
991 InstructionOperand shift_31 = g.UseImmediate(31);
992 InstructionOperand outputs[] = {temp_operand};
993 InstructionOperand inputs[] = {result_operand, shift_31};
994 selector->Emit(kPPC_ShiftRightAlg32, 1, outputs, 2, inputs);
997 VisitCompare(selector, kPPC_Cmp32, high32_operand, temp_operand, cont);
1002 void InstructionSelector::VisitInt32Mul(Node* node) {
1003 VisitRRR(
this, kPPC_Mul32, node);
1006 #if V8_TARGET_ARCH_PPC64 1007 void InstructionSelector::VisitInt64Mul(Node* node) {
1008 VisitRRR(
this, kPPC_Mul64, node);
1012 void InstructionSelector::VisitInt32MulHigh(Node* node) {
1013 PPCOperandGenerator g(
this);
1014 Emit(kPPC_MulHigh32, g.DefineAsRegister(node),
1015 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
1018 void InstructionSelector::VisitUint32MulHigh(Node* node) {
1019 PPCOperandGenerator g(
this);
1020 Emit(kPPC_MulHighU32, g.DefineAsRegister(node),
1021 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
1024 void InstructionSelector::VisitInt32Div(Node* node) {
1025 VisitRRR(
this, kPPC_Div32, node);
1028 #if V8_TARGET_ARCH_PPC64 1029 void InstructionSelector::VisitInt64Div(Node* node) {
1030 VisitRRR(
this, kPPC_Div64, node);
1034 void InstructionSelector::VisitUint32Div(Node* node) {
1035 VisitRRR(
this, kPPC_DivU32, node);
1038 #if V8_TARGET_ARCH_PPC64 1039 void InstructionSelector::VisitUint64Div(Node* node) {
1040 VisitRRR(
this, kPPC_DivU64, node);
1044 void InstructionSelector::VisitInt32Mod(Node* node) {
1045 VisitRRR(
this, kPPC_Mod32, node);
1048 #if V8_TARGET_ARCH_PPC64 1049 void InstructionSelector::VisitInt64Mod(Node* node) {
1050 VisitRRR(
this, kPPC_Mod64, node);
1054 void InstructionSelector::VisitUint32Mod(Node* node) {
1055 VisitRRR(
this, kPPC_ModU32, node);
1058 #if V8_TARGET_ARCH_PPC64 1059 void InstructionSelector::VisitUint64Mod(Node* node) {
1060 VisitRRR(
this, kPPC_ModU64, node);
1064 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
1065 VisitRR(
this, kPPC_Float32ToDouble, node);
1068 void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) {
1069 VisitRR(
this, kPPC_Int32ToFloat32, node);
1072 void InstructionSelector::VisitRoundUint32ToFloat32(Node* node) {
1073 VisitRR(
this, kPPC_Uint32ToFloat32, node);
1076 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
1077 VisitRR(
this, kPPC_Int32ToDouble, node);
1080 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
1081 VisitRR(
this, kPPC_Uint32ToDouble, node);
1084 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
1085 VisitRR(
this, kPPC_DoubleToInt32, node);
1088 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
1089 VisitRR(
this, kPPC_DoubleToUint32, node);
1092 void InstructionSelector::VisitTruncateFloat64ToUint32(Node* node) {
1093 VisitRR(
this, kPPC_DoubleToUint32, node);
1096 void InstructionSelector::VisitSignExtendWord8ToInt32(Node* node) {
1098 VisitRR(
this, kPPC_ExtendSignWord8, node);
1101 void InstructionSelector::VisitSignExtendWord16ToInt32(Node* node) {
1103 VisitRR(
this, kPPC_ExtendSignWord16, node);
1106 #if V8_TARGET_ARCH_PPC64 1107 void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
1108 VisitTryTruncateDouble(
this, kPPC_DoubleToInt64, node);
1111 void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
1112 VisitTryTruncateDouble(
this, kPPC_DoubleToInt64, node);
1115 void InstructionSelector::VisitTruncateFloat64ToInt64(Node* node) {
1116 VisitRR(
this, kPPC_DoubleToInt64, node);
1119 void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
1120 VisitTryTruncateDouble(
this, kPPC_DoubleToUint64, node);
1123 void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
1124 VisitTryTruncateDouble(
this, kPPC_DoubleToUint64, node);
1127 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
1129 VisitRR(
this, kPPC_ExtendSignWord32, node);
1132 void InstructionSelector::VisitSignExtendWord8ToInt64(Node* node) {
1134 VisitRR(
this, kPPC_ExtendSignWord8, node);
1137 void InstructionSelector::VisitSignExtendWord16ToInt64(Node* node) {
1139 VisitRR(
this, kPPC_ExtendSignWord16, node);
1142 void InstructionSelector::VisitSignExtendWord32ToInt64(Node* node) {
1144 VisitRR(
this, kPPC_ExtendSignWord32, node);
1147 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
1149 VisitRR(
this, kPPC_Uint32ToUint64, node);
1152 void InstructionSelector::VisitChangeFloat64ToUint64(Node* node) {
1153 VisitRR(
this, kPPC_DoubleToUint64, node);
1156 void InstructionSelector::VisitChangeFloat64ToInt64(Node* node) {
1157 VisitRR(
this, kPPC_DoubleToInt64, node);
1161 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
1162 VisitRR(
this, kPPC_DoubleToFloat32, node);
1165 void InstructionSelector::VisitTruncateFloat64ToWord32(Node* node) {
1166 VisitRR(
this, kArchTruncateDoubleToI, node);
1169 void InstructionSelector::VisitRoundFloat64ToInt32(Node* node) {
1170 VisitRR(
this, kPPC_DoubleToInt32, node);
1173 void InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) {
1174 VisitRR(
this, kPPC_DoubleToInt32, node);
1177 void InstructionSelector::VisitTruncateFloat32ToUint32(Node* node) {
1178 VisitRR(
this, kPPC_DoubleToUint32, node);
1181 #if V8_TARGET_ARCH_PPC64 1182 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
1184 VisitRR(
this, kPPC_Int64ToInt32, node);
1187 void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
1188 VisitRR(
this, kPPC_Int64ToFloat32, node);
1191 void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
1192 VisitRR(
this, kPPC_Int64ToDouble, node);
1195 void InstructionSelector::VisitChangeInt64ToFloat64(Node* node) {
1196 VisitRR(
this, kPPC_Int64ToDouble, node);
1199 void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
1200 VisitRR(
this, kPPC_Uint64ToFloat32, node);
1203 void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
1204 VisitRR(
this, kPPC_Uint64ToDouble, node);
1208 void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
1209 VisitRR(
this, kPPC_BitcastFloat32ToInt32, node);
1212 #if V8_TARGET_ARCH_PPC64 1213 void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
1214 VisitRR(
this, kPPC_BitcastDoubleToInt64, node);
1218 void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) {
1219 VisitRR(
this, kPPC_BitcastInt32ToFloat32, node);
1222 #if V8_TARGET_ARCH_PPC64 1223 void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
1224 VisitRR(
this, kPPC_BitcastInt64ToDouble, node);
1228 void InstructionSelector::VisitFloat32Add(Node* node) {
1229 VisitRRR(
this, kPPC_AddDouble | MiscField::encode(1), node);
1232 void InstructionSelector::VisitFloat64Add(Node* node) {
1234 VisitRRR(
this, kPPC_AddDouble, node);
1237 void InstructionSelector::VisitFloat32Sub(Node* node) {
1238 VisitRRR(
this, kPPC_SubDouble | MiscField::encode(1), node);
1241 void InstructionSelector::VisitFloat64Sub(Node* node) {
1243 VisitRRR(
this, kPPC_SubDouble, node);
1246 void InstructionSelector::VisitFloat32Mul(Node* node) {
1247 VisitRRR(
this, kPPC_MulDouble | MiscField::encode(1), node);
1250 void InstructionSelector::VisitFloat64Mul(Node* node) {
1252 VisitRRR(
this, kPPC_MulDouble, node);
1255 void InstructionSelector::VisitFloat32Div(Node* node) {
1256 VisitRRR(
this, kPPC_DivDouble | MiscField::encode(1), node);
1259 void InstructionSelector::VisitFloat64Div(Node* node) {
1260 VisitRRR(
this, kPPC_DivDouble, node);
1263 void InstructionSelector::VisitFloat64Mod(Node* node) {
1264 PPCOperandGenerator g(
this);
1265 Emit(kPPC_ModDouble, g.DefineAsFixed(node, d1),
1266 g.UseFixed(node->InputAt(0), d1), g.UseFixed(node->InputAt(1), d2))
1270 void InstructionSelector::VisitFloat32Max(Node* node) {
1271 VisitRRR(
this, kPPC_MaxDouble | MiscField::encode(1), node);
1274 void InstructionSelector::VisitFloat64Max(Node* node) {
1275 VisitRRR(
this, kPPC_MaxDouble, node);
1278 void InstructionSelector::VisitFloat64SilenceNaN(Node* node) {
1279 VisitRR(
this, kPPC_Float64SilenceNaN, node);
1282 void InstructionSelector::VisitFloat32Min(Node* node) {
1283 VisitRRR(
this, kPPC_MinDouble | MiscField::encode(1), node);
1286 void InstructionSelector::VisitFloat64Min(Node* node) {
1287 VisitRRR(
this, kPPC_MinDouble, node);
1290 void InstructionSelector::VisitFloat32Abs(Node* node) {
1291 VisitRR(
this, kPPC_AbsDouble | MiscField::encode(1), node);
1294 void InstructionSelector::VisitFloat64Abs(Node* node) {
1295 VisitRR(
this, kPPC_AbsDouble, node);
1298 void InstructionSelector::VisitFloat32Sqrt(Node* node) {
1299 VisitRR(
this, kPPC_SqrtDouble | MiscField::encode(1), node);
1302 void InstructionSelector::VisitFloat64Ieee754Unop(Node* node,
1303 InstructionCode opcode) {
1304 PPCOperandGenerator g(
this);
1305 Emit(opcode, g.DefineAsFixed(node, d1), g.UseFixed(node->InputAt(0), d1))
1309 void InstructionSelector::VisitFloat64Ieee754Binop(Node* node,
1310 InstructionCode opcode) {
1311 PPCOperandGenerator g(
this);
1312 Emit(opcode, g.DefineAsFixed(node, d1), g.UseFixed(node->InputAt(0), d1),
1313 g.UseFixed(node->InputAt(1), d2))
1317 void InstructionSelector::VisitFloat64Sqrt(Node* node) {
1318 VisitRR(
this, kPPC_SqrtDouble, node);
1321 void InstructionSelector::VisitFloat32RoundDown(Node* node) {
1322 VisitRR(
this, kPPC_FloorDouble | MiscField::encode(1), node);
1325 void InstructionSelector::VisitFloat64RoundDown(Node* node) {
1326 VisitRR(
this, kPPC_FloorDouble, node);
1329 void InstructionSelector::VisitFloat32RoundUp(Node* node) {
1330 VisitRR(
this, kPPC_CeilDouble | MiscField::encode(1), node);
1333 void InstructionSelector::VisitFloat64RoundUp(Node* node) {
1334 VisitRR(
this, kPPC_CeilDouble, node);
1337 void InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
1338 VisitRR(
this, kPPC_TruncateDouble | MiscField::encode(1), node);
1341 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
1342 VisitRR(
this, kPPC_TruncateDouble, node);
1345 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
1346 VisitRR(
this, kPPC_RoundDouble, node);
1349 void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) {
1353 void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
1357 void InstructionSelector::VisitFloat32Neg(Node* node) {
1358 VisitRR(
this, kPPC_NegDouble, node);
1361 void InstructionSelector::VisitFloat64Neg(Node* node) {
1362 VisitRR(
this, kPPC_NegDouble, node);
1365 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
1366 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1367 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1368 return VisitBinop<Int32BinopMatcher>(
this, node, kPPC_AddWithOverflow32,
1371 FlagsContinuation cont;
1372 VisitBinop<Int32BinopMatcher>(
this, node, kPPC_AddWithOverflow32, kInt16Imm,
1376 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
1377 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1378 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1379 return VisitBinop<Int32BinopMatcher>(
this, node, kPPC_SubWithOverflow32,
1380 kInt16Imm_Negate, &cont);
1382 FlagsContinuation cont;
1383 VisitBinop<Int32BinopMatcher>(
this, node, kPPC_SubWithOverflow32,
1384 kInt16Imm_Negate, &cont);
1387 #if V8_TARGET_ARCH_PPC64 1388 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
1389 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1390 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1391 return VisitBinop<Int64BinopMatcher>(
this, node, kPPC_Add64, kInt16Imm,
1394 FlagsContinuation cont;
1395 VisitBinop<Int64BinopMatcher>(
this, node, kPPC_Add64, kInt16Imm, &cont);
1398 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
1399 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1400 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1401 return VisitBinop<Int64BinopMatcher>(
this, node, kPPC_Sub, kInt16Imm_Negate,
1404 FlagsContinuation cont;
1405 VisitBinop<Int64BinopMatcher>(
this, node, kPPC_Sub, kInt16Imm_Negate, &cont);
1409 static bool CompareLogical(FlagsContinuation* cont) {
1410 switch (cont->condition()) {
1411 case kUnsignedLessThan:
1412 case kUnsignedGreaterThanOrEqual:
1413 case kUnsignedLessThanOrEqual:
1414 case kUnsignedGreaterThan:
1425 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1426 InstructionOperand left, InstructionOperand right,
1427 FlagsContinuation* cont) {
1428 selector->EmitWithContinuation(opcode, left, right, cont);
1432 void VisitWordCompare(InstructionSelector* selector, Node* node,
1433 InstructionCode opcode, FlagsContinuation* cont,
1434 bool commutative, ImmediateMode immediate_mode) {
1435 PPCOperandGenerator g(selector);
1436 Node* left = node->InputAt(0);
1437 Node* right = node->InputAt(1);
1440 if (g.CanBeImmediate(right, immediate_mode)) {
1441 VisitCompare(selector, opcode, g.UseRegisterOrStackPointer(left),
1442 g.UseImmediate(right), cont);
1443 }
else if (g.CanBeImmediate(left, immediate_mode)) {
1444 if (!commutative) cont->Commute();
1445 VisitCompare(selector, opcode, g.UseRegisterOrStackPointer(right),
1446 g.UseImmediate(left), cont);
1448 VisitCompare(selector, opcode, g.UseRegisterOrStackPointer(left),
1449 g.UseRegisterOrStackPointer(right), cont);
1453 void VisitWord32Compare(InstructionSelector* selector, Node* node,
1454 FlagsContinuation* cont) {
1455 ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm);
1456 VisitWordCompare(selector, node, kPPC_Cmp32, cont,
false, mode);
1459 #if V8_TARGET_ARCH_PPC64 1460 void VisitWord64Compare(InstructionSelector* selector, Node* node,
1461 FlagsContinuation* cont) {
1462 ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm);
1463 VisitWordCompare(selector, node, kPPC_Cmp64, cont,
false, mode);
1468 void VisitFloat32Compare(InstructionSelector* selector, Node* node,
1469 FlagsContinuation* cont) {
1470 PPCOperandGenerator g(selector);
1471 Node* left = node->InputAt(0);
1472 Node* right = node->InputAt(1);
1473 VisitCompare(selector, kPPC_CmpDouble, g.UseRegister(left),
1474 g.UseRegister(right), cont);
1478 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
1479 FlagsContinuation* cont) {
1480 PPCOperandGenerator g(selector);
1481 Node* left = node->InputAt(0);
1482 Node* right = node->InputAt(1);
1483 VisitCompare(selector, kPPC_CmpDouble, g.UseRegister(left),
1484 g.UseRegister(right), cont);
1490 void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
1491 FlagsContinuation* cont) {
1493 while (value->opcode() == IrOpcode::kWord32Equal && CanCover(user, value)) {
1494 Int32BinopMatcher m(value);
1495 if (!m.right().Is(0))
break;
1498 value = m.left().node();
1502 if (CanCover(user, value)) {
1503 switch (value->opcode()) {
1504 case IrOpcode::kWord32Equal:
1505 cont->OverwriteAndNegateIfEqual(kEqual);
1506 return VisitWord32Compare(
this, value, cont);
1507 case IrOpcode::kInt32LessThan:
1508 cont->OverwriteAndNegateIfEqual(kSignedLessThan);
1509 return VisitWord32Compare(
this, value, cont);
1510 case IrOpcode::kInt32LessThanOrEqual:
1511 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
1512 return VisitWord32Compare(
this, value, cont);
1513 case IrOpcode::kUint32LessThan:
1514 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1515 return VisitWord32Compare(
this, value, cont);
1516 case IrOpcode::kUint32LessThanOrEqual:
1517 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1518 return VisitWord32Compare(
this, value, cont);
1519 #if V8_TARGET_ARCH_PPC64 1520 case IrOpcode::kWord64Equal:
1521 cont->OverwriteAndNegateIfEqual(kEqual);
1522 return VisitWord64Compare(
this, value, cont);
1523 case IrOpcode::kInt64LessThan:
1524 cont->OverwriteAndNegateIfEqual(kSignedLessThan);
1525 return VisitWord64Compare(
this, value, cont);
1526 case IrOpcode::kInt64LessThanOrEqual:
1527 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
1528 return VisitWord64Compare(
this, value, cont);
1529 case IrOpcode::kUint64LessThan:
1530 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1531 return VisitWord64Compare(
this, value, cont);
1532 case IrOpcode::kUint64LessThanOrEqual:
1533 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1534 return VisitWord64Compare(
this, value, cont);
1536 case IrOpcode::kFloat32Equal:
1537 cont->OverwriteAndNegateIfEqual(kEqual);
1538 return VisitFloat32Compare(
this, value, cont);
1539 case IrOpcode::kFloat32LessThan:
1540 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1541 return VisitFloat32Compare(
this, value, cont);
1542 case IrOpcode::kFloat32LessThanOrEqual:
1543 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1544 return VisitFloat32Compare(
this, value, cont);
1545 case IrOpcode::kFloat64Equal:
1546 cont->OverwriteAndNegateIfEqual(kEqual);
1547 return VisitFloat64Compare(
this, value, cont);
1548 case IrOpcode::kFloat64LessThan:
1549 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1550 return VisitFloat64Compare(
this, value, cont);
1551 case IrOpcode::kFloat64LessThanOrEqual:
1552 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1553 return VisitFloat64Compare(
this, value, cont);
1554 case IrOpcode::kProjection:
1557 if (ProjectionIndexOf(value->op()) == 1u) {
1563 Node*
const node = value->InputAt(0);
1564 Node*
const result = NodeProperties::FindProjection(node, 0);
1565 if (result ==
nullptr || IsDefined(result)) {
1566 switch (node->opcode()) {
1567 case IrOpcode::kInt32AddWithOverflow:
1568 cont->OverwriteAndNegateIfEqual(kOverflow);
1569 return VisitBinop<Int32BinopMatcher>(
1570 this, node, kPPC_AddWithOverflow32, kInt16Imm, cont);
1571 case IrOpcode::kInt32SubWithOverflow:
1572 cont->OverwriteAndNegateIfEqual(kOverflow);
1573 return VisitBinop<Int32BinopMatcher>(
1574 this, node, kPPC_SubWithOverflow32, kInt16Imm_Negate, cont);
1575 case IrOpcode::kInt32MulWithOverflow:
1576 cont->OverwriteAndNegateIfEqual(kNotEqual);
1577 return EmitInt32MulWithOverflow(
this, node, cont);
1578 #if V8_TARGET_ARCH_PPC64 1579 case IrOpcode::kInt64AddWithOverflow:
1580 cont->OverwriteAndNegateIfEqual(kOverflow);
1581 return VisitBinop<Int64BinopMatcher>(
this, node, kPPC_Add64,
1583 case IrOpcode::kInt64SubWithOverflow:
1584 cont->OverwriteAndNegateIfEqual(kOverflow);
1585 return VisitBinop<Int64BinopMatcher>(
this, node, kPPC_Sub,
1586 kInt16Imm_Negate, cont);
1594 case IrOpcode::kInt32Sub:
1595 return VisitWord32Compare(
this, value, cont);
1596 case IrOpcode::kWord32And:
1598 return VisitWordCompare(
this, value, kPPC_Tst32, cont,
true,
1599 kInt16Imm_Unsigned);
1608 #if V8_TARGET_ARCH_PPC64 1609 case IrOpcode::kInt64Sub:
1610 return VisitWord64Compare(
this, value, cont);
1611 case IrOpcode::kWord64And:
1613 return VisitWordCompare(
this, value, kPPC_Tst64, cont,
true,
1614 kInt16Imm_Unsigned);
1630 PPCOperandGenerator g(
this);
1631 VisitCompare(
this, kPPC_Cmp32, g.UseRegister(value), g.TempImmediate(0),
1635 void InstructionSelector::VisitSwitch(Node* node,
const SwitchInfo& sw) {
1636 PPCOperandGenerator g(
this);
1637 InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
1640 if (enable_switch_jump_table_ == kEnableSwitchJumpTable) {
1641 static const size_t kMaxTableSwitchValueRange = 2 << 16;
1642 size_t table_space_cost = 4 + sw.value_range();
1643 size_t table_time_cost = 3;
1644 size_t lookup_space_cost = 3 + 2 * sw.case_count();
1645 size_t lookup_time_cost = sw.case_count();
1646 if (sw.case_count() > 0 &&
1647 table_space_cost + 3 * table_time_cost <=
1648 lookup_space_cost + 3 * lookup_time_cost &&
1649 sw.min_value() > std::numeric_limits<int32_t>::min() &&
1650 sw.value_range() <= kMaxTableSwitchValueRange) {
1651 InstructionOperand index_operand = value_operand;
1652 if (sw.min_value()) {
1653 index_operand = g.TempRegister();
1654 Emit(kPPC_Sub, index_operand, value_operand,
1655 g.TempImmediate(sw.min_value()));
1658 return EmitTableSwitch(sw, index_operand);
1663 return EmitBinarySearchSwitch(sw, value_operand);
1666 void InstructionSelector::VisitWord32Equal(Node*
const node) {
1667 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1668 VisitWord32Compare(
this, node, &cont);
1671 void InstructionSelector::VisitInt32LessThan(Node* node) {
1672 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
1673 VisitWord32Compare(
this, node, &cont);
1676 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
1677 FlagsContinuation cont =
1678 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
1679 VisitWord32Compare(
this, node, &cont);
1682 void InstructionSelector::VisitUint32LessThan(Node* node) {
1683 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
1684 VisitWord32Compare(
this, node, &cont);
1687 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
1688 FlagsContinuation cont =
1689 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
1690 VisitWord32Compare(
this, node, &cont);
1693 #if V8_TARGET_ARCH_PPC64 1694 void InstructionSelector::VisitWord64Equal(Node*
const node) {
1695 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1696 VisitWord64Compare(
this, node, &cont);
1699 void InstructionSelector::VisitInt64LessThan(Node* node) {
1700 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
1701 VisitWord64Compare(
this, node, &cont);
1704 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
1705 FlagsContinuation cont =
1706 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
1707 VisitWord64Compare(
this, node, &cont);
1710 void InstructionSelector::VisitUint64LessThan(Node* node) {
1711 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
1712 VisitWord64Compare(
this, node, &cont);
1715 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
1716 FlagsContinuation cont =
1717 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
1718 VisitWord64Compare(
this, node, &cont);
1722 void InstructionSelector::VisitInt32MulWithOverflow(Node* node) {
1723 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1724 FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf);
1725 return EmitInt32MulWithOverflow(
this, node, &cont);
1727 FlagsContinuation cont;
1728 EmitInt32MulWithOverflow(
this, node, &cont);
1731 void InstructionSelector::VisitFloat32Equal(Node* node) {
1732 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1733 VisitFloat32Compare(
this, node, &cont);
1736 void InstructionSelector::VisitFloat32LessThan(Node* node) {
1737 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
1738 VisitFloat32Compare(
this, node, &cont);
1741 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
1742 FlagsContinuation cont =
1743 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
1744 VisitFloat32Compare(
this, node, &cont);
1747 void InstructionSelector::VisitFloat64Equal(Node* node) {
1748 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1749 VisitFloat64Compare(
this, node, &cont);
1752 void InstructionSelector::VisitFloat64LessThan(Node* node) {
1753 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
1754 VisitFloat64Compare(
this, node, &cont);
1757 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
1758 FlagsContinuation cont =
1759 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
1760 VisitFloat64Compare(
this, node, &cont);
1763 void InstructionSelector::EmitPrepareArguments(
1764 ZoneVector<PushParameter>* arguments,
const CallDescriptor* call_descriptor,
1766 PPCOperandGenerator g(
this);
1769 if (call_descriptor->IsCFunctionCall()) {
1770 Emit(kArchPrepareCallCFunction | MiscField::encode(static_cast<int>(
1771 call_descriptor->ParameterCount())),
1772 0,
nullptr, 0,
nullptr);
1775 int slot = kStackFrameExtraParamSlot;
1776 for (PushParameter input : (*arguments)) {
1777 if (input.node ==
nullptr)
continue;
1778 Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node),
1779 g.TempImmediate(slot));
1784 for (PushParameter input : base::Reversed(*arguments)) {
1786 if (input.node ==
nullptr)
continue;
1787 Emit(kPPC_Push, g.NoOutput(), g.UseRegister(input.node));
1792 bool InstructionSelector::IsTailCallAddressImmediate() {
return false; }
1794 int InstructionSelector::GetTempsCountForTailCallFromJSFunction() {
return 3; }
1796 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
1797 PPCOperandGenerator g(
this);
1798 Emit(kPPC_DoubleExtractLowWord32, g.DefineAsRegister(node),
1799 g.UseRegister(node->InputAt(0)));
1802 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
1803 PPCOperandGenerator g(
this);
1804 Emit(kPPC_DoubleExtractHighWord32, g.DefineAsRegister(node),
1805 g.UseRegister(node->InputAt(0)));
1808 void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
1809 PPCOperandGenerator g(
this);
1810 Node* left = node->InputAt(0);
1811 Node* right = node->InputAt(1);
1812 if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 &&
1813 CanCover(node, left)) {
1814 left = left->InputAt(1);
1815 Emit(kPPC_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(left),
1816 g.UseRegister(right));
1819 Emit(kPPC_DoubleInsertLowWord32, g.DefineSameAsFirst(node),
1820 g.UseRegister(left), g.UseRegister(right));
1823 void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
1824 PPCOperandGenerator g(
this);
1825 Node* left = node->InputAt(0);
1826 Node* right = node->InputAt(1);
1827 if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 &&
1828 CanCover(node, left)) {
1829 left = left->InputAt(1);
1830 Emit(kPPC_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(right),
1831 g.UseRegister(left));
1834 Emit(kPPC_DoubleInsertHighWord32, g.DefineSameAsFirst(node),
1835 g.UseRegister(left), g.UseRegister(right));
1838 void InstructionSelector::VisitWord32AtomicLoad(Node* node) { VisitLoad(node); }
1840 void InstructionSelector::VisitWord64AtomicLoad(Node* node) { VisitLoad(node); }
1842 void InstructionSelector::VisitWord32AtomicStore(Node* node) {
1846 void InstructionSelector::VisitWord64AtomicStore(Node* node) {
1850 void VisitAtomicExchange(InstructionSelector* selector, Node* node,
1851 ArchOpcode opcode) {
1852 PPCOperandGenerator g(selector);
1853 Node* base = node->InputAt(0);
1854 Node* index = node->InputAt(1);
1855 Node* value = node->InputAt(2);
1857 AddressingMode addressing_mode = kMode_MRR;
1858 InstructionOperand inputs[3];
1859 size_t input_count = 0;
1860 inputs[input_count++] = g.UseUniqueRegister(base);
1861 inputs[input_count++] = g.UseUniqueRegister(index);
1862 inputs[input_count++] = g.UseUniqueRegister(value);
1863 InstructionOperand outputs[1];
1864 outputs[0] = g.UseUniqueRegister(node);
1865 InstructionCode code = opcode | AddressingModeField::encode(addressing_mode);
1866 selector->Emit(code, 1, outputs, input_count, inputs);
1869 void InstructionSelector::VisitWord32AtomicExchange(Node* node) {
1870 ArchOpcode opcode = kArchNop;
1871 MachineType type = AtomicOpType(node->op());
1872 if (type == MachineType::Int8()) {
1873 opcode = kWord32AtomicExchangeInt8;
1874 }
else if (type == MachineType::Uint8()) {
1875 opcode = kPPC_AtomicExchangeUint8;
1876 }
else if (type == MachineType::Int16()) {
1877 opcode = kWord32AtomicExchangeInt16;
1878 }
else if (type == MachineType::Uint16()) {
1879 opcode = kPPC_AtomicExchangeUint16;
1880 }
else if (type == MachineType::Int32() || type == MachineType::Uint32()) {
1881 opcode = kPPC_AtomicExchangeWord32;
1886 VisitAtomicExchange(
this, node, opcode);
1889 void InstructionSelector::VisitWord64AtomicExchange(Node* node) {
1890 ArchOpcode opcode = kArchNop;
1891 MachineType type = AtomicOpType(node->op());
1892 if (type == MachineType::Uint8()) {
1893 opcode = kPPC_AtomicExchangeUint8;
1894 }
else if (type == MachineType::Uint16()) {
1895 opcode = kPPC_AtomicExchangeUint16;
1896 }
else if (type == MachineType::Uint32()) {
1897 opcode = kPPC_AtomicExchangeWord32;
1898 }
else if (type == MachineType::Uint64()) {
1899 opcode = kPPC_AtomicExchangeWord64;
1904 VisitAtomicExchange(
this, node, opcode);
1907 void VisitAtomicCompareExchange(InstructionSelector* selector, Node* node,
1908 ArchOpcode opcode) {
1909 PPCOperandGenerator g(selector);
1910 Node* base = node->InputAt(0);
1911 Node* index = node->InputAt(1);
1912 Node* old_value = node->InputAt(2);
1913 Node* new_value = node->InputAt(3);
1915 AddressingMode addressing_mode = kMode_MRR;
1916 InstructionCode code = opcode | AddressingModeField::encode(addressing_mode);
1918 InstructionOperand inputs[4];
1919 size_t input_count = 0;
1920 inputs[input_count++] = g.UseUniqueRegister(base);
1921 inputs[input_count++] = g.UseUniqueRegister(index);
1922 inputs[input_count++] = g.UseUniqueRegister(old_value);
1923 inputs[input_count++] = g.UseUniqueRegister(new_value);
1925 InstructionOperand outputs[1];
1926 size_t output_count = 0;
1927 outputs[output_count++] = g.DefineAsRegister(node);
1929 selector->Emit(code, output_count, outputs, input_count, inputs);
1932 void InstructionSelector::VisitWord32AtomicCompareExchange(Node* node) {
1933 MachineType type = AtomicOpType(node->op());
1934 ArchOpcode opcode = kArchNop;
1935 if (type == MachineType::Int8()) {
1936 opcode = kWord32AtomicCompareExchangeInt8;
1937 }
else if (type == MachineType::Uint8()) {
1938 opcode = kPPC_AtomicCompareExchangeUint8;
1939 }
else if (type == MachineType::Int16()) {
1940 opcode = kWord32AtomicCompareExchangeInt16;
1941 }
else if (type == MachineType::Uint16()) {
1942 opcode = kPPC_AtomicCompareExchangeUint16;
1943 }
else if (type == MachineType::Int32() || type == MachineType::Uint32()) {
1944 opcode = kPPC_AtomicCompareExchangeWord32;
1949 VisitAtomicCompareExchange(
this, node, opcode);
1952 void InstructionSelector::VisitWord64AtomicCompareExchange(Node* node) {
1953 MachineType type = AtomicOpType(node->op());
1954 ArchOpcode opcode = kArchNop;
1955 if (type == MachineType::Uint8()) {
1956 opcode = kPPC_AtomicCompareExchangeUint8;
1957 }
else if (type == MachineType::Uint16()) {
1958 opcode = kPPC_AtomicCompareExchangeUint16;
1959 }
else if (type == MachineType::Uint32()) {
1960 opcode = kPPC_AtomicCompareExchangeWord32;
1961 }
else if (type == MachineType::Uint64()) {
1962 opcode = kPPC_AtomicCompareExchangeWord64;
1967 VisitAtomicCompareExchange(
this, node, opcode);
1970 void VisitAtomicBinaryOperation(InstructionSelector* selector, Node* node,
1971 ArchOpcode int8_op, ArchOpcode uint8_op,
1972 ArchOpcode int16_op, ArchOpcode uint16_op,
1973 ArchOpcode int32_op, ArchOpcode uint32_op,
1974 ArchOpcode int64_op, ArchOpcode uint64_op) {
1975 PPCOperandGenerator g(selector);
1976 Node* base = node->InputAt(0);
1977 Node* index = node->InputAt(1);
1978 Node* value = node->InputAt(2);
1979 MachineType type = AtomicOpType(node->op());
1981 ArchOpcode opcode = kArchNop;
1983 if (type == MachineType::Int8()) {
1985 }
else if (type == MachineType::Uint8()) {
1987 }
else if (type == MachineType::Int16()) {
1989 }
else if (type == MachineType::Uint16()) {
1991 }
else if (type == MachineType::Int32()) {
1993 }
else if (type == MachineType::Uint32()) {
1995 }
else if (type == MachineType::Int64()) {
1997 }
else if (type == MachineType::Uint64()) {
2004 AddressingMode addressing_mode = kMode_MRR;
2005 InstructionCode code = opcode | AddressingModeField::encode(addressing_mode);
2006 InstructionOperand inputs[3];
2008 size_t input_count = 0;
2009 inputs[input_count++] = g.UseUniqueRegister(base);
2010 inputs[input_count++] = g.UseUniqueRegister(index);
2011 inputs[input_count++] = g.UseUniqueRegister(value);
2013 InstructionOperand outputs[1];
2014 size_t output_count = 0;
2015 outputs[output_count++] = g.DefineAsRegister(node);
2017 selector->Emit(code, output_count, outputs, input_count, inputs);
2020 void InstructionSelector::VisitWord32AtomicBinaryOperation(
2021 Node* node, ArchOpcode int8_op, ArchOpcode uint8_op, ArchOpcode int16_op,
2022 ArchOpcode uint16_op, ArchOpcode word32_op) {
2027 void InstructionSelector::VisitWord64AtomicBinaryOperation(
2028 Node* node, ArchOpcode uint8_op, ArchOpcode uint16_op, ArchOpcode uint32_op,
2029 ArchOpcode uint64_op) {
2034 #define VISIT_ATOMIC_BINOP(op) \ 2035 void InstructionSelector::VisitWord32Atomic##op(Node* node) { \ 2036 VisitAtomicBinaryOperation( \ 2037 this, node, kPPC_Atomic##op##Int8, kPPC_Atomic##op##Uint8, \ 2038 kPPC_Atomic##op##Int16, kPPC_Atomic##op##Uint16, \ 2039 kPPC_Atomic##op##Int32, kPPC_Atomic##op##Uint32, \ 2040 kPPC_Atomic##op##Int64, kPPC_Atomic##op##Uint64); \ 2042 void InstructionSelector::VisitWord64Atomic##op(Node* node) { \ 2043 VisitAtomicBinaryOperation( \ 2044 this, node, kPPC_Atomic##op##Int8, kPPC_Atomic##op##Uint8, \ 2045 kPPC_Atomic##op##Int16, kPPC_Atomic##op##Uint16, \ 2046 kPPC_Atomic##op##Int32, kPPC_Atomic##op##Uint32, \ 2047 kPPC_Atomic##op##Int64, kPPC_Atomic##op##Uint64); \ 2049 VISIT_ATOMIC_BINOP(Add)
2050 VISIT_ATOMIC_BINOP(Sub)
2051 VISIT_ATOMIC_BINOP(And)
2052 VISIT_ATOMIC_BINOP(Or)
2053 VISIT_ATOMIC_BINOP(Xor)
2054 #undef VISIT_ATOMIC_BINOP 2056 void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
2060 void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
2064 void InstructionSelector::VisitI32x4Splat(Node* node) { UNIMPLEMENTED(); }
2066 void InstructionSelector::VisitI32x4ExtractLane(Node* node) { UNIMPLEMENTED(); }
2068 void InstructionSelector::VisitI32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2070 void InstructionSelector::VisitI32x4Add(Node* node) { UNIMPLEMENTED(); }
2072 void InstructionSelector::VisitI32x4Sub(Node* node) { UNIMPLEMENTED(); }
2074 void InstructionSelector::VisitI32x4Shl(Node* node) { UNIMPLEMENTED(); }
2076 void InstructionSelector::VisitI32x4ShrS(Node* node) { UNIMPLEMENTED(); }
2078 void InstructionSelector::VisitI32x4Mul(Node* node) { UNIMPLEMENTED(); }
2080 void InstructionSelector::VisitI32x4MaxS(Node* node) { UNIMPLEMENTED(); }
2082 void InstructionSelector::VisitI32x4MinS(Node* node) { UNIMPLEMENTED(); }
2084 void InstructionSelector::VisitI32x4Eq(Node* node) { UNIMPLEMENTED(); }
2086 void InstructionSelector::VisitI32x4Ne(Node* node) { UNIMPLEMENTED(); }
2088 void InstructionSelector::VisitI32x4MinU(Node* node) { UNIMPLEMENTED(); }
2090 void InstructionSelector::VisitI32x4MaxU(Node* node) { UNIMPLEMENTED(); }
2092 void InstructionSelector::VisitI32x4ShrU(Node* node) { UNIMPLEMENTED(); }
2094 void InstructionSelector::VisitI32x4Neg(Node* node) { UNIMPLEMENTED(); }
2096 void InstructionSelector::VisitI32x4GtS(Node* node) { UNIMPLEMENTED(); }
2098 void InstructionSelector::VisitI32x4GeS(Node* node) { UNIMPLEMENTED(); }
2100 void InstructionSelector::VisitI32x4GtU(Node* node) { UNIMPLEMENTED(); }
2102 void InstructionSelector::VisitI32x4GeU(Node* node) { UNIMPLEMENTED(); }
2104 void InstructionSelector::VisitI16x8Splat(Node* node) { UNIMPLEMENTED(); }
2106 void InstructionSelector::VisitI16x8ExtractLane(Node* node) { UNIMPLEMENTED(); }
2108 void InstructionSelector::VisitI16x8ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2110 void InstructionSelector::VisitI16x8Shl(Node* node) { UNIMPLEMENTED(); }
2112 void InstructionSelector::VisitI16x8ShrS(Node* node) { UNIMPLEMENTED(); }
2114 void InstructionSelector::VisitI16x8ShrU(Node* node) { UNIMPLEMENTED(); }
2116 void InstructionSelector::VisitI16x8Add(Node* node) { UNIMPLEMENTED(); }
2118 void InstructionSelector::VisitI16x8AddSaturateS(Node* node) {
2122 void InstructionSelector::VisitI16x8Sub(Node* node) { UNIMPLEMENTED(); }
2124 void InstructionSelector::VisitI16x8SubSaturateS(Node* node) {
2128 void InstructionSelector::VisitI16x8Mul(Node* node) { UNIMPLEMENTED(); }
2130 void InstructionSelector::VisitI16x8MinS(Node* node) { UNIMPLEMENTED(); }
2132 void InstructionSelector::VisitI16x8MaxS(Node* node) { UNIMPLEMENTED(); }
2134 void InstructionSelector::VisitI16x8Eq(Node* node) { UNIMPLEMENTED(); }
2136 void InstructionSelector::VisitI16x8Ne(Node* node) { UNIMPLEMENTED(); }
2138 void InstructionSelector::VisitI16x8AddSaturateU(Node* node) {
2142 void InstructionSelector::VisitI16x8SubSaturateU(Node* node) {
2146 void InstructionSelector::VisitI16x8MinU(Node* node) { UNIMPLEMENTED(); }
2148 void InstructionSelector::VisitI16x8MaxU(Node* node) { UNIMPLEMENTED(); }
2150 void InstructionSelector::VisitI16x8Neg(Node* node) { UNIMPLEMENTED(); }
2152 void InstructionSelector::VisitI16x8GtS(Node* node) { UNIMPLEMENTED(); }
2154 void InstructionSelector::VisitI16x8GeS(Node* node) { UNIMPLEMENTED(); }
2156 void InstructionSelector::VisitI16x8GtU(Node* node) { UNIMPLEMENTED(); }
2158 void InstructionSelector::VisitI16x8GeU(Node* node) { UNIMPLEMENTED(); }
2160 void InstructionSelector::VisitI8x16Neg(Node* node) { UNIMPLEMENTED(); }
2162 void InstructionSelector::VisitI8x16Splat(Node* node) { UNIMPLEMENTED(); }
2164 void InstructionSelector::VisitI8x16ExtractLane(Node* node) { UNIMPLEMENTED(); }
2166 void InstructionSelector::VisitI8x16ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2168 void InstructionSelector::VisitI8x16Add(Node* node) { UNIMPLEMENTED(); }
2170 void InstructionSelector::VisitI8x16AddSaturateS(Node* node) {
2174 void InstructionSelector::VisitI8x16Sub(Node* node) { UNIMPLEMENTED(); }
2176 void InstructionSelector::VisitI8x16SubSaturateS(Node* node) {
2180 void InstructionSelector::VisitI8x16MinS(Node* node) { UNIMPLEMENTED(); }
2182 void InstructionSelector::VisitI8x16MaxS(Node* node) { UNIMPLEMENTED(); }
2184 void InstructionSelector::VisitI8x16Eq(Node* node) { UNIMPLEMENTED(); }
2186 void InstructionSelector::VisitI8x16Ne(Node* node) { UNIMPLEMENTED(); }
2188 void InstructionSelector::VisitI8x16GtS(Node* node) { UNIMPLEMENTED(); }
2190 void InstructionSelector::VisitI8x16GeS(Node* node) { UNIMPLEMENTED(); }
2192 void InstructionSelector::VisitI8x16AddSaturateU(Node* node) {
2196 void InstructionSelector::VisitI8x16SubSaturateU(Node* node) {
2200 void InstructionSelector::VisitI8x16MinU(Node* node) { UNIMPLEMENTED(); }
2202 void InstructionSelector::VisitI8x16MaxU(Node* node) { UNIMPLEMENTED(); }
2204 void InstructionSelector::VisitI8x16GtU(Node* node) { UNIMPLEMENTED(); }
2206 void InstructionSelector::VisitI8x16GeU(Node* node) { UNIMPLEMENTED(); }
2208 void InstructionSelector::VisitS128And(Node* node) { UNIMPLEMENTED(); }
2210 void InstructionSelector::VisitS128Or(Node* node) { UNIMPLEMENTED(); }
2212 void InstructionSelector::VisitS128Xor(Node* node) { UNIMPLEMENTED(); }
2214 void InstructionSelector::VisitS128Not(Node* node) { UNIMPLEMENTED(); }
2216 void InstructionSelector::VisitS128Zero(Node* node) { UNIMPLEMENTED(); }
2218 void InstructionSelector::VisitF32x4Eq(Node* node) { UNIMPLEMENTED(); }
2220 void InstructionSelector::VisitF32x4Ne(Node* node) { UNIMPLEMENTED(); }
2222 void InstructionSelector::VisitF32x4Lt(Node* node) { UNIMPLEMENTED(); }
2224 void InstructionSelector::VisitF32x4Le(Node* node) { UNIMPLEMENTED(); }
2226 void InstructionSelector::VisitF32x4Splat(Node* node) { UNIMPLEMENTED(); }
2228 void InstructionSelector::VisitF32x4ExtractLane(Node* node) { UNIMPLEMENTED(); }
2230 void InstructionSelector::VisitF32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2232 void InstructionSelector::EmitPrepareResults(
2233 ZoneVector<PushParameter>* results,
const CallDescriptor* call_descriptor,
2238 void InstructionSelector::VisitF32x4Add(Node* node) { UNIMPLEMENTED(); }
2240 void InstructionSelector::VisitF32x4Sub(Node* node) { UNIMPLEMENTED(); }
2242 void InstructionSelector::VisitF32x4Mul(Node* node) { UNIMPLEMENTED(); }
2244 void InstructionSelector::VisitF32x4Min(Node* node) { UNIMPLEMENTED(); }
2246 void InstructionSelector::VisitF32x4Max(Node* node) { UNIMPLEMENTED(); }
2248 void InstructionSelector::VisitS128Select(Node* node) { UNIMPLEMENTED(); }
2250 void InstructionSelector::VisitF32x4Neg(Node* node) { UNIMPLEMENTED(); }
2252 void InstructionSelector::VisitF32x4Abs(Node* node) { UNIMPLEMENTED(); }
2254 void InstructionSelector::VisitF32x4RecipSqrtApprox(Node* node) {
2258 void InstructionSelector::VisitF32x4RecipApprox(Node* node) { UNIMPLEMENTED(); }
2260 void InstructionSelector::VisitF32x4AddHoriz(Node* node) { UNIMPLEMENTED(); }
2261 void InstructionSelector::VisitI32x4AddHoriz(Node* node) { UNIMPLEMENTED(); }
2262 void InstructionSelector::VisitI16x8AddHoriz(Node* node) { UNIMPLEMENTED(); }
2264 void InstructionSelector::VisitF32x4SConvertI32x4(Node* node) {
2268 void InstructionSelector::VisitF32x4UConvertI32x4(Node* node) {
2272 void InstructionSelector::VisitI32x4SConvertF32x4(Node* node) {
2276 void InstructionSelector::VisitI32x4UConvertF32x4(Node* node) {
2280 void InstructionSelector::VisitI32x4SConvertI16x8Low(Node* node) {
2284 void InstructionSelector::VisitI32x4SConvertI16x8High(Node* node) {
2288 void InstructionSelector::VisitI32x4UConvertI16x8Low(Node* node) {
2292 void InstructionSelector::VisitI32x4UConvertI16x8High(Node* node) {
2296 void InstructionSelector::VisitI16x8SConvertI8x16Low(Node* node) {
2300 void InstructionSelector::VisitI16x8SConvertI8x16High(Node* node) {
2304 void InstructionSelector::VisitI16x8UConvertI8x16Low(Node* node) {
2308 void InstructionSelector::VisitI16x8UConvertI8x16High(Node* node) {
2312 void InstructionSelector::VisitI16x8SConvertI32x4(Node* node) {
2315 void InstructionSelector::VisitI16x8UConvertI32x4(Node* node) {
2319 void InstructionSelector::VisitI8x16SConvertI16x8(Node* node) {
2323 void InstructionSelector::VisitI8x16UConvertI16x8(Node* node) {
2327 void InstructionSelector::VisitS1x4AnyTrue(Node* node) { UNIMPLEMENTED(); }
2329 void InstructionSelector::VisitS1x4AllTrue(Node* node) { UNIMPLEMENTED(); }
2331 void InstructionSelector::VisitS1x8AnyTrue(Node* node) { UNIMPLEMENTED(); }
2333 void InstructionSelector::VisitS1x8AllTrue(Node* node) { UNIMPLEMENTED(); }
2335 void InstructionSelector::VisitS1x16AnyTrue(Node* node) { UNIMPLEMENTED(); }
2337 void InstructionSelector::VisitS1x16AllTrue(Node* node) { UNIMPLEMENTED(); }
2339 void InstructionSelector::VisitI8x16Shl(Node* node) { UNIMPLEMENTED(); }
2341 void InstructionSelector::VisitI8x16ShrS(Node* node) { UNIMPLEMENTED(); }
2343 void InstructionSelector::VisitI8x16ShrU(Node* node) { UNIMPLEMENTED(); }
2345 void InstructionSelector::VisitI8x16Mul(Node* node) { UNIMPLEMENTED(); }
2348 MachineOperatorBuilder::Flags
2349 InstructionSelector::SupportedMachineOperatorFlags() {
2350 return MachineOperatorBuilder::kFloat32RoundDown |
2351 MachineOperatorBuilder::kFloat64RoundDown |
2352 MachineOperatorBuilder::kFloat32RoundUp |
2353 MachineOperatorBuilder::kFloat64RoundUp |
2354 MachineOperatorBuilder::kFloat32RoundTruncate |
2355 MachineOperatorBuilder::kFloat64RoundTruncate |
2356 MachineOperatorBuilder::kFloat64RoundTiesAway |
2357 MachineOperatorBuilder::kWord32Popcnt |
2358 MachineOperatorBuilder::kWord64Popcnt;
2363 MachineOperatorBuilder::AlignmentRequirements
2364 InstructionSelector::AlignmentRequirements() {
2365 return MachineOperatorBuilder::AlignmentRequirements::
2366 FullUnalignedAccessSupport();