• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "src/compiler/backend/instruction-selector.h"
6 
7 #include <limits>
8 
9 #include "src/base/iterator.h"
10 #include "src/codegen/assembler-inl.h"
11 #include "src/codegen/tick-counter.h"
12 #include "src/compiler/backend/instruction-selector-impl.h"
13 #include "src/compiler/compiler-source-position-table.h"
14 #include "src/compiler/js-heap-broker.h"
15 #include "src/compiler/node-matchers.h"
16 #include "src/compiler/node-properties.h"
17 #include "src/compiler/pipeline.h"
18 #include "src/compiler/schedule.h"
19 #include "src/compiler/state-values-utils.h"
20 #include "src/deoptimizer/deoptimizer.h"
21 #include "src/wasm/simd-shuffle.h"
22 
23 namespace v8 {
24 namespace internal {
25 namespace compiler {
26 
InstructionSelector(Zone * zone,size_t node_count,Linkage * linkage,InstructionSequence * sequence,Schedule * schedule,SourcePositionTable * source_positions,Frame * frame,EnableSwitchJumpTable enable_switch_jump_table,TickCounter * tick_counter,JSHeapBroker * broker,size_t * max_unoptimized_frame_height,size_t * max_pushed_argument_count,SourcePositionMode source_position_mode,Features features,EnableScheduling enable_scheduling,EnableRootsRelativeAddressing enable_roots_relative_addressing,PoisoningMitigationLevel poisoning_level,EnableTraceTurboJson trace_turbo)27 InstructionSelector::InstructionSelector(
28     Zone* zone, size_t node_count, Linkage* linkage,
29     InstructionSequence* sequence, Schedule* schedule,
30     SourcePositionTable* source_positions, Frame* frame,
31     EnableSwitchJumpTable enable_switch_jump_table, TickCounter* tick_counter,
32     JSHeapBroker* broker, size_t* max_unoptimized_frame_height,
33     size_t* max_pushed_argument_count, SourcePositionMode source_position_mode,
34     Features features, EnableScheduling enable_scheduling,
35     EnableRootsRelativeAddressing enable_roots_relative_addressing,
36     PoisoningMitigationLevel poisoning_level, EnableTraceTurboJson trace_turbo)
37     : zone_(zone),
38       linkage_(linkage),
39       sequence_(sequence),
40       source_positions_(source_positions),
41       source_position_mode_(source_position_mode),
42       features_(features),
43       schedule_(schedule),
44       current_block_(nullptr),
45       instructions_(zone),
46       continuation_inputs_(sequence->zone()),
47       continuation_outputs_(sequence->zone()),
48       continuation_temps_(sequence->zone()),
49       defined_(node_count, false, zone),
50       used_(node_count, false, zone),
51       effect_level_(node_count, 0, zone),
52       virtual_registers_(node_count,
53                          InstructionOperand::kInvalidVirtualRegister, zone),
54       virtual_register_rename_(zone),
55       scheduler_(nullptr),
56       enable_scheduling_(enable_scheduling),
57       enable_roots_relative_addressing_(enable_roots_relative_addressing),
58       enable_switch_jump_table_(enable_switch_jump_table),
59       poisoning_level_(poisoning_level),
60       frame_(frame),
61       instruction_selection_failed_(false),
62       instr_origins_(sequence->zone()),
63       trace_turbo_(trace_turbo),
64       tick_counter_(tick_counter),
65       broker_(broker),
66       max_unoptimized_frame_height_(max_unoptimized_frame_height),
67       max_pushed_argument_count_(max_pushed_argument_count)
68 #if V8_TARGET_ARCH_64_BIT
69       ,
70       phi_states_(node_count, Upper32BitsState::kNotYetChecked, zone)
71 #endif
72 {
73   DCHECK_EQ(*max_unoptimized_frame_height, 0);  // Caller-initialized.
74 
75   instructions_.reserve(node_count);
76   continuation_inputs_.reserve(5);
77   continuation_outputs_.reserve(2);
78 
79   if (trace_turbo_ == kEnableTraceTurboJson) {
80     instr_origins_.assign(node_count, {-1, 0});
81   }
82 }
83 
SelectInstructions()84 bool InstructionSelector::SelectInstructions() {
85   // Mark the inputs of all phis in loop headers as used.
86   BasicBlockVector* blocks = schedule()->rpo_order();
87   for (auto const block : *blocks) {
88     if (!block->IsLoopHeader()) continue;
89     DCHECK_LE(2u, block->PredecessorCount());
90     for (Node* const phi : *block) {
91       if (phi->opcode() != IrOpcode::kPhi) continue;
92 
93       // Mark all inputs as used.
94       for (Node* const input : phi->inputs()) {
95         MarkAsUsed(input);
96       }
97     }
98   }
99 
100   // Visit each basic block in post order.
101   for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) {
102     VisitBlock(*i);
103     if (instruction_selection_failed()) return false;
104   }
105 
106   // Schedule the selected instructions.
107   if (UseInstructionScheduling()) {
108     scheduler_ = zone()->New<InstructionScheduler>(zone(), sequence());
109   }
110 
111   for (auto const block : *blocks) {
112     InstructionBlock* instruction_block =
113         sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
114     for (size_t i = 0; i < instruction_block->phis().size(); i++) {
115       UpdateRenamesInPhi(instruction_block->PhiAt(i));
116     }
117     size_t end = instruction_block->code_end();
118     size_t start = instruction_block->code_start();
119     DCHECK_LE(end, start);
120     StartBlock(RpoNumber::FromInt(block->rpo_number()));
121     if (end != start) {
122       while (start-- > end + 1) {
123         UpdateRenames(instructions_[start]);
124         AddInstruction(instructions_[start]);
125       }
126       UpdateRenames(instructions_[end]);
127       AddTerminator(instructions_[end]);
128     }
129     EndBlock(RpoNumber::FromInt(block->rpo_number()));
130   }
131 #if DEBUG
132   sequence()->ValidateSSA();
133 #endif
134   return true;
135 }
136 
StartBlock(RpoNumber rpo)137 void InstructionSelector::StartBlock(RpoNumber rpo) {
138   if (UseInstructionScheduling()) {
139     DCHECK_NOT_NULL(scheduler_);
140     scheduler_->StartBlock(rpo);
141   } else {
142     sequence()->StartBlock(rpo);
143   }
144 }
145 
EndBlock(RpoNumber rpo)146 void InstructionSelector::EndBlock(RpoNumber rpo) {
147   if (UseInstructionScheduling()) {
148     DCHECK_NOT_NULL(scheduler_);
149     scheduler_->EndBlock(rpo);
150   } else {
151     sequence()->EndBlock(rpo);
152   }
153 }
154 
AddTerminator(Instruction * instr)155 void InstructionSelector::AddTerminator(Instruction* instr) {
156   if (UseInstructionScheduling()) {
157     DCHECK_NOT_NULL(scheduler_);
158     scheduler_->AddTerminator(instr);
159   } else {
160     sequence()->AddInstruction(instr);
161   }
162 }
163 
AddInstruction(Instruction * instr)164 void InstructionSelector::AddInstruction(Instruction* instr) {
165   if (UseInstructionScheduling()) {
166     DCHECK_NOT_NULL(scheduler_);
167     scheduler_->AddInstruction(instr);
168   } else {
169     sequence()->AddInstruction(instr);
170   }
171 }
172 
Emit(InstructionCode opcode,InstructionOperand output,size_t temp_count,InstructionOperand * temps)173 Instruction* InstructionSelector::Emit(InstructionCode opcode,
174                                        InstructionOperand output,
175                                        size_t temp_count,
176                                        InstructionOperand* temps) {
177   size_t output_count = output.IsInvalid() ? 0 : 1;
178   return Emit(opcode, output_count, &output, 0, nullptr, temp_count, temps);
179 }
180 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,size_t temp_count,InstructionOperand * temps)181 Instruction* InstructionSelector::Emit(InstructionCode opcode,
182                                        InstructionOperand output,
183                                        InstructionOperand a, size_t temp_count,
184                                        InstructionOperand* temps) {
185   size_t output_count = output.IsInvalid() ? 0 : 1;
186   return Emit(opcode, output_count, &output, 1, &a, temp_count, temps);
187 }
188 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,InstructionOperand b,size_t temp_count,InstructionOperand * temps)189 Instruction* InstructionSelector::Emit(InstructionCode opcode,
190                                        InstructionOperand output,
191                                        InstructionOperand a,
192                                        InstructionOperand b, size_t temp_count,
193                                        InstructionOperand* temps) {
194   size_t output_count = output.IsInvalid() ? 0 : 1;
195   InstructionOperand inputs[] = {a, b};
196   size_t input_count = arraysize(inputs);
197   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
198               temps);
199 }
200 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,InstructionOperand b,InstructionOperand c,size_t temp_count,InstructionOperand * temps)201 Instruction* InstructionSelector::Emit(InstructionCode opcode,
202                                        InstructionOperand output,
203                                        InstructionOperand a,
204                                        InstructionOperand b,
205                                        InstructionOperand c, size_t temp_count,
206                                        InstructionOperand* temps) {
207   size_t output_count = output.IsInvalid() ? 0 : 1;
208   InstructionOperand inputs[] = {a, b, c};
209   size_t input_count = arraysize(inputs);
210   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
211               temps);
212 }
213 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,InstructionOperand b,InstructionOperand c,InstructionOperand d,size_t temp_count,InstructionOperand * temps)214 Instruction* InstructionSelector::Emit(
215     InstructionCode opcode, InstructionOperand output, InstructionOperand a,
216     InstructionOperand b, InstructionOperand c, InstructionOperand d,
217     size_t temp_count, InstructionOperand* temps) {
218   size_t output_count = output.IsInvalid() ? 0 : 1;
219   InstructionOperand inputs[] = {a, b, c, d};
220   size_t input_count = arraysize(inputs);
221   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
222               temps);
223 }
224 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,InstructionOperand b,InstructionOperand c,InstructionOperand d,InstructionOperand e,size_t temp_count,InstructionOperand * temps)225 Instruction* InstructionSelector::Emit(
226     InstructionCode opcode, InstructionOperand output, InstructionOperand a,
227     InstructionOperand b, InstructionOperand c, InstructionOperand d,
228     InstructionOperand e, size_t temp_count, InstructionOperand* temps) {
229   size_t output_count = output.IsInvalid() ? 0 : 1;
230   InstructionOperand inputs[] = {a, b, c, d, e};
231   size_t input_count = arraysize(inputs);
232   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
233               temps);
234 }
235 
Emit(InstructionCode opcode,InstructionOperand output,InstructionOperand a,InstructionOperand b,InstructionOperand c,InstructionOperand d,InstructionOperand e,InstructionOperand f,size_t temp_count,InstructionOperand * temps)236 Instruction* InstructionSelector::Emit(
237     InstructionCode opcode, InstructionOperand output, InstructionOperand a,
238     InstructionOperand b, InstructionOperand c, InstructionOperand d,
239     InstructionOperand e, InstructionOperand f, size_t temp_count,
240     InstructionOperand* temps) {
241   size_t output_count = output.IsInvalid() ? 0 : 1;
242   InstructionOperand inputs[] = {a, b, c, d, e, f};
243   size_t input_count = arraysize(inputs);
244   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
245               temps);
246 }
247 
Emit(InstructionCode opcode,size_t output_count,InstructionOperand * outputs,size_t input_count,InstructionOperand * inputs,size_t temp_count,InstructionOperand * temps)248 Instruction* InstructionSelector::Emit(
249     InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
250     size_t input_count, InstructionOperand* inputs, size_t temp_count,
251     InstructionOperand* temps) {
252   if (output_count >= Instruction::kMaxOutputCount ||
253       input_count >= Instruction::kMaxInputCount ||
254       temp_count >= Instruction::kMaxTempCount) {
255     set_instruction_selection_failed();
256     return nullptr;
257   }
258 
259   Instruction* instr =
260       Instruction::New(instruction_zone(), opcode, output_count, outputs,
261                        input_count, inputs, temp_count, temps);
262   return Emit(instr);
263 }
264 
Emit(Instruction * instr)265 Instruction* InstructionSelector::Emit(Instruction* instr) {
266   instructions_.push_back(instr);
267   return instr;
268 }
269 
CanCover(Node * user,Node * node) const270 bool InstructionSelector::CanCover(Node* user, Node* node) const {
271   // 1. Both {user} and {node} must be in the same basic block.
272   if (schedule()->block(node) != schedule()->block(user)) {
273     return false;
274   }
275   // 2. Pure {node}s must be owned by the {user}.
276   if (node->op()->HasProperty(Operator::kPure)) {
277     return node->OwnedBy(user);
278   }
279   // 3. Impure {node}s must match the effect level of {user}.
280   if (GetEffectLevel(node) != GetEffectLevel(user)) {
281     return false;
282   }
283   // 4. Only {node} must have value edges pointing to {user}.
284   for (Edge const edge : node->use_edges()) {
285     if (edge.from() != user && NodeProperties::IsValueEdge(edge)) {
286       return false;
287     }
288   }
289   return true;
290 }
291 
CanCoverTransitively(Node * user,Node * node,Node * node_input) const292 bool InstructionSelector::CanCoverTransitively(Node* user, Node* node,
293                                                Node* node_input) const {
294   if (CanCover(user, node) && CanCover(node, node_input)) {
295     // If {node} is pure, transitivity might not hold.
296     if (node->op()->HasProperty(Operator::kPure)) {
297       // If {node_input} is pure, the effect levels do not matter.
298       if (node_input->op()->HasProperty(Operator::kPure)) return true;
299       // Otherwise, {user} and {node_input} must have the same effect level.
300       return GetEffectLevel(user) == GetEffectLevel(node_input);
301     }
302     return true;
303   }
304   return false;
305 }
306 
IsOnlyUserOfNodeInSameBlock(Node * user,Node * node) const307 bool InstructionSelector::IsOnlyUserOfNodeInSameBlock(Node* user,
308                                                       Node* node) const {
309   BasicBlock* bb_user = schedule()->block(user);
310   BasicBlock* bb_node = schedule()->block(node);
311   if (bb_user != bb_node) return false;
312   for (Edge const edge : node->use_edges()) {
313     Node* from = edge.from();
314     if ((from != user) && (schedule()->block(from) == bb_user)) {
315       return false;
316     }
317   }
318   return true;
319 }
320 
UpdateRenames(Instruction * instruction)321 void InstructionSelector::UpdateRenames(Instruction* instruction) {
322   for (size_t i = 0; i < instruction->InputCount(); i++) {
323     TryRename(instruction->InputAt(i));
324   }
325 }
326 
UpdateRenamesInPhi(PhiInstruction * phi)327 void InstructionSelector::UpdateRenamesInPhi(PhiInstruction* phi) {
328   for (size_t i = 0; i < phi->operands().size(); i++) {
329     int vreg = phi->operands()[i];
330     int renamed = GetRename(vreg);
331     if (vreg != renamed) {
332       phi->RenameInput(i, renamed);
333     }
334   }
335 }
336 
GetRename(int virtual_register)337 int InstructionSelector::GetRename(int virtual_register) {
338   int rename = virtual_register;
339   while (true) {
340     if (static_cast<size_t>(rename) >= virtual_register_rename_.size()) break;
341     int next = virtual_register_rename_[rename];
342     if (next == InstructionOperand::kInvalidVirtualRegister) {
343       break;
344     }
345     rename = next;
346   }
347   return rename;
348 }
349 
TryRename(InstructionOperand * op)350 void InstructionSelector::TryRename(InstructionOperand* op) {
351   if (!op->IsUnallocated()) return;
352   UnallocatedOperand* unalloc = UnallocatedOperand::cast(op);
353   int vreg = unalloc->virtual_register();
354   int rename = GetRename(vreg);
355   if (rename != vreg) {
356     *unalloc = UnallocatedOperand(*unalloc, rename);
357   }
358 }
359 
SetRename(const Node * node,const Node * rename)360 void InstructionSelector::SetRename(const Node* node, const Node* rename) {
361   int vreg = GetVirtualRegister(node);
362   if (static_cast<size_t>(vreg) >= virtual_register_rename_.size()) {
363     int invalid = InstructionOperand::kInvalidVirtualRegister;
364     virtual_register_rename_.resize(vreg + 1, invalid);
365   }
366   virtual_register_rename_[vreg] = GetVirtualRegister(rename);
367 }
368 
GetVirtualRegister(const Node * node)369 int InstructionSelector::GetVirtualRegister(const Node* node) {
370   DCHECK_NOT_NULL(node);
371   size_t const id = node->id();
372   DCHECK_LT(id, virtual_registers_.size());
373   int virtual_register = virtual_registers_[id];
374   if (virtual_register == InstructionOperand::kInvalidVirtualRegister) {
375     virtual_register = sequence()->NextVirtualRegister();
376     virtual_registers_[id] = virtual_register;
377   }
378   return virtual_register;
379 }
380 
GetVirtualRegistersForTesting() const381 const std::map<NodeId, int> InstructionSelector::GetVirtualRegistersForTesting()
382     const {
383   std::map<NodeId, int> virtual_registers;
384   for (size_t n = 0; n < virtual_registers_.size(); ++n) {
385     if (virtual_registers_[n] != InstructionOperand::kInvalidVirtualRegister) {
386       NodeId const id = static_cast<NodeId>(n);
387       virtual_registers.insert(std::make_pair(id, virtual_registers_[n]));
388     }
389   }
390   return virtual_registers;
391 }
392 
IsDefined(Node * node) const393 bool InstructionSelector::IsDefined(Node* node) const {
394   DCHECK_NOT_NULL(node);
395   size_t const id = node->id();
396   DCHECK_LT(id, defined_.size());
397   return defined_[id];
398 }
399 
MarkAsDefined(Node * node)400 void InstructionSelector::MarkAsDefined(Node* node) {
401   DCHECK_NOT_NULL(node);
402   size_t const id = node->id();
403   DCHECK_LT(id, defined_.size());
404   defined_[id] = true;
405 }
406 
IsUsed(Node * node) const407 bool InstructionSelector::IsUsed(Node* node) const {
408   DCHECK_NOT_NULL(node);
409   // TODO(bmeurer): This is a terrible monster hack, but we have to make sure
410   // that the Retain is actually emitted, otherwise the GC will mess up.
411   if (node->opcode() == IrOpcode::kRetain) return true;
412   if (!node->op()->HasProperty(Operator::kEliminatable)) return true;
413   size_t const id = node->id();
414   DCHECK_LT(id, used_.size());
415   return used_[id];
416 }
417 
MarkAsUsed(Node * node)418 void InstructionSelector::MarkAsUsed(Node* node) {
419   DCHECK_NOT_NULL(node);
420   size_t const id = node->id();
421   DCHECK_LT(id, used_.size());
422   used_[id] = true;
423 }
424 
GetEffectLevel(Node * node) const425 int InstructionSelector::GetEffectLevel(Node* node) const {
426   DCHECK_NOT_NULL(node);
427   size_t const id = node->id();
428   DCHECK_LT(id, effect_level_.size());
429   return effect_level_[id];
430 }
431 
GetEffectLevel(Node * node,FlagsContinuation * cont) const432 int InstructionSelector::GetEffectLevel(Node* node,
433                                         FlagsContinuation* cont) const {
434   return cont->IsBranch()
435              ? GetEffectLevel(
436                    cont->true_block()->PredecessorAt(0)->control_input())
437              : GetEffectLevel(node);
438 }
439 
SetEffectLevel(Node * node,int effect_level)440 void InstructionSelector::SetEffectLevel(Node* node, int effect_level) {
441   DCHECK_NOT_NULL(node);
442   size_t const id = node->id();
443   DCHECK_LT(id, effect_level_.size());
444   effect_level_[id] = effect_level;
445 }
446 
CanAddressRelativeToRootsRegister(const ExternalReference & reference) const447 bool InstructionSelector::CanAddressRelativeToRootsRegister(
448     const ExternalReference& reference) const {
449   // There are three things to consider here:
450   // 1. CanUseRootsRegister: Is kRootRegister initialized?
451   const bool root_register_is_available_and_initialized = CanUseRootsRegister();
452   if (!root_register_is_available_and_initialized) return false;
453 
454   // 2. enable_roots_relative_addressing_: Can we address everything on the heap
455   //    through the root register, i.e. are root-relative addresses to arbitrary
456   //    addresses guaranteed not to change between code generation and
457   //    execution?
458   const bool all_root_relative_offsets_are_constant =
459       (enable_roots_relative_addressing_ == kEnableRootsRelativeAddressing);
460   if (all_root_relative_offsets_are_constant) return true;
461 
462   // 3. IsAddressableThroughRootRegister: Is the target address guaranteed to
463   //    have a fixed root-relative offset? If so, we can ignore 2.
464   const bool this_root_relative_offset_is_constant =
465       TurboAssemblerBase::IsAddressableThroughRootRegister(isolate(),
466                                                            reference);
467   return this_root_relative_offset_is_constant;
468 }
469 
CanUseRootsRegister() const470 bool InstructionSelector::CanUseRootsRegister() const {
471   return linkage()->GetIncomingDescriptor()->flags() &
472          CallDescriptor::kCanUseRoots;
473 }
474 
MarkAsRepresentation(MachineRepresentation rep,const InstructionOperand & op)475 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
476                                                const InstructionOperand& op) {
477   UnallocatedOperand unalloc = UnallocatedOperand::cast(op);
478   sequence()->MarkAsRepresentation(rep, unalloc.virtual_register());
479 }
480 
MarkAsRepresentation(MachineRepresentation rep,Node * node)481 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
482                                                Node* node) {
483   sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node));
484 }
485 
486 namespace {
487 
OperandForDeopt(Isolate * isolate,OperandGenerator * g,Node * input,FrameStateInputKind kind,MachineRepresentation rep)488 InstructionOperand OperandForDeopt(Isolate* isolate, OperandGenerator* g,
489                                    Node* input, FrameStateInputKind kind,
490                                    MachineRepresentation rep) {
491   if (rep == MachineRepresentation::kNone) {
492     return g->TempImmediate(FrameStateDescriptor::kImpossibleValue);
493   }
494 
495   switch (input->opcode()) {
496     case IrOpcode::kInt32Constant:
497     case IrOpcode::kInt64Constant:
498     case IrOpcode::kNumberConstant:
499     case IrOpcode::kFloat32Constant:
500     case IrOpcode::kFloat64Constant:
501     case IrOpcode::kDelayedStringConstant:
502       return g->UseImmediate(input);
503     case IrOpcode::kCompressedHeapConstant:
504     case IrOpcode::kHeapConstant: {
505       if (!CanBeTaggedOrCompressedPointer(rep)) {
506         // If we have inconsistent static and dynamic types, e.g. if we
507         // smi-check a string, we can get here with a heap object that
508         // says it is a smi. In that case, we return an invalid instruction
509         // operand, which will be interpreted as an optimized-out value.
510 
511         // TODO(jarin) Ideally, we should turn the current instruction
512         // into an abort (we should never execute it).
513         return InstructionOperand();
514       }
515 
516       Handle<HeapObject> constant = HeapConstantOf(input->op());
517       RootIndex root_index;
518       if (isolate->roots_table().IsRootHandle(constant, &root_index) &&
519           root_index == RootIndex::kOptimizedOut) {
520         // For an optimized-out object we return an invalid instruction
521         // operand, so that we take the fast path for optimized-out values.
522         return InstructionOperand();
523       }
524 
525       return g->UseImmediate(input);
526     }
527     case IrOpcode::kArgumentsElementsState:
528     case IrOpcode::kArgumentsLengthState:
529     case IrOpcode::kObjectState:
530     case IrOpcode::kTypedObjectState:
531       UNREACHABLE();
532     default:
533       switch (kind) {
534         case FrameStateInputKind::kStackSlot:
535           return g->UseUniqueSlot(input);
536         case FrameStateInputKind::kAny:
537           // Currently deopts "wrap" other operations, so the deopt's inputs
538           // are potentially needed until the end of the deoptimising code.
539           return g->UseAnyAtEnd(input);
540       }
541   }
542   UNREACHABLE();
543 }
544 
545 }  // namespace
546 
547 class StateObjectDeduplicator {
548  public:
StateObjectDeduplicator(Zone * zone)549   explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {}
550   static const size_t kNotDuplicated = SIZE_MAX;
551 
GetObjectId(Node * node)552   size_t GetObjectId(Node* node) {
553     DCHECK(node->opcode() == IrOpcode::kTypedObjectState ||
554            node->opcode() == IrOpcode::kObjectId ||
555            node->opcode() == IrOpcode::kArgumentsElementsState);
556     for (size_t i = 0; i < objects_.size(); ++i) {
557       if (objects_[i] == node) return i;
558       // ObjectId nodes are the Turbofan way to express objects with the same
559       // identity in the deopt info. So they should always be mapped to
560       // previously appearing TypedObjectState nodes.
561       if (HasObjectId(objects_[i]) && HasObjectId(node) &&
562           ObjectIdOf(objects_[i]->op()) == ObjectIdOf(node->op())) {
563         return i;
564       }
565     }
566     DCHECK(node->opcode() == IrOpcode::kTypedObjectState ||
567            node->opcode() == IrOpcode::kArgumentsElementsState);
568     return kNotDuplicated;
569   }
570 
InsertObject(Node * node)571   size_t InsertObject(Node* node) {
572     DCHECK(node->opcode() == IrOpcode::kTypedObjectState ||
573            node->opcode() == IrOpcode::kObjectId ||
574            node->opcode() == IrOpcode::kArgumentsElementsState);
575     size_t id = objects_.size();
576     objects_.push_back(node);
577     return id;
578   }
579 
580  private:
HasObjectId(Node * node)581   static bool HasObjectId(Node* node) {
582     return node->opcode() == IrOpcode::kTypedObjectState ||
583            node->opcode() == IrOpcode::kObjectId;
584   }
585 
586   ZoneVector<Node*> objects_;
587 };
588 
589 // Returns the number of instruction operands added to inputs.
AddOperandToStateValueDescriptor(StateValueList * values,InstructionOperandVector * inputs,OperandGenerator * g,StateObjectDeduplicator * deduplicator,Node * input,MachineType type,FrameStateInputKind kind,Zone * zone)590 size_t InstructionSelector::AddOperandToStateValueDescriptor(
591     StateValueList* values, InstructionOperandVector* inputs,
592     OperandGenerator* g, StateObjectDeduplicator* deduplicator, Node* input,
593     MachineType type, FrameStateInputKind kind, Zone* zone) {
594   DCHECK_NOT_NULL(input);
595   switch (input->opcode()) {
596     case IrOpcode::kArgumentsElementsState: {
597       values->PushArgumentsElements(ArgumentsStateTypeOf(input->op()));
598       // The elements backing store of an arguments object participates in the
599       // duplicate object counting, but can itself never appear duplicated.
600       DCHECK_EQ(StateObjectDeduplicator::kNotDuplicated,
601                 deduplicator->GetObjectId(input));
602       deduplicator->InsertObject(input);
603       return 0;
604     }
605     case IrOpcode::kArgumentsLengthState: {
606       values->PushArgumentsLength();
607       return 0;
608     }
609     case IrOpcode::kObjectState:
610       UNREACHABLE();
611     case IrOpcode::kTypedObjectState:
612     case IrOpcode::kObjectId: {
613       size_t id = deduplicator->GetObjectId(input);
614       if (id == StateObjectDeduplicator::kNotDuplicated) {
615         DCHECK_EQ(IrOpcode::kTypedObjectState, input->opcode());
616         size_t entries = 0;
617         id = deduplicator->InsertObject(input);
618         StateValueList* nested = values->PushRecursiveField(zone, id);
619         int const input_count = input->op()->ValueInputCount();
620         ZoneVector<MachineType> const* types = MachineTypesOf(input->op());
621         for (int i = 0; i < input_count; ++i) {
622           entries += AddOperandToStateValueDescriptor(
623               nested, inputs, g, deduplicator, input->InputAt(i), types->at(i),
624               kind, zone);
625         }
626         return entries;
627       } else {
628         // Deoptimizer counts duplicate objects for the running id, so we have
629         // to push the input again.
630         deduplicator->InsertObject(input);
631         values->PushDuplicate(id);
632         return 0;
633       }
634     }
635     default: {
636       InstructionOperand op =
637           OperandForDeopt(isolate(), g, input, kind, type.representation());
638       if (op.kind() == InstructionOperand::INVALID) {
639         // Invalid operand means the value is impossible or optimized-out.
640         values->PushOptimizedOut();
641         return 0;
642       } else {
643         inputs->push_back(op);
644         values->PushPlain(type);
645         return 1;
646       }
647     }
648   }
649 }
650 
AddInputsToFrameStateDescriptor(StateValueList * values,InstructionOperandVector * inputs,OperandGenerator * g,StateObjectDeduplicator * deduplicator,Node * node,FrameStateInputKind kind,Zone * zone)651 size_t InstructionSelector::AddInputsToFrameStateDescriptor(
652     StateValueList* values, InstructionOperandVector* inputs,
653     OperandGenerator* g, StateObjectDeduplicator* deduplicator, Node* node,
654     FrameStateInputKind kind, Zone* zone) {
655   size_t entries = 0;
656   StateValuesAccess::iterator it = StateValuesAccess(node).begin();
657   // Take advantage of sparse nature of StateValuesAccess to skip over multiple
658   // empty nodes at once pushing repeated OptimizedOuts all in one go.
659   while (!it.done()) {
660     values->PushOptimizedOut(it.AdvanceTillNotEmpty());
661     if (it.done()) break;
662     StateValuesAccess::TypedNode input_node = *it;
663     entries += AddOperandToStateValueDescriptor(values, inputs, g, deduplicator,
664                                                 input_node.node,
665                                                 input_node.type, kind, zone);
666     ++it;
667   }
668   return entries;
669 }
670 
671 // Returns the number of instruction operands added to inputs.
AddInputsToFrameStateDescriptor(FrameStateDescriptor * descriptor,Node * state,OperandGenerator * g,StateObjectDeduplicator * deduplicator,InstructionOperandVector * inputs,FrameStateInputKind kind,Zone * zone)672 size_t InstructionSelector::AddInputsToFrameStateDescriptor(
673     FrameStateDescriptor* descriptor, Node* state, OperandGenerator* g,
674     StateObjectDeduplicator* deduplicator, InstructionOperandVector* inputs,
675     FrameStateInputKind kind, Zone* zone) {
676   DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
677 
678   size_t entries = 0;
679   size_t initial_size = inputs->size();
680   USE(initial_size);  // initial_size is only used for debug.
681 
682   if (descriptor->outer_state()) {
683     entries += AddInputsToFrameStateDescriptor(
684         descriptor->outer_state(), state->InputAt(kFrameStateOuterStateInput),
685         g, deduplicator, inputs, kind, zone);
686   }
687 
688   Node* parameters = state->InputAt(kFrameStateParametersInput);
689   Node* locals = state->InputAt(kFrameStateLocalsInput);
690   Node* stack = state->InputAt(kFrameStateStackInput);
691   Node* context = state->InputAt(kFrameStateContextInput);
692   Node* function = state->InputAt(kFrameStateFunctionInput);
693 
694   DCHECK_EQ(descriptor->parameters_count(),
695             StateValuesAccess(parameters).size());
696   DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size());
697   DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size());
698 
699   StateValueList* values_descriptor = descriptor->GetStateValueDescriptors();
700 
701   DCHECK_EQ(values_descriptor->size(), 0u);
702   values_descriptor->ReserveSize(descriptor->GetSize());
703 
704   DCHECK_NOT_NULL(function);
705   entries += AddOperandToStateValueDescriptor(
706       values_descriptor, inputs, g, deduplicator, function,
707       MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
708 
709   entries += AddInputsToFrameStateDescriptor(
710       values_descriptor, inputs, g, deduplicator, parameters, kind, zone);
711 
712   if (descriptor->HasContext()) {
713     DCHECK_NOT_NULL(context);
714     entries += AddOperandToStateValueDescriptor(
715         values_descriptor, inputs, g, deduplicator, context,
716         MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
717   }
718 
719   entries += AddInputsToFrameStateDescriptor(values_descriptor, inputs, g,
720                                              deduplicator, locals, kind, zone);
721   entries += AddInputsToFrameStateDescriptor(values_descriptor, inputs, g,
722                                              deduplicator, stack, kind, zone);
723   DCHECK_EQ(initial_size + entries, inputs->size());
724   return entries;
725 }
726 
EmitWithContinuation(InstructionCode opcode,FlagsContinuation * cont)727 Instruction* InstructionSelector::EmitWithContinuation(
728     InstructionCode opcode, FlagsContinuation* cont) {
729   return EmitWithContinuation(opcode, 0, nullptr, 0, nullptr, cont);
730 }
731 
EmitWithContinuation(InstructionCode opcode,InstructionOperand a,FlagsContinuation * cont)732 Instruction* InstructionSelector::EmitWithContinuation(
733     InstructionCode opcode, InstructionOperand a, FlagsContinuation* cont) {
734   return EmitWithContinuation(opcode, 0, nullptr, 1, &a, cont);
735 }
736 
EmitWithContinuation(InstructionCode opcode,InstructionOperand a,InstructionOperand b,FlagsContinuation * cont)737 Instruction* InstructionSelector::EmitWithContinuation(
738     InstructionCode opcode, InstructionOperand a, InstructionOperand b,
739     FlagsContinuation* cont) {
740   InstructionOperand inputs[] = {a, b};
741   return EmitWithContinuation(opcode, 0, nullptr, arraysize(inputs), inputs,
742                               cont);
743 }
744 
EmitWithContinuation(InstructionCode opcode,InstructionOperand a,InstructionOperand b,InstructionOperand c,FlagsContinuation * cont)745 Instruction* InstructionSelector::EmitWithContinuation(
746     InstructionCode opcode, InstructionOperand a, InstructionOperand b,
747     InstructionOperand c, FlagsContinuation* cont) {
748   InstructionOperand inputs[] = {a, b, c};
749   return EmitWithContinuation(opcode, 0, nullptr, arraysize(inputs), inputs,
750                               cont);
751 }
752 
EmitWithContinuation(InstructionCode opcode,size_t output_count,InstructionOperand * outputs,size_t input_count,InstructionOperand * inputs,FlagsContinuation * cont)753 Instruction* InstructionSelector::EmitWithContinuation(
754     InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
755     size_t input_count, InstructionOperand* inputs, FlagsContinuation* cont) {
756   return EmitWithContinuation(opcode, output_count, outputs, input_count,
757                               inputs, 0, nullptr, cont);
758 }
759 
EmitWithContinuation(InstructionCode opcode,size_t output_count,InstructionOperand * outputs,size_t input_count,InstructionOperand * inputs,size_t temp_count,InstructionOperand * temps,FlagsContinuation * cont)760 Instruction* InstructionSelector::EmitWithContinuation(
761     InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
762     size_t input_count, InstructionOperand* inputs, size_t temp_count,
763     InstructionOperand* temps, FlagsContinuation* cont) {
764   OperandGenerator g(this);
765 
766   opcode = cont->Encode(opcode);
767 
768   continuation_inputs_.resize(0);
769   for (size_t i = 0; i < input_count; i++) {
770     continuation_inputs_.push_back(inputs[i]);
771   }
772 
773   continuation_outputs_.resize(0);
774   for (size_t i = 0; i < output_count; i++) {
775     continuation_outputs_.push_back(outputs[i]);
776   }
777 
778   continuation_temps_.resize(0);
779   for (size_t i = 0; i < temp_count; i++) {
780     continuation_temps_.push_back(temps[i]);
781   }
782 
783   if (cont->IsBranch()) {
784     continuation_inputs_.push_back(g.Label(cont->true_block()));
785     continuation_inputs_.push_back(g.Label(cont->false_block()));
786   } else if (cont->IsDeoptimize()) {
787     opcode |= MiscField::encode(static_cast<int>(input_count));
788     AppendDeoptimizeArguments(&continuation_inputs_, cont->kind(),
789                               cont->reason(), cont->feedback(),
790                               cont->frame_state());
791   } else if (cont->IsSet()) {
792     continuation_outputs_.push_back(g.DefineAsRegister(cont->result()));
793   } else if (cont->IsTrap()) {
794     int trap_id = static_cast<int>(cont->trap_id());
795     continuation_inputs_.push_back(g.UseImmediate(trap_id));
796   } else {
797     DCHECK(cont->IsNone());
798   }
799 
800   size_t const emit_inputs_size = continuation_inputs_.size();
801   auto* emit_inputs =
802       emit_inputs_size ? &continuation_inputs_.front() : nullptr;
803   size_t const emit_outputs_size = continuation_outputs_.size();
804   auto* emit_outputs =
805       emit_outputs_size ? &continuation_outputs_.front() : nullptr;
806   size_t const emit_temps_size = continuation_temps_.size();
807   auto* emit_temps = emit_temps_size ? &continuation_temps_.front() : nullptr;
808   return Emit(opcode, emit_outputs_size, emit_outputs, emit_inputs_size,
809               emit_inputs, emit_temps_size, emit_temps);
810 }
811 
AppendDeoptimizeArguments(InstructionOperandVector * args,DeoptimizeKind kind,DeoptimizeReason reason,FeedbackSource const & feedback,Node * frame_state)812 void InstructionSelector::AppendDeoptimizeArguments(
813     InstructionOperandVector* args, DeoptimizeKind kind,
814     DeoptimizeReason reason, FeedbackSource const& feedback,
815     Node* frame_state) {
816   OperandGenerator g(this);
817   FrameStateDescriptor* const descriptor = GetFrameStateDescriptor(frame_state);
818   DCHECK_NE(DeoptimizeKind::kLazy, kind);
819   int const state_id =
820       sequence()->AddDeoptimizationEntry(descriptor, kind, reason, feedback);
821   args->push_back(g.TempImmediate(state_id));
822   StateObjectDeduplicator deduplicator(instruction_zone());
823   AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator,
824                                   args, FrameStateInputKind::kAny,
825                                   instruction_zone());
826 }
827 
828 // An internal helper class for generating the operands to calls.
829 // TODO(bmeurer): Get rid of the CallBuffer business and make
830 // InstructionSelector::VisitCall platform independent instead.
831 struct CallBuffer {
CallBufferv8::internal::compiler::CallBuffer832   CallBuffer(Zone* zone, const CallDescriptor* call_descriptor,
833              FrameStateDescriptor* frame_state)
834       : descriptor(call_descriptor),
835         frame_state_descriptor(frame_state),
836         output_nodes(zone),
837         outputs(zone),
838         instruction_args(zone),
839         pushed_nodes(zone) {
840     output_nodes.reserve(call_descriptor->ReturnCount());
841     outputs.reserve(call_descriptor->ReturnCount());
842     pushed_nodes.reserve(input_count());
843     instruction_args.reserve(input_count() + frame_state_value_count());
844   }
845 
846   const CallDescriptor* descriptor;
847   FrameStateDescriptor* frame_state_descriptor;
848   ZoneVector<PushParameter> output_nodes;
849   InstructionOperandVector outputs;
850   InstructionOperandVector instruction_args;
851   ZoneVector<PushParameter> pushed_nodes;
852 
input_countv8::internal::compiler::CallBuffer853   size_t input_count() const { return descriptor->InputCount(); }
854 
frame_state_countv8::internal::compiler::CallBuffer855   size_t frame_state_count() const { return descriptor->FrameStateCount(); }
856 
frame_state_value_countv8::internal::compiler::CallBuffer857   size_t frame_state_value_count() const {
858     return (frame_state_descriptor == nullptr)
859                ? 0
860                : (frame_state_descriptor->GetTotalSize() +
861                   1);  // Include deopt id.
862   }
863 };
864 
865 // TODO(bmeurer): Get rid of the CallBuffer business and make
866 // InstructionSelector::VisitCall platform independent instead.
InitializeCallBuffer(Node * call,CallBuffer * buffer,CallBufferFlags flags,bool is_tail_call,int stack_param_delta)867 void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
868                                                CallBufferFlags flags,
869                                                bool is_tail_call,
870                                                int stack_param_delta) {
871   OperandGenerator g(this);
872   size_t ret_count = buffer->descriptor->ReturnCount();
873   DCHECK_LE(call->op()->ValueOutputCount(), ret_count);
874   DCHECK_EQ(
875       call->op()->ValueInputCount(),
876       static_cast<int>(buffer->input_count() + buffer->frame_state_count()));
877 
878   if (ret_count > 0) {
879     // Collect the projections that represent multiple outputs from this call.
880     if (ret_count == 1) {
881       PushParameter result = {call, buffer->descriptor->GetReturnLocation(0)};
882       buffer->output_nodes.push_back(result);
883     } else {
884       buffer->output_nodes.resize(ret_count);
885       int stack_count = 0;
886       for (size_t i = 0; i < ret_count; ++i) {
887         LinkageLocation location = buffer->descriptor->GetReturnLocation(i);
888         buffer->output_nodes[i] = PushParameter(nullptr, location);
889         if (location.IsCallerFrameSlot()) {
890           stack_count += location.GetSizeInPointers();
891         }
892       }
893       for (Edge const edge : call->use_edges()) {
894         if (!NodeProperties::IsValueEdge(edge)) continue;
895         Node* node = edge.from();
896         DCHECK_EQ(IrOpcode::kProjection, node->opcode());
897         size_t const index = ProjectionIndexOf(node->op());
898 
899         DCHECK_LT(index, buffer->output_nodes.size());
900         DCHECK(!buffer->output_nodes[index].node);
901         buffer->output_nodes[index].node = node;
902       }
903       frame_->EnsureReturnSlots(stack_count);
904     }
905 
906     // Filter out the outputs that aren't live because no projection uses them.
907     size_t outputs_needed_by_framestate =
908         buffer->frame_state_descriptor == nullptr
909             ? 0
910             : buffer->frame_state_descriptor->state_combine()
911                   .ConsumedOutputCount();
912     for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
913       bool output_is_live = buffer->output_nodes[i].node != nullptr ||
914                             i < outputs_needed_by_framestate;
915       if (output_is_live) {
916         LinkageLocation location = buffer->output_nodes[i].location;
917         MachineRepresentation rep = location.GetType().representation();
918 
919         Node* output = buffer->output_nodes[i].node;
920         InstructionOperand op = output == nullptr
921                                     ? g.TempLocation(location)
922                                     : g.DefineAsLocation(output, location);
923         MarkAsRepresentation(rep, op);
924 
925         if (!UnallocatedOperand::cast(op).HasFixedSlotPolicy()) {
926           buffer->outputs.push_back(op);
927           buffer->output_nodes[i].node = nullptr;
928         }
929       }
930     }
931   }
932 
933   // The first argument is always the callee code.
934   Node* callee = call->InputAt(0);
935   bool call_code_immediate = (flags & kCallCodeImmediate) != 0;
936   bool call_address_immediate = (flags & kCallAddressImmediate) != 0;
937   bool call_use_fixed_target_reg = (flags & kCallFixedTargetRegister) != 0;
938   switch (buffer->descriptor->kind()) {
939     case CallDescriptor::kCallCodeObject:
940       // TODO(jgruber, v8:7449): The below is a hack to support tail-calls from
941       // JS-linkage callers with a register code target. The problem is that the
942       // code target register may be clobbered before the final jmp by
943       // AssemblePopArgumentsAdaptorFrame. As a more permanent fix we could
944       // entirely remove support for tail-calls from JS-linkage callers.
945       buffer->instruction_args.push_back(
946           (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant)
947               ? g.UseImmediate(callee)
948               : call_use_fixed_target_reg
949                     ? g.UseFixed(callee, kJavaScriptCallCodeStartRegister)
950                     : is_tail_call ? g.UseUniqueRegister(callee)
951                                    : g.UseRegister(callee));
952       break;
953     case CallDescriptor::kCallAddress:
954       buffer->instruction_args.push_back(
955           (call_address_immediate &&
956            callee->opcode() == IrOpcode::kExternalConstant)
957               ? g.UseImmediate(callee)
958               : call_use_fixed_target_reg
959                     ? g.UseFixed(callee, kJavaScriptCallCodeStartRegister)
960                     : g.UseRegister(callee));
961       break;
962     case CallDescriptor::kCallWasmCapiFunction:
963     case CallDescriptor::kCallWasmFunction:
964     case CallDescriptor::kCallWasmImportWrapper:
965       buffer->instruction_args.push_back(
966           (call_address_immediate &&
967            (callee->opcode() == IrOpcode::kRelocatableInt64Constant ||
968             callee->opcode() == IrOpcode::kRelocatableInt32Constant))
969               ? g.UseImmediate(callee)
970               : call_use_fixed_target_reg
971                     ? g.UseFixed(callee, kJavaScriptCallCodeStartRegister)
972                     : g.UseRegister(callee));
973       break;
974     case CallDescriptor::kCallBuiltinPointer:
975       // The common case for builtin pointers is to have the target in a
976       // register. If we have a constant, we use a register anyway to simplify
977       // related code.
978       buffer->instruction_args.push_back(
979           call_use_fixed_target_reg
980               ? g.UseFixed(callee, kJavaScriptCallCodeStartRegister)
981               : g.UseRegister(callee));
982       break;
983     case CallDescriptor::kCallJSFunction:
984       buffer->instruction_args.push_back(
985           g.UseLocation(callee, buffer->descriptor->GetInputLocation(0)));
986       break;
987   }
988   DCHECK_EQ(1u, buffer->instruction_args.size());
989 
990   // Argument 1 is used for poison-alias index (encoded in a word-sized
991   // immediate. This an index of the operand that aliases with poison register
992   // or -1 if there is no aliasing.
993   buffer->instruction_args.push_back(g.TempImmediate(-1));
994   const size_t poison_alias_index = 1;
995   DCHECK_EQ(buffer->instruction_args.size() - 1, poison_alias_index);
996 
997   // If the call needs a frame state, we insert the state information as
998   // follows (n is the number of value inputs to the frame state):
999   // arg 2               : deoptimization id.
1000   // arg 3 - arg (n + 2) : value inputs to the frame state.
1001   size_t frame_state_entries = 0;
1002   USE(frame_state_entries);  // frame_state_entries is only used for debug.
1003   if (buffer->frame_state_descriptor != nullptr) {
1004     Node* frame_state =
1005         call->InputAt(static_cast<int>(buffer->descriptor->InputCount()));
1006 
1007     // If it was a syntactic tail call we need to drop the current frame and
1008     // all the frames on top of it that are either an arguments adaptor frame
1009     // or a tail caller frame.
1010     if (is_tail_call) {
1011       frame_state = NodeProperties::GetFrameStateInput(frame_state);
1012       buffer->frame_state_descriptor =
1013           buffer->frame_state_descriptor->outer_state();
1014       while (buffer->frame_state_descriptor != nullptr &&
1015              buffer->frame_state_descriptor->type() ==
1016                  FrameStateType::kArgumentsAdaptor) {
1017         frame_state = NodeProperties::GetFrameStateInput(frame_state);
1018         buffer->frame_state_descriptor =
1019             buffer->frame_state_descriptor->outer_state();
1020       }
1021     }
1022 
1023     int const state_id = sequence()->AddDeoptimizationEntry(
1024         buffer->frame_state_descriptor, DeoptimizeKind::kLazy,
1025         DeoptimizeReason::kUnknown, FeedbackSource());
1026     buffer->instruction_args.push_back(g.TempImmediate(state_id));
1027 
1028     StateObjectDeduplicator deduplicator(instruction_zone());
1029 
1030     frame_state_entries =
1031         1 + AddInputsToFrameStateDescriptor(
1032                 buffer->frame_state_descriptor, frame_state, &g, &deduplicator,
1033                 &buffer->instruction_args, FrameStateInputKind::kStackSlot,
1034                 instruction_zone());
1035 
1036     DCHECK_EQ(2 + frame_state_entries, buffer->instruction_args.size());
1037   }
1038 
1039   size_t input_count = static_cast<size_t>(buffer->input_count());
1040 
1041   // Split the arguments into pushed_nodes and instruction_args. Pushed
1042   // arguments require an explicit push instruction before the call and do
1043   // not appear as arguments to the call. Everything else ends up
1044   // as an InstructionOperand argument to the call.
1045   auto iter(call->inputs().begin());
1046   size_t pushed_count = 0;
1047   bool call_tail = (flags & kCallTail) != 0;
1048   for (size_t index = 0; index < input_count; ++iter, ++index) {
1049     DCHECK(iter != call->inputs().end());
1050     DCHECK_NE(IrOpcode::kFrameState, (*iter)->op()->opcode());
1051     if (index == 0) continue;  // The first argument (callee) is already done.
1052 
1053     LinkageLocation location = buffer->descriptor->GetInputLocation(index);
1054     if (call_tail) {
1055       location = LinkageLocation::ConvertToTailCallerLocation(
1056           location, stack_param_delta);
1057     }
1058     InstructionOperand op = g.UseLocation(*iter, location);
1059     UnallocatedOperand unallocated = UnallocatedOperand::cast(op);
1060     if (unallocated.HasFixedSlotPolicy() && !call_tail) {
1061       int stack_index = buffer->descriptor->GetStackIndexFromSlot(
1062           unallocated.fixed_slot_index());
1063       // This can insert empty slots before stack_index and will insert enough
1064       // slots after stack_index to store the parameter.
1065       if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
1066         int num_slots = std::max(
1067             1, (ElementSizeInBytes(location.GetType().representation()) /
1068                 kSystemPointerSize));
1069         buffer->pushed_nodes.resize(stack_index + num_slots);
1070       }
1071       PushParameter param = {*iter, location};
1072       buffer->pushed_nodes[stack_index] = param;
1073       pushed_count++;
1074     } else {
1075       // If we do load poisoning and the linkage uses the poisoning register,
1076       // then we request the input in memory location, and during code
1077       // generation, we move the input to the register.
1078       if (poisoning_level_ != PoisoningMitigationLevel::kDontPoison &&
1079           unallocated.HasFixedRegisterPolicy()) {
1080         int reg = unallocated.fixed_register_index();
1081         if (Register::from_code(reg) == kSpeculationPoisonRegister) {
1082           buffer->instruction_args[poison_alias_index] = g.TempImmediate(
1083               static_cast<int32_t>(buffer->instruction_args.size()));
1084           op = g.UseRegisterOrSlotOrConstant(*iter);
1085         }
1086       }
1087       buffer->instruction_args.push_back(op);
1088     }
1089   }
1090   DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count -
1091                              frame_state_entries - 1);
1092   if (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK && call_tail &&
1093       stack_param_delta != 0) {
1094     // For tail calls that change the size of their parameter list and keep
1095     // their return address on the stack, move the return address to just above
1096     // the parameters.
1097     LinkageLocation saved_return_location =
1098         LinkageLocation::ForSavedCallerReturnAddress();
1099     InstructionOperand return_address =
1100         g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation(
1101                                  saved_return_location, stack_param_delta),
1102                              saved_return_location);
1103     buffer->instruction_args.push_back(return_address);
1104   }
1105 }
1106 
IsSourcePositionUsed(Node * node)1107 bool InstructionSelector::IsSourcePositionUsed(Node* node) {
1108   return (source_position_mode_ == kAllSourcePositions ||
1109           node->opcode() == IrOpcode::kCall ||
1110           node->opcode() == IrOpcode::kTrapIf ||
1111           node->opcode() == IrOpcode::kTrapUnless ||
1112           node->opcode() == IrOpcode::kProtectedLoad ||
1113           node->opcode() == IrOpcode::kProtectedStore);
1114 }
1115 
VisitBlock(BasicBlock * block)1116 void InstructionSelector::VisitBlock(BasicBlock* block) {
1117   DCHECK(!current_block_);
1118   current_block_ = block;
1119   auto current_num_instructions = [&] {
1120     DCHECK_GE(kMaxInt, instructions_.size());
1121     return static_cast<int>(instructions_.size());
1122   };
1123   int current_block_end = current_num_instructions();
1124 
1125   int effect_level = 0;
1126   for (Node* const node : *block) {
1127     SetEffectLevel(node, effect_level);
1128     if (node->opcode() == IrOpcode::kStore ||
1129         node->opcode() == IrOpcode::kUnalignedStore ||
1130         node->opcode() == IrOpcode::kCall ||
1131         node->opcode() == IrOpcode::kProtectedLoad ||
1132         node->opcode() == IrOpcode::kProtectedStore ||
1133         node->opcode() == IrOpcode::kLoadTransform ||
1134 #define ADD_EFFECT_FOR_ATOMIC_OP(Opcode) \
1135   node->opcode() == IrOpcode::k##Opcode ||
1136         MACHINE_ATOMIC_OP_LIST(ADD_EFFECT_FOR_ATOMIC_OP)
1137 #undef ADD_EFFECT_FOR_ATOMIC_OP
1138                 node->opcode() == IrOpcode::kMemoryBarrier) {
1139       ++effect_level;
1140     }
1141   }
1142 
1143   // We visit the control first, then the nodes in the block, so the block's
1144   // control input should be on the same effect level as the last node.
1145   if (block->control_input() != nullptr) {
1146     SetEffectLevel(block->control_input(), effect_level);
1147   }
1148 
1149   auto FinishEmittedInstructions = [&](Node* node, int instruction_start) {
1150     if (instruction_selection_failed()) return false;
1151     if (current_num_instructions() == instruction_start) return true;
1152     std::reverse(instructions_.begin() + instruction_start,
1153                  instructions_.end());
1154     if (!node) return true;
1155     if (!source_positions_) return true;
1156     SourcePosition source_position = source_positions_->GetSourcePosition(node);
1157     if (source_position.IsKnown() && IsSourcePositionUsed(node)) {
1158       sequence()->SetSourcePosition(instructions_[instruction_start],
1159                                     source_position);
1160     }
1161     return true;
1162   };
1163 
1164   // Generate code for the block control "top down", but schedule the code
1165   // "bottom up".
1166   VisitControl(block);
1167   if (!FinishEmittedInstructions(block->control_input(), current_block_end))
1168     return;
1169 
1170   // Visit code in reverse control flow order, because architecture-specific
1171   // matching may cover more than one node at a time.
1172   for (auto node : base::Reversed(*block)) {
1173     int current_node_end = current_num_instructions();
1174     // Skip nodes that are unused or already defined.
1175     if (IsUsed(node) && !IsDefined(node)) {
1176       // Generate code for this node "top down", but schedule the code "bottom
1177       // up".
1178       VisitNode(node);
1179       if (!FinishEmittedInstructions(node, current_node_end)) return;
1180     }
1181     if (trace_turbo_ == kEnableTraceTurboJson) {
1182       instr_origins_[node->id()] = {current_num_instructions(),
1183                                     current_node_end};
1184     }
1185   }
1186 
1187   // We're done with the block.
1188   InstructionBlock* instruction_block =
1189       sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
1190   if (current_num_instructions() == current_block_end) {
1191     // Avoid empty block: insert a {kArchNop} instruction.
1192     Emit(Instruction::New(sequence()->zone(), kArchNop));
1193   }
1194   instruction_block->set_code_start(current_num_instructions());
1195   instruction_block->set_code_end(current_block_end);
1196   current_block_ = nullptr;
1197 }
1198 
VisitControl(BasicBlock * block)1199 void InstructionSelector::VisitControl(BasicBlock* block) {
1200 #ifdef DEBUG
1201   // SSA deconstruction requires targets of branches not to have phis.
1202   // Edge split form guarantees this property, but is more strict.
1203   if (block->SuccessorCount() > 1) {
1204     for (BasicBlock* const successor : block->successors()) {
1205       for (Node* const node : *successor) {
1206         if (IrOpcode::IsPhiOpcode(node->opcode())) {
1207           std::ostringstream str;
1208           str << "You might have specified merged variables for a label with "
1209               << "only one predecessor." << std::endl
1210               << "# Current Block: " << *successor << std::endl
1211               << "#          Node: " << *node;
1212           FATAL("%s", str.str().c_str());
1213         }
1214       }
1215     }
1216   }
1217 #endif
1218 
1219   Node* input = block->control_input();
1220   int instruction_end = static_cast<int>(instructions_.size());
1221   switch (block->control()) {
1222     case BasicBlock::kGoto:
1223       VisitGoto(block->SuccessorAt(0));
1224       break;
1225     case BasicBlock::kCall: {
1226       DCHECK_EQ(IrOpcode::kCall, input->opcode());
1227       BasicBlock* success = block->SuccessorAt(0);
1228       BasicBlock* exception = block->SuccessorAt(1);
1229       VisitCall(input, exception);
1230       VisitGoto(success);
1231       break;
1232     }
1233     case BasicBlock::kTailCall: {
1234       DCHECK_EQ(IrOpcode::kTailCall, input->opcode());
1235       VisitTailCall(input);
1236       break;
1237     }
1238     case BasicBlock::kBranch: {
1239       DCHECK_EQ(IrOpcode::kBranch, input->opcode());
1240       BasicBlock* tbranch = block->SuccessorAt(0);
1241       BasicBlock* fbranch = block->SuccessorAt(1);
1242       if (tbranch == fbranch) {
1243         VisitGoto(tbranch);
1244       } else {
1245         VisitBranch(input, tbranch, fbranch);
1246       }
1247       break;
1248     }
1249     case BasicBlock::kSwitch: {
1250       DCHECK_EQ(IrOpcode::kSwitch, input->opcode());
1251       // Last successor must be {IfDefault}.
1252       BasicBlock* default_branch = block->successors().back();
1253       DCHECK_EQ(IrOpcode::kIfDefault, default_branch->front()->opcode());
1254       // All other successors must be {IfValue}s.
1255       int32_t min_value = std::numeric_limits<int32_t>::max();
1256       int32_t max_value = std::numeric_limits<int32_t>::min();
1257       size_t case_count = block->SuccessorCount() - 1;
1258       ZoneVector<CaseInfo> cases(case_count, zone());
1259       for (size_t i = 0; i < case_count; ++i) {
1260         BasicBlock* branch = block->SuccessorAt(i);
1261         const IfValueParameters& p = IfValueParametersOf(branch->front()->op());
1262         cases[i] = CaseInfo{p.value(), p.comparison_order(), branch};
1263         if (min_value > p.value()) min_value = p.value();
1264         if (max_value < p.value()) max_value = p.value();
1265       }
1266       SwitchInfo sw(cases, min_value, max_value, default_branch);
1267       VisitSwitch(input, sw);
1268       break;
1269     }
1270     case BasicBlock::kReturn: {
1271       DCHECK_EQ(IrOpcode::kReturn, input->opcode());
1272       VisitReturn(input);
1273       break;
1274     }
1275     case BasicBlock::kDeoptimize: {
1276       DeoptimizeParameters p = DeoptimizeParametersOf(input->op());
1277       Node* value = input->InputAt(0);
1278       VisitDeoptimize(p.kind(), p.reason(), p.feedback(), value);
1279       break;
1280     }
1281     case BasicBlock::kThrow:
1282       DCHECK_EQ(IrOpcode::kThrow, input->opcode());
1283       VisitThrow(input);
1284       break;
1285     case BasicBlock::kNone: {
1286       // Exit block doesn't have control.
1287       DCHECK_NULL(input);
1288       break;
1289     }
1290     default:
1291       UNREACHABLE();
1292   }
1293   if (trace_turbo_ == kEnableTraceTurboJson && input) {
1294     int instruction_start = static_cast<int>(instructions_.size());
1295     instr_origins_[input->id()] = {instruction_start, instruction_end};
1296   }
1297 }
1298 
MarkPairProjectionsAsWord32(Node * node)1299 void InstructionSelector::MarkPairProjectionsAsWord32(Node* node) {
1300   Node* projection0 = NodeProperties::FindProjection(node, 0);
1301   if (projection0) {
1302     MarkAsWord32(projection0);
1303   }
1304   Node* projection1 = NodeProperties::FindProjection(node, 1);
1305   if (projection1) {
1306     MarkAsWord32(projection1);
1307   }
1308 }
1309 
VisitNode(Node * node)1310 void InstructionSelector::VisitNode(Node* node) {
1311   tick_counter_->TickAndMaybeEnterSafepoint();
1312   DCHECK_NOT_NULL(schedule()->block(node));  // should only use scheduled nodes.
1313   switch (node->opcode()) {
1314     case IrOpcode::kStart:
1315     case IrOpcode::kLoop:
1316     case IrOpcode::kEnd:
1317     case IrOpcode::kBranch:
1318     case IrOpcode::kIfTrue:
1319     case IrOpcode::kIfFalse:
1320     case IrOpcode::kIfSuccess:
1321     case IrOpcode::kSwitch:
1322     case IrOpcode::kIfValue:
1323     case IrOpcode::kIfDefault:
1324     case IrOpcode::kEffectPhi:
1325     case IrOpcode::kMerge:
1326     case IrOpcode::kTerminate:
1327     case IrOpcode::kBeginRegion:
1328       // No code needed for these graph artifacts.
1329       return;
1330     case IrOpcode::kIfException:
1331       return MarkAsTagged(node), VisitIfException(node);
1332     case IrOpcode::kFinishRegion:
1333       return MarkAsTagged(node), VisitFinishRegion(node);
1334     case IrOpcode::kParameter: {
1335       // Parameters should always be scheduled to the first block.
1336       DCHECK_EQ(schedule()->block(node)->rpo_number(), 0);
1337       MachineType type =
1338           linkage()->GetParameterType(ParameterIndexOf(node->op()));
1339       MarkAsRepresentation(type.representation(), node);
1340       return VisitParameter(node);
1341     }
1342     case IrOpcode::kOsrValue:
1343       return MarkAsTagged(node), VisitOsrValue(node);
1344     case IrOpcode::kPhi: {
1345       MachineRepresentation rep = PhiRepresentationOf(node->op());
1346       if (rep == MachineRepresentation::kNone) return;
1347       MarkAsRepresentation(rep, node);
1348       return VisitPhi(node);
1349     }
1350     case IrOpcode::kProjection:
1351       return VisitProjection(node);
1352     case IrOpcode::kInt32Constant:
1353     case IrOpcode::kInt64Constant:
1354     case IrOpcode::kTaggedIndexConstant:
1355     case IrOpcode::kExternalConstant:
1356     case IrOpcode::kRelocatableInt32Constant:
1357     case IrOpcode::kRelocatableInt64Constant:
1358       return VisitConstant(node);
1359     case IrOpcode::kFloat32Constant:
1360       return MarkAsFloat32(node), VisitConstant(node);
1361     case IrOpcode::kFloat64Constant:
1362       return MarkAsFloat64(node), VisitConstant(node);
1363     case IrOpcode::kHeapConstant:
1364       return MarkAsTagged(node), VisitConstant(node);
1365     case IrOpcode::kCompressedHeapConstant:
1366       return MarkAsCompressed(node), VisitConstant(node);
1367     case IrOpcode::kNumberConstant: {
1368       double value = OpParameter<double>(node->op());
1369       if (!IsSmiDouble(value)) MarkAsTagged(node);
1370       return VisitConstant(node);
1371     }
1372     case IrOpcode::kDelayedStringConstant:
1373       return MarkAsTagged(node), VisitConstant(node);
1374     case IrOpcode::kCall:
1375       return VisitCall(node);
1376     case IrOpcode::kDeoptimizeIf:
1377       return VisitDeoptimizeIf(node);
1378     case IrOpcode::kDeoptimizeUnless:
1379       return VisitDeoptimizeUnless(node);
1380     case IrOpcode::kTrapIf:
1381       return VisitTrapIf(node, TrapIdOf(node->op()));
1382     case IrOpcode::kTrapUnless:
1383       return VisitTrapUnless(node, TrapIdOf(node->op()));
1384     case IrOpcode::kFrameState:
1385     case IrOpcode::kStateValues:
1386     case IrOpcode::kObjectState:
1387       return;
1388     case IrOpcode::kAbortCSAAssert:
1389       VisitAbortCSAAssert(node);
1390       return;
1391     case IrOpcode::kDebugBreak:
1392       VisitDebugBreak(node);
1393       return;
1394     case IrOpcode::kUnreachable:
1395       VisitUnreachable(node);
1396       return;
1397     case IrOpcode::kStaticAssert:
1398       VisitStaticAssert(node);
1399       return;
1400     case IrOpcode::kDeadValue:
1401       VisitDeadValue(node);
1402       return;
1403     case IrOpcode::kComment:
1404       VisitComment(node);
1405       return;
1406     case IrOpcode::kRetain:
1407       VisitRetain(node);
1408       return;
1409     case IrOpcode::kLoad: {
1410       LoadRepresentation type = LoadRepresentationOf(node->op());
1411       MarkAsRepresentation(type.representation(), node);
1412       return VisitLoad(node);
1413     }
1414     case IrOpcode::kLoadTransform: {
1415       MarkAsRepresentation(MachineRepresentation::kSimd128, node);
1416       return VisitLoadTransform(node);
1417     }
1418     case IrOpcode::kLoadLane: {
1419       MarkAsRepresentation(MachineRepresentation::kSimd128, node);
1420       return VisitLoadLane(node);
1421     }
1422     case IrOpcode::kPoisonedLoad: {
1423       LoadRepresentation type = LoadRepresentationOf(node->op());
1424       MarkAsRepresentation(type.representation(), node);
1425       return VisitPoisonedLoad(node);
1426     }
1427     case IrOpcode::kStore:
1428       return VisitStore(node);
1429     case IrOpcode::kProtectedStore:
1430       return VisitProtectedStore(node);
1431     case IrOpcode::kStoreLane: {
1432       MarkAsRepresentation(MachineRepresentation::kSimd128, node);
1433       return VisitStoreLane(node);
1434     }
1435     case IrOpcode::kWord32And:
1436       return MarkAsWord32(node), VisitWord32And(node);
1437     case IrOpcode::kWord32Or:
1438       return MarkAsWord32(node), VisitWord32Or(node);
1439     case IrOpcode::kWord32Xor:
1440       return MarkAsWord32(node), VisitWord32Xor(node);
1441     case IrOpcode::kWord32Shl:
1442       return MarkAsWord32(node), VisitWord32Shl(node);
1443     case IrOpcode::kWord32Shr:
1444       return MarkAsWord32(node), VisitWord32Shr(node);
1445     case IrOpcode::kWord32Sar:
1446       return MarkAsWord32(node), VisitWord32Sar(node);
1447     case IrOpcode::kWord32Rol:
1448       return MarkAsWord32(node), VisitWord32Rol(node);
1449     case IrOpcode::kWord32Ror:
1450       return MarkAsWord32(node), VisitWord32Ror(node);
1451     case IrOpcode::kWord32Equal:
1452       return VisitWord32Equal(node);
1453     case IrOpcode::kWord32Clz:
1454       return MarkAsWord32(node), VisitWord32Clz(node);
1455     case IrOpcode::kWord32Ctz:
1456       return MarkAsWord32(node), VisitWord32Ctz(node);
1457     case IrOpcode::kWord32ReverseBits:
1458       return MarkAsWord32(node), VisitWord32ReverseBits(node);
1459     case IrOpcode::kWord32ReverseBytes:
1460       return MarkAsWord32(node), VisitWord32ReverseBytes(node);
1461     case IrOpcode::kInt32AbsWithOverflow:
1462       return MarkAsWord32(node), VisitInt32AbsWithOverflow(node);
1463     case IrOpcode::kWord32Popcnt:
1464       return MarkAsWord32(node), VisitWord32Popcnt(node);
1465     case IrOpcode::kWord64Popcnt:
1466       return MarkAsWord32(node), VisitWord64Popcnt(node);
1467     case IrOpcode::kWord64And:
1468       return MarkAsWord64(node), VisitWord64And(node);
1469     case IrOpcode::kWord64Or:
1470       return MarkAsWord64(node), VisitWord64Or(node);
1471     case IrOpcode::kWord64Xor:
1472       return MarkAsWord64(node), VisitWord64Xor(node);
1473     case IrOpcode::kWord64Shl:
1474       return MarkAsWord64(node), VisitWord64Shl(node);
1475     case IrOpcode::kWord64Shr:
1476       return MarkAsWord64(node), VisitWord64Shr(node);
1477     case IrOpcode::kWord64Sar:
1478       return MarkAsWord64(node), VisitWord64Sar(node);
1479     case IrOpcode::kWord64Rol:
1480       return MarkAsWord64(node), VisitWord64Rol(node);
1481     case IrOpcode::kWord64Ror:
1482       return MarkAsWord64(node), VisitWord64Ror(node);
1483     case IrOpcode::kWord64Clz:
1484       return MarkAsWord64(node), VisitWord64Clz(node);
1485     case IrOpcode::kWord64Ctz:
1486       return MarkAsWord64(node), VisitWord64Ctz(node);
1487     case IrOpcode::kWord64ReverseBits:
1488       return MarkAsWord64(node), VisitWord64ReverseBits(node);
1489     case IrOpcode::kWord64ReverseBytes:
1490       return MarkAsWord64(node), VisitWord64ReverseBytes(node);
1491     case IrOpcode::kSimd128ReverseBytes:
1492       return MarkAsSimd128(node), VisitSimd128ReverseBytes(node);
1493     case IrOpcode::kInt64AbsWithOverflow:
1494       return MarkAsWord64(node), VisitInt64AbsWithOverflow(node);
1495     case IrOpcode::kWord64Equal:
1496       return VisitWord64Equal(node);
1497     case IrOpcode::kInt32Add:
1498       return MarkAsWord32(node), VisitInt32Add(node);
1499     case IrOpcode::kInt32AddWithOverflow:
1500       return MarkAsWord32(node), VisitInt32AddWithOverflow(node);
1501     case IrOpcode::kInt32Sub:
1502       return MarkAsWord32(node), VisitInt32Sub(node);
1503     case IrOpcode::kInt32SubWithOverflow:
1504       return VisitInt32SubWithOverflow(node);
1505     case IrOpcode::kInt32Mul:
1506       return MarkAsWord32(node), VisitInt32Mul(node);
1507     case IrOpcode::kInt32MulWithOverflow:
1508       return MarkAsWord32(node), VisitInt32MulWithOverflow(node);
1509     case IrOpcode::kInt32MulHigh:
1510       return VisitInt32MulHigh(node);
1511     case IrOpcode::kInt32Div:
1512       return MarkAsWord32(node), VisitInt32Div(node);
1513     case IrOpcode::kInt32Mod:
1514       return MarkAsWord32(node), VisitInt32Mod(node);
1515     case IrOpcode::kInt32LessThan:
1516       return VisitInt32LessThan(node);
1517     case IrOpcode::kInt32LessThanOrEqual:
1518       return VisitInt32LessThanOrEqual(node);
1519     case IrOpcode::kUint32Div:
1520       return MarkAsWord32(node), VisitUint32Div(node);
1521     case IrOpcode::kUint32LessThan:
1522       return VisitUint32LessThan(node);
1523     case IrOpcode::kUint32LessThanOrEqual:
1524       return VisitUint32LessThanOrEqual(node);
1525     case IrOpcode::kUint32Mod:
1526       return MarkAsWord32(node), VisitUint32Mod(node);
1527     case IrOpcode::kUint32MulHigh:
1528       return VisitUint32MulHigh(node);
1529     case IrOpcode::kInt64Add:
1530       return MarkAsWord64(node), VisitInt64Add(node);
1531     case IrOpcode::kInt64AddWithOverflow:
1532       return MarkAsWord64(node), VisitInt64AddWithOverflow(node);
1533     case IrOpcode::kInt64Sub:
1534       return MarkAsWord64(node), VisitInt64Sub(node);
1535     case IrOpcode::kInt64SubWithOverflow:
1536       return MarkAsWord64(node), VisitInt64SubWithOverflow(node);
1537     case IrOpcode::kInt64Mul:
1538       return MarkAsWord64(node), VisitInt64Mul(node);
1539     case IrOpcode::kInt64Div:
1540       return MarkAsWord64(node), VisitInt64Div(node);
1541     case IrOpcode::kInt64Mod:
1542       return MarkAsWord64(node), VisitInt64Mod(node);
1543     case IrOpcode::kInt64LessThan:
1544       return VisitInt64LessThan(node);
1545     case IrOpcode::kInt64LessThanOrEqual:
1546       return VisitInt64LessThanOrEqual(node);
1547     case IrOpcode::kUint64Div:
1548       return MarkAsWord64(node), VisitUint64Div(node);
1549     case IrOpcode::kUint64LessThan:
1550       return VisitUint64LessThan(node);
1551     case IrOpcode::kUint64LessThanOrEqual:
1552       return VisitUint64LessThanOrEqual(node);
1553     case IrOpcode::kUint64Mod:
1554       return MarkAsWord64(node), VisitUint64Mod(node);
1555     case IrOpcode::kBitcastTaggedToWord:
1556     case IrOpcode::kBitcastTaggedToWordForTagAndSmiBits:
1557       return MarkAsRepresentation(MachineType::PointerRepresentation(), node),
1558              VisitBitcastTaggedToWord(node);
1559     case IrOpcode::kBitcastWordToTagged:
1560       return MarkAsTagged(node), VisitBitcastWordToTagged(node);
1561     case IrOpcode::kBitcastWordToTaggedSigned:
1562       return MarkAsRepresentation(MachineRepresentation::kTaggedSigned, node),
1563              EmitIdentity(node);
1564     case IrOpcode::kChangeFloat32ToFloat64:
1565       return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node);
1566     case IrOpcode::kChangeInt32ToFloat64:
1567       return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node);
1568     case IrOpcode::kChangeInt64ToFloat64:
1569       return MarkAsFloat64(node), VisitChangeInt64ToFloat64(node);
1570     case IrOpcode::kChangeUint32ToFloat64:
1571       return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node);
1572     case IrOpcode::kChangeFloat64ToInt32:
1573       return MarkAsWord32(node), VisitChangeFloat64ToInt32(node);
1574     case IrOpcode::kChangeFloat64ToInt64:
1575       return MarkAsWord64(node), VisitChangeFloat64ToInt64(node);
1576     case IrOpcode::kChangeFloat64ToUint32:
1577       return MarkAsWord32(node), VisitChangeFloat64ToUint32(node);
1578     case IrOpcode::kChangeFloat64ToUint64:
1579       return MarkAsWord64(node), VisitChangeFloat64ToUint64(node);
1580     case IrOpcode::kFloat64SilenceNaN:
1581       MarkAsFloat64(node);
1582       if (CanProduceSignalingNaN(node->InputAt(0))) {
1583         return VisitFloat64SilenceNaN(node);
1584       } else {
1585         return EmitIdentity(node);
1586       }
1587     case IrOpcode::kTruncateFloat64ToInt64:
1588       return MarkAsWord64(node), VisitTruncateFloat64ToInt64(node);
1589     case IrOpcode::kTruncateFloat64ToUint32:
1590       return MarkAsWord32(node), VisitTruncateFloat64ToUint32(node);
1591     case IrOpcode::kTruncateFloat32ToInt32:
1592       return MarkAsWord32(node), VisitTruncateFloat32ToInt32(node);
1593     case IrOpcode::kTruncateFloat32ToUint32:
1594       return MarkAsWord32(node), VisitTruncateFloat32ToUint32(node);
1595     case IrOpcode::kTryTruncateFloat32ToInt64:
1596       return MarkAsWord64(node), VisitTryTruncateFloat32ToInt64(node);
1597     case IrOpcode::kTryTruncateFloat64ToInt64:
1598       return MarkAsWord64(node), VisitTryTruncateFloat64ToInt64(node);
1599     case IrOpcode::kTryTruncateFloat32ToUint64:
1600       return MarkAsWord64(node), VisitTryTruncateFloat32ToUint64(node);
1601     case IrOpcode::kTryTruncateFloat64ToUint64:
1602       return MarkAsWord64(node), VisitTryTruncateFloat64ToUint64(node);
1603     case IrOpcode::kBitcastWord32ToWord64:
1604       return MarkAsWord64(node), VisitBitcastWord32ToWord64(node);
1605     case IrOpcode::kChangeInt32ToInt64:
1606       return MarkAsWord64(node), VisitChangeInt32ToInt64(node);
1607     case IrOpcode::kChangeUint32ToUint64:
1608       return MarkAsWord64(node), VisitChangeUint32ToUint64(node);
1609     case IrOpcode::kTruncateFloat64ToFloat32:
1610       return MarkAsFloat32(node), VisitTruncateFloat64ToFloat32(node);
1611     case IrOpcode::kTruncateFloat64ToWord32:
1612       return MarkAsWord32(node), VisitTruncateFloat64ToWord32(node);
1613     case IrOpcode::kTruncateInt64ToInt32:
1614       return MarkAsWord32(node), VisitTruncateInt64ToInt32(node);
1615     case IrOpcode::kRoundFloat64ToInt32:
1616       return MarkAsWord32(node), VisitRoundFloat64ToInt32(node);
1617     case IrOpcode::kRoundInt64ToFloat32:
1618       return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node);
1619     case IrOpcode::kRoundInt32ToFloat32:
1620       return MarkAsFloat32(node), VisitRoundInt32ToFloat32(node);
1621     case IrOpcode::kRoundInt64ToFloat64:
1622       return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node);
1623     case IrOpcode::kBitcastFloat32ToInt32:
1624       return MarkAsWord32(node), VisitBitcastFloat32ToInt32(node);
1625     case IrOpcode::kRoundUint32ToFloat32:
1626       return MarkAsFloat32(node), VisitRoundUint32ToFloat32(node);
1627     case IrOpcode::kRoundUint64ToFloat32:
1628       return MarkAsFloat64(node), VisitRoundUint64ToFloat32(node);
1629     case IrOpcode::kRoundUint64ToFloat64:
1630       return MarkAsFloat64(node), VisitRoundUint64ToFloat64(node);
1631     case IrOpcode::kBitcastFloat64ToInt64:
1632       return MarkAsWord64(node), VisitBitcastFloat64ToInt64(node);
1633     case IrOpcode::kBitcastInt32ToFloat32:
1634       return MarkAsFloat32(node), VisitBitcastInt32ToFloat32(node);
1635     case IrOpcode::kBitcastInt64ToFloat64:
1636       return MarkAsFloat64(node), VisitBitcastInt64ToFloat64(node);
1637     case IrOpcode::kFloat32Add:
1638       return MarkAsFloat32(node), VisitFloat32Add(node);
1639     case IrOpcode::kFloat32Sub:
1640       return MarkAsFloat32(node), VisitFloat32Sub(node);
1641     case IrOpcode::kFloat32Neg:
1642       return MarkAsFloat32(node), VisitFloat32Neg(node);
1643     case IrOpcode::kFloat32Mul:
1644       return MarkAsFloat32(node), VisitFloat32Mul(node);
1645     case IrOpcode::kFloat32Div:
1646       return MarkAsFloat32(node), VisitFloat32Div(node);
1647     case IrOpcode::kFloat32Abs:
1648       return MarkAsFloat32(node), VisitFloat32Abs(node);
1649     case IrOpcode::kFloat32Sqrt:
1650       return MarkAsFloat32(node), VisitFloat32Sqrt(node);
1651     case IrOpcode::kFloat32Equal:
1652       return VisitFloat32Equal(node);
1653     case IrOpcode::kFloat32LessThan:
1654       return VisitFloat32LessThan(node);
1655     case IrOpcode::kFloat32LessThanOrEqual:
1656       return VisitFloat32LessThanOrEqual(node);
1657     case IrOpcode::kFloat32Max:
1658       return MarkAsFloat32(node), VisitFloat32Max(node);
1659     case IrOpcode::kFloat32Min:
1660       return MarkAsFloat32(node), VisitFloat32Min(node);
1661     case IrOpcode::kFloat64Add:
1662       return MarkAsFloat64(node), VisitFloat64Add(node);
1663     case IrOpcode::kFloat64Sub:
1664       return MarkAsFloat64(node), VisitFloat64Sub(node);
1665     case IrOpcode::kFloat64Neg:
1666       return MarkAsFloat64(node), VisitFloat64Neg(node);
1667     case IrOpcode::kFloat64Mul:
1668       return MarkAsFloat64(node), VisitFloat64Mul(node);
1669     case IrOpcode::kFloat64Div:
1670       return MarkAsFloat64(node), VisitFloat64Div(node);
1671     case IrOpcode::kFloat64Mod:
1672       return MarkAsFloat64(node), VisitFloat64Mod(node);
1673     case IrOpcode::kFloat64Min:
1674       return MarkAsFloat64(node), VisitFloat64Min(node);
1675     case IrOpcode::kFloat64Max:
1676       return MarkAsFloat64(node), VisitFloat64Max(node);
1677     case IrOpcode::kFloat64Abs:
1678       return MarkAsFloat64(node), VisitFloat64Abs(node);
1679     case IrOpcode::kFloat64Acos:
1680       return MarkAsFloat64(node), VisitFloat64Acos(node);
1681     case IrOpcode::kFloat64Acosh:
1682       return MarkAsFloat64(node), VisitFloat64Acosh(node);
1683     case IrOpcode::kFloat64Asin:
1684       return MarkAsFloat64(node), VisitFloat64Asin(node);
1685     case IrOpcode::kFloat64Asinh:
1686       return MarkAsFloat64(node), VisitFloat64Asinh(node);
1687     case IrOpcode::kFloat64Atan:
1688       return MarkAsFloat64(node), VisitFloat64Atan(node);
1689     case IrOpcode::kFloat64Atanh:
1690       return MarkAsFloat64(node), VisitFloat64Atanh(node);
1691     case IrOpcode::kFloat64Atan2:
1692       return MarkAsFloat64(node), VisitFloat64Atan2(node);
1693     case IrOpcode::kFloat64Cbrt:
1694       return MarkAsFloat64(node), VisitFloat64Cbrt(node);
1695     case IrOpcode::kFloat64Cos:
1696       return MarkAsFloat64(node), VisitFloat64Cos(node);
1697     case IrOpcode::kFloat64Cosh:
1698       return MarkAsFloat64(node), VisitFloat64Cosh(node);
1699     case IrOpcode::kFloat64Exp:
1700       return MarkAsFloat64(node), VisitFloat64Exp(node);
1701     case IrOpcode::kFloat64Expm1:
1702       return MarkAsFloat64(node), VisitFloat64Expm1(node);
1703     case IrOpcode::kFloat64Log:
1704       return MarkAsFloat64(node), VisitFloat64Log(node);
1705     case IrOpcode::kFloat64Log1p:
1706       return MarkAsFloat64(node), VisitFloat64Log1p(node);
1707     case IrOpcode::kFloat64Log10:
1708       return MarkAsFloat64(node), VisitFloat64Log10(node);
1709     case IrOpcode::kFloat64Log2:
1710       return MarkAsFloat64(node), VisitFloat64Log2(node);
1711     case IrOpcode::kFloat64Pow:
1712       return MarkAsFloat64(node), VisitFloat64Pow(node);
1713     case IrOpcode::kFloat64Sin:
1714       return MarkAsFloat64(node), VisitFloat64Sin(node);
1715     case IrOpcode::kFloat64Sinh:
1716       return MarkAsFloat64(node), VisitFloat64Sinh(node);
1717     case IrOpcode::kFloat64Sqrt:
1718       return MarkAsFloat64(node), VisitFloat64Sqrt(node);
1719     case IrOpcode::kFloat64Tan:
1720       return MarkAsFloat64(node), VisitFloat64Tan(node);
1721     case IrOpcode::kFloat64Tanh:
1722       return MarkAsFloat64(node), VisitFloat64Tanh(node);
1723     case IrOpcode::kFloat64Equal:
1724       return VisitFloat64Equal(node);
1725     case IrOpcode::kFloat64LessThan:
1726       return VisitFloat64LessThan(node);
1727     case IrOpcode::kFloat64LessThanOrEqual:
1728       return VisitFloat64LessThanOrEqual(node);
1729     case IrOpcode::kFloat32RoundDown:
1730       return MarkAsFloat32(node), VisitFloat32RoundDown(node);
1731     case IrOpcode::kFloat64RoundDown:
1732       return MarkAsFloat64(node), VisitFloat64RoundDown(node);
1733     case IrOpcode::kFloat32RoundUp:
1734       return MarkAsFloat32(node), VisitFloat32RoundUp(node);
1735     case IrOpcode::kFloat64RoundUp:
1736       return MarkAsFloat64(node), VisitFloat64RoundUp(node);
1737     case IrOpcode::kFloat32RoundTruncate:
1738       return MarkAsFloat32(node), VisitFloat32RoundTruncate(node);
1739     case IrOpcode::kFloat64RoundTruncate:
1740       return MarkAsFloat64(node), VisitFloat64RoundTruncate(node);
1741     case IrOpcode::kFloat64RoundTiesAway:
1742       return MarkAsFloat64(node), VisitFloat64RoundTiesAway(node);
1743     case IrOpcode::kFloat32RoundTiesEven:
1744       return MarkAsFloat32(node), VisitFloat32RoundTiesEven(node);
1745     case IrOpcode::kFloat64RoundTiesEven:
1746       return MarkAsFloat64(node), VisitFloat64RoundTiesEven(node);
1747     case IrOpcode::kFloat64ExtractLowWord32:
1748       return MarkAsWord32(node), VisitFloat64ExtractLowWord32(node);
1749     case IrOpcode::kFloat64ExtractHighWord32:
1750       return MarkAsWord32(node), VisitFloat64ExtractHighWord32(node);
1751     case IrOpcode::kFloat64InsertLowWord32:
1752       return MarkAsFloat64(node), VisitFloat64InsertLowWord32(node);
1753     case IrOpcode::kFloat64InsertHighWord32:
1754       return MarkAsFloat64(node), VisitFloat64InsertHighWord32(node);
1755     case IrOpcode::kTaggedPoisonOnSpeculation:
1756       return MarkAsTagged(node), VisitTaggedPoisonOnSpeculation(node);
1757     case IrOpcode::kWord32PoisonOnSpeculation:
1758       return MarkAsWord32(node), VisitWord32PoisonOnSpeculation(node);
1759     case IrOpcode::kWord64PoisonOnSpeculation:
1760       return MarkAsWord64(node), VisitWord64PoisonOnSpeculation(node);
1761     case IrOpcode::kStackSlot:
1762       return VisitStackSlot(node);
1763     case IrOpcode::kStackPointerGreaterThan:
1764       return VisitStackPointerGreaterThan(node);
1765     case IrOpcode::kLoadStackCheckOffset:
1766       return VisitLoadStackCheckOffset(node);
1767     case IrOpcode::kLoadFramePointer:
1768       return VisitLoadFramePointer(node);
1769     case IrOpcode::kLoadParentFramePointer:
1770       return VisitLoadParentFramePointer(node);
1771     case IrOpcode::kUnalignedLoad: {
1772       LoadRepresentation type = LoadRepresentationOf(node->op());
1773       MarkAsRepresentation(type.representation(), node);
1774       return VisitUnalignedLoad(node);
1775     }
1776     case IrOpcode::kUnalignedStore:
1777       return VisitUnalignedStore(node);
1778     case IrOpcode::kInt32PairAdd:
1779       MarkAsWord32(node);
1780       MarkPairProjectionsAsWord32(node);
1781       return VisitInt32PairAdd(node);
1782     case IrOpcode::kInt32PairSub:
1783       MarkAsWord32(node);
1784       MarkPairProjectionsAsWord32(node);
1785       return VisitInt32PairSub(node);
1786     case IrOpcode::kInt32PairMul:
1787       MarkAsWord32(node);
1788       MarkPairProjectionsAsWord32(node);
1789       return VisitInt32PairMul(node);
1790     case IrOpcode::kWord32PairShl:
1791       MarkAsWord32(node);
1792       MarkPairProjectionsAsWord32(node);
1793       return VisitWord32PairShl(node);
1794     case IrOpcode::kWord32PairShr:
1795       MarkAsWord32(node);
1796       MarkPairProjectionsAsWord32(node);
1797       return VisitWord32PairShr(node);
1798     case IrOpcode::kWord32PairSar:
1799       MarkAsWord32(node);
1800       MarkPairProjectionsAsWord32(node);
1801       return VisitWord32PairSar(node);
1802     case IrOpcode::kMemoryBarrier:
1803       return VisitMemoryBarrier(node);
1804     case IrOpcode::kWord32AtomicLoad: {
1805       LoadRepresentation type = LoadRepresentationOf(node->op());
1806       MarkAsRepresentation(type.representation(), node);
1807       return VisitWord32AtomicLoad(node);
1808     }
1809     case IrOpcode::kWord64AtomicLoad: {
1810       LoadRepresentation type = LoadRepresentationOf(node->op());
1811       MarkAsRepresentation(type.representation(), node);
1812       return VisitWord64AtomicLoad(node);
1813     }
1814     case IrOpcode::kWord32AtomicStore:
1815       return VisitWord32AtomicStore(node);
1816     case IrOpcode::kWord64AtomicStore:
1817       return VisitWord64AtomicStore(node);
1818     case IrOpcode::kWord32AtomicPairStore:
1819       return VisitWord32AtomicPairStore(node);
1820     case IrOpcode::kWord32AtomicPairLoad: {
1821       MarkAsWord32(node);
1822       MarkPairProjectionsAsWord32(node);
1823       return VisitWord32AtomicPairLoad(node);
1824     }
1825 #define ATOMIC_CASE(name, rep)                         \
1826   case IrOpcode::k##rep##Atomic##name: {               \
1827     MachineType type = AtomicOpType(node->op());       \
1828     MarkAsRepresentation(type.representation(), node); \
1829     return Visit##rep##Atomic##name(node);             \
1830   }
1831       ATOMIC_CASE(Add, Word32)
1832       ATOMIC_CASE(Add, Word64)
1833       ATOMIC_CASE(Sub, Word32)
1834       ATOMIC_CASE(Sub, Word64)
1835       ATOMIC_CASE(And, Word32)
1836       ATOMIC_CASE(And, Word64)
1837       ATOMIC_CASE(Or, Word32)
1838       ATOMIC_CASE(Or, Word64)
1839       ATOMIC_CASE(Xor, Word32)
1840       ATOMIC_CASE(Xor, Word64)
1841       ATOMIC_CASE(Exchange, Word32)
1842       ATOMIC_CASE(Exchange, Word64)
1843       ATOMIC_CASE(CompareExchange, Word32)
1844       ATOMIC_CASE(CompareExchange, Word64)
1845 #undef ATOMIC_CASE
1846 #define ATOMIC_CASE(name)                     \
1847   case IrOpcode::kWord32AtomicPair##name: {   \
1848     MarkAsWord32(node);                       \
1849     MarkPairProjectionsAsWord32(node);        \
1850     return VisitWord32AtomicPair##name(node); \
1851   }
1852       ATOMIC_CASE(Add)
1853       ATOMIC_CASE(Sub)
1854       ATOMIC_CASE(And)
1855       ATOMIC_CASE(Or)
1856       ATOMIC_CASE(Xor)
1857       ATOMIC_CASE(Exchange)
1858       ATOMIC_CASE(CompareExchange)
1859 #undef ATOMIC_CASE
1860     case IrOpcode::kProtectedLoad: {
1861       LoadRepresentation type = LoadRepresentationOf(node->op());
1862       MarkAsRepresentation(type.representation(), node);
1863       return VisitProtectedLoad(node);
1864     }
1865     case IrOpcode::kSignExtendWord8ToInt32:
1866       return MarkAsWord32(node), VisitSignExtendWord8ToInt32(node);
1867     case IrOpcode::kSignExtendWord16ToInt32:
1868       return MarkAsWord32(node), VisitSignExtendWord16ToInt32(node);
1869     case IrOpcode::kSignExtendWord8ToInt64:
1870       return MarkAsWord64(node), VisitSignExtendWord8ToInt64(node);
1871     case IrOpcode::kSignExtendWord16ToInt64:
1872       return MarkAsWord64(node), VisitSignExtendWord16ToInt64(node);
1873     case IrOpcode::kSignExtendWord32ToInt64:
1874       return MarkAsWord64(node), VisitSignExtendWord32ToInt64(node);
1875     case IrOpcode::kUnsafePointerAdd:
1876       MarkAsRepresentation(MachineType::PointerRepresentation(), node);
1877       return VisitUnsafePointerAdd(node);
1878     case IrOpcode::kF64x2Splat:
1879       return MarkAsSimd128(node), VisitF64x2Splat(node);
1880     case IrOpcode::kF64x2ExtractLane:
1881       return MarkAsFloat64(node), VisitF64x2ExtractLane(node);
1882     case IrOpcode::kF64x2ReplaceLane:
1883       return MarkAsSimd128(node), VisitF64x2ReplaceLane(node);
1884     case IrOpcode::kF64x2Abs:
1885       return MarkAsSimd128(node), VisitF64x2Abs(node);
1886     case IrOpcode::kF64x2Neg:
1887       return MarkAsSimd128(node), VisitF64x2Neg(node);
1888     case IrOpcode::kF64x2Sqrt:
1889       return MarkAsSimd128(node), VisitF64x2Sqrt(node);
1890     case IrOpcode::kF64x2Add:
1891       return MarkAsSimd128(node), VisitF64x2Add(node);
1892     case IrOpcode::kF64x2Sub:
1893       return MarkAsSimd128(node), VisitF64x2Sub(node);
1894     case IrOpcode::kF64x2Mul:
1895       return MarkAsSimd128(node), VisitF64x2Mul(node);
1896     case IrOpcode::kF64x2Div:
1897       return MarkAsSimd128(node), VisitF64x2Div(node);
1898     case IrOpcode::kF64x2Min:
1899       return MarkAsSimd128(node), VisitF64x2Min(node);
1900     case IrOpcode::kF64x2Max:
1901       return MarkAsSimd128(node), VisitF64x2Max(node);
1902     case IrOpcode::kF64x2Eq:
1903       return MarkAsSimd128(node), VisitF64x2Eq(node);
1904     case IrOpcode::kF64x2Ne:
1905       return MarkAsSimd128(node), VisitF64x2Ne(node);
1906     case IrOpcode::kF64x2Lt:
1907       return MarkAsSimd128(node), VisitF64x2Lt(node);
1908     case IrOpcode::kF64x2Le:
1909       return MarkAsSimd128(node), VisitF64x2Le(node);
1910     case IrOpcode::kF64x2Qfma:
1911       return MarkAsSimd128(node), VisitF64x2Qfma(node);
1912     case IrOpcode::kF64x2Qfms:
1913       return MarkAsSimd128(node), VisitF64x2Qfms(node);
1914     case IrOpcode::kF64x2Pmin:
1915       return MarkAsSimd128(node), VisitF64x2Pmin(node);
1916     case IrOpcode::kF64x2Pmax:
1917       return MarkAsSimd128(node), VisitF64x2Pmax(node);
1918     case IrOpcode::kF64x2Ceil:
1919       return MarkAsSimd128(node), VisitF64x2Ceil(node);
1920     case IrOpcode::kF64x2Floor:
1921       return MarkAsSimd128(node), VisitF64x2Floor(node);
1922     case IrOpcode::kF64x2Trunc:
1923       return MarkAsSimd128(node), VisitF64x2Trunc(node);
1924     case IrOpcode::kF64x2NearestInt:
1925       return MarkAsSimd128(node), VisitF64x2NearestInt(node);
1926     case IrOpcode::kF32x4Splat:
1927       return MarkAsSimd128(node), VisitF32x4Splat(node);
1928     case IrOpcode::kF32x4ExtractLane:
1929       return MarkAsFloat32(node), VisitF32x4ExtractLane(node);
1930     case IrOpcode::kF32x4ReplaceLane:
1931       return MarkAsSimd128(node), VisitF32x4ReplaceLane(node);
1932     case IrOpcode::kF32x4SConvertI32x4:
1933       return MarkAsSimd128(node), VisitF32x4SConvertI32x4(node);
1934     case IrOpcode::kF32x4UConvertI32x4:
1935       return MarkAsSimd128(node), VisitF32x4UConvertI32x4(node);
1936     case IrOpcode::kF32x4Abs:
1937       return MarkAsSimd128(node), VisitF32x4Abs(node);
1938     case IrOpcode::kF32x4Neg:
1939       return MarkAsSimd128(node), VisitF32x4Neg(node);
1940     case IrOpcode::kF32x4Sqrt:
1941       return MarkAsSimd128(node), VisitF32x4Sqrt(node);
1942     case IrOpcode::kF32x4RecipApprox:
1943       return MarkAsSimd128(node), VisitF32x4RecipApprox(node);
1944     case IrOpcode::kF32x4RecipSqrtApprox:
1945       return MarkAsSimd128(node), VisitF32x4RecipSqrtApprox(node);
1946     case IrOpcode::kF32x4Add:
1947       return MarkAsSimd128(node), VisitF32x4Add(node);
1948     case IrOpcode::kF32x4AddHoriz:
1949       return MarkAsSimd128(node), VisitF32x4AddHoriz(node);
1950     case IrOpcode::kF32x4Sub:
1951       return MarkAsSimd128(node), VisitF32x4Sub(node);
1952     case IrOpcode::kF32x4Mul:
1953       return MarkAsSimd128(node), VisitF32x4Mul(node);
1954     case IrOpcode::kF32x4Div:
1955       return MarkAsSimd128(node), VisitF32x4Div(node);
1956     case IrOpcode::kF32x4Min:
1957       return MarkAsSimd128(node), VisitF32x4Min(node);
1958     case IrOpcode::kF32x4Max:
1959       return MarkAsSimd128(node), VisitF32x4Max(node);
1960     case IrOpcode::kF32x4Eq:
1961       return MarkAsSimd128(node), VisitF32x4Eq(node);
1962     case IrOpcode::kF32x4Ne:
1963       return MarkAsSimd128(node), VisitF32x4Ne(node);
1964     case IrOpcode::kF32x4Lt:
1965       return MarkAsSimd128(node), VisitF32x4Lt(node);
1966     case IrOpcode::kF32x4Le:
1967       return MarkAsSimd128(node), VisitF32x4Le(node);
1968     case IrOpcode::kF32x4Qfma:
1969       return MarkAsSimd128(node), VisitF32x4Qfma(node);
1970     case IrOpcode::kF32x4Qfms:
1971       return MarkAsSimd128(node), VisitF32x4Qfms(node);
1972     case IrOpcode::kF32x4Pmin:
1973       return MarkAsSimd128(node), VisitF32x4Pmin(node);
1974     case IrOpcode::kF32x4Pmax:
1975       return MarkAsSimd128(node), VisitF32x4Pmax(node);
1976     case IrOpcode::kF32x4Ceil:
1977       return MarkAsSimd128(node), VisitF32x4Ceil(node);
1978     case IrOpcode::kF32x4Floor:
1979       return MarkAsSimd128(node), VisitF32x4Floor(node);
1980     case IrOpcode::kF32x4Trunc:
1981       return MarkAsSimd128(node), VisitF32x4Trunc(node);
1982     case IrOpcode::kF32x4NearestInt:
1983       return MarkAsSimd128(node), VisitF32x4NearestInt(node);
1984     case IrOpcode::kI64x2Splat:
1985       return MarkAsSimd128(node), VisitI64x2Splat(node);
1986     case IrOpcode::kI64x2SplatI32Pair:
1987       return MarkAsSimd128(node), VisitI64x2SplatI32Pair(node);
1988     case IrOpcode::kI64x2ExtractLane:
1989       return MarkAsWord64(node), VisitI64x2ExtractLane(node);
1990     case IrOpcode::kI64x2ReplaceLane:
1991       return MarkAsSimd128(node), VisitI64x2ReplaceLane(node);
1992     case IrOpcode::kI64x2ReplaceLaneI32Pair:
1993       return MarkAsSimd128(node), VisitI64x2ReplaceLaneI32Pair(node);
1994     case IrOpcode::kI64x2Neg:
1995       return MarkAsSimd128(node), VisitI64x2Neg(node);
1996     case IrOpcode::kI64x2SConvertI32x4Low:
1997       return MarkAsSimd128(node), VisitI64x2SConvertI32x4Low(node);
1998     case IrOpcode::kI64x2SConvertI32x4High:
1999       return MarkAsSimd128(node), VisitI64x2SConvertI32x4High(node);
2000     case IrOpcode::kI64x2UConvertI32x4Low:
2001       return MarkAsSimd128(node), VisitI64x2UConvertI32x4Low(node);
2002     case IrOpcode::kI64x2UConvertI32x4High:
2003       return MarkAsSimd128(node), VisitI64x2UConvertI32x4High(node);
2004     case IrOpcode::kI64x2BitMask:
2005       return MarkAsWord32(node), VisitI64x2BitMask(node);
2006     case IrOpcode::kI64x2Shl:
2007       return MarkAsSimd128(node), VisitI64x2Shl(node);
2008     case IrOpcode::kI64x2ShrS:
2009       return MarkAsSimd128(node), VisitI64x2ShrS(node);
2010     case IrOpcode::kI64x2Add:
2011       return MarkAsSimd128(node), VisitI64x2Add(node);
2012     case IrOpcode::kI64x2Sub:
2013       return MarkAsSimd128(node), VisitI64x2Sub(node);
2014     case IrOpcode::kI64x2Mul:
2015       return MarkAsSimd128(node), VisitI64x2Mul(node);
2016     case IrOpcode::kI64x2Eq:
2017       return MarkAsSimd128(node), VisitI64x2Eq(node);
2018     case IrOpcode::kI64x2ShrU:
2019       return MarkAsSimd128(node), VisitI64x2ShrU(node);
2020     case IrOpcode::kI64x2ExtMulLowI32x4S:
2021       return MarkAsSimd128(node), VisitI64x2ExtMulLowI32x4S(node);
2022     case IrOpcode::kI64x2ExtMulHighI32x4S:
2023       return MarkAsSimd128(node), VisitI64x2ExtMulHighI32x4S(node);
2024     case IrOpcode::kI64x2ExtMulLowI32x4U:
2025       return MarkAsSimd128(node), VisitI64x2ExtMulLowI32x4U(node);
2026     case IrOpcode::kI64x2ExtMulHighI32x4U:
2027       return MarkAsSimd128(node), VisitI64x2ExtMulHighI32x4U(node);
2028     case IrOpcode::kI64x2SignSelect:
2029       return MarkAsSimd128(node), VisitI64x2SignSelect(node);
2030     case IrOpcode::kI32x4Splat:
2031       return MarkAsSimd128(node), VisitI32x4Splat(node);
2032     case IrOpcode::kI32x4ExtractLane:
2033       return MarkAsWord32(node), VisitI32x4ExtractLane(node);
2034     case IrOpcode::kI32x4ReplaceLane:
2035       return MarkAsSimd128(node), VisitI32x4ReplaceLane(node);
2036     case IrOpcode::kI32x4SConvertF32x4:
2037       return MarkAsSimd128(node), VisitI32x4SConvertF32x4(node);
2038     case IrOpcode::kI32x4SConvertI16x8Low:
2039       return MarkAsSimd128(node), VisitI32x4SConvertI16x8Low(node);
2040     case IrOpcode::kI32x4SConvertI16x8High:
2041       return MarkAsSimd128(node), VisitI32x4SConvertI16x8High(node);
2042     case IrOpcode::kI32x4Neg:
2043       return MarkAsSimd128(node), VisitI32x4Neg(node);
2044     case IrOpcode::kI32x4Shl:
2045       return MarkAsSimd128(node), VisitI32x4Shl(node);
2046     case IrOpcode::kI32x4ShrS:
2047       return MarkAsSimd128(node), VisitI32x4ShrS(node);
2048     case IrOpcode::kI32x4Add:
2049       return MarkAsSimd128(node), VisitI32x4Add(node);
2050     case IrOpcode::kI32x4AddHoriz:
2051       return MarkAsSimd128(node), VisitI32x4AddHoriz(node);
2052     case IrOpcode::kI32x4Sub:
2053       return MarkAsSimd128(node), VisitI32x4Sub(node);
2054     case IrOpcode::kI32x4Mul:
2055       return MarkAsSimd128(node), VisitI32x4Mul(node);
2056     case IrOpcode::kI32x4MinS:
2057       return MarkAsSimd128(node), VisitI32x4MinS(node);
2058     case IrOpcode::kI32x4MaxS:
2059       return MarkAsSimd128(node), VisitI32x4MaxS(node);
2060     case IrOpcode::kI32x4Eq:
2061       return MarkAsSimd128(node), VisitI32x4Eq(node);
2062     case IrOpcode::kI32x4Ne:
2063       return MarkAsSimd128(node), VisitI32x4Ne(node);
2064     case IrOpcode::kI32x4GtS:
2065       return MarkAsSimd128(node), VisitI32x4GtS(node);
2066     case IrOpcode::kI32x4GeS:
2067       return MarkAsSimd128(node), VisitI32x4GeS(node);
2068     case IrOpcode::kI32x4UConvertF32x4:
2069       return MarkAsSimd128(node), VisitI32x4UConvertF32x4(node);
2070     case IrOpcode::kI32x4UConvertI16x8Low:
2071       return MarkAsSimd128(node), VisitI32x4UConvertI16x8Low(node);
2072     case IrOpcode::kI32x4UConvertI16x8High:
2073       return MarkAsSimd128(node), VisitI32x4UConvertI16x8High(node);
2074     case IrOpcode::kI32x4ShrU:
2075       return MarkAsSimd128(node), VisitI32x4ShrU(node);
2076     case IrOpcode::kI32x4MinU:
2077       return MarkAsSimd128(node), VisitI32x4MinU(node);
2078     case IrOpcode::kI32x4MaxU:
2079       return MarkAsSimd128(node), VisitI32x4MaxU(node);
2080     case IrOpcode::kI32x4GtU:
2081       return MarkAsSimd128(node), VisitI32x4GtU(node);
2082     case IrOpcode::kI32x4GeU:
2083       return MarkAsSimd128(node), VisitI32x4GeU(node);
2084     case IrOpcode::kI32x4Abs:
2085       return MarkAsSimd128(node), VisitI32x4Abs(node);
2086     case IrOpcode::kI32x4BitMask:
2087       return MarkAsWord32(node), VisitI32x4BitMask(node);
2088     case IrOpcode::kI32x4DotI16x8S:
2089       return MarkAsSimd128(node), VisitI32x4DotI16x8S(node);
2090     case IrOpcode::kI32x4ExtMulLowI16x8S:
2091       return MarkAsSimd128(node), VisitI32x4ExtMulLowI16x8S(node);
2092     case IrOpcode::kI32x4ExtMulHighI16x8S:
2093       return MarkAsSimd128(node), VisitI32x4ExtMulHighI16x8S(node);
2094     case IrOpcode::kI32x4ExtMulLowI16x8U:
2095       return MarkAsSimd128(node), VisitI32x4ExtMulLowI16x8U(node);
2096     case IrOpcode::kI32x4ExtMulHighI16x8U:
2097       return MarkAsSimd128(node), VisitI32x4ExtMulHighI16x8U(node);
2098     case IrOpcode::kI32x4SignSelect:
2099       return MarkAsSimd128(node), VisitI32x4SignSelect(node);
2100     case IrOpcode::kI32x4ExtAddPairwiseI16x8S:
2101       return MarkAsSimd128(node), VisitI32x4ExtAddPairwiseI16x8S(node);
2102     case IrOpcode::kI32x4ExtAddPairwiseI16x8U:
2103       return MarkAsSimd128(node), VisitI32x4ExtAddPairwiseI16x8U(node);
2104     case IrOpcode::kI16x8Splat:
2105       return MarkAsSimd128(node), VisitI16x8Splat(node);
2106     case IrOpcode::kI16x8ExtractLaneU:
2107       return MarkAsWord32(node), VisitI16x8ExtractLaneU(node);
2108     case IrOpcode::kI16x8ExtractLaneS:
2109       return MarkAsWord32(node), VisitI16x8ExtractLaneS(node);
2110     case IrOpcode::kI16x8ReplaceLane:
2111       return MarkAsSimd128(node), VisitI16x8ReplaceLane(node);
2112     case IrOpcode::kI16x8SConvertI8x16Low:
2113       return MarkAsSimd128(node), VisitI16x8SConvertI8x16Low(node);
2114     case IrOpcode::kI16x8SConvertI8x16High:
2115       return MarkAsSimd128(node), VisitI16x8SConvertI8x16High(node);
2116     case IrOpcode::kI16x8Neg:
2117       return MarkAsSimd128(node), VisitI16x8Neg(node);
2118     case IrOpcode::kI16x8Shl:
2119       return MarkAsSimd128(node), VisitI16x8Shl(node);
2120     case IrOpcode::kI16x8ShrS:
2121       return MarkAsSimd128(node), VisitI16x8ShrS(node);
2122     case IrOpcode::kI16x8SConvertI32x4:
2123       return MarkAsSimd128(node), VisitI16x8SConvertI32x4(node);
2124     case IrOpcode::kI16x8Add:
2125       return MarkAsSimd128(node), VisitI16x8Add(node);
2126     case IrOpcode::kI16x8AddSatS:
2127       return MarkAsSimd128(node), VisitI16x8AddSatS(node);
2128     case IrOpcode::kI16x8AddHoriz:
2129       return MarkAsSimd128(node), VisitI16x8AddHoriz(node);
2130     case IrOpcode::kI16x8Sub:
2131       return MarkAsSimd128(node), VisitI16x8Sub(node);
2132     case IrOpcode::kI16x8SubSatS:
2133       return MarkAsSimd128(node), VisitI16x8SubSatS(node);
2134     case IrOpcode::kI16x8Mul:
2135       return MarkAsSimd128(node), VisitI16x8Mul(node);
2136     case IrOpcode::kI16x8MinS:
2137       return MarkAsSimd128(node), VisitI16x8MinS(node);
2138     case IrOpcode::kI16x8MaxS:
2139       return MarkAsSimd128(node), VisitI16x8MaxS(node);
2140     case IrOpcode::kI16x8Eq:
2141       return MarkAsSimd128(node), VisitI16x8Eq(node);
2142     case IrOpcode::kI16x8Ne:
2143       return MarkAsSimd128(node), VisitI16x8Ne(node);
2144     case IrOpcode::kI16x8GtS:
2145       return MarkAsSimd128(node), VisitI16x8GtS(node);
2146     case IrOpcode::kI16x8GeS:
2147       return MarkAsSimd128(node), VisitI16x8GeS(node);
2148     case IrOpcode::kI16x8UConvertI8x16Low:
2149       return MarkAsSimd128(node), VisitI16x8UConvertI8x16Low(node);
2150     case IrOpcode::kI16x8UConvertI8x16High:
2151       return MarkAsSimd128(node), VisitI16x8UConvertI8x16High(node);
2152     case IrOpcode::kI16x8ShrU:
2153       return MarkAsSimd128(node), VisitI16x8ShrU(node);
2154     case IrOpcode::kI16x8UConvertI32x4:
2155       return MarkAsSimd128(node), VisitI16x8UConvertI32x4(node);
2156     case IrOpcode::kI16x8AddSatU:
2157       return MarkAsSimd128(node), VisitI16x8AddSatU(node);
2158     case IrOpcode::kI16x8SubSatU:
2159       return MarkAsSimd128(node), VisitI16x8SubSatU(node);
2160     case IrOpcode::kI16x8MinU:
2161       return MarkAsSimd128(node), VisitI16x8MinU(node);
2162     case IrOpcode::kI16x8MaxU:
2163       return MarkAsSimd128(node), VisitI16x8MaxU(node);
2164     case IrOpcode::kI16x8GtU:
2165       return MarkAsSimd128(node), VisitI16x8GtU(node);
2166     case IrOpcode::kI16x8GeU:
2167       return MarkAsSimd128(node), VisitI16x8GeU(node);
2168     case IrOpcode::kI16x8RoundingAverageU:
2169       return MarkAsSimd128(node), VisitI16x8RoundingAverageU(node);
2170     case IrOpcode::kI16x8Q15MulRSatS:
2171       return MarkAsSimd128(node), VisitI16x8Q15MulRSatS(node);
2172     case IrOpcode::kI16x8Abs:
2173       return MarkAsSimd128(node), VisitI16x8Abs(node);
2174     case IrOpcode::kI16x8BitMask:
2175       return MarkAsWord32(node), VisitI16x8BitMask(node);
2176     case IrOpcode::kI16x8ExtMulLowI8x16S:
2177       return MarkAsSimd128(node), VisitI16x8ExtMulLowI8x16S(node);
2178     case IrOpcode::kI16x8ExtMulHighI8x16S:
2179       return MarkAsSimd128(node), VisitI16x8ExtMulHighI8x16S(node);
2180     case IrOpcode::kI16x8ExtMulLowI8x16U:
2181       return MarkAsSimd128(node), VisitI16x8ExtMulLowI8x16U(node);
2182     case IrOpcode::kI16x8ExtMulHighI8x16U:
2183       return MarkAsSimd128(node), VisitI16x8ExtMulHighI8x16U(node);
2184     case IrOpcode::kI16x8SignSelect:
2185       return MarkAsSimd128(node), VisitI16x8SignSelect(node);
2186     case IrOpcode::kI16x8ExtAddPairwiseI8x16S:
2187       return MarkAsSimd128(node), VisitI16x8ExtAddPairwiseI8x16S(node);
2188     case IrOpcode::kI16x8ExtAddPairwiseI8x16U:
2189       return MarkAsSimd128(node), VisitI16x8ExtAddPairwiseI8x16U(node);
2190     case IrOpcode::kI8x16Splat:
2191       return MarkAsSimd128(node), VisitI8x16Splat(node);
2192     case IrOpcode::kI8x16ExtractLaneU:
2193       return MarkAsWord32(node), VisitI8x16ExtractLaneU(node);
2194     case IrOpcode::kI8x16ExtractLaneS:
2195       return MarkAsWord32(node), VisitI8x16ExtractLaneS(node);
2196     case IrOpcode::kI8x16ReplaceLane:
2197       return MarkAsSimd128(node), VisitI8x16ReplaceLane(node);
2198     case IrOpcode::kI8x16Neg:
2199       return MarkAsSimd128(node), VisitI8x16Neg(node);
2200     case IrOpcode::kI8x16Shl:
2201       return MarkAsSimd128(node), VisitI8x16Shl(node);
2202     case IrOpcode::kI8x16ShrS:
2203       return MarkAsSimd128(node), VisitI8x16ShrS(node);
2204     case IrOpcode::kI8x16SConvertI16x8:
2205       return MarkAsSimd128(node), VisitI8x16SConvertI16x8(node);
2206     case IrOpcode::kI8x16Add:
2207       return MarkAsSimd128(node), VisitI8x16Add(node);
2208     case IrOpcode::kI8x16AddSatS:
2209       return MarkAsSimd128(node), VisitI8x16AddSatS(node);
2210     case IrOpcode::kI8x16Sub:
2211       return MarkAsSimd128(node), VisitI8x16Sub(node);
2212     case IrOpcode::kI8x16SubSatS:
2213       return MarkAsSimd128(node), VisitI8x16SubSatS(node);
2214     case IrOpcode::kI8x16Mul:
2215       return MarkAsSimd128(node), VisitI8x16Mul(node);
2216     case IrOpcode::kI8x16MinS:
2217       return MarkAsSimd128(node), VisitI8x16MinS(node);
2218     case IrOpcode::kI8x16MaxS:
2219       return MarkAsSimd128(node), VisitI8x16MaxS(node);
2220     case IrOpcode::kI8x16Eq:
2221       return MarkAsSimd128(node), VisitI8x16Eq(node);
2222     case IrOpcode::kI8x16Ne:
2223       return MarkAsSimd128(node), VisitI8x16Ne(node);
2224     case IrOpcode::kI8x16GtS:
2225       return MarkAsSimd128(node), VisitI8x16GtS(node);
2226     case IrOpcode::kI8x16GeS:
2227       return MarkAsSimd128(node), VisitI8x16GeS(node);
2228     case IrOpcode::kI8x16ShrU:
2229       return MarkAsSimd128(node), VisitI8x16ShrU(node);
2230     case IrOpcode::kI8x16UConvertI16x8:
2231       return MarkAsSimd128(node), VisitI8x16UConvertI16x8(node);
2232     case IrOpcode::kI8x16AddSatU:
2233       return MarkAsSimd128(node), VisitI8x16AddSatU(node);
2234     case IrOpcode::kI8x16SubSatU:
2235       return MarkAsSimd128(node), VisitI8x16SubSatU(node);
2236     case IrOpcode::kI8x16MinU:
2237       return MarkAsSimd128(node), VisitI8x16MinU(node);
2238     case IrOpcode::kI8x16MaxU:
2239       return MarkAsSimd128(node), VisitI8x16MaxU(node);
2240     case IrOpcode::kI8x16GtU:
2241       return MarkAsSimd128(node), VisitI8x16GtU(node);
2242     case IrOpcode::kI8x16GeU:
2243       return MarkAsSimd128(node), VisitI8x16GeU(node);
2244     case IrOpcode::kI8x16RoundingAverageU:
2245       return MarkAsSimd128(node), VisitI8x16RoundingAverageU(node);
2246     case IrOpcode::kI8x16Popcnt:
2247       return MarkAsSimd128(node), VisitI8x16Popcnt(node);
2248     case IrOpcode::kI8x16Abs:
2249       return MarkAsSimd128(node), VisitI8x16Abs(node);
2250     case IrOpcode::kI8x16BitMask:
2251       return MarkAsWord32(node), VisitI8x16BitMask(node);
2252     case IrOpcode::kI8x16SignSelect:
2253       return MarkAsSimd128(node), VisitI8x16SignSelect(node);
2254     case IrOpcode::kS128Const:
2255       return MarkAsSimd128(node), VisitS128Const(node);
2256     case IrOpcode::kS128Zero:
2257       return MarkAsSimd128(node), VisitS128Zero(node);
2258     case IrOpcode::kS128And:
2259       return MarkAsSimd128(node), VisitS128And(node);
2260     case IrOpcode::kS128Or:
2261       return MarkAsSimd128(node), VisitS128Or(node);
2262     case IrOpcode::kS128Xor:
2263       return MarkAsSimd128(node), VisitS128Xor(node);
2264     case IrOpcode::kS128Not:
2265       return MarkAsSimd128(node), VisitS128Not(node);
2266     case IrOpcode::kS128Select:
2267       return MarkAsSimd128(node), VisitS128Select(node);
2268     case IrOpcode::kS128AndNot:
2269       return MarkAsSimd128(node), VisitS128AndNot(node);
2270     case IrOpcode::kI8x16Swizzle:
2271       return MarkAsSimd128(node), VisitI8x16Swizzle(node);
2272     case IrOpcode::kI8x16Shuffle:
2273       return MarkAsSimd128(node), VisitI8x16Shuffle(node);
2274     case IrOpcode::kV32x4AnyTrue:
2275       return MarkAsWord32(node), VisitV32x4AnyTrue(node);
2276     case IrOpcode::kV32x4AllTrue:
2277       return MarkAsWord32(node), VisitV32x4AllTrue(node);
2278     case IrOpcode::kV16x8AnyTrue:
2279       return MarkAsWord32(node), VisitV16x8AnyTrue(node);
2280     case IrOpcode::kV16x8AllTrue:
2281       return MarkAsWord32(node), VisitV16x8AllTrue(node);
2282     case IrOpcode::kV8x16AnyTrue:
2283       return MarkAsWord32(node), VisitV8x16AnyTrue(node);
2284     case IrOpcode::kV8x16AllTrue:
2285       return MarkAsWord32(node), VisitV8x16AllTrue(node);
2286     default:
2287       FATAL("Unexpected operator #%d:%s @ node #%d", node->opcode(),
2288             node->op()->mnemonic(), node->id());
2289       break;
2290   }
2291 }
2292 
EmitWordPoisonOnSpeculation(Node * node)2293 void InstructionSelector::EmitWordPoisonOnSpeculation(Node* node) {
2294   if (poisoning_level_ != PoisoningMitigationLevel::kDontPoison) {
2295     OperandGenerator g(this);
2296     Node* input_node = NodeProperties::GetValueInput(node, 0);
2297     InstructionOperand input = g.UseRegister(input_node);
2298     InstructionOperand output = g.DefineSameAsFirst(node);
2299     Emit(kArchWordPoisonOnSpeculation, output, input);
2300   } else {
2301     EmitIdentity(node);
2302   }
2303 }
2304 
VisitWord32PoisonOnSpeculation(Node * node)2305 void InstructionSelector::VisitWord32PoisonOnSpeculation(Node* node) {
2306   EmitWordPoisonOnSpeculation(node);
2307 }
2308 
VisitWord64PoisonOnSpeculation(Node * node)2309 void InstructionSelector::VisitWord64PoisonOnSpeculation(Node* node) {
2310   EmitWordPoisonOnSpeculation(node);
2311 }
2312 
VisitTaggedPoisonOnSpeculation(Node * node)2313 void InstructionSelector::VisitTaggedPoisonOnSpeculation(Node* node) {
2314   EmitWordPoisonOnSpeculation(node);
2315 }
2316 
VisitStackPointerGreaterThan(Node * node)2317 void InstructionSelector::VisitStackPointerGreaterThan(Node* node) {
2318   FlagsContinuation cont =
2319       FlagsContinuation::ForSet(kStackPointerGreaterThanCondition, node);
2320   VisitStackPointerGreaterThan(node, &cont);
2321 }
2322 
VisitLoadStackCheckOffset(Node * node)2323 void InstructionSelector::VisitLoadStackCheckOffset(Node* node) {
2324   OperandGenerator g(this);
2325   Emit(kArchStackCheckOffset, g.DefineAsRegister(node));
2326 }
2327 
VisitLoadFramePointer(Node * node)2328 void InstructionSelector::VisitLoadFramePointer(Node* node) {
2329   OperandGenerator g(this);
2330   Emit(kArchFramePointer, g.DefineAsRegister(node));
2331 }
2332 
VisitLoadParentFramePointer(Node * node)2333 void InstructionSelector::VisitLoadParentFramePointer(Node* node) {
2334   OperandGenerator g(this);
2335   Emit(kArchParentFramePointer, g.DefineAsRegister(node));
2336 }
2337 
VisitFloat64Acos(Node * node)2338 void InstructionSelector::VisitFloat64Acos(Node* node) {
2339   VisitFloat64Ieee754Unop(node, kIeee754Float64Acos);
2340 }
2341 
VisitFloat64Acosh(Node * node)2342 void InstructionSelector::VisitFloat64Acosh(Node* node) {
2343   VisitFloat64Ieee754Unop(node, kIeee754Float64Acosh);
2344 }
2345 
VisitFloat64Asin(Node * node)2346 void InstructionSelector::VisitFloat64Asin(Node* node) {
2347   VisitFloat64Ieee754Unop(node, kIeee754Float64Asin);
2348 }
2349 
VisitFloat64Asinh(Node * node)2350 void InstructionSelector::VisitFloat64Asinh(Node* node) {
2351   VisitFloat64Ieee754Unop(node, kIeee754Float64Asinh);
2352 }
2353 
VisitFloat64Atan(Node * node)2354 void InstructionSelector::VisitFloat64Atan(Node* node) {
2355   VisitFloat64Ieee754Unop(node, kIeee754Float64Atan);
2356 }
2357 
VisitFloat64Atanh(Node * node)2358 void InstructionSelector::VisitFloat64Atanh(Node* node) {
2359   VisitFloat64Ieee754Unop(node, kIeee754Float64Atanh);
2360 }
2361 
VisitFloat64Atan2(Node * node)2362 void InstructionSelector::VisitFloat64Atan2(Node* node) {
2363   VisitFloat64Ieee754Binop(node, kIeee754Float64Atan2);
2364 }
2365 
VisitFloat64Cbrt(Node * node)2366 void InstructionSelector::VisitFloat64Cbrt(Node* node) {
2367   VisitFloat64Ieee754Unop(node, kIeee754Float64Cbrt);
2368 }
2369 
VisitFloat64Cos(Node * node)2370 void InstructionSelector::VisitFloat64Cos(Node* node) {
2371   VisitFloat64Ieee754Unop(node, kIeee754Float64Cos);
2372 }
2373 
VisitFloat64Cosh(Node * node)2374 void InstructionSelector::VisitFloat64Cosh(Node* node) {
2375   VisitFloat64Ieee754Unop(node, kIeee754Float64Cosh);
2376 }
2377 
VisitFloat64Exp(Node * node)2378 void InstructionSelector::VisitFloat64Exp(Node* node) {
2379   VisitFloat64Ieee754Unop(node, kIeee754Float64Exp);
2380 }
2381 
VisitFloat64Expm1(Node * node)2382 void InstructionSelector::VisitFloat64Expm1(Node* node) {
2383   VisitFloat64Ieee754Unop(node, kIeee754Float64Expm1);
2384 }
2385 
VisitFloat64Log(Node * node)2386 void InstructionSelector::VisitFloat64Log(Node* node) {
2387   VisitFloat64Ieee754Unop(node, kIeee754Float64Log);
2388 }
2389 
VisitFloat64Log1p(Node * node)2390 void InstructionSelector::VisitFloat64Log1p(Node* node) {
2391   VisitFloat64Ieee754Unop(node, kIeee754Float64Log1p);
2392 }
2393 
VisitFloat64Log2(Node * node)2394 void InstructionSelector::VisitFloat64Log2(Node* node) {
2395   VisitFloat64Ieee754Unop(node, kIeee754Float64Log2);
2396 }
2397 
VisitFloat64Log10(Node * node)2398 void InstructionSelector::VisitFloat64Log10(Node* node) {
2399   VisitFloat64Ieee754Unop(node, kIeee754Float64Log10);
2400 }
2401 
VisitFloat64Pow(Node * node)2402 void InstructionSelector::VisitFloat64Pow(Node* node) {
2403   VisitFloat64Ieee754Binop(node, kIeee754Float64Pow);
2404 }
2405 
VisitFloat64Sin(Node * node)2406 void InstructionSelector::VisitFloat64Sin(Node* node) {
2407   VisitFloat64Ieee754Unop(node, kIeee754Float64Sin);
2408 }
2409 
VisitFloat64Sinh(Node * node)2410 void InstructionSelector::VisitFloat64Sinh(Node* node) {
2411   VisitFloat64Ieee754Unop(node, kIeee754Float64Sinh);
2412 }
2413 
VisitFloat64Tan(Node * node)2414 void InstructionSelector::VisitFloat64Tan(Node* node) {
2415   VisitFloat64Ieee754Unop(node, kIeee754Float64Tan);
2416 }
2417 
VisitFloat64Tanh(Node * node)2418 void InstructionSelector::VisitFloat64Tanh(Node* node) {
2419   VisitFloat64Ieee754Unop(node, kIeee754Float64Tanh);
2420 }
2421 
EmitTableSwitch(const SwitchInfo & sw,InstructionOperand const & index_operand)2422 void InstructionSelector::EmitTableSwitch(
2423     const SwitchInfo& sw, InstructionOperand const& index_operand) {
2424   OperandGenerator g(this);
2425   size_t input_count = 2 + sw.value_range();
2426   DCHECK_LE(sw.value_range(), std::numeric_limits<size_t>::max() - 2);
2427   auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
2428   inputs[0] = index_operand;
2429   InstructionOperand default_operand = g.Label(sw.default_branch());
2430   std::fill(&inputs[1], &inputs[input_count], default_operand);
2431   for (const CaseInfo& c : sw.CasesUnsorted()) {
2432     size_t value = c.value - sw.min_value();
2433     DCHECK_LE(0u, value);
2434     DCHECK_LT(value + 2, input_count);
2435     inputs[value + 2] = g.Label(c.branch);
2436   }
2437   Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
2438 }
2439 
EmitBinarySearchSwitch(const SwitchInfo & sw,InstructionOperand const & value_operand)2440 void InstructionSelector::EmitBinarySearchSwitch(
2441     const SwitchInfo& sw, InstructionOperand const& value_operand) {
2442   OperandGenerator g(this);
2443   size_t input_count = 2 + sw.case_count() * 2;
2444   DCHECK_LE(sw.case_count(), (std::numeric_limits<size_t>::max() - 2) / 2);
2445   auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
2446   inputs[0] = value_operand;
2447   inputs[1] = g.Label(sw.default_branch());
2448   std::vector<CaseInfo> cases = sw.CasesSortedByValue();
2449   for (size_t index = 0; index < cases.size(); ++index) {
2450     const CaseInfo& c = cases[index];
2451     inputs[index * 2 + 2 + 0] = g.TempImmediate(c.value);
2452     inputs[index * 2 + 2 + 1] = g.Label(c.branch);
2453   }
2454   Emit(kArchBinarySearchSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
2455 }
2456 
VisitBitcastTaggedToWord(Node * node)2457 void InstructionSelector::VisitBitcastTaggedToWord(Node* node) {
2458   EmitIdentity(node);
2459 }
2460 
VisitBitcastWordToTagged(Node * node)2461 void InstructionSelector::VisitBitcastWordToTagged(Node* node) {
2462   OperandGenerator g(this);
2463   Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(node->InputAt(0)));
2464 }
2465 
2466 // 32 bit targets do not implement the following instructions.
2467 #if V8_TARGET_ARCH_32_BIT
2468 
VisitWord64And(Node * node)2469 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
2470 
VisitWord64Or(Node * node)2471 void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); }
2472 
VisitWord64Xor(Node * node)2473 void InstructionSelector::VisitWord64Xor(Node* node) { UNIMPLEMENTED(); }
2474 
VisitWord64Shl(Node * node)2475 void InstructionSelector::VisitWord64Shl(Node* node) { UNIMPLEMENTED(); }
2476 
VisitWord64Shr(Node * node)2477 void InstructionSelector::VisitWord64Shr(Node* node) { UNIMPLEMENTED(); }
2478 
VisitWord64Sar(Node * node)2479 void InstructionSelector::VisitWord64Sar(Node* node) { UNIMPLEMENTED(); }
2480 
VisitWord64Rol(Node * node)2481 void InstructionSelector::VisitWord64Rol(Node* node) { UNIMPLEMENTED(); }
2482 
VisitWord64Ror(Node * node)2483 void InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); }
2484 
VisitWord64Clz(Node * node)2485 void InstructionSelector::VisitWord64Clz(Node* node) { UNIMPLEMENTED(); }
2486 
VisitWord64Ctz(Node * node)2487 void InstructionSelector::VisitWord64Ctz(Node* node) { UNIMPLEMENTED(); }
2488 
VisitWord64ReverseBits(Node * node)2489 void InstructionSelector::VisitWord64ReverseBits(Node* node) {
2490   UNIMPLEMENTED();
2491 }
2492 
VisitWord64Popcnt(Node * node)2493 void InstructionSelector::VisitWord64Popcnt(Node* node) { UNIMPLEMENTED(); }
2494 
VisitWord64Equal(Node * node)2495 void InstructionSelector::VisitWord64Equal(Node* node) { UNIMPLEMENTED(); }
2496 
VisitInt64Add(Node * node)2497 void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); }
2498 
VisitInt64AddWithOverflow(Node * node)2499 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
2500   UNIMPLEMENTED();
2501 }
2502 
VisitInt64Sub(Node * node)2503 void InstructionSelector::VisitInt64Sub(Node* node) { UNIMPLEMENTED(); }
2504 
VisitInt64SubWithOverflow(Node * node)2505 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
2506   UNIMPLEMENTED();
2507 }
2508 
VisitInt64Mul(Node * node)2509 void InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); }
2510 
VisitInt64Div(Node * node)2511 void InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); }
2512 
VisitInt64LessThan(Node * node)2513 void InstructionSelector::VisitInt64LessThan(Node* node) { UNIMPLEMENTED(); }
2514 
VisitInt64LessThanOrEqual(Node * node)2515 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
2516   UNIMPLEMENTED();
2517 }
2518 
VisitUint64Div(Node * node)2519 void InstructionSelector::VisitUint64Div(Node* node) { UNIMPLEMENTED(); }
2520 
VisitInt64Mod(Node * node)2521 void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); }
2522 
VisitUint64LessThan(Node * node)2523 void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); }
2524 
VisitUint64LessThanOrEqual(Node * node)2525 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
2526   UNIMPLEMENTED();
2527 }
2528 
VisitUint64Mod(Node * node)2529 void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); }
2530 
VisitBitcastWord32ToWord64(Node * node)2531 void InstructionSelector::VisitBitcastWord32ToWord64(Node* node) {
2532   UNIMPLEMENTED();
2533 }
2534 
VisitChangeInt32ToInt64(Node * node)2535 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
2536   UNIMPLEMENTED();
2537 }
2538 
VisitChangeInt64ToFloat64(Node * node)2539 void InstructionSelector::VisitChangeInt64ToFloat64(Node* node) {
2540   UNIMPLEMENTED();
2541 }
2542 
VisitChangeUint32ToUint64(Node * node)2543 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
2544   UNIMPLEMENTED();
2545 }
2546 
VisitChangeFloat64ToInt64(Node * node)2547 void InstructionSelector::VisitChangeFloat64ToInt64(Node* node) {
2548   UNIMPLEMENTED();
2549 }
2550 
VisitChangeFloat64ToUint64(Node * node)2551 void InstructionSelector::VisitChangeFloat64ToUint64(Node* node) {
2552   UNIMPLEMENTED();
2553 }
2554 
VisitTruncateFloat64ToInt64(Node * node)2555 void InstructionSelector::VisitTruncateFloat64ToInt64(Node* node) {
2556   UNIMPLEMENTED();
2557 }
2558 
VisitTryTruncateFloat32ToInt64(Node * node)2559 void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
2560   UNIMPLEMENTED();
2561 }
2562 
VisitTryTruncateFloat64ToInt64(Node * node)2563 void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
2564   UNIMPLEMENTED();
2565 }
2566 
VisitTryTruncateFloat32ToUint64(Node * node)2567 void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
2568   UNIMPLEMENTED();
2569 }
2570 
VisitTryTruncateFloat64ToUint64(Node * node)2571 void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
2572   UNIMPLEMENTED();
2573 }
2574 
VisitTruncateInt64ToInt32(Node * node)2575 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
2576   UNIMPLEMENTED();
2577 }
2578 
VisitRoundInt64ToFloat32(Node * node)2579 void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
2580   UNIMPLEMENTED();
2581 }
2582 
VisitRoundInt64ToFloat64(Node * node)2583 void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
2584   UNIMPLEMENTED();
2585 }
2586 
VisitRoundUint64ToFloat32(Node * node)2587 void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
2588   UNIMPLEMENTED();
2589 }
2590 
VisitRoundUint64ToFloat64(Node * node)2591 void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
2592   UNIMPLEMENTED();
2593 }
2594 
VisitBitcastFloat64ToInt64(Node * node)2595 void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
2596   UNIMPLEMENTED();
2597 }
2598 
VisitBitcastInt64ToFloat64(Node * node)2599 void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
2600   UNIMPLEMENTED();
2601 }
2602 
VisitSignExtendWord8ToInt64(Node * node)2603 void InstructionSelector::VisitSignExtendWord8ToInt64(Node* node) {
2604   UNIMPLEMENTED();
2605 }
2606 
VisitSignExtendWord16ToInt64(Node * node)2607 void InstructionSelector::VisitSignExtendWord16ToInt64(Node* node) {
2608   UNIMPLEMENTED();
2609 }
2610 
VisitSignExtendWord32ToInt64(Node * node)2611 void InstructionSelector::VisitSignExtendWord32ToInt64(Node* node) {
2612   UNIMPLEMENTED();
2613 }
2614 #endif  // V8_TARGET_ARCH_32_BIT
2615 
2616 // 64 bit targets do not implement the following instructions.
2617 #if V8_TARGET_ARCH_64_BIT
VisitInt32PairAdd(Node * node)2618 void InstructionSelector::VisitInt32PairAdd(Node* node) { UNIMPLEMENTED(); }
2619 
VisitInt32PairSub(Node * node)2620 void InstructionSelector::VisitInt32PairSub(Node* node) { UNIMPLEMENTED(); }
2621 
VisitInt32PairMul(Node * node)2622 void InstructionSelector::VisitInt32PairMul(Node* node) { UNIMPLEMENTED(); }
2623 
VisitWord32PairShl(Node * node)2624 void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); }
2625 
VisitWord32PairShr(Node * node)2626 void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); }
2627 
VisitWord32PairSar(Node * node)2628 void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); }
2629 #endif  // V8_TARGET_ARCH_64_BIT
2630 
2631 #if !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS
VisitWord32AtomicPairLoad(Node * node)2632 void InstructionSelector::VisitWord32AtomicPairLoad(Node* node) {
2633   UNIMPLEMENTED();
2634 }
2635 
VisitWord32AtomicPairStore(Node * node)2636 void InstructionSelector::VisitWord32AtomicPairStore(Node* node) {
2637   UNIMPLEMENTED();
2638 }
2639 
VisitWord32AtomicPairAdd(Node * node)2640 void InstructionSelector::VisitWord32AtomicPairAdd(Node* node) {
2641   UNIMPLEMENTED();
2642 }
2643 
VisitWord32AtomicPairSub(Node * node)2644 void InstructionSelector::VisitWord32AtomicPairSub(Node* node) {
2645   UNIMPLEMENTED();
2646 }
2647 
VisitWord32AtomicPairAnd(Node * node)2648 void InstructionSelector::VisitWord32AtomicPairAnd(Node* node) {
2649   UNIMPLEMENTED();
2650 }
2651 
VisitWord32AtomicPairOr(Node * node)2652 void InstructionSelector::VisitWord32AtomicPairOr(Node* node) {
2653   UNIMPLEMENTED();
2654 }
2655 
VisitWord32AtomicPairXor(Node * node)2656 void InstructionSelector::VisitWord32AtomicPairXor(Node* node) {
2657   UNIMPLEMENTED();
2658 }
2659 
VisitWord32AtomicPairExchange(Node * node)2660 void InstructionSelector::VisitWord32AtomicPairExchange(Node* node) {
2661   UNIMPLEMENTED();
2662 }
2663 
VisitWord32AtomicPairCompareExchange(Node * node)2664 void InstructionSelector::VisitWord32AtomicPairCompareExchange(Node* node) {
2665   UNIMPLEMENTED();
2666 }
2667 #endif  // !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS
2668 
2669 #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS64 && \
2670     !V8_TARGET_ARCH_S390 && !V8_TARGET_ARCH_PPC64
VisitWord64AtomicLoad(Node * node)2671 void InstructionSelector::VisitWord64AtomicLoad(Node* node) { UNIMPLEMENTED(); }
2672 
VisitWord64AtomicStore(Node * node)2673 void InstructionSelector::VisitWord64AtomicStore(Node* node) {
2674   UNIMPLEMENTED();
2675 }
2676 
VisitWord64AtomicAdd(Node * node)2677 void InstructionSelector::VisitWord64AtomicAdd(Node* node) { UNIMPLEMENTED(); }
2678 
VisitWord64AtomicSub(Node * node)2679 void InstructionSelector::VisitWord64AtomicSub(Node* node) { UNIMPLEMENTED(); }
2680 
VisitWord64AtomicAnd(Node * node)2681 void InstructionSelector::VisitWord64AtomicAnd(Node* node) { UNIMPLEMENTED(); }
2682 
VisitWord64AtomicOr(Node * node)2683 void InstructionSelector::VisitWord64AtomicOr(Node* node) { UNIMPLEMENTED(); }
2684 
VisitWord64AtomicXor(Node * node)2685 void InstructionSelector::VisitWord64AtomicXor(Node* node) { UNIMPLEMENTED(); }
2686 
VisitWord64AtomicExchange(Node * node)2687 void InstructionSelector::VisitWord64AtomicExchange(Node* node) {
2688   UNIMPLEMENTED();
2689 }
2690 
VisitWord64AtomicCompareExchange(Node * node)2691 void InstructionSelector::VisitWord64AtomicCompareExchange(Node* node) {
2692   UNIMPLEMENTED();
2693 }
2694 #endif  // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_PPC64
2695         // !V8_TARGET_ARCH_MIPS64 && !V8_TARGET_ARCH_S390
2696 
2697 #if !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM
2698 // This is only needed on 32-bit to split the 64-bit value into two operands.
VisitI64x2SplatI32Pair(Node * node)2699 void InstructionSelector::VisitI64x2SplatI32Pair(Node* node) {
2700   UNIMPLEMENTED();
2701 }
VisitI64x2ReplaceLaneI32Pair(Node * node)2702 void InstructionSelector::VisitI64x2ReplaceLaneI32Pair(Node* node) {
2703   UNIMPLEMENTED();
2704 }
2705 #endif  // !V8_TARGET_ARCH_IA32
2706 
2707 #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_S390X
2708 #if !V8_TARGET_ARCH_ARM64
2709 #if !V8_TARGET_ARCH_MIPS64
VisitI64x2Splat(Node * node)2710 void InstructionSelector::VisitI64x2Splat(Node* node) { UNIMPLEMENTED(); }
VisitI64x2ExtractLane(Node * node)2711 void InstructionSelector::VisitI64x2ExtractLane(Node* node) { UNIMPLEMENTED(); }
VisitI64x2ReplaceLane(Node * node)2712 void InstructionSelector::VisitI64x2ReplaceLane(Node* node) { UNIMPLEMENTED(); }
2713 #endif  // !V8_TARGET_ARCH_MIPS64
VisitI64x2Eq(Node * node)2714 void InstructionSelector::VisitI64x2Eq(Node* node) { UNIMPLEMENTED(); }
VisitF64x2Qfma(Node * node)2715 void InstructionSelector::VisitF64x2Qfma(Node* node) { UNIMPLEMENTED(); }
VisitF64x2Qfms(Node * node)2716 void InstructionSelector::VisitF64x2Qfms(Node* node) { UNIMPLEMENTED(); }
VisitF32x4Qfma(Node * node)2717 void InstructionSelector::VisitF32x4Qfma(Node* node) { UNIMPLEMENTED(); }
VisitF32x4Qfms(Node * node)2718 void InstructionSelector::VisitF32x4Qfms(Node* node) { UNIMPLEMENTED(); }
2719 #endif  // !V8_TARGET_ARCH_ARM64
2720 #endif  // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_S390X
2721 
2722 #if !V8_TARGET_ARCH_ARM64
2723 // TODO(v8:10971) Prototype i16x8.q15mulr_sat_s
VisitI16x8Q15MulRSatS(Node * node)2724 void InstructionSelector::VisitI16x8Q15MulRSatS(Node* node) { UNIMPLEMENTED(); }
2725 
2726 // TODO(v8:10972) Prototype i64x2 widen i32x4.
VisitI64x2SConvertI32x4Low(Node * node)2727 void InstructionSelector::VisitI64x2SConvertI32x4Low(Node* node) {
2728   UNIMPLEMENTED();
2729 }
2730 
VisitI64x2SConvertI32x4High(Node * node)2731 void InstructionSelector::VisitI64x2SConvertI32x4High(Node* node) {
2732   UNIMPLEMENTED();
2733 }
2734 
VisitI64x2UConvertI32x4Low(Node * node)2735 void InstructionSelector::VisitI64x2UConvertI32x4Low(Node* node) {
2736   UNIMPLEMENTED();
2737 }
2738 
VisitI64x2UConvertI32x4High(Node * node)2739 void InstructionSelector::VisitI64x2UConvertI32x4High(Node* node) {
2740   UNIMPLEMENTED();
2741 }
2742 
2743 // TODO(v8:11002) Prototype i8x16.popcnt.
VisitI8x16Popcnt(Node * node)2744 void InstructionSelector::VisitI8x16Popcnt(Node* node) { UNIMPLEMENTED(); }
2745 
2746 // TODO(v8:11008) Prototype extended multiplication.
VisitI64x2ExtMulLowI32x4S(Node * node)2747 void InstructionSelector::VisitI64x2ExtMulLowI32x4S(Node* node) {
2748   UNIMPLEMENTED();
2749 }
VisitI64x2ExtMulHighI32x4S(Node * node)2750 void InstructionSelector::VisitI64x2ExtMulHighI32x4S(Node* node) {
2751   UNIMPLEMENTED();
2752 }
VisitI64x2ExtMulLowI32x4U(Node * node)2753 void InstructionSelector::VisitI64x2ExtMulLowI32x4U(Node* node) {
2754   UNIMPLEMENTED();
2755 }
VisitI64x2ExtMulHighI32x4U(Node * node)2756 void InstructionSelector::VisitI64x2ExtMulHighI32x4U(Node* node) {
2757   UNIMPLEMENTED();
2758 }
VisitI32x4ExtMulLowI16x8S(Node * node)2759 void InstructionSelector::VisitI32x4ExtMulLowI16x8S(Node* node) {
2760   UNIMPLEMENTED();
2761 }
VisitI32x4ExtMulHighI16x8S(Node * node)2762 void InstructionSelector::VisitI32x4ExtMulHighI16x8S(Node* node) {
2763   UNIMPLEMENTED();
2764 }
VisitI32x4ExtMulLowI16x8U(Node * node)2765 void InstructionSelector::VisitI32x4ExtMulLowI16x8U(Node* node) {
2766   UNIMPLEMENTED();
2767 }
VisitI32x4ExtMulHighI16x8U(Node * node)2768 void InstructionSelector::VisitI32x4ExtMulHighI16x8U(Node* node) {
2769   UNIMPLEMENTED();
2770 }
VisitI16x8ExtMulLowI8x16S(Node * node)2771 void InstructionSelector::VisitI16x8ExtMulLowI8x16S(Node* node) {
2772   UNIMPLEMENTED();
2773 }
VisitI16x8ExtMulHighI8x16S(Node * node)2774 void InstructionSelector::VisitI16x8ExtMulHighI8x16S(Node* node) {
2775   UNIMPLEMENTED();
2776 }
VisitI16x8ExtMulLowI8x16U(Node * node)2777 void InstructionSelector::VisitI16x8ExtMulLowI8x16U(Node* node) {
2778   UNIMPLEMENTED();
2779 }
VisitI16x8ExtMulHighI8x16U(Node * node)2780 void InstructionSelector::VisitI16x8ExtMulHighI8x16U(Node* node) {
2781   UNIMPLEMENTED();
2782 }
2783 
2784 // TODO(v8:11086) Prototype extended pairwise add.
VisitI32x4ExtAddPairwiseI16x8S(Node * node)2785 void InstructionSelector::VisitI32x4ExtAddPairwiseI16x8S(Node* node) {
2786   UNIMPLEMENTED();
2787 }
VisitI32x4ExtAddPairwiseI16x8U(Node * node)2788 void InstructionSelector::VisitI32x4ExtAddPairwiseI16x8U(Node* node) {
2789   UNIMPLEMENTED();
2790 }
VisitI16x8ExtAddPairwiseI8x16S(Node * node)2791 void InstructionSelector::VisitI16x8ExtAddPairwiseI8x16S(Node* node) {
2792   UNIMPLEMENTED();
2793 }
VisitI16x8ExtAddPairwiseI8x16U(Node * node)2794 void InstructionSelector::VisitI16x8ExtAddPairwiseI8x16U(Node* node) {
2795   UNIMPLEMENTED();
2796 }
2797 #endif  // !V8_TARGET_ARCH_ARM64
2798 
2799 #if !V8_TARGET_ARCH_X64
2800 // TODO(v8:10975): Prototyping load lane and store lane.
VisitLoadLane(Node * node)2801 void InstructionSelector::VisitLoadLane(Node* node) { UNIMPLEMENTED(); }
VisitStoreLane(Node * node)2802 void InstructionSelector::VisitStoreLane(Node* node) { UNIMPLEMENTED(); }
2803 
2804 // TODO(v8:10997) Prototype i64x2.bitmask.
VisitI64x2BitMask(Node * node)2805 void InstructionSelector::VisitI64x2BitMask(Node* node) { UNIMPLEMENTED(); }
2806 
2807 // TODO(v8:10983) Prototyping sign select.
VisitI8x16SignSelect(Node * node)2808 void InstructionSelector::VisitI8x16SignSelect(Node* node) { UNIMPLEMENTED(); }
VisitI16x8SignSelect(Node * node)2809 void InstructionSelector::VisitI16x8SignSelect(Node* node) { UNIMPLEMENTED(); }
VisitI32x4SignSelect(Node * node)2810 void InstructionSelector::VisitI32x4SignSelect(Node* node) { UNIMPLEMENTED(); }
VisitI64x2SignSelect(Node * node)2811 void InstructionSelector::VisitI64x2SignSelect(Node* node) { UNIMPLEMENTED(); }
2812 #endif  // !V8_TARGET_ARCH_X64
2813 
VisitFinishRegion(Node * node)2814 void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); }
2815 
VisitParameter(Node * node)2816 void InstructionSelector::VisitParameter(Node* node) {
2817   OperandGenerator g(this);
2818   int index = ParameterIndexOf(node->op());
2819   InstructionOperand op =
2820       linkage()->ParameterHasSecondaryLocation(index)
2821           ? g.DefineAsDualLocation(
2822                 node, linkage()->GetParameterLocation(index),
2823                 linkage()->GetParameterSecondaryLocation(index))
2824           : g.DefineAsLocation(node, linkage()->GetParameterLocation(index));
2825 
2826   Emit(kArchNop, op);
2827 }
2828 
2829 namespace {
2830 
ExceptionLocation()2831 LinkageLocation ExceptionLocation() {
2832   return LinkageLocation::ForRegister(kReturnRegister0.code(),
2833                                       MachineType::IntPtr());
2834 }
2835 
EncodeCallDescriptorFlags(InstructionCode opcode,CallDescriptor::Flags flags)2836 constexpr InstructionCode EncodeCallDescriptorFlags(
2837     InstructionCode opcode, CallDescriptor::Flags flags) {
2838   // Note: Not all bits of `flags` are preserved.
2839   STATIC_ASSERT(CallDescriptor::kFlagsBitsEncodedInInstructionCode ==
2840                 MiscField::kSize);
2841   CONSTEXPR_DCHECK(Instruction::IsCallWithDescriptorFlags(opcode));
2842   return opcode | MiscField::encode(flags & MiscField::kMax);
2843 }
2844 
2845 }  // namespace
2846 
VisitIfException(Node * node)2847 void InstructionSelector::VisitIfException(Node* node) {
2848   OperandGenerator g(this);
2849   DCHECK_EQ(IrOpcode::kCall, node->InputAt(1)->opcode());
2850   Emit(kArchNop, g.DefineAsLocation(node, ExceptionLocation()));
2851 }
2852 
VisitOsrValue(Node * node)2853 void InstructionSelector::VisitOsrValue(Node* node) {
2854   OperandGenerator g(this);
2855   int index = OsrValueIndexOf(node->op());
2856   Emit(kArchNop,
2857        g.DefineAsLocation(node, linkage()->GetOsrValueLocation(index)));
2858 }
2859 
VisitPhi(Node * node)2860 void InstructionSelector::VisitPhi(Node* node) {
2861   const int input_count = node->op()->ValueInputCount();
2862   DCHECK_EQ(input_count, current_block_->PredecessorCount());
2863   PhiInstruction* phi = instruction_zone()->New<PhiInstruction>(
2864       instruction_zone(), GetVirtualRegister(node),
2865       static_cast<size_t>(input_count));
2866   sequence()
2867       ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number()))
2868       ->AddPhi(phi);
2869   for (int i = 0; i < input_count; ++i) {
2870     Node* const input = node->InputAt(i);
2871     MarkAsUsed(input);
2872     phi->SetInput(static_cast<size_t>(i), GetVirtualRegister(input));
2873   }
2874 }
2875 
VisitProjection(Node * node)2876 void InstructionSelector::VisitProjection(Node* node) {
2877   OperandGenerator g(this);
2878   Node* value = node->InputAt(0);
2879   switch (value->opcode()) {
2880     case IrOpcode::kInt32AddWithOverflow:
2881     case IrOpcode::kInt32SubWithOverflow:
2882     case IrOpcode::kInt32MulWithOverflow:
2883     case IrOpcode::kInt64AddWithOverflow:
2884     case IrOpcode::kInt64SubWithOverflow:
2885     case IrOpcode::kTryTruncateFloat32ToInt64:
2886     case IrOpcode::kTryTruncateFloat64ToInt64:
2887     case IrOpcode::kTryTruncateFloat32ToUint64:
2888     case IrOpcode::kTryTruncateFloat64ToUint64:
2889     case IrOpcode::kInt32PairAdd:
2890     case IrOpcode::kInt32PairSub:
2891     case IrOpcode::kInt32PairMul:
2892     case IrOpcode::kWord32PairShl:
2893     case IrOpcode::kWord32PairShr:
2894     case IrOpcode::kWord32PairSar:
2895     case IrOpcode::kInt32AbsWithOverflow:
2896     case IrOpcode::kInt64AbsWithOverflow:
2897       if (ProjectionIndexOf(node->op()) == 0u) {
2898         Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
2899       } else {
2900         DCHECK_EQ(1u, ProjectionIndexOf(node->op()));
2901         MarkAsUsed(value);
2902       }
2903       break;
2904     default:
2905       break;
2906   }
2907 }
2908 
VisitConstant(Node * node)2909 void InstructionSelector::VisitConstant(Node* node) {
2910   // We must emit a NOP here because every live range needs a defining
2911   // instruction in the register allocator.
2912   OperandGenerator g(this);
2913   Emit(kArchNop, g.DefineAsConstant(node));
2914 }
2915 
UpdateMaxPushedArgumentCount(size_t count)2916 void InstructionSelector::UpdateMaxPushedArgumentCount(size_t count) {
2917   *max_pushed_argument_count_ = std::max(count, *max_pushed_argument_count_);
2918 }
2919 
VisitCall(Node * node,BasicBlock * handler)2920 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
2921   OperandGenerator g(this);
2922   auto call_descriptor = CallDescriptorOf(node->op());
2923 
2924   if (call_descriptor->NeedsCallerSavedRegisters()) {
2925     SaveFPRegsMode mode = call_descriptor->NeedsCallerSavedFPRegisters()
2926                               ? kSaveFPRegs
2927                               : kDontSaveFPRegs;
2928     Emit(kArchSaveCallerRegisters | MiscField::encode(static_cast<int>(mode)),
2929          g.NoOutput());
2930   }
2931 
2932   FrameStateDescriptor* frame_state_descriptor = nullptr;
2933   if (call_descriptor->NeedsFrameState()) {
2934     frame_state_descriptor = GetFrameStateDescriptor(
2935         node->InputAt(static_cast<int>(call_descriptor->InputCount())));
2936   }
2937 
2938   CallBuffer buffer(zone(), call_descriptor, frame_state_descriptor);
2939   CallDescriptor::Flags flags = call_descriptor->flags();
2940 
2941   // Compute InstructionOperands for inputs and outputs.
2942   // TODO(turbofan): on some architectures it's probably better to use
2943   // the code object in a register if there are multiple uses of it.
2944   // Improve constant pool and the heuristics in the register allocator
2945   // for where to emit constants.
2946   CallBufferFlags call_buffer_flags(kCallCodeImmediate | kCallAddressImmediate);
2947   InitializeCallBuffer(node, &buffer, call_buffer_flags, false);
2948 
2949   EmitPrepareArguments(&buffer.pushed_nodes, call_descriptor, node);
2950   UpdateMaxPushedArgumentCount(buffer.pushed_nodes.size());
2951 
2952   // Pass label of exception handler block.
2953   if (handler) {
2954     DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode());
2955     flags |= CallDescriptor::kHasExceptionHandler;
2956     buffer.instruction_args.push_back(g.Label(handler));
2957   }
2958 
2959   // Select the appropriate opcode based on the call type.
2960   InstructionCode opcode;
2961   switch (call_descriptor->kind()) {
2962     case CallDescriptor::kCallAddress: {
2963       int misc_field = static_cast<int>(call_descriptor->ParameterCount());
2964 #if ABI_USES_FUNCTION_DESCRIPTORS
2965       // Highest misc_field bit is used on AIX to indicate if a CFunction call
2966       // has function descriptor or not.
2967       STATIC_ASSERT(MiscField::kSize == kHasFunctionDescriptorBitShift + 1);
2968       if (!call_descriptor->NoFunctionDescriptor()) {
2969         misc_field |= 1 << kHasFunctionDescriptorBitShift;
2970       }
2971 #endif
2972       opcode = kArchCallCFunction | MiscField::encode(misc_field);
2973       break;
2974     }
2975     case CallDescriptor::kCallCodeObject:
2976       opcode = EncodeCallDescriptorFlags(kArchCallCodeObject, flags);
2977       break;
2978     case CallDescriptor::kCallJSFunction:
2979       opcode = EncodeCallDescriptorFlags(kArchCallJSFunction, flags);
2980       break;
2981     case CallDescriptor::kCallWasmCapiFunction:
2982     case CallDescriptor::kCallWasmFunction:
2983     case CallDescriptor::kCallWasmImportWrapper:
2984       opcode = EncodeCallDescriptorFlags(kArchCallWasmFunction, flags);
2985       break;
2986     case CallDescriptor::kCallBuiltinPointer:
2987       opcode = EncodeCallDescriptorFlags(kArchCallBuiltinPointer, flags);
2988       break;
2989   }
2990 
2991   // Emit the call instruction.
2992   size_t const output_count = buffer.outputs.size();
2993   auto* outputs = output_count ? &buffer.outputs.front() : nullptr;
2994   Instruction* call_instr =
2995       Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
2996            &buffer.instruction_args.front());
2997   if (instruction_selection_failed()) return;
2998   call_instr->MarkAsCall();
2999 
3000   EmitPrepareResults(&(buffer.output_nodes), call_descriptor, node);
3001 
3002   if (call_descriptor->NeedsCallerSavedRegisters()) {
3003     SaveFPRegsMode mode = call_descriptor->NeedsCallerSavedFPRegisters()
3004                               ? kSaveFPRegs
3005                               : kDontSaveFPRegs;
3006     Emit(
3007         kArchRestoreCallerRegisters | MiscField::encode(static_cast<int>(mode)),
3008         g.NoOutput());
3009   }
3010 }
3011 
VisitTailCall(Node * node)3012 void InstructionSelector::VisitTailCall(Node* node) {
3013   OperandGenerator g(this);
3014   auto call_descriptor = CallDescriptorOf(node->op());
3015 
3016   CallDescriptor* caller = linkage()->GetIncomingDescriptor();
3017   const CallDescriptor* callee = CallDescriptorOf(node->op());
3018   DCHECK(caller->CanTailCall(callee));
3019   const int stack_param_delta = callee->GetStackParameterDelta(caller);
3020   CallBuffer buffer(zone(), call_descriptor, nullptr);
3021 
3022   // Compute InstructionOperands for inputs and outputs.
3023   CallBufferFlags flags(kCallCodeImmediate | kCallTail);
3024   if (IsTailCallAddressImmediate()) {
3025     flags |= kCallAddressImmediate;
3026   }
3027   if (callee->flags() & CallDescriptor::kFixedTargetRegister) {
3028     flags |= kCallFixedTargetRegister;
3029   }
3030   InitializeCallBuffer(node, &buffer, flags, true, stack_param_delta);
3031   UpdateMaxPushedArgumentCount(stack_param_delta);
3032 
3033   // Select the appropriate opcode based on the call type.
3034   InstructionCode opcode;
3035   InstructionOperandVector temps(zone());
3036   if (caller->IsJSFunctionCall()) {
3037     switch (call_descriptor->kind()) {
3038       case CallDescriptor::kCallCodeObject:
3039         opcode = kArchTailCallCodeObjectFromJSFunction;
3040         break;
3041       default:
3042         UNREACHABLE();
3043     }
3044     int temps_count = GetTempsCountForTailCallFromJSFunction();
3045     for (int i = 0; i < temps_count; i++) {
3046       temps.push_back(g.TempRegister());
3047     }
3048   } else {
3049     switch (call_descriptor->kind()) {
3050       case CallDescriptor::kCallCodeObject:
3051         opcode = kArchTailCallCodeObject;
3052         break;
3053       case CallDescriptor::kCallAddress:
3054         opcode = kArchTailCallAddress;
3055         break;
3056       case CallDescriptor::kCallWasmFunction:
3057         opcode = kArchTailCallWasm;
3058         break;
3059       default:
3060         UNREACHABLE();
3061     }
3062   }
3063   opcode = EncodeCallDescriptorFlags(opcode, call_descriptor->flags());
3064 
3065   Emit(kArchPrepareTailCall, g.NoOutput());
3066 
3067   // Add an immediate operand that represents the first slot that is unused
3068   // with respect to the stack pointer that has been updated for the tail call
3069   // instruction. This is used by backends that need to pad arguments for stack
3070   // alignment, in order to store an optional slot of padding above the
3071   // arguments.
3072   const int optional_padding_slot = callee->GetFirstUnusedStackSlot();
3073   buffer.instruction_args.push_back(g.TempImmediate(optional_padding_slot));
3074 
3075   const int first_unused_stack_slot =
3076       kReturnAddressStackSlotCount + stack_param_delta;
3077   buffer.instruction_args.push_back(g.TempImmediate(first_unused_stack_slot));
3078 
3079   // Emit the tailcall instruction.
3080   Emit(opcode, 0, nullptr, buffer.instruction_args.size(),
3081        &buffer.instruction_args.front(), temps.size(),
3082        temps.empty() ? nullptr : &temps.front());
3083 }
3084 
VisitGoto(BasicBlock * target)3085 void InstructionSelector::VisitGoto(BasicBlock* target) {
3086   // jump to the next block.
3087   OperandGenerator g(this);
3088   Emit(kArchJmp, g.NoOutput(), g.Label(target));
3089 }
3090 
VisitReturn(Node * ret)3091 void InstructionSelector::VisitReturn(Node* ret) {
3092   OperandGenerator g(this);
3093   const int input_count = linkage()->GetIncomingDescriptor()->ReturnCount() == 0
3094                               ? 1
3095                               : ret->op()->ValueInputCount();
3096   DCHECK_GE(input_count, 1);
3097   auto value_locations = zone()->NewArray<InstructionOperand>(input_count);
3098   Node* pop_count = ret->InputAt(0);
3099   value_locations[0] = (pop_count->opcode() == IrOpcode::kInt32Constant ||
3100                         pop_count->opcode() == IrOpcode::kInt64Constant)
3101                            ? g.UseImmediate(pop_count)
3102                            : g.UseRegister(pop_count);
3103   for (int i = 1; i < input_count; ++i) {
3104     value_locations[i] =
3105         g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i - 1));
3106   }
3107   Emit(kArchRet, 0, nullptr, input_count, value_locations);
3108 }
3109 
VisitBranch(Node * branch,BasicBlock * tbranch,BasicBlock * fbranch)3110 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
3111                                       BasicBlock* fbranch) {
3112   if (NeedsPoisoning(IsSafetyCheckOf(branch->op()))) {
3113     FlagsContinuation cont =
3114         FlagsContinuation::ForBranchAndPoison(kNotEqual, tbranch, fbranch);
3115     VisitWordCompareZero(branch, branch->InputAt(0), &cont);
3116   } else {
3117     FlagsContinuation cont =
3118         FlagsContinuation::ForBranch(kNotEqual, tbranch, fbranch);
3119     VisitWordCompareZero(branch, branch->InputAt(0), &cont);
3120   }
3121 }
3122 
VisitDeoptimizeIf(Node * node)3123 void InstructionSelector::VisitDeoptimizeIf(Node* node) {
3124   DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
3125   if (NeedsPoisoning(p.is_safety_check())) {
3126     FlagsContinuation cont = FlagsContinuation::ForDeoptimizeAndPoison(
3127         kNotEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
3128     VisitWordCompareZero(node, node->InputAt(0), &cont);
3129   } else {
3130     FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
3131         kNotEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
3132     VisitWordCompareZero(node, node->InputAt(0), &cont);
3133   }
3134 }
3135 
VisitDeoptimizeUnless(Node * node)3136 void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
3137   DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
3138   if (NeedsPoisoning(p.is_safety_check())) {
3139     FlagsContinuation cont = FlagsContinuation::ForDeoptimizeAndPoison(
3140         kEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
3141     VisitWordCompareZero(node, node->InputAt(0), &cont);
3142   } else {
3143     FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
3144         kEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
3145     VisitWordCompareZero(node, node->InputAt(0), &cont);
3146   }
3147 }
3148 
VisitTrapIf(Node * node,TrapId trap_id)3149 void InstructionSelector::VisitTrapIf(Node* node, TrapId trap_id) {
3150   FlagsContinuation cont =
3151       FlagsContinuation::ForTrap(kNotEqual, trap_id, node->InputAt(1));
3152   VisitWordCompareZero(node, node->InputAt(0), &cont);
3153 }
3154 
VisitTrapUnless(Node * node,TrapId trap_id)3155 void InstructionSelector::VisitTrapUnless(Node* node, TrapId trap_id) {
3156   FlagsContinuation cont =
3157       FlagsContinuation::ForTrap(kEqual, trap_id, node->InputAt(1));
3158   VisitWordCompareZero(node, node->InputAt(0), &cont);
3159 }
3160 
EmitIdentity(Node * node)3161 void InstructionSelector::EmitIdentity(Node* node) {
3162   MarkAsUsed(node->InputAt(0));
3163   SetRename(node, node->InputAt(0));
3164 }
3165 
VisitDeoptimize(DeoptimizeKind kind,DeoptimizeReason reason,FeedbackSource const & feedback,Node * frame_state)3166 void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind,
3167                                           DeoptimizeReason reason,
3168                                           FeedbackSource const& feedback,
3169                                           Node* frame_state) {
3170   InstructionOperandVector args(instruction_zone());
3171   AppendDeoptimizeArguments(&args, kind, reason, feedback, frame_state);
3172   Emit(kArchDeoptimize, 0, nullptr, args.size(), &args.front(), 0, nullptr);
3173 }
3174 
VisitThrow(Node * node)3175 void InstructionSelector::VisitThrow(Node* node) {
3176   OperandGenerator g(this);
3177   Emit(kArchThrowTerminator, g.NoOutput());
3178 }
3179 
VisitDebugBreak(Node * node)3180 void InstructionSelector::VisitDebugBreak(Node* node) {
3181   OperandGenerator g(this);
3182   Emit(kArchDebugBreak, g.NoOutput());
3183 }
3184 
VisitUnreachable(Node * node)3185 void InstructionSelector::VisitUnreachable(Node* node) {
3186   OperandGenerator g(this);
3187   Emit(kArchDebugBreak, g.NoOutput());
3188 }
3189 
VisitStaticAssert(Node * node)3190 void InstructionSelector::VisitStaticAssert(Node* node) {
3191   Node* asserted = node->InputAt(0);
3192   UnparkedScopeIfNeeded scope(broker_);
3193   AllowHandleDereference allow_handle_dereference;
3194   asserted->Print(4);
3195   FATAL(
3196       "Expected Turbofan static assert to hold, but got non-true input:\n  %s",
3197       StaticAssertSourceOf(node->op()));
3198 }
3199 
VisitDeadValue(Node * node)3200 void InstructionSelector::VisitDeadValue(Node* node) {
3201   OperandGenerator g(this);
3202   MarkAsRepresentation(DeadValueRepresentationOf(node->op()), node);
3203   Emit(kArchDebugBreak, g.DefineAsConstant(node));
3204 }
3205 
VisitComment(Node * node)3206 void InstructionSelector::VisitComment(Node* node) {
3207   OperandGenerator g(this);
3208   InstructionOperand operand(g.UseImmediate(node));
3209   Emit(kArchComment, 0, nullptr, 1, &operand);
3210 }
3211 
VisitUnsafePointerAdd(Node * node)3212 void InstructionSelector::VisitUnsafePointerAdd(Node* node) {
3213 #if V8_TARGET_ARCH_64_BIT
3214   VisitInt64Add(node);
3215 #else   // V8_TARGET_ARCH_64_BIT
3216   VisitInt32Add(node);
3217 #endif  // V8_TARGET_ARCH_64_BIT
3218 }
3219 
VisitRetain(Node * node)3220 void InstructionSelector::VisitRetain(Node* node) {
3221   OperandGenerator g(this);
3222   Emit(kArchNop, g.NoOutput(), g.UseAny(node->InputAt(0)));
3223 }
3224 
CanProduceSignalingNaN(Node * node)3225 bool InstructionSelector::CanProduceSignalingNaN(Node* node) {
3226   // TODO(jarin) Improve the heuristic here.
3227   if (node->opcode() == IrOpcode::kFloat64Add ||
3228       node->opcode() == IrOpcode::kFloat64Sub ||
3229       node->opcode() == IrOpcode::kFloat64Mul) {
3230     return false;
3231   }
3232   return true;
3233 }
3234 
3235 #if V8_TARGET_ARCH_64_BIT
ZeroExtendsWord32ToWord64(Node * node,int recursion_depth)3236 bool InstructionSelector::ZeroExtendsWord32ToWord64(Node* node,
3237                                                     int recursion_depth) {
3238   // To compute whether a Node sets its upper 32 bits to zero, there are three
3239   // cases.
3240   // 1. Phi node, with a computed result already available in phi_states_:
3241   //    Read the value from phi_states_.
3242   // 2. Phi node, with no result available in phi_states_ yet:
3243   //    Recursively check its inputs, and store the result in phi_states_.
3244   // 3. Anything else:
3245   //    Call the architecture-specific ZeroExtendsWord32ToWord64NoPhis.
3246 
3247   // Limit recursion depth to avoid the possibility of stack overflow on very
3248   // large functions.
3249   const int kMaxRecursionDepth = 100;
3250 
3251   if (node->opcode() == IrOpcode::kPhi) {
3252     Upper32BitsState current = phi_states_[node->id()];
3253     if (current != Upper32BitsState::kNotYetChecked) {
3254       return current == Upper32BitsState::kUpperBitsGuaranteedZero;
3255     }
3256 
3257     // If further recursion is prevented, we can't make any assumptions about
3258     // the output of this phi node.
3259     if (recursion_depth >= kMaxRecursionDepth) {
3260       return false;
3261     }
3262 
3263     // Mark the current node so that we skip it if we recursively visit it
3264     // again. Or, said differently, we compute a largest fixed-point so we can
3265     // be optimistic when we hit cycles.
3266     phi_states_[node->id()] = Upper32BitsState::kUpperBitsGuaranteedZero;
3267 
3268     int input_count = node->op()->ValueInputCount();
3269     for (int i = 0; i < input_count; ++i) {
3270       Node* input = NodeProperties::GetValueInput(node, i);
3271       if (!ZeroExtendsWord32ToWord64(input, recursion_depth + 1)) {
3272         phi_states_[node->id()] = Upper32BitsState::kNoGuarantee;
3273         return false;
3274       }
3275     }
3276 
3277     return true;
3278   }
3279   return ZeroExtendsWord32ToWord64NoPhis(node);
3280 }
3281 #endif  // V8_TARGET_ARCH_64_BIT
3282 
3283 namespace {
3284 
GetFrameStateDescriptorInternal(Zone * zone,Node * state)3285 FrameStateDescriptor* GetFrameStateDescriptorInternal(Zone* zone, Node* state) {
3286   DCHECK_EQ(IrOpcode::kFrameState, state->opcode());
3287   DCHECK_EQ(kFrameStateInputCount, state->InputCount());
3288   const FrameStateInfo& state_info = FrameStateInfoOf(state->op());
3289   int parameters = state_info.parameter_count();
3290   int locals = state_info.local_count();
3291   int stack = state_info.type() == FrameStateType::kInterpretedFunction ? 1 : 0;
3292 
3293   FrameStateDescriptor* outer_state = nullptr;
3294   Node* outer_node = state->InputAt(kFrameStateOuterStateInput);
3295   if (outer_node->opcode() == IrOpcode::kFrameState) {
3296     outer_state = GetFrameStateDescriptorInternal(zone, outer_node);
3297   }
3298 
3299   return zone->New<FrameStateDescriptor>(
3300       zone, state_info.type(), state_info.bailout_id(),
3301       state_info.state_combine(), parameters, locals, stack,
3302       state_info.shared_info(), outer_state);
3303 }
3304 
3305 }  // namespace
3306 
GetFrameStateDescriptor(Node * state)3307 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
3308     Node* state) {
3309   auto* desc = GetFrameStateDescriptorInternal(instruction_zone(), state);
3310   *max_unoptimized_frame_height_ =
3311       std::max(*max_unoptimized_frame_height_,
3312                desc->total_conservative_frame_size_in_bytes());
3313   return desc;
3314 }
3315 
CanonicalizeShuffle(Node * node,uint8_t * shuffle,bool * is_swizzle)3316 void InstructionSelector::CanonicalizeShuffle(Node* node, uint8_t* shuffle,
3317                                               bool* is_swizzle) {
3318   // Get raw shuffle indices.
3319   memcpy(shuffle, S128ImmediateParameterOf(node->op()).data(), kSimd128Size);
3320   bool needs_swap;
3321   bool inputs_equal = GetVirtualRegister(node->InputAt(0)) ==
3322                       GetVirtualRegister(node->InputAt(1));
3323   wasm::SimdShuffle::CanonicalizeShuffle(inputs_equal, shuffle, &needs_swap,
3324                                          is_swizzle);
3325   if (needs_swap) {
3326     SwapShuffleInputs(node);
3327   }
3328   // Duplicate the first input; for some shuffles on some architectures, it's
3329   // easiest to implement a swizzle as a shuffle so it might be used.
3330   if (*is_swizzle) {
3331     node->ReplaceInput(1, node->InputAt(0));
3332   }
3333 }
3334 
3335 // static
SwapShuffleInputs(Node * node)3336 void InstructionSelector::SwapShuffleInputs(Node* node) {
3337   Node* input0 = node->InputAt(0);
3338   Node* input1 = node->InputAt(1);
3339   node->ReplaceInput(0, input1);
3340   node->ReplaceInput(1, input0);
3341 }
3342 
3343 // static
NeedsPoisoning(IsSafetyCheck safety_check) const3344 bool InstructionSelector::NeedsPoisoning(IsSafetyCheck safety_check) const {
3345   switch (poisoning_level_) {
3346     case PoisoningMitigationLevel::kDontPoison:
3347       return false;
3348     case PoisoningMitigationLevel::kPoisonAll:
3349       return safety_check != IsSafetyCheck::kNoSafetyCheck;
3350     case PoisoningMitigationLevel::kPoisonCriticalOnly:
3351       return safety_check == IsSafetyCheck::kCriticalSafetyCheck;
3352   }
3353   UNREACHABLE();
3354 }
3355 }  // namespace compiler
3356 }  // namespace internal
3357 }  // namespace v8
3358