b0048c9d2aa28c6113960647f2ac8265cb1d0fc6
[platform/upstream/dotnet/runtime.git] / src / coreclr / jit / codegenlinear.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3
4 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6 XX                                                                           XX
7 XX            Code Generation Support Methods for Linear Codegen             XX
8 XX                                                                           XX
9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11 */
12 #include "jitpch.h"
13 #ifdef _MSC_VER
14 #pragma hdrstop
15 #endif
16
17 #include "emit.h"
18 #include "codegen.h"
19
20 //------------------------------------------------------------------------
21 // genInitializeRegisterState: Initialize the register state contained in 'regSet'.
22 //
23 // Assumptions:
24 //    On exit the "rsModifiedRegsMask" (in "regSet") holds all the registers' masks hosting an argument on the function
25 //    and elements of "rsSpillDesc" (in "regSet") are setted to nullptr.
26 //
27 // Notes:
28 //    This method is intended to be called only from initializeStructuresBeforeBlockCodeGeneration.
29 void CodeGen::genInitializeRegisterState()
30 {
31     // Initialize the spill tracking logic
32
33     regSet.rsSpillBeg();
34
35     // If any arguments live in registers, mark those regs as such
36
37     unsigned   varNum;
38     LclVarDsc* varDsc;
39
40     for (varNum = 0, varDsc = compiler->lvaTable; varNum < compiler->lvaCount; varNum++, varDsc++)
41     {
42         // Is this variable a parameter assigned to a register?
43         if (!varDsc->lvIsParam || !varDsc->lvRegister)
44         {
45             continue;
46         }
47
48         // Is the argument live on entry to the method?
49         if (!VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex))
50         {
51             continue;
52         }
53
54         if (varDsc->IsAddressExposed())
55         {
56             continue;
57         }
58
59         // Mark the register as holding the variable
60         regNumber reg = varDsc->GetRegNum();
61         if (genIsValidIntReg(reg))
62         {
63             regSet.verifyRegUsed(reg);
64         }
65     }
66 }
67
68 //------------------------------------------------------------------------
69 // genInitialize: Initialize Scopes, registers, gcInfo and current liveness variables structures
70 // used in the generation of blocks' code before.
71 //
72 // Assumptions:
73 //    -The pointer logic in "gcInfo" for pointers on registers and variable is cleaned.
74 //    -"compiler->compCurLife" becomes an empty set
75 //    -"compiler->compCurLife" are set to be a clean set
76 //    -If there is local var info siScopes scope logic in codegen is initialized in "siInit()"
77 //
78 // Notes:
79 //    This method is intended to be called when code generation for blocks happens, and before the list of blocks is
80 //    iterated.
81 void CodeGen::genInitialize()
82 {
83     // Initialize the line# tracking logic
84     if (compiler->opts.compScopeInfo)
85     {
86         siInit();
87     }
88
89     initializeVariableLiveKeeper();
90
91     genPendingCallLabel = nullptr;
92
93     // Initialize the pointer tracking code
94
95     gcInfo.gcRegPtrSetInit();
96     gcInfo.gcVarPtrSetInit();
97
98     // Initialize the register set logic
99
100     genInitializeRegisterState();
101
102     // Make sure a set is allocated for compiler->compCurLife (in the long case), so we can set it to empty without
103     // allocation at the start of each basic block.
104     VarSetOps::AssignNoCopy(compiler, compiler->compCurLife, VarSetOps::MakeEmpty(compiler));
105
106     // We initialize the stack level before first "BasicBlock" code is generated in case we need to report stack
107     // variable needs home and so its stack offset.
108     SetStackLevel(0);
109 }
110
111 //------------------------------------------------------------------------
112 // genCodeForBBlist: Generate code for all the blocks in a method
113 //
114 // Arguments:
115 //    None
116 //
117 // Notes:
118 //    This is the main method for linear codegen. It calls genCodeForTreeNode
119 //    to generate the code for each node in each BasicBlock, and handles BasicBlock
120 //    boundaries and branches.
121 //
122 void CodeGen::genCodeForBBlist()
123 {
124     unsigned savedStkLvl;
125
126 #ifdef DEBUG
127     genInterruptibleUsed = true;
128
129     // You have to be careful if you create basic blocks from now on
130     compiler->fgSafeBasicBlockCreation = false;
131 #endif // DEBUG
132
133 #if defined(DEBUG) && defined(TARGET_X86)
134
135     // Check stack pointer on call stress mode is not compatible with fully interruptible GC. REVIEW: why?
136     //
137     if (GetInterruptible() && compiler->opts.compStackCheckOnCall)
138     {
139         compiler->opts.compStackCheckOnCall = false;
140     }
141
142 #endif // defined(DEBUG) && defined(TARGET_X86)
143
144 #if defined(DEBUG) && defined(TARGET_XARCH)
145
146     // Check stack pointer on return stress mode is not compatible with fully interruptible GC. REVIEW: why?
147     // It is also not compatible with any function that makes a tailcall: we aren't smart enough to only
148     // insert the SP check in the non-tailcall returns.
149     //
150     if ((GetInterruptible() || compiler->compTailCallUsed) && compiler->opts.compStackCheckOnRet)
151     {
152         compiler->opts.compStackCheckOnRet = false;
153     }
154
155 #endif // defined(DEBUG) && defined(TARGET_XARCH)
156
157     genMarkLabelsForCodegen();
158
159     assert(!compiler->fgFirstBBScratch ||
160            compiler->fgFirstBB == compiler->fgFirstBBScratch); // compiler->fgFirstBBScratch has to be first.
161
162     /* Initialize structures used in the block list iteration */
163     genInitialize();
164
165     /*-------------------------------------------------------------------------
166      *
167      *  Walk the basic blocks and generate code for each one
168      *
169      */
170
171     BasicBlock* block;
172
173     for (block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
174     {
175
176 #ifdef DEBUG
177         if (compiler->verbose)
178         {
179             printf("\n=============== Generating ");
180             block->dspBlockHeader(compiler, true, true);
181             compiler->fgDispBBLiveness(block);
182         }
183 #endif // DEBUG
184
185         assert(LIR::AsRange(block).CheckLIR(compiler));
186
187         // Figure out which registers hold variables on entry to this block
188
189         regSet.ClearMaskVars();
190         gcInfo.gcRegGCrefSetCur = RBM_NONE;
191         gcInfo.gcRegByrefSetCur = RBM_NONE;
192
193         compiler->m_pLinearScan->recordVarLocationsAtStartOfBB(block);
194
195         // Updating variable liveness after last instruction of previous block was emitted
196         // and before first of the current block is emitted
197         genUpdateLife(block->bbLiveIn);
198
199         // Even if liveness didn't change, we need to update the registers containing GC references.
200         // genUpdateLife will update the registers live due to liveness changes. But what about registers that didn't
201         // change? We cleared them out above. Maybe we should just not clear them out, but update the ones that change
202         // here. That would require handling the changes in recordVarLocationsAtStartOfBB().
203
204         regMaskTP newLiveRegSet  = RBM_NONE;
205         regMaskTP newRegGCrefSet = RBM_NONE;
206         regMaskTP newRegByrefSet = RBM_NONE;
207 #ifdef DEBUG
208         VARSET_TP removedGCVars(VarSetOps::MakeEmpty(compiler));
209         VARSET_TP addedGCVars(VarSetOps::MakeEmpty(compiler));
210 #endif
211         VarSetOps::Iter iter(compiler, block->bbLiveIn);
212         unsigned        varIndex = 0;
213         while (iter.NextElem(&varIndex))
214         {
215             LclVarDsc* varDsc = compiler->lvaGetDescByTrackedIndex(varIndex);
216
217             if (varDsc->lvIsInReg())
218             {
219                 newLiveRegSet |= varDsc->lvRegMask();
220                 if (varDsc->lvType == TYP_REF)
221                 {
222                     newRegGCrefSet |= varDsc->lvRegMask();
223                 }
224                 else if (varDsc->lvType == TYP_BYREF)
225                 {
226                     newRegByrefSet |= varDsc->lvRegMask();
227                 }
228                 if (!varDsc->IsAlwaysAliveInMemory())
229                 {
230 #ifdef DEBUG
231                     if (verbose && VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
232                     {
233                         VarSetOps::AddElemD(compiler, removedGCVars, varIndex);
234                     }
235 #endif // DEBUG
236                     VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
237                 }
238             }
239             if ((!varDsc->lvIsInReg() || varDsc->IsAlwaysAliveInMemory()) && compiler->lvaIsGCTracked(varDsc))
240             {
241 #ifdef DEBUG
242                 if (verbose && !VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
243                 {
244                     VarSetOps::AddElemD(compiler, addedGCVars, varIndex);
245                 }
246 #endif // DEBUG
247                 VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
248             }
249         }
250
251         regSet.SetMaskVars(newLiveRegSet);
252
253 #ifdef DEBUG
254         if (compiler->verbose)
255         {
256             if (!VarSetOps::IsEmpty(compiler, addedGCVars))
257             {
258                 printf("\t\t\t\t\t\t\tAdded GCVars: ");
259                 dumpConvertedVarSet(compiler, addedGCVars);
260                 printf("\n");
261             }
262             if (!VarSetOps::IsEmpty(compiler, removedGCVars))
263             {
264                 printf("\t\t\t\t\t\t\tRemoved GCVars: ");
265                 dumpConvertedVarSet(compiler, removedGCVars);
266                 printf("\n");
267             }
268         }
269 #endif // DEBUG
270
271         gcInfo.gcMarkRegSetGCref(newRegGCrefSet DEBUGARG(true));
272         gcInfo.gcMarkRegSetByref(newRegByrefSet DEBUGARG(true));
273
274         /* Blocks with handlerGetsXcptnObj()==true use GT_CATCH_ARG to
275            represent the exception object (TYP_REF).
276            We mark REG_EXCEPTION_OBJECT as holding a GC object on entry
277            to the block,  it will be the first thing evaluated
278            (thanks to GTF_ORDER_SIDEEFF).
279          */
280
281         if (handlerGetsXcptnObj(block->bbCatchTyp))
282         {
283             for (GenTree* node : LIR::AsRange(block))
284             {
285                 if (node->OperGet() == GT_CATCH_ARG)
286                 {
287                     gcInfo.gcMarkRegSetGCref(RBM_EXCEPTION_OBJECT);
288                     break;
289                 }
290             }
291         }
292
293 #if defined(TARGET_ARM)
294         genInsertNopForUnwinder(block);
295 #endif
296
297         /* Start a new code output block */
298
299         genUpdateCurrentFunclet(block);
300
301         genLogLabel(block);
302
303         // Tell everyone which basic block we're working on
304
305         compiler->compCurBB = block;
306
307         block->bbEmitCookie = nullptr;
308
309         // If this block is a jump target or it requires a label then set 'needLabel' to true,
310         //
311         bool needLabel = (block->bbFlags & BBF_HAS_LABEL) != 0;
312
313         if (block == compiler->fgFirstColdBlock)
314         {
315 #ifdef DEBUG
316             if (compiler->verbose)
317             {
318                 printf("\nThis is the start of the cold region of the method\n");
319             }
320 #endif
321             // We should never have a block that falls through into the Cold section
322             noway_assert(!block->bbPrev->bbFallsThrough());
323
324             needLabel = true;
325         }
326
327         // We also want to start a new Instruction group by calling emitAddLabel below,
328         // when we need accurate bbWeights for this block in the emitter.  We force this
329         // whenever our previous block was a BBJ_COND and it has a different weight than us.
330         //
331         // Note: We need to have set compCurBB before calling emitAddLabel
332         //
333         if ((block->bbPrev != nullptr) && (block->bbPrev->bbJumpKind == BBJ_COND) &&
334             (block->bbWeight != block->bbPrev->bbWeight))
335         {
336             JITDUMP("Adding label due to BB weight difference: BBJ_COND " FMT_BB " with weight " FMT_WT
337                     " different from " FMT_BB " with weight " FMT_WT "\n",
338                     block->bbPrev->bbNum, block->bbPrev->bbWeight, block->bbNum, block->bbWeight);
339             needLabel = true;
340         }
341
342 #if FEATURE_LOOP_ALIGN
343         if (GetEmitter()->emitEndsWithAlignInstr())
344         {
345             // Force new label if current IG ends with an align instruction.
346             needLabel = true;
347         }
348 #endif
349
350         if (needLabel)
351         {
352             // Mark a label and update the current set of live GC refs
353
354             block->bbEmitCookie = GetEmitter()->emitAddLabel(gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
355                                                              gcInfo.gcRegByrefSetCur, false DEBUG_ARG(block));
356         }
357
358         if (block == compiler->fgFirstColdBlock)
359         {
360             // We require the block that starts the Cold section to have a label
361             noway_assert(block->bbEmitCookie);
362             GetEmitter()->emitSetFirstColdIGCookie(block->bbEmitCookie);
363         }
364
365         // Both stacks are always empty on entry to a basic block.
366         assert(genStackLevel == 0);
367         genAdjustStackLevel(block);
368         savedStkLvl = genStackLevel;
369
370         // Needed when jitting debug code
371         siBeginBlock(block);
372
373         // BBF_INTERNAL blocks don't correspond to any single IL instruction.
374         if (compiler->opts.compDbgInfo && (block->bbFlags & BBF_INTERNAL) &&
375             !compiler->fgBBisScratch(block)) // If the block is the distinguished first scratch block, then no need to
376                                              // emit a NO_MAPPING entry, immediately after the prolog.
377         {
378             genIPmappingAdd(IPmappingDscKind::NoMapping, DebugInfo(), true);
379         }
380
381         bool firstMapping = true;
382
383 #if defined(FEATURE_EH_FUNCLETS)
384         if (block->bbFlags & BBF_FUNCLET_BEG)
385         {
386             genReserveFuncletProlog(block);
387         }
388 #endif // FEATURE_EH_FUNCLETS
389
390         // Clear compCurStmt and compCurLifeTree.
391         compiler->compCurStmt     = nullptr;
392         compiler->compCurLifeTree = nullptr;
393
394         // Emit poisoning into scratch BB that comes right after prolog.
395         // We cannot emit this code in the prolog as it might make the prolog too large.
396         if (compiler->compShouldPoisonFrame() && compiler->fgBBisScratch(block))
397         {
398             genPoisonFrame(newLiveRegSet);
399         }
400
401         // Traverse the block in linear order, generating code for each node as we
402         // as we encounter it.
403         CLANG_FORMAT_COMMENT_ANCHOR;
404
405 #ifdef DEBUG
406         // Set the use-order numbers for each node.
407         {
408             int useNum = 0;
409             for (GenTree* node : LIR::AsRange(block))
410             {
411                 assert((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) == 0);
412
413                 node->gtUseNum = -1;
414                 if (node->isContained() || node->IsCopyOrReload())
415                 {
416                     continue;
417                 }
418
419                 for (GenTree* operand : node->Operands())
420                 {
421                     genNumberOperandUse(operand, useNum);
422                 }
423             }
424         }
425 #endif // DEBUG
426
427         bool addRichMappings = JitConfig.RichDebugInfo() != 0;
428
429         INDEBUG(addRichMappings |= JitConfig.JitDisasmWithDebugInfo() != 0);
430         INDEBUG(addRichMappings |= JitConfig.WriteRichDebugInfoFile() != nullptr);
431
432         DebugInfo currentDI;
433         for (GenTree* node : LIR::AsRange(block))
434         {
435             // Do we have a new IL offset?
436             if (node->OperGet() == GT_IL_OFFSET)
437             {
438                 GenTreeILOffset* ilOffset = node->AsILOffset();
439                 DebugInfo        rootDI   = ilOffset->gtStmtDI.GetRoot();
440                 if (rootDI.IsValid())
441                 {
442                     genEnsureCodeEmitted(currentDI);
443                     currentDI = rootDI;
444                     genIPmappingAdd(IPmappingDscKind::Normal, currentDI, firstMapping);
445                     firstMapping = false;
446                 }
447
448                 if (addRichMappings && ilOffset->gtStmtDI.IsValid())
449                 {
450                     genAddRichIPMappingHere(ilOffset->gtStmtDI);
451                 }
452
453 #ifdef DEBUG
454                 assert(ilOffset->gtStmtLastILoffs <= compiler->info.compILCodeSize ||
455                        ilOffset->gtStmtLastILoffs == BAD_IL_OFFSET);
456
457                 if (compiler->opts.dspCode && compiler->opts.dspInstrs && ilOffset->gtStmtLastILoffs != BAD_IL_OFFSET)
458                 {
459                     while (genCurDispOffset <= ilOffset->gtStmtLastILoffs)
460                     {
461                         genCurDispOffset += dumpSingleInstr(compiler->info.compCode, genCurDispOffset, ">    ");
462                     }
463                 }
464
465 #endif // DEBUG
466             }
467
468             genCodeForTreeNode(node);
469             if (node->gtHasReg(compiler) && node->IsUnusedValue())
470             {
471                 genConsumeReg(node);
472             }
473         } // end for each node in block
474
475 #ifdef DEBUG
476         // The following set of register spill checks and GC pointer tracking checks used to be
477         // performed at statement boundaries. Now, with LIR, there are no statements, so they are
478         // performed at the end of each block.
479         // TODO: could these checks be performed more frequently? E.g., at each location where
480         // the register allocator says there are no live non-variable registers. Perhaps this could
481         // be done by using the map maintained by LSRA (operandToLocationInfoMap) to mark a node
482         // somehow when, after the execution of that node, there will be no live non-variable registers.
483
484         regSet.rsSpillChk();
485
486         /* Make sure we didn't bungle pointer register tracking */
487
488         regMaskTP ptrRegs       = gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur;
489         regMaskTP nonVarPtrRegs = ptrRegs & ~regSet.GetMaskVars();
490
491         // If return is a GC-type, clear it.  Note that if a common
492         // epilog is generated (genReturnBB) it has a void return
493         // even though we might return a ref.  We can't use the compRetType
494         // as the determiner because something we are tracking as a byref
495         // might be used as a return value of a int function (which is legal)
496         GenTree* blockLastNode = block->lastNode();
497         if ((blockLastNode != nullptr) && (blockLastNode->gtOper == GT_RETURN) &&
498             (varTypeIsGC(compiler->info.compRetType) ||
499              (blockLastNode->AsOp()->gtOp1 != nullptr && varTypeIsGC(blockLastNode->AsOp()->gtOp1->TypeGet()))))
500         {
501             nonVarPtrRegs &= ~RBM_INTRET;
502         }
503
504         if (nonVarPtrRegs)
505         {
506             printf("Regset after " FMT_BB " gcr=", block->bbNum);
507             printRegMaskInt(gcInfo.gcRegGCrefSetCur & ~regSet.GetMaskVars());
508             compiler->GetEmitter()->emitDispRegSet(gcInfo.gcRegGCrefSetCur & ~regSet.GetMaskVars());
509             printf(", byr=");
510             printRegMaskInt(gcInfo.gcRegByrefSetCur & ~regSet.GetMaskVars());
511             compiler->GetEmitter()->emitDispRegSet(gcInfo.gcRegByrefSetCur & ~regSet.GetMaskVars());
512             printf(", regVars=");
513             printRegMaskInt(regSet.GetMaskVars());
514             compiler->GetEmitter()->emitDispRegSet(regSet.GetMaskVars());
515             printf("\n");
516         }
517
518         noway_assert(nonVarPtrRegs == RBM_NONE);
519 #endif // DEBUG
520
521 #if defined(DEBUG)
522         if (block->bbNext == nullptr)
523         {
524 // Unit testing of the emitter: generate a bunch of instructions into the last block
525 // (it's as good as any, but better than the prologue, which can only be a single instruction
526 // group) then use DOTNET_JitLateDisasm=* to see if the late disassembler
527 // thinks the instructions are the same as we do.
528 #if defined(TARGET_AMD64) && defined(LATE_DISASM)
529             genAmd64EmitterUnitTests();
530 #elif defined(TARGET_ARM64)
531             genArm64EmitterUnitTests();
532 #endif // TARGET_ARM64
533         }
534 #endif // defined(DEBUG)
535
536         // It is possible to reach the end of the block without generating code for the current IL offset.
537         // For example, if the following IR ends the current block, no code will have been generated for
538         // offset 21:
539         //
540         //          (  0,  0) [000040] ------------                il_offset void   IL offset: 21
541         //
542         //     N001 (  0,  0) [000039] ------------                nop       void
543         //
544         // This can lead to problems when debugging the generated code. To prevent these issues, make sure
545         // we've generated code for the last IL offset we saw in the block.
546         genEnsureCodeEmitted(currentDI);
547
548         /* Is this the last block, and are there any open scopes left ? */
549
550         bool isLastBlockProcessed = (block->bbNext == nullptr);
551         if (block->isBBCallAlwaysPair())
552         {
553             isLastBlockProcessed = (block->bbNext->bbNext == nullptr);
554         }
555
556         if (compiler->opts.compDbgInfo && isLastBlockProcessed)
557         {
558             varLiveKeeper->siEndAllVariableLiveRange(compiler->compCurLife);
559         }
560
561         if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
562         {
563             siEndBlock(block);
564         }
565
566         SubtractStackLevel(savedStkLvl);
567
568 #ifdef DEBUG
569         // compCurLife should be equal to the liveOut set, except that we don't keep
570         // it up to date for vars that are not register candidates
571         // (it would be nice to have a xor set function)
572
573         VARSET_TP mismatchLiveVars(VarSetOps::Diff(compiler, block->bbLiveOut, compiler->compCurLife));
574         VarSetOps::UnionD(compiler, mismatchLiveVars,
575                           VarSetOps::Diff(compiler, compiler->compCurLife, block->bbLiveOut));
576         VarSetOps::Iter mismatchLiveVarIter(compiler, mismatchLiveVars);
577         unsigned        mismatchLiveVarIndex  = 0;
578         bool            foundMismatchedRegVar = false;
579         while (mismatchLiveVarIter.NextElem(&mismatchLiveVarIndex))
580         {
581             LclVarDsc* varDsc = compiler->lvaGetDescByTrackedIndex(mismatchLiveVarIndex);
582             if (varDsc->lvIsRegCandidate())
583             {
584                 if (!foundMismatchedRegVar)
585                 {
586                     JITDUMP("Mismatched live reg vars after " FMT_BB ":", block->bbNum);
587                     foundMismatchedRegVar = true;
588                 }
589                 JITDUMP(" V%02u", compiler->lvaTrackedIndexToLclNum(mismatchLiveVarIndex));
590             }
591         }
592         if (foundMismatchedRegVar)
593         {
594             JITDUMP("\n");
595             assert(!"Found mismatched live reg var(s) after block");
596         }
597 #endif
598
599         /* Both stacks should always be empty on exit from a basic block */
600         noway_assert(genStackLevel == 0);
601
602 #ifdef TARGET_AMD64
603         // On AMD64, we need to generate a NOP after a call that is the last instruction of the block, in several
604         // situations, to support proper exception handling semantics. This is mostly to ensure that when the stack
605         // walker computes an instruction pointer for a frame, that instruction pointer is in the correct EH region.
606         // The document "X64 and ARM ABIs.docx" has more details. The situations:
607         // 1. If the call instruction is in a different EH region as the instruction that follows it.
608         // 2. If the call immediately precedes an OS epilog. (Note that what the JIT or VM consider an epilog might
609         //    be slightly different from what the OS considers an epilog, and it is the OS-reported epilog that matters
610         //    here.)
611         // We handle case #1 here, and case #2 in the emitter.
612         if (GetEmitter()->emitIsLastInsCall())
613         {
614             // Ok, the last instruction generated is a call instruction. Do any of the other conditions hold?
615             // Note: we may be generating a few too many NOPs for the case of call preceding an epilog. Technically,
616             // if the next block is a BBJ_RETURN, an epilog will be generated, but there may be some instructions
617             // generated before the OS epilog starts, such as a GS cookie check.
618             if ((block->bbNext == nullptr) || !BasicBlock::sameEHRegion(block, block->bbNext))
619             {
620                 // We only need the NOP if we're not going to generate any more code as part of the block end.
621
622                 switch (block->bbJumpKind)
623                 {
624                     case BBJ_ALWAYS:
625                     case BBJ_THROW:
626                     case BBJ_CALLFINALLY:
627                     case BBJ_EHCATCHRET:
628                     // We're going to generate more code below anyway, so no need for the NOP.
629
630                     case BBJ_RETURN:
631                     case BBJ_EHFINALLYRET:
632                     case BBJ_EHFAULTRET:
633                     case BBJ_EHFILTERRET:
634                         // These are the "epilog follows" case, handled in the emitter.
635
636                         break;
637
638                     case BBJ_NONE:
639                         if (block->bbNext == nullptr)
640                         {
641                             // Call immediately before the end of the code; we should never get here    .
642                             instGen(INS_BREAKPOINT); // This should never get executed
643                         }
644                         else
645                         {
646                             // We need the NOP
647                             instGen(INS_nop);
648                         }
649                         break;
650
651                     case BBJ_COND:
652                     case BBJ_SWITCH:
653                     // These can't have a call as the last instruction!
654
655                     default:
656                         noway_assert(!"Unexpected bbJumpKind");
657                         break;
658                 }
659             }
660         }
661 #endif // TARGET_AMD64
662
663         /* Do we need to generate a jump or return? */
664
665         switch (block->bbJumpKind)
666         {
667             case BBJ_RETURN:
668                 genExitCode(block);
669                 break;
670
671             case BBJ_THROW:
672                 // If we have a throw at the end of a function or funclet, we need to emit another instruction
673                 // afterwards to help the OS unwinder determine the correct context during unwind.
674                 // We insert an unexecuted breakpoint instruction in several situations
675                 // following a throw instruction:
676                 // 1. If the throw is the last instruction of the function or funclet. This helps
677                 //    the OS unwinder determine the correct context during an unwind from the
678                 //    thrown exception.
679                 // 2. If this is this is the last block of the hot section.
680                 // 3. If the subsequent block is a special throw block.
681                 // 4. On AMD64, if the next block is in a different EH region.
682                 if ((block->bbNext == nullptr) || (block->bbNext->bbFlags & BBF_FUNCLET_BEG) ||
683                     !BasicBlock::sameEHRegion(block, block->bbNext) ||
684                     (!isFramePointerUsed() && compiler->fgIsThrowHlpBlk(block->bbNext)) ||
685                     block->bbNext == compiler->fgFirstColdBlock)
686                 {
687                     instGen(INS_BREAKPOINT); // This should never get executed
688                 }
689                 // Do likewise for blocks that end in DOES_NOT_RETURN calls
690                 // that were not caught by the above rules. This ensures that
691                 // gc register liveness doesn't change across call instructions
692                 // in fully-interruptible mode.
693                 else
694                 {
695                     GenTree* call = block->lastNode();
696
697                     if ((call != nullptr) && (call->gtOper == GT_CALL))
698                     {
699                         if ((call->AsCall()->gtCallMoreFlags & GTF_CALL_M_DOES_NOT_RETURN) != 0)
700                         {
701                             instGen(INS_BREAKPOINT); // This should never get executed
702                         }
703                     }
704                 }
705
706                 break;
707
708             case BBJ_CALLFINALLY:
709                 block = genCallFinally(block);
710                 break;
711
712 #if defined(FEATURE_EH_FUNCLETS)
713
714             case BBJ_EHCATCHRET:
715                 genEHCatchRet(block);
716                 FALLTHROUGH;
717
718             case BBJ_EHFINALLYRET:
719             case BBJ_EHFAULTRET:
720             case BBJ_EHFILTERRET:
721                 genReserveFuncletEpilog(block);
722                 break;
723
724 #else // !FEATURE_EH_FUNCLETS
725
726             case BBJ_EHCATCHRET:
727                 noway_assert(!"Unexpected BBJ_EHCATCHRET"); // not used on x86
728                 break;
729
730             case BBJ_EHFINALLYRET:
731             case BBJ_EHFAULTRET:
732             case BBJ_EHFILTERRET:
733                 genEHFinallyOrFilterRet(block);
734                 break;
735
736 #endif // !FEATURE_EH_FUNCLETS
737
738             case BBJ_NONE:
739             case BBJ_SWITCH:
740                 break;
741
742             case BBJ_ALWAYS:
743 #ifdef TARGET_XARCH
744             {
745                 // If a block was selected to place an alignment instruction because it ended
746                 // with a jump, do not remove jumps from such blocks.
747                 // Do not remove a jump between hot and cold regions.
748                 bool isRemovableJmpCandidate =
749                     !block->hasAlign() && !compiler->fgInDifferentRegions(block, block->bbJumpDest);
750
751 #ifdef TARGET_AMD64
752                 // AMD64 requires an instruction after a call instruction for unwinding
753                 // inside an EH region so if the last instruction generated was a call instruction
754                 // do not allow this jump to be marked for possible later removal.
755                 isRemovableJmpCandidate = isRemovableJmpCandidate && !GetEmitter()->emitIsLastInsCall();
756 #endif // TARGET_AMD64
757
758                 inst_JMP(EJ_jmp, block->bbJumpDest, isRemovableJmpCandidate);
759             }
760 #else
761                 inst_JMP(EJ_jmp, block->bbJumpDest);
762 #endif // TARGET_XARCH
763
764                 FALLTHROUGH;
765
766             case BBJ_COND:
767
768 #if FEATURE_LOOP_ALIGN
769                 // This is the last place where we operate on blocks and after this, we operate
770                 // on IG. Hence, if we know that the destination of "block" is the first block
771                 // of a loop and needs alignment (it has BBF_LOOP_ALIGN), then "block" represents
772                 // end of the loop. Propagate that information on the IG through "igLoopBackEdge".
773                 //
774                 // During emitter, this information will be used to calculate the loop size.
775                 // Depending on the loop size, decision of whether to align a loop or not will be taken.
776                 //
777                 // In the emitter, we need to calculate the loop size from `block->bbJumpDest` through
778                 // `block` (inclusive). Thus, we need to ensure there is a label on the lexical fall-through
779                 // block, even if one is not otherwise needed, to be able to calculate the size of this
780                 // loop (loop size is calculated by walking the instruction groups; see emitter::getLoopSize()).
781
782                 if (block->bbJumpDest->isLoopAlign())
783                 {
784                     GetEmitter()->emitSetLoopBackEdge(block->bbJumpDest);
785
786                     if (block->bbNext != nullptr)
787                     {
788                         JITDUMP("Mark " FMT_BB " as label: alignment end-of-loop\n", block->bbNext->bbNum);
789                         block->bbNext->bbFlags |= BBF_HAS_LABEL;
790                     }
791                 }
792 #endif // FEATURE_LOOP_ALIGN
793
794                 break;
795
796             default:
797                 noway_assert(!"Unexpected bbJumpKind");
798                 break;
799         }
800
801 #if FEATURE_LOOP_ALIGN
802         if (block->hasAlign())
803         {
804             // If this block has 'align' instruction in the end (identified by BBF_HAS_ALIGN),
805             // then need to add align instruction in the current "block".
806             //
807             // For non-adaptive alignment, add alignment instruction of size depending on the
808             // compJitAlignLoopBoundary.
809             // For adaptive alignment, alignment instruction will always be of 15 bytes for xarch
810             // and 16 bytes for arm64.
811
812             assert(ShouldAlignLoops());
813             assert(!block->isBBCallAlwaysPairTail());
814 #if FEATURE_EH_CALLFINALLY_THUNKS
815             assert(block->bbJumpKind != BBJ_CALLFINALLY);
816 #endif // FEATURE_EH_CALLFINALLY_THUNKS
817
818             GetEmitter()->emitLoopAlignment(DEBUG_ARG1(block->bbJumpKind == BBJ_ALWAYS));
819         }
820
821         if ((block->bbNext != nullptr) && (block->bbNext->isLoopAlign()))
822         {
823             if (compiler->opts.compJitHideAlignBehindJmp)
824             {
825                 // The current IG is the one that is just before the IG having loop start.
826                 // Establish a connection of recent align instruction emitted to the loop
827                 // it actually is aligning using 'idaLoopHeadPredIG'.
828                 GetEmitter()->emitConnectAlignInstrWithCurIG();
829             }
830         }
831 #endif
832
833 #ifdef DEBUG
834         if (compiler->verbose)
835         {
836             varLiveKeeper->dumpBlockVariableLiveRanges(block);
837         }
838         compiler->compCurBB = nullptr;
839 #endif // DEBUG
840     }  //------------------ END-FOR each block of the method -------------------
841
842     // There could be variables alive at this point. For example see lvaKeepAliveAndReportThis.
843     // This call is for cleaning the GC refs
844     genUpdateLife(VarSetOps::MakeEmpty(compiler));
845
846     /* Finalize the spill  tracking logic */
847
848     regSet.rsSpillEnd();
849
850     /* Finalize the temp   tracking logic */
851
852     regSet.tmpEnd();
853
854 #ifdef DEBUG
855     if (compiler->verbose)
856     {
857         printf("\n# ");
858         printf("compCycleEstimate = %6d, compSizeEstimate = %5d ", compiler->compCycleEstimate,
859                compiler->compSizeEstimate);
860         printf("%s\n", compiler->info.compFullName);
861     }
862 #endif
863 }
864
865 /*
866 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
867 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
868 XX                                                                           XX
869 XX                         Register Management                               XX
870 XX                                                                           XX
871 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
872 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
873 */
874
875 //------------------------------------------------------------------------
876 // genSpillVar: Spill a local variable
877 //
878 // Arguments:
879 //    tree      - the lclVar node for the variable being spilled
880 //
881 // Return Value:
882 //    None.
883 //
884 // Assumptions:
885 //    The lclVar must be a register candidate (lvRegCandidate)
886
887 void CodeGen::genSpillVar(GenTree* tree)
888 {
889     unsigned   varNum = tree->AsLclVarCommon()->GetLclNum();
890     LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
891
892     assert(varDsc->lvIsRegCandidate());
893
894     // We don't actually need to spill if it is already living in memory
895     bool needsSpill = ((tree->gtFlags & GTF_VAR_DEF) == 0 && varDsc->lvIsInReg());
896     if (needsSpill)
897     {
898         // In order for a lclVar to have been allocated to a register, it must not have been aliasable, and can
899         // therefore be store-normalized (rather than load-normalized). In fact, not performing store normalization
900         // can lead to problems on architectures where a lclVar may be allocated to a register that is not
901         // addressable at the granularity of the lclVar's defined type (e.g. x86).
902         var_types lclType = varDsc->GetStackSlotHomeType();
903         emitAttr  size    = emitTypeSize(lclType);
904
905         // If this is a write-thru or a single-def variable, we don't actually spill at a use,
906         // but we will kill the var in the reg (below).
907         if (!varDsc->IsAlwaysAliveInMemory())
908         {
909             instruction storeIns = ins_Store(lclType, compiler->isSIMDTypeLocalAligned(varNum));
910             assert(varDsc->GetRegNum() == tree->GetRegNum());
911             inst_TT_RV(storeIns, size, tree, tree->GetRegNum());
912         }
913
914         // We should only have both GTF_SPILL (i.e. the flag causing this method to be called) and
915         // GTF_SPILLED on a write-thru/single-def def, for which we should not be calling this method.
916         assert((tree->gtFlags & GTF_SPILLED) == 0);
917
918         // Remove the live var from the register.
919         genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(tree));
920         gcInfo.gcMarkRegSetNpt(varDsc->lvRegMask());
921
922         if (VarSetOps::IsMember(compiler, gcInfo.gcTrkStkPtrLcls, varDsc->lvVarIndex))
923         {
924 #ifdef DEBUG
925             if (!VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
926             {
927                 JITDUMP("\t\t\t\t\t\t\tVar V%02u becoming live\n", varNum);
928             }
929             else
930             {
931                 JITDUMP("\t\t\t\t\t\t\tVar V%02u continuing live\n", varNum);
932             }
933 #endif
934             VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
935         }
936     }
937
938     tree->gtFlags &= ~GTF_SPILL;
939     // If this is NOT a write-thru, reset the var location.
940     if ((tree->gtFlags & GTF_SPILLED) == 0)
941     {
942         varDsc->SetRegNum(REG_STK);
943         if (varTypeIsMultiReg(tree))
944         {
945             varDsc->SetOtherReg(REG_STK);
946         }
947     }
948     else
949     {
950         // We only have 'GTF_SPILL' and 'GTF_SPILLED' on a def of a write-thru lclVar
951         // or a single-def var that is to be spilled at its definition.
952         assert((varDsc->IsAlwaysAliveInMemory()) && ((tree->gtFlags & GTF_VAR_DEF) != 0));
953     }
954
955     if (needsSpill)
956     {
957         // We need this after "lvRegNum" has change because now we are sure that varDsc->lvIsInReg() is false.
958         // "SiVarLoc" constructor uses the "LclVarDsc" of the variable.
959         varLiveKeeper->siUpdateVariableLiveRange(varDsc, varNum);
960     }
961 }
962
963 //------------------------------------------------------------------------
964 // genUpdateVarReg: Update the current register location for a multi-reg lclVar
965 //
966 // Arguments:
967 //    varDsc   - the LclVarDsc for the lclVar
968 //    tree     - the lclVar node
969 //    regIndex - the index of the register in the node
970 //
971 // inline
972 void CodeGenInterface::genUpdateVarReg(LclVarDsc* varDsc, GenTree* tree, int regIndex)
973 {
974     // This should only be called for multireg lclVars.
975     assert(compiler->lvaEnregMultiRegVars);
976     assert(tree->IsMultiRegLclVar() || (tree->gtOper == GT_COPY));
977     varDsc->SetRegNum(tree->GetRegByIndex(regIndex));
978 }
979
980 //------------------------------------------------------------------------
981 // genUpdateVarReg: Update the current register location for a lclVar
982 //
983 // Arguments:
984 //    varDsc - the LclVarDsc for the lclVar
985 //    tree   - the lclVar node
986 //
987 // inline
988 void CodeGenInterface::genUpdateVarReg(LclVarDsc* varDsc, GenTree* tree)
989 {
990     // This should not be called for multireg lclVars.
991     assert((tree->OperIsScalarLocal() && !tree->IsMultiRegLclVar()) || (tree->gtOper == GT_COPY));
992     varDsc->SetRegNum(tree->GetRegNum());
993 }
994
995 //------------------------------------------------------------------------
996 // sameRegAsDst: Return the child that has the same reg as the dst (if any)
997 //
998 // Arguments:
999 //    tree  - the node of interest
1000 //    other - an out parameter to return the other child
1001 //
1002 // Notes:
1003 //    If 'tree' has a child with the same assigned register as its target reg,
1004 //    that child will be returned, and 'other' will contain the non-matching child.
1005 //    Otherwise, both other and the return value will be nullptr.
1006 //
1007 GenTree* sameRegAsDst(GenTree* tree, GenTree*& other /*out*/)
1008 {
1009     if (tree->GetRegNum() == REG_NA)
1010     {
1011         other = nullptr;
1012         return nullptr;
1013     }
1014
1015     GenTree* op1 = tree->AsOp()->gtOp1;
1016     GenTree* op2 = tree->AsOp()->gtOp2;
1017     if (op1->GetRegNum() == tree->GetRegNum())
1018     {
1019         other = op2;
1020         return op1;
1021     }
1022     if (op2->GetRegNum() == tree->GetRegNum())
1023     {
1024         other = op1;
1025         return op2;
1026     }
1027     else
1028     {
1029         other = nullptr;
1030         return nullptr;
1031     }
1032 }
1033
1034 //------------------------------------------------------------------------
1035 // genUnspillLocal: Reload a register candidate local into a register, if needed.
1036 //
1037 // Arguments:
1038 //     varNum    - The variable number of the local to be reloaded (unspilled).
1039 //                 It may be a local field.
1040 //     type      - The type of the local.
1041 //     lclNode   - The node being unspilled. Note that for a multi-reg local,
1042 //                 the gtLclNum will be that of the parent struct.
1043 //     regNum    - The register that 'varNum' should be loaded to.
1044 //     reSpill   - True if it will be immediately spilled after use.
1045 //     isLastUse - True if this is a last use of 'varNum'.
1046 //
1047 // Notes:
1048 //     The caller must have determined that this local needs to be unspilled.
1049 void CodeGen::genUnspillLocal(
1050     unsigned varNum, var_types type, GenTreeLclVar* lclNode, regNumber regNum, bool reSpill, bool isLastUse)
1051 {
1052     LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
1053     inst_set_SV_var(lclNode);
1054     instruction ins = ins_Load(type, compiler->isSIMDTypeLocalAligned(varNum));
1055     GetEmitter()->emitIns_R_S(ins, emitTypeSize(type), regNum, varNum, 0);
1056
1057     // TODO-Review: We would like to call:
1058     //      genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(tree));
1059     // instead of the following code, but this ends up hitting this assert:
1060     //      assert((regSet.GetMaskVars() & regMask) == 0);
1061     // due to issues with LSRA resolution moves.
1062     // So, just force it for now. This probably indicates a condition that creates a GC hole!
1063     //
1064     // Extra note: I think we really want to call something like gcInfo.gcUpdateForRegVarMove,
1065     // because the variable is not really going live or dead, but that method is somewhat poorly
1066     // factored because it, in turn, updates rsMaskVars which is part of RegSet not GCInfo.
1067     // TODO-Cleanup: This code exists in other CodeGen*.cpp files, and should be moved to CodeGenCommon.cpp.
1068
1069     // Don't update the variable's location if we are just re-spilling it again.
1070
1071     if (!reSpill)
1072     {
1073         varDsc->SetRegNum(regNum);
1074
1075         // We want "VariableLiveRange" inclusive on the beginning and exclusive on the ending.
1076         // For that we shouldn't report an update of the variable location if is becoming dead
1077         // on the same native offset.
1078         if (!isLastUse)
1079         {
1080             // Report the home change for this variable
1081             varLiveKeeper->siUpdateVariableLiveRange(varDsc, varNum);
1082         }
1083
1084         if (!varDsc->IsAlwaysAliveInMemory())
1085         {
1086 #ifdef DEBUG
1087             if (VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
1088             {
1089                 JITDUMP("\t\t\t\t\t\t\tRemoving V%02u from gcVarPtrSetCur\n", varNum);
1090             }
1091 #endif // DEBUG
1092             VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
1093         }
1094
1095 #ifdef DEBUG
1096         if (compiler->verbose)
1097         {
1098             printf("\t\t\t\t\t\t\tV%02u in reg ", varNum);
1099             varDsc->PrintVarReg();
1100             printf(" is becoming live  ");
1101             compiler->printTreeID(lclNode);
1102             printf("\n");
1103         }
1104 #endif // DEBUG
1105
1106         regSet.AddMaskVars(genGetRegMask(varDsc));
1107     }
1108
1109     gcInfo.gcMarkRegPtrVal(regNum, type);
1110 }
1111
1112 //------------------------------------------------------------------------
1113 // genUnspillRegIfNeeded: Reload a MultiReg source value into a register, if needed
1114 //
1115 // Arguments:
1116 //    tree          - the MultiReg node of interest.
1117 //    multiRegIndex - the index of the value to reload, if needed.
1118 //
1119 // Notes:
1120 //    It must *not* be a GT_LCL_VAR (those are handled separately).
1121 //    In the normal case, the value will be reloaded into the register it
1122 //    was originally computed into. However, if that register is not available,
1123 //    the register allocator will have allocated a different register, and
1124 //    inserted a GT_RELOAD to indicate the register into which it should be
1125 //    reloaded.
1126 //
1127 void CodeGen::genUnspillRegIfNeeded(GenTree* tree, unsigned multiRegIndex)
1128 {
1129     GenTree* unspillTree = tree;
1130     assert(unspillTree->IsMultiRegNode());
1131
1132     if (tree->gtOper == GT_RELOAD)
1133     {
1134         unspillTree = tree->AsOp()->gtOp1;
1135     }
1136
1137     // In case of multi-reg node, GTF_SPILLED flag on it indicates that
1138     // one or more of its result regs are spilled.  Individual spill flags need to be
1139     // queried to determine which specific result regs need to be unspilled.
1140     if ((unspillTree->gtFlags & GTF_SPILLED) == 0)
1141     {
1142         return;
1143     }
1144     GenTreeFlags spillFlags = unspillTree->GetRegSpillFlagByIdx(multiRegIndex);
1145     if ((spillFlags & GTF_SPILLED) == 0)
1146     {
1147         return;
1148     }
1149
1150     regNumber dstReg = tree->GetRegByIndex(multiRegIndex);
1151     if (dstReg == REG_NA)
1152     {
1153         assert(tree->IsCopyOrReload());
1154         dstReg = unspillTree->GetRegByIndex(multiRegIndex);
1155     }
1156     if (tree->IsMultiRegLclVar())
1157     {
1158         GenTreeLclVar* lclNode     = tree->AsLclVar();
1159         unsigned       fieldVarNum = compiler->lvaGetDesc(lclNode)->lvFieldLclStart + multiRegIndex;
1160         bool           reSpill     = ((spillFlags & GTF_SPILL) != 0);
1161         bool           isLastUse   = lclNode->IsLastUse(multiRegIndex);
1162         genUnspillLocal(fieldVarNum, compiler->lvaGetDesc(fieldVarNum)->TypeGet(), lclNode, dstReg, reSpill, isLastUse);
1163     }
1164     else
1165     {
1166         var_types dstType        = unspillTree->GetRegTypeByIndex(multiRegIndex);
1167         regNumber unspillTreeReg = unspillTree->GetRegByIndex(multiRegIndex);
1168         TempDsc*  t              = regSet.rsUnspillInPlace(unspillTree, unspillTreeReg, multiRegIndex);
1169         emitAttr  emitType       = emitActualTypeSize(dstType);
1170         GetEmitter()->emitIns_R_S(ins_Load(dstType), emitType, dstReg, t->tdTempNum(), 0);
1171         regSet.tmpRlsTemp(t);
1172         gcInfo.gcMarkRegPtrVal(dstReg, dstType);
1173     }
1174 }
1175
1176 //------------------------------------------------------------------------
1177 // genUnspillRegIfNeeded: Reload the value into a register, if needed
1178 //
1179 // Arguments:
1180 //    tree - the node of interest.
1181 //
1182 // Notes:
1183 //    In the normal case, the value will be reloaded into the register it
1184 //    was originally computed into. However, if that register is not available,
1185 //    the register allocator will have allocated a different register, and
1186 //    inserted a GT_RELOAD to indicate the register into which it should be
1187 //    reloaded.
1188 //
1189 //    A GT_RELOAD never has a reg candidate lclVar or multi-reg lclVar as its child.
1190 //    This is because register candidates locals always have distinct tree nodes
1191 //    for uses and definitions. (This is unlike non-register candidate locals which
1192 //    may be "defined" by a GT_LCL_VAR node that loads it into a register. It may
1193 //    then have a GT_RELOAD inserted if it needs a different register, though this
1194 //    is unlikely to happen except in stress modes.)
1195 //
1196 void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
1197 {
1198     GenTree* unspillTree = tree;
1199     if (tree->gtOper == GT_RELOAD)
1200     {
1201         unspillTree = tree->AsOp()->gtOp1;
1202     }
1203
1204     if ((unspillTree->gtFlags & GTF_SPILLED) != 0)
1205     {
1206         if (genIsRegCandidateLocal(unspillTree))
1207         {
1208             // We never have a GT_RELOAD for this case.
1209             assert(tree == unspillTree);
1210
1211             // Reset spilled flag, since we are going to load a local variable from its home location.
1212             unspillTree->gtFlags &= ~GTF_SPILLED;
1213
1214             GenTreeLclVar* lcl         = unspillTree->AsLclVar();
1215             LclVarDsc*     varDsc      = compiler->lvaGetDesc(lcl);
1216             var_types      unspillType = varDsc->GetRegisterType(lcl);
1217             assert(unspillType != TYP_UNDEF);
1218
1219 // TODO-Cleanup: The following code could probably be further merged and cleaned up.
1220 #if defined(TARGET_XARCH) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
1221
1222             // Pick type to reload register from stack with. Note that in
1223             // general, the type of 'lcl' does not have any relation to the
1224             // type of 'varDsc':
1225             //
1226             // * For normalize-on-load (NOL) locals it is wider under normal
1227             // circumstances, where morph has added a cast on top. In some
1228             // cases it is the same, when morph has used a subrange assertion
1229             // to avoid normalizing.
1230             //
1231             // * For all locals it can be narrower in some cases, when
1232             // lowering optimizes to use a smaller typed `cmp` (e.g. 32-bit cmp
1233             // for 64-bit local, or 8-bit cmp for 16-bit local).
1234             //
1235             // * For byrefs it can differ in GC-ness (TYP_I_IMPL vs TYP_BYREF).
1236             //
1237             // In the NOL case the potential use of subrange assertions means
1238             // we always have to normalize, even if 'lcl' is wide; we could
1239             // have a GTF_SPILLED LCL_VAR<int>(NOL local) with a future
1240             // LCL_VAR<ushort>(same NOL local), where the latter local then
1241             // relies on the normalization to have happened here as part of
1242             // unspilling.
1243             //
1244             if (varDsc->lvNormalizeOnLoad())
1245             {
1246                 unspillType = varDsc->TypeGet();
1247             }
1248             else
1249             {
1250                 // Potentially narrower -- see if we should widen.
1251                 var_types lclLoadType = varDsc->GetStackSlotHomeType();
1252                 assert(lclLoadType != TYP_UNDEF);
1253                 if (genTypeSize(unspillType) < genTypeSize(lclLoadType))
1254                 {
1255                     unspillType = lclLoadType;
1256                 }
1257             }
1258
1259 #if defined(TARGET_LOONGARCH64)
1260             if (varTypeIsFloating(spillType) && emitter::isGeneralRegister(tree->GetRegNum()))
1261             {
1262                 unspillType = unspillType == TYP_FLOAT ? TYP_INT : TYP_LONG;
1263             }
1264 #endif
1265 #elif defined(TARGET_ARM)
1266 // No normalizing for ARM
1267 #else
1268             NYI("Unspilling not implemented for this target architecture.");
1269 #endif
1270
1271             bool reSpill   = ((unspillTree->gtFlags & GTF_SPILL) != 0);
1272             bool isLastUse = lcl->IsLastUse(0);
1273             genUnspillLocal(lcl->GetLclNum(), unspillType, lcl->AsLclVar(), tree->GetRegNum(), reSpill, isLastUse);
1274         }
1275         else if (unspillTree->IsMultiRegLclVar())
1276         {
1277             // We never have a GT_RELOAD for this case.
1278             assert(tree == unspillTree);
1279
1280             GenTreeLclVar* lclNode  = unspillTree->AsLclVar();
1281             LclVarDsc*     varDsc   = compiler->lvaGetDesc(lclNode);
1282             unsigned       regCount = varDsc->lvFieldCnt;
1283
1284             for (unsigned i = 0; i < regCount; ++i)
1285             {
1286                 GenTreeFlags spillFlags = lclNode->GetRegSpillFlagByIdx(i);
1287                 if ((spillFlags & GTF_SPILLED) != 0)
1288                 {
1289                     regNumber reg         = lclNode->GetRegNumByIdx(i);
1290                     unsigned  fieldVarNum = varDsc->lvFieldLclStart + i;
1291                     bool      reSpill     = ((spillFlags & GTF_SPILL) != 0);
1292                     bool      isLastUse   = lclNode->IsLastUse(i);
1293                     genUnspillLocal(fieldVarNum, compiler->lvaGetDesc(fieldVarNum)->TypeGet(), lclNode, reg, reSpill,
1294                                     isLastUse);
1295                 }
1296             }
1297         }
1298         else if (unspillTree->IsMultiRegNode())
1299         {
1300             // Here we may have a GT_RELOAD, and we will need to use that node ('tree') to
1301             // do the unspilling if needed. However, that tree doesn't have the register
1302             // count, so we use 'unspillTree' for that.
1303             unsigned regCount = unspillTree->GetMultiRegCount(compiler);
1304             for (unsigned i = 0; i < regCount; ++i)
1305             {
1306                 genUnspillRegIfNeeded(tree, i);
1307             }
1308             unspillTree->gtFlags &= ~GTF_SPILLED;
1309         }
1310         else
1311         {
1312             // Here we may have a GT_RELOAD.
1313             // The spill temp allocated for it is associated with the original tree that defined the
1314             // register that it was spilled from.
1315             // So we use 'unspillTree' to recover that spill temp.
1316             TempDsc* t        = regSet.rsUnspillInPlace(unspillTree, unspillTree->GetRegNum());
1317             emitAttr emitType = emitActualTypeSize(unspillTree->TypeGet());
1318             // Reload into the register specified by 'tree' which may be a GT_RELOAD.
1319             regNumber dstReg = tree->GetRegNum();
1320             GetEmitter()->emitIns_R_S(ins_Load(unspillTree->gtType), emitType, dstReg, t->tdTempNum(), 0);
1321             regSet.tmpRlsTemp(t);
1322
1323             unspillTree->gtFlags &= ~GTF_SPILLED;
1324             gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
1325         }
1326     }
1327 }
1328
1329 //------------------------------------------------------------------------
1330 // genCopyRegIfNeeded: Copy the given node into the specified register
1331 //
1332 // Arguments:
1333 //    node - The node that has been evaluated (consumed).
1334 //    needReg - The register in which its value is needed.
1335 //
1336 // Notes:
1337 //    This must be a node that has a register.
1338 //
1339 void CodeGen::genCopyRegIfNeeded(GenTree* node, regNumber needReg)
1340 {
1341     assert((node->GetRegNum() != REG_NA) && (needReg != REG_NA));
1342     assert(!node->isUsedFromSpillTemp());
1343     inst_Mov(node->TypeGet(), needReg, node->GetRegNum(), /* canSkip */ true);
1344 }
1345
1346 // Do Liveness update for a subnodes that is being consumed by codegen
1347 // including the logic for reload in case is needed and also takes care
1348 // of locating the value on the desired register.
1349 void CodeGen::genConsumeRegAndCopy(GenTree* node, regNumber needReg)
1350 {
1351     if (needReg == REG_NA)
1352     {
1353         return;
1354     }
1355     genConsumeReg(node);
1356     genCopyRegIfNeeded(node, needReg);
1357 }
1358
1359 // Check that registers are consumed in the right order for the current node being generated.
1360 #ifdef DEBUG
1361 void CodeGen::genNumberOperandUse(GenTree* const operand, int& useNum) const
1362 {
1363     assert(operand != nullptr);
1364     assert(operand->gtUseNum == -1);
1365
1366     if (!operand->isContained() && !operand->IsCopyOrReload())
1367     {
1368         operand->gtUseNum = useNum;
1369         useNum++;
1370     }
1371     else
1372     {
1373         for (GenTree* op : operand->Operands())
1374         {
1375             genNumberOperandUse(op, useNum);
1376         }
1377     }
1378 }
1379
1380 void CodeGen::genCheckConsumeNode(GenTree* const node)
1381 {
1382     assert(node != nullptr);
1383
1384     if (verbose)
1385     {
1386         if (node->gtUseNum == -1)
1387         {
1388             // nothing wrong if the node was not consumed
1389         }
1390         else if ((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) != 0)
1391         {
1392             printf("Node was consumed twice:\n");
1393             compiler->gtDispTree(node, nullptr, nullptr, true);
1394         }
1395         else if ((lastConsumedNode != nullptr) && (node->gtUseNum < lastConsumedNode->gtUseNum))
1396         {
1397             printf("Nodes were consumed out-of-order:\n");
1398             compiler->gtDispTree(lastConsumedNode, nullptr, nullptr, true);
1399             compiler->gtDispTree(node, nullptr, nullptr, true);
1400         }
1401     }
1402
1403     assert((node->OperGet() == GT_CATCH_ARG) || ((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) == 0));
1404     assert((lastConsumedNode == nullptr) || (node->gtUseNum == -1) || (node->gtUseNum > lastConsumedNode->gtUseNum));
1405
1406     node->gtDebugFlags |= GTF_DEBUG_NODE_CG_CONSUMED;
1407     lastConsumedNode = node;
1408 }
1409 #endif // DEBUG
1410
1411 //--------------------------------------------------------------------
1412 // genConsumeReg: Do liveness update for a single register of a multireg child node
1413 //                that is being consumed by codegen.
1414 //
1415 // Arguments:
1416 //    tree          - GenTree node
1417 //    multiRegIndex - The index of the register to be consumed
1418 //
1419 // Return Value:
1420 //    Returns the reg number for the given multiRegIndex.
1421 //
1422 regNumber CodeGen::genConsumeReg(GenTree* tree, unsigned multiRegIndex)
1423 {
1424     regNumber reg = tree->GetRegByIndex(multiRegIndex);
1425     if (tree->OperIs(GT_COPY))
1426     {
1427         reg = genRegCopy(tree, multiRegIndex);
1428     }
1429     else if (reg == REG_NA)
1430     {
1431         assert(tree->OperIs(GT_RELOAD));
1432         reg = tree->gtGetOp1()->GetRegByIndex(multiRegIndex);
1433         assert(reg != REG_NA);
1434     }
1435     genUnspillRegIfNeeded(tree, multiRegIndex);
1436
1437     // UpdateLifeFieldVar() will return true if local var should be spilled.
1438     if (tree->IsMultiRegLclVar() && treeLifeUpdater->UpdateLifeFieldVar(tree->AsLclVar(), multiRegIndex))
1439     {
1440         GenTreeLclVar* lcl = tree->AsLclVar();
1441         genSpillLocal(lcl->GetLclNum(), lcl->GetFieldTypeByIndex(compiler, multiRegIndex), lcl,
1442                       lcl->GetRegByIndex(multiRegIndex));
1443     }
1444
1445     if (tree->gtSkipReloadOrCopy()->OperIs(GT_LCL_VAR))
1446     {
1447         assert(compiler->lvaEnregMultiRegVars);
1448
1449         GenTreeLclVar* lcl = tree->gtSkipReloadOrCopy()->AsLclVar();
1450         assert(lcl->IsMultiReg());
1451
1452         LclVarDsc* varDsc = compiler->lvaGetDesc(lcl);
1453         assert(varDsc->lvPromoted);
1454         assert(multiRegIndex < varDsc->lvFieldCnt);
1455         unsigned   fieldVarNum = varDsc->lvFieldLclStart + multiRegIndex;
1456         LclVarDsc* fldVarDsc   = compiler->lvaGetDesc(fieldVarNum);
1457         assert(fldVarDsc->lvLRACandidate);
1458
1459         if (fldVarDsc->GetRegNum() == REG_STK)
1460         {
1461             // We have loaded this into a register only temporarily
1462             gcInfo.gcMarkRegSetNpt(genRegMask(reg));
1463         }
1464         else if (lcl->IsLastUse(multiRegIndex))
1465         {
1466             gcInfo.gcMarkRegSetNpt(genRegMask(fldVarDsc->GetRegNum()));
1467         }
1468     }
1469     else
1470     {
1471         gcInfo.gcMarkRegSetNpt(tree->gtGetRegMask());
1472     }
1473     return reg;
1474 }
1475
1476 //--------------------------------------------------------------------
1477 // genConsumeReg: Do liveness update for a subnode that is being
1478 // consumed by codegen.
1479 //
1480 // Arguments:
1481 //    tree - GenTree node
1482 //
1483 // Return Value:
1484 //    Returns the reg number of tree.
1485 //    In case of multi-reg call node returns the first reg number
1486 //    of the multi-reg return.
1487 //
1488 regNumber CodeGen::genConsumeReg(GenTree* tree)
1489 {
1490     if (tree->OperGet() == GT_COPY)
1491     {
1492         genRegCopy(tree);
1493     }
1494
1495     // Handle the case where we have a lclVar that needs to be copied before use (i.e. because it
1496     // interferes with one of the other sources (or the target, if it's a "delayed use" register)).
1497     // TODO-Cleanup: This is a special copyReg case in LSRA - consider eliminating these and
1498     // always using GT_COPY to make the lclVar location explicit.
1499     // Note that we have to do this before calling genUpdateLife because otherwise if we spill it
1500     // the lvRegNum will be set to REG_STK and we will lose track of what register currently holds
1501     // the lclVar (normally when a lclVar is spilled it is then used from its former register
1502     // location, which matches the GetRegNum() on the node).
1503     // (Note that it doesn't matter if we call this before or after genUnspillRegIfNeeded
1504     // because if it's on the stack it will always get reloaded into tree->GetRegNum()).
1505     if (genIsRegCandidateLocal(tree))
1506     {
1507         GenTreeLclVarCommon* lcl    = tree->AsLclVarCommon();
1508         LclVarDsc*           varDsc = compiler->lvaGetDesc(lcl);
1509         if (varDsc->GetRegNum() != REG_STK)
1510         {
1511             var_types regType = varDsc->GetRegisterType(lcl);
1512             inst_Mov(regType, tree->GetRegNum(), varDsc->GetRegNum(), /* canSkip */ true);
1513         }
1514     }
1515
1516     genUnspillRegIfNeeded(tree);
1517
1518     // genUpdateLife() will also spill local var if marked as GTF_SPILL by calling CodeGen::genSpillVar
1519     genUpdateLife(tree);
1520
1521     // there are three cases where consuming a reg means clearing the bit in the live mask
1522     // 1. it was not produced by a local
1523     // 2. it was produced by a local that is going dead
1524     // 3. it was produced by a local that does not live in that reg (like one allocated on the stack)
1525
1526     if (genIsRegCandidateLocal(tree))
1527     {
1528         assert(tree->gtHasReg(compiler));
1529
1530         GenTreeLclVarCommon* lcl    = tree->AsLclVar();
1531         LclVarDsc*           varDsc = compiler->lvaGetDesc(lcl);
1532         assert(varDsc->lvLRACandidate);
1533
1534         if (varDsc->GetRegNum() == REG_STK)
1535         {
1536             // We have loaded this into a register only temporarily
1537             gcInfo.gcMarkRegSetNpt(genRegMask(tree->GetRegNum()));
1538         }
1539         else if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
1540         {
1541             gcInfo.gcMarkRegSetNpt(genRegMask(varDsc->GetRegNum()));
1542         }
1543     }
1544     else if (tree->gtSkipReloadOrCopy()->IsMultiRegLclVar())
1545     {
1546         assert(compiler->lvaEnregMultiRegVars);
1547         GenTreeLclVar* lcl              = tree->gtSkipReloadOrCopy()->AsLclVar();
1548         LclVarDsc*     varDsc           = compiler->lvaGetDesc(lcl);
1549         unsigned       firstFieldVarNum = varDsc->lvFieldLclStart;
1550         for (unsigned i = 0; i < varDsc->lvFieldCnt; ++i)
1551         {
1552             LclVarDsc* fldVarDsc = compiler->lvaGetDesc(firstFieldVarNum + i);
1553             assert(fldVarDsc->lvLRACandidate);
1554             regNumber reg;
1555             if (tree->OperIs(GT_COPY, GT_RELOAD) && (tree->AsCopyOrReload()->GetRegByIndex(i) != REG_NA))
1556             {
1557                 reg = tree->AsCopyOrReload()->GetRegByIndex(i);
1558             }
1559             else
1560             {
1561                 reg = lcl->AsLclVar()->GetRegNumByIdx(i);
1562             }
1563
1564             if (fldVarDsc->GetRegNum() == REG_STK)
1565             {
1566                 // We have loaded this into a register only temporarily
1567                 gcInfo.gcMarkRegSetNpt(genRegMask(reg));
1568             }
1569             else if (lcl->IsLastUse(i))
1570             {
1571                 gcInfo.gcMarkRegSetNpt(genRegMask(fldVarDsc->GetRegNum()));
1572             }
1573         }
1574     }
1575     else
1576     {
1577         gcInfo.gcMarkRegSetNpt(tree->gtGetRegMask());
1578     }
1579
1580     genCheckConsumeNode(tree);
1581     return tree->GetRegNum();
1582 }
1583
1584 // Do liveness update for an address tree: one of GT_LEA, GT_LCL_VAR, or GT_CNS_INT (for call indirect).
1585 void CodeGen::genConsumeAddress(GenTree* addr)
1586 {
1587     if (!addr->isContained())
1588     {
1589         genConsumeReg(addr);
1590     }
1591     else if (addr->OperGet() == GT_LEA)
1592     {
1593         genConsumeAddrMode(addr->AsAddrMode());
1594     }
1595 }
1596
1597 // do liveness update for a subnode that is being consumed by codegen
1598 void CodeGen::genConsumeAddrMode(GenTreeAddrMode* addr)
1599 {
1600     genConsumeOperands(addr);
1601 }
1602
1603 void CodeGen::genConsumeRegs(GenTree* tree)
1604 {
1605 #if !defined(TARGET_64BIT)
1606     if (tree->OperGet() == GT_LONG)
1607     {
1608         genConsumeRegs(tree->gtGetOp1());
1609         genConsumeRegs(tree->gtGetOp2());
1610         return;
1611     }
1612 #endif // !defined(TARGET_64BIT)
1613
1614     if (tree->isUsedFromSpillTemp())
1615     {
1616         // spill temps are un-tracked and hence no need to update life
1617     }
1618     else if (tree->isContained())
1619     {
1620         if (tree->OperIsIndir())
1621         {
1622             genConsumeAddress(tree->AsIndir()->Addr());
1623         }
1624         else if (tree->OperIs(GT_LEA))
1625         {
1626             genConsumeAddress(tree);
1627         }
1628 #if defined(TARGET_XARCH) || defined(TARGET_ARM64)
1629         else if (tree->OperIsCompare())
1630         {
1631             // Compares can be contained by SELECT/compare chains.
1632             genConsumeRegs(tree->gtGetOp1());
1633             genConsumeRegs(tree->gtGetOp2());
1634         }
1635 #endif
1636 #ifdef TARGET_ARM64
1637         else if (tree->OperIs(GT_BFIZ))
1638         {
1639             // Can be contained as part of LEA on ARM64
1640             GenTreeCast* cast = tree->gtGetOp1()->AsCast();
1641             assert(cast->isContained());
1642             genConsumeAddress(cast->CastOp());
1643         }
1644         else if (tree->OperIs(GT_CAST))
1645         {
1646             // Can be contained as part of LEA on ARM64
1647             GenTreeCast* cast = tree->AsCast();
1648             assert(cast->isContained());
1649             genConsumeAddress(cast->CastOp());
1650         }
1651         else if (tree->OperIs(GT_AND))
1652         {
1653             // ANDs may be contained in a chain.
1654             genConsumeRegs(tree->gtGetOp1());
1655             genConsumeRegs(tree->gtGetOp2());
1656         }
1657         else if (tree->OperIsFieldList())
1658         {
1659             for (GenTreeFieldList::Use& use : tree->AsFieldList()->Uses())
1660             {
1661                 GenTree* fieldNode = use.GetNode();
1662                 genConsumeRegs(fieldNode);
1663             }
1664         }
1665 #endif
1666         else if (tree->OperIsLocalRead())
1667         {
1668             // A contained lcl var must be living on stack and marked as reg optional, or not be a
1669             // register candidate.
1670             unsigned   varNum = tree->AsLclVarCommon()->GetLclNum();
1671             LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
1672
1673             noway_assert(varDsc->GetRegNum() == REG_STK);
1674             noway_assert(tree->IsRegOptional() || !varDsc->lvLRACandidate);
1675
1676             // Update the life of the lcl var.
1677             genUpdateLife(tree);
1678         }
1679 #ifdef TARGET_XARCH
1680 #ifdef FEATURE_HW_INTRINSICS
1681         else if (tree->OperIs(GT_HWINTRINSIC))
1682         {
1683             GenTreeHWIntrinsic* hwintrinsic = tree->AsHWIntrinsic();
1684             genConsumeMultiOpOperands(hwintrinsic);
1685         }
1686 #endif // FEATURE_HW_INTRINSICS
1687 #endif // TARGET_XARCH
1688         else if (tree->OperIs(GT_BITCAST, GT_NEG, GT_CAST, GT_LSH, GT_RSH, GT_RSZ, GT_BSWAP, GT_BSWAP16))
1689         {
1690             genConsumeRegs(tree->gtGetOp1());
1691         }
1692         else if (tree->OperIs(GT_MUL))
1693         {
1694             genConsumeRegs(tree->gtGetOp1());
1695             genConsumeRegs(tree->gtGetOp2());
1696         }
1697         else
1698         {
1699 #ifdef FEATURE_SIMD
1700             // (In)Equality operation that produces bool result, when compared
1701             // against Vector zero, marks its Vector Zero operand as contained.
1702             assert(tree->OperIsLeaf() || tree->IsVectorZero());
1703 #else
1704             assert(tree->OperIsLeaf());
1705 #endif
1706         }
1707     }
1708     else
1709     {
1710         genConsumeReg(tree);
1711     }
1712 }
1713
1714 //------------------------------------------------------------------------
1715 // genConsumeOperands: Do liveness update for the operands of a unary or binary tree
1716 //
1717 // Arguments:
1718 //    tree - the GenTreeOp whose operands will have their liveness updated.
1719 //
1720 // Return Value:
1721 //    None.
1722 //
1723 void CodeGen::genConsumeOperands(GenTreeOp* tree)
1724 {
1725     GenTree* firstOp  = tree->gtOp1;
1726     GenTree* secondOp = tree->gtOp2;
1727
1728     if (firstOp != nullptr)
1729     {
1730         genConsumeRegs(firstOp);
1731     }
1732     if (secondOp != nullptr)
1733     {
1734         genConsumeRegs(secondOp);
1735     }
1736 }
1737
1738 #if defined(FEATURE_SIMD) || defined(FEATURE_HW_INTRINSICS)
1739 //------------------------------------------------------------------------
1740 // genConsumeOperands: Do liveness update for the operands of a multi-operand node,
1741 //                     currently GT_HWINTRINSIC
1742 //
1743 // Arguments:
1744 //    tree - the GenTreeMultiOp whose operands will have their liveness updated.
1745 //
1746 // Return Value:
1747 //    None.
1748 //
1749 void CodeGen::genConsumeMultiOpOperands(GenTreeMultiOp* tree)
1750 {
1751     for (GenTree* operand : tree->Operands())
1752     {
1753         genConsumeRegs(operand);
1754     }
1755 }
1756 #endif // defined(FEATURE_SIMD) || defined(FEATURE_HW_INTRINSICS)
1757
1758 #if FEATURE_PUT_STRUCT_ARG_STK
1759 //------------------------------------------------------------------------
1760 // genConsumePutStructArgStk: Do liveness update for the operands of a PutArgStk node.
1761 //                      Also loads in the right register the addresses of the
1762 //                      src/dst for rep mov operation.
1763 //
1764 // Arguments:
1765 //    putArgNode - the PUTARG_STK tree.
1766 //    dstReg     - the dstReg for the rep move operation.
1767 //    srcReg     - the srcReg for the rep move operation.
1768 //    sizeReg    - the sizeReg for the rep move operation.
1769 //
1770 // Return Value:
1771 //    None.
1772 //
1773 // Notes:
1774 //    sizeReg can be REG_NA when this function is used to consume the dstReg and srcReg
1775 //    for copying on the stack a struct with references.
1776 //    The source address/offset is determined from the address on the GT_BLK node, while
1777 //    the destination address is the address contained in 'm_stkArgVarNum' plus the offset
1778 //    provided in the 'putArgNode'.
1779 //    m_stkArgVarNum must be set to  the varnum for the local used for placing the "by-value" args on the stack.
1780
1781 void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode,
1782                                         regNumber         dstReg,
1783                                         regNumber         srcReg,
1784                                         regNumber         sizeReg)
1785 {
1786     // The putArgNode children are always contained. We should not consume any registers.
1787     assert(putArgNode->Data()->isContained());
1788
1789     // Get the source.
1790     GenTree*  src        = putArgNode->Data();
1791     regNumber srcAddrReg = REG_NA;
1792     assert(varTypeIsStruct(src));
1793     assert(src->OperIs(GT_BLK) || src->OperIsLocalRead() || (src->OperIs(GT_IND) && varTypeIsSIMD(src)));
1794
1795     assert(dstReg != REG_NA);
1796     assert(srcReg != REG_NA);
1797
1798     // Consume the register for the source address if needed.
1799     if (src->OperIsIndir())
1800     {
1801         srcAddrReg = genConsumeReg(src->AsIndir()->Addr());
1802     }
1803
1804     // If the op1 is already in the dstReg - nothing to do.
1805     // Otherwise load the op1 (the address) into the dstReg to copy the struct on the stack by value.
1806     CLANG_FORMAT_COMMENT_ANCHOR;
1807
1808 #ifdef TARGET_X86
1809     assert(dstReg != REG_SPBASE);
1810     inst_Mov(TYP_I_IMPL, dstReg, REG_SPBASE, /* canSkip */ false);
1811 #else  // !TARGET_X86
1812     GenTree* dstAddr = putArgNode;
1813     if (dstAddr->GetRegNum() != dstReg)
1814     {
1815         // Generate LEA instruction to load the stack of the outgoing var + SlotNum offset (or the incoming arg area
1816         // for tail calls) in RDI.
1817         // Destination is always local (on the stack) - use EA_PTRSIZE.
1818         assert(m_stkArgVarNum != BAD_VAR_NUM);
1819         GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, dstReg, m_stkArgVarNum, putArgNode->getArgOffset());
1820     }
1821 #endif // !TARGET_X86
1822
1823     if (srcAddrReg != REG_NA)
1824     {
1825         // Source is not known to be on the stack. Use EA_BYREF.
1826         GetEmitter()->emitIns_Mov(INS_mov, EA_BYREF, srcReg, srcAddrReg, /* canSkip */ true);
1827     }
1828     else
1829     {
1830         // Generate LEA instruction to load the LclVar address in RSI.
1831         // Source is known to be on the stack. Use EA_PTRSIZE.
1832         GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, srcReg, src->AsLclVarCommon()->GetLclNum(),
1833                                   src->AsLclVarCommon()->GetLclOffs());
1834     }
1835
1836     if (sizeReg != REG_NA)
1837     {
1838         unsigned size = putArgNode->GetStackByteSize();
1839         inst_RV_IV(INS_mov, sizeReg, size, EA_PTRSIZE);
1840     }
1841 }
1842 #endif // FEATURE_PUT_STRUCT_ARG_STK
1843
1844 #if FEATURE_ARG_SPLIT
1845 //------------------------------------------------------------------------
1846 // genConsumeArgRegSplit: Consume register(s) in Call node to set split struct argument.
1847 //
1848 // Arguments:
1849 //    putArgNode - the PUTARG_STK tree.
1850 //
1851 // Return Value:
1852 //    None.
1853 //
1854 void CodeGen::genConsumeArgSplitStruct(GenTreePutArgSplit* putArgNode)
1855 {
1856     assert(putArgNode->OperGet() == GT_PUTARG_SPLIT);
1857     assert(putArgNode->gtHasReg(compiler));
1858
1859     genUnspillRegIfNeeded(putArgNode);
1860
1861     gcInfo.gcMarkRegSetNpt(putArgNode->gtGetRegMask());
1862
1863     genCheckConsumeNode(putArgNode);
1864 }
1865 #endif // FEATURE_ARG_SPLIT
1866
1867 //------------------------------------------------------------------------
1868 // genPutArgStkFieldList: Generate code for a putArgStk whose source is a GT_FIELD_LIST
1869 //
1870 // Arguments:
1871 //    putArgStk    - The putArgStk node
1872 //    outArgVarNum - The lclVar num for the argument
1873 //
1874 // Notes:
1875 //    The x86 version of this is in codegenxarch.cpp, and doesn't take an
1876 //    outArgVarNum, as it pushes its args onto the stack.
1877 //
1878 #ifndef TARGET_X86
1879 void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArgVarNum)
1880 {
1881     assert(putArgStk->gtOp1->OperIs(GT_FIELD_LIST));
1882
1883     // Evaluate each of the GT_FIELD_LIST items into their register
1884     // and store their register into the outgoing argument area.
1885     const unsigned argOffset = putArgStk->getArgOffset();
1886     for (GenTreeFieldList::Use& use : putArgStk->gtOp1->AsFieldList()->Uses())
1887     {
1888         GenTree* nextArgNode = use.GetNode();
1889         genConsumeReg(nextArgNode);
1890
1891         regNumber reg             = nextArgNode->GetRegNum();
1892         var_types type            = use.GetType();
1893         unsigned  thisFieldOffset = argOffset + use.GetOffset();
1894
1895 // Emit store instructions to store the registers produced by the GT_FIELD_LIST into the outgoing
1896 // argument area.
1897
1898 #if defined(FEATURE_SIMD)
1899         if (type == TYP_SIMD12)
1900         {
1901             GetEmitter()->emitStoreSimd12ToLclOffset(outArgVarNum, thisFieldOffset, reg, nextArgNode);
1902         }
1903         else
1904 #endif // FEATURE_SIMD
1905         {
1906             emitAttr attr = emitTypeSize(type);
1907             GetEmitter()->emitIns_S_R(ins_Store(type), attr, reg, outArgVarNum, thisFieldOffset);
1908         }
1909
1910 // We can't write beyond the arg area unless this is a tail call, in which case we use
1911 // the first stack arg as the base of the incoming arg area.
1912 #ifdef DEBUG
1913         unsigned areaSize = compiler->lvaLclSize(outArgVarNum);
1914 #if FEATURE_FASTTAILCALL
1915         if (putArgStk->gtCall->IsFastTailCall())
1916         {
1917             areaSize = compiler->info.compArgStackSize;
1918         }
1919 #endif
1920
1921         assert((thisFieldOffset + genTypeSize(type)) <= areaSize);
1922 #endif
1923     }
1924 }
1925 #endif // !TARGET_X86
1926
1927 //------------------------------------------------------------------------
1928 // genSetBlockSize: Ensure that the block size is in the given register
1929 //
1930 // Arguments:
1931 //    blkNode - The block node
1932 //    sizeReg - The register into which the block's size should go
1933 //
1934
1935 void CodeGen::genSetBlockSize(GenTreeBlk* blkNode, regNumber sizeReg)
1936 {
1937     if (sizeReg != REG_NA)
1938     {
1939         unsigned blockSize = blkNode->Size();
1940         if (!blkNode->OperIs(GT_STORE_DYN_BLK))
1941         {
1942             assert((blkNode->gtRsvdRegs & genRegMask(sizeReg)) != 0);
1943             // This can go via helper which takes the size as a native uint.
1944             instGen_Set_Reg_To_Imm(EA_PTRSIZE, sizeReg, blockSize);
1945         }
1946         else
1947         {
1948             GenTree* sizeNode = blkNode->AsStoreDynBlk()->gtDynamicSize;
1949             inst_Mov(sizeNode->TypeGet(), sizeReg, sizeNode->GetRegNum(), /* canSkip */ true);
1950         }
1951     }
1952 }
1953
1954 //------------------------------------------------------------------------
1955 // genConsumeBlockSrc: Consume the source address register of a block node, if any.
1956 //
1957 // Arguments:
1958 //    blkNode - The block node
1959
1960 void CodeGen::genConsumeBlockSrc(GenTreeBlk* blkNode)
1961 {
1962     GenTree* src = blkNode->Data();
1963     if (blkNode->OperIsCopyBlkOp())
1964     {
1965         // For a CopyBlk we need the address of the source.
1966         assert(src->isContained());
1967         if (src->OperGet() == GT_IND)
1968         {
1969             src = src->AsOp()->gtOp1;
1970         }
1971         else
1972         {
1973             // This must be a local.
1974             // For this case, there is no source address register, as it is a
1975             // stack-based address.
1976             assert(src->OperIsLocal());
1977             return;
1978         }
1979     }
1980     else
1981     {
1982         if (src->OperIsInitVal())
1983         {
1984             src = src->gtGetOp1();
1985         }
1986     }
1987     genConsumeReg(src);
1988 }
1989
1990 //------------------------------------------------------------------------
1991 // genSetBlockSrc: Ensure that the block source is in its allocated register.
1992 //
1993 // Arguments:
1994 //    blkNode - The block node
1995 //    srcReg  - The register in which to set the source (address or init val).
1996 //
1997 void CodeGen::genSetBlockSrc(GenTreeBlk* blkNode, regNumber srcReg)
1998 {
1999     GenTree* src = blkNode->Data();
2000     if (blkNode->OperIsCopyBlkOp())
2001     {
2002         // For a CopyBlk we need the address of the source.
2003         if (src->OperGet() == GT_IND)
2004         {
2005             src = src->AsOp()->gtOp1;
2006         }
2007         else
2008         {
2009             // This must be a local struct.
2010             // Load its address into srcReg.
2011             unsigned varNum = src->AsLclVarCommon()->GetLclNum();
2012             unsigned offset = src->AsLclVarCommon()->GetLclOffs();
2013             GetEmitter()->emitIns_R_S(INS_lea, EA_BYREF, srcReg, varNum, offset);
2014             return;
2015         }
2016     }
2017     else
2018     {
2019         if (src->OperIsInitVal())
2020         {
2021             src = src->gtGetOp1();
2022         }
2023     }
2024     genCopyRegIfNeeded(src, srcReg);
2025 }
2026
2027 //------------------------------------------------------------------------
2028 // genConsumeBlockOp: Ensure that the block's operands are enregistered
2029 //                    as needed.
2030 // Arguments:
2031 //    blkNode - The block node
2032 //
2033 // Notes:
2034 //    This ensures that the operands are consumed in the proper order to
2035 //    obey liveness modeling.
2036
2037 void CodeGen::genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg)
2038 {
2039     // We have to consume the registers, and perform any copies, in the actual execution order: dst, src, size.
2040     //
2041     // Note that the register allocator ensures that the registers ON THE NODES will not interfere
2042     // with one another if consumed (i.e. reloaded or moved to their ASSIGNED reg) in execution order.
2043     // Further, it ensures that they will not interfere with one another if they are then copied
2044     // to the REQUIRED register (if a fixed register requirement) in execution order.  This requires,
2045     // then, that we first consume all the operands, then do any necessary moves.
2046
2047     GenTree* const dstAddr = blkNode->Addr();
2048
2049     // First, consume all the sources in order, and verify that registers have been allocated appropriately,
2050     // based on the 'gtBlkOpKind'.
2051
2052     // The destination is always in a register; 'genConsumeReg' asserts that.
2053     genConsumeReg(dstAddr);
2054     // The source may be a local or in a register; 'genConsumeBlockSrc' will check that.
2055     genConsumeBlockSrc(blkNode);
2056     // 'genSetBlockSize' (called below) will ensure that a register has been reserved as needed
2057     // in the case where the size is a constant (i.e. it is not GT_STORE_DYN_BLK).
2058     if (blkNode->OperGet() == GT_STORE_DYN_BLK)
2059     {
2060         genConsumeReg(blkNode->AsStoreDynBlk()->gtDynamicSize);
2061     }
2062
2063     // Next, perform any necessary moves.
2064     genCopyRegIfNeeded(dstAddr, dstReg);
2065     genSetBlockSrc(blkNode, srcReg);
2066     genSetBlockSize(blkNode, sizeReg);
2067 }
2068
2069 //-------------------------------------------------------------------------
2070 // genSpillLocal: Generate the actual spill of a local var.
2071 //
2072 // Arguments:
2073 //     varNum    - The variable number of the local to be spilled.
2074 //                 It may be a local field.
2075 //     type      - The type of the local.
2076 //     lclNode   - The node being spilled. Note that for a multi-reg local,
2077 //                 the gtLclNum will be that of the parent struct.
2078 //     regNum    - The register that 'varNum' is currently in.
2079 //
2080 // Return Value:
2081 //     None.
2082 //
2083 void CodeGen::genSpillLocal(unsigned varNum, var_types type, GenTreeLclVar* lclNode, regNumber regNum)
2084 {
2085     const LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
2086     assert(!varDsc->lvNormalizeOnStore() || (type == varDsc->GetStackSlotHomeType()));
2087
2088     // We have a register candidate local that is marked with GTF_SPILL.
2089     // This flag generally means that we need to spill this local.
2090     // The exception is the case of a use of an EH/spill-at-single-def var use that is being "spilled"
2091     // to the stack, indicated by GTF_SPILL (note that all EH lclVar defs are always
2092     // spilled, i.e. write-thru. Likewise, single-def vars that are spilled at its definitions).
2093     // An EH or single-def var use is always valid on the stack (so we don't need to actually spill it),
2094     // but the GTF_SPILL flag records the fact that the register value is going dead.
2095     if (((lclNode->gtFlags & GTF_VAR_DEF) != 0) || (!varDsc->IsAlwaysAliveInMemory()))
2096     {
2097         // Store local variable to its home location.
2098         // Ensure that lclVar stores are typed correctly.
2099         GetEmitter()->emitIns_S_R(ins_Store(type, compiler->isSIMDTypeLocalAligned(varNum)), emitTypeSize(type), regNum,
2100                                   varNum, 0);
2101     }
2102 }
2103
2104 //-------------------------------------------------------------------------
2105 // genProduceReg: do liveness update for register produced by the current
2106 // node in codegen after code has been emitted for it.
2107 //
2108 // Arguments:
2109 //     tree   -  Gentree node
2110 //
2111 // Return Value:
2112 //     None.
2113 void CodeGen::genProduceReg(GenTree* tree)
2114 {
2115 #ifdef DEBUG
2116     assert((tree->gtDebugFlags & GTF_DEBUG_NODE_CG_PRODUCED) == 0);
2117     tree->gtDebugFlags |= GTF_DEBUG_NODE_CG_PRODUCED;
2118 #endif
2119
2120     if (tree->gtFlags & GTF_SPILL)
2121     {
2122         // Code for GT_COPY node gets generated as part of consuming regs by its parent.
2123         // A GT_COPY node in turn produces reg result and it should never be marked to
2124         // spill.
2125         //
2126         // Similarly GT_RELOAD node gets generated as part of consuming regs by its
2127         // parent and should never be marked for spilling.
2128         noway_assert(!tree->IsCopyOrReload());
2129
2130         if (genIsRegCandidateLocal(tree))
2131         {
2132             GenTreeLclVar*   lclNode   = tree->AsLclVar();
2133             const LclVarDsc* varDsc    = compiler->lvaGetDesc(lclNode);
2134             const unsigned   varNum    = lclNode->GetLclNum();
2135             const var_types  spillType = varDsc->GetRegisterType(lclNode);
2136             genSpillLocal(varNum, spillType, lclNode, tree->GetRegNum());
2137         }
2138         else if (tree->IsMultiRegLclVar())
2139         {
2140             assert(compiler->lvaEnregMultiRegVars);
2141
2142             GenTreeLclVar*   lclNode  = tree->AsLclVar();
2143             const LclVarDsc* varDsc   = compiler->lvaGetDesc(lclNode);
2144             const unsigned   regCount = lclNode->GetFieldCount(compiler);
2145
2146             for (unsigned i = 0; i < regCount; ++i)
2147             {
2148                 GenTreeFlags flags = lclNode->GetRegSpillFlagByIdx(i);
2149                 if ((flags & GTF_SPILL) != 0)
2150                 {
2151                     const regNumber reg         = lclNode->GetRegNumByIdx(i);
2152                     const unsigned  fieldVarNum = varDsc->lvFieldLclStart + i;
2153                     const var_types spillType   = compiler->lvaGetDesc(fieldVarNum)->GetRegisterType();
2154                     genSpillLocal(fieldVarNum, spillType, lclNode, reg);
2155                 }
2156             }
2157         }
2158         else
2159         {
2160             if (tree->IsMultiRegNode())
2161             {
2162                 // In case of multi-reg node, spill flag on it indicates that one or more of its allocated regs need to
2163                 // be spilled, and it needs to be further queried to know which of its result regs needs to be spilled.
2164                 const unsigned regCount = tree->GetMultiRegCount(compiler);
2165
2166                 for (unsigned i = 0; i < regCount; ++i)
2167                 {
2168                     GenTreeFlags flags = tree->GetRegSpillFlagByIdx(i);
2169                     if ((flags & GTF_SPILL) != 0)
2170                     {
2171                         regNumber reg = tree->GetRegByIndex(i);
2172                         regSet.rsSpillTree(reg, tree, i);
2173                         gcInfo.gcMarkRegSetNpt(genRegMask(reg));
2174                     }
2175                 }
2176             }
2177             else
2178             {
2179                 regSet.rsSpillTree(tree->GetRegNum(), tree);
2180                 gcInfo.gcMarkRegSetNpt(genRegMask(tree->GetRegNum()));
2181             }
2182
2183             tree->gtFlags |= GTF_SPILLED;
2184             tree->gtFlags &= ~GTF_SPILL;
2185
2186             return;
2187         }
2188     }
2189
2190     // Updating variable liveness after instruction was emitted
2191     genUpdateLife(tree);
2192
2193     // If we've produced a register, mark it as a pointer, as needed.
2194     if (tree->gtHasReg(compiler))
2195     {
2196         // We only mark the register in the following cases:
2197         // 1. It is not a register candidate local. In this case, we're producing a
2198         //    register from a local, but the local is not a register candidate. Thus,
2199         //    we must be loading it as a temp register, and any "last use" flag on
2200         //    the register wouldn't be relevant.
2201         // 2. The register candidate local is going dead. There's no point to mark
2202         //    the register as live, with a GC pointer, if the variable is dead.
2203         if (!genIsRegCandidateLocal(tree) || ((tree->gtFlags & GTF_VAR_DEATH) == 0))
2204         {
2205             // Multi-reg nodes will produce more than one register result.
2206             // Mark all the regs produced by the node.
2207             if (tree->IsMultiRegCall())
2208             {
2209                 const GenTreeCall*    call        = tree->AsCall();
2210                 const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
2211                 const unsigned        regCount    = retTypeDesc->GetReturnRegCount();
2212
2213                 for (unsigned i = 0; i < regCount; ++i)
2214                 {
2215                     regNumber reg  = call->GetRegNumByIdx(i);
2216                     var_types type = retTypeDesc->GetReturnRegType(i);
2217                     gcInfo.gcMarkRegPtrVal(reg, type);
2218                 }
2219             }
2220             else if (tree->IsCopyOrReloadOfMultiRegCall())
2221             {
2222                 // we should never see reload of multi-reg call here
2223                 // because GT_RELOAD gets generated in reg consuming path.
2224                 noway_assert(tree->OperGet() == GT_COPY);
2225
2226                 // A multi-reg GT_COPY node produces those regs to which
2227                 // copy has taken place.
2228                 const GenTreeCopyOrReload* copy        = tree->AsCopyOrReload();
2229                 const GenTreeCall*         call        = copy->gtGetOp1()->AsCall();
2230                 const ReturnTypeDesc*      retTypeDesc = call->GetReturnTypeDesc();
2231                 const unsigned             regCount    = retTypeDesc->GetReturnRegCount();
2232
2233                 for (unsigned i = 0; i < regCount; ++i)
2234                 {
2235                     var_types type  = retTypeDesc->GetReturnRegType(i);
2236                     regNumber toReg = copy->GetRegNumByIdx(i);
2237
2238                     if (toReg != REG_NA)
2239                     {
2240                         gcInfo.gcMarkRegPtrVal(toReg, type);
2241                     }
2242                 }
2243             }
2244             else if (tree->IsMultiRegLclVar())
2245             {
2246                 assert(compiler->lvaEnregMultiRegVars);
2247                 GenTreeLclVar* lclNode  = tree->AsLclVar();
2248                 LclVarDsc*     varDsc   = compiler->lvaGetDesc(lclNode);
2249                 unsigned       regCount = varDsc->lvFieldCnt;
2250                 for (unsigned i = 0; i < regCount; i++)
2251                 {
2252                     if (!lclNode->IsLastUse(i))
2253                     {
2254                         regNumber reg = lclNode->GetRegByIndex(i);
2255                         if (reg != REG_NA)
2256                         {
2257                             var_types type = compiler->lvaGetDesc(varDsc->lvFieldLclStart + i)->TypeGet();
2258                             gcInfo.gcMarkRegPtrVal(reg, type);
2259                         }
2260                     }
2261                 }
2262             }
2263             else
2264             {
2265                 gcInfo.gcMarkRegPtrVal(tree->GetRegNum(), tree->TypeGet());
2266             }
2267         }
2268     }
2269 }
2270
2271 // transfer gc/byref status of src reg to dst reg
2272 void CodeGen::genTransferRegGCState(regNumber dst, regNumber src)
2273 {
2274     regMaskTP srcMask = genRegMask(src);
2275     regMaskTP dstMask = genRegMask(dst);
2276
2277     if (gcInfo.gcRegGCrefSetCur & srcMask)
2278     {
2279         gcInfo.gcMarkRegSetGCref(dstMask);
2280     }
2281     else if (gcInfo.gcRegByrefSetCur & srcMask)
2282     {
2283         gcInfo.gcMarkRegSetByref(dstMask);
2284     }
2285     else
2286     {
2287         gcInfo.gcMarkRegSetNpt(dstMask);
2288     }
2289 }
2290
2291 // generates an ip-relative call or indirect call via reg ('call reg')
2292 //     pass in 'addr' for a relative call or 'base' for a indirect register call
2293 //     methHnd - optional, only used for pretty printing
2294 //     retSize - emitter type of return for GC purposes, should be EA_BYREF, EA_GCREF, or EA_PTRSIZE(not GC)
2295 //
2296 // clang-format off
2297 void CodeGen::genEmitCall(int                   callType,
2298                           CORINFO_METHOD_HANDLE methHnd,
2299                           INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
2300                           void*                 addr
2301                           X86_ARG(int argSize),
2302                           emitAttr              retSize
2303                           MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
2304                           const DebugInfo& di,
2305                           regNumber             base,
2306                           bool                  isJump)
2307 {
2308 #if !defined(TARGET_X86)
2309     int argSize = 0;
2310 #endif // !defined(TARGET_X86)
2311
2312     // This should have been put in volatile registers to ensure it does not
2313     // get overridden by epilog sequence during tailcall.
2314     noway_assert(!isJump || (base == REG_NA) || ((RBM_INT_CALLEE_TRASH & genRegMask(base)) != 0));
2315
2316     GetEmitter()->emitIns_Call(emitter::EmitCallType(callType),
2317                                methHnd,
2318                                INDEBUG_LDISASM_COMMA(sigInfo)
2319                                addr,
2320                                argSize,
2321                                retSize
2322                                MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
2323                                gcInfo.gcVarPtrSetCur,
2324                                gcInfo.gcRegGCrefSetCur,
2325                                gcInfo.gcRegByrefSetCur,
2326                                di, base, REG_NA, 0, 0, isJump);
2327 }
2328 // clang-format on
2329
2330 // generates an indirect call via addressing mode (call []) given an indir node
2331 //     methHnd - optional, only used for pretty printing
2332 //     retSize - emitter type of return for GC purposes, should be EA_BYREF, EA_GCREF, or EA_PTRSIZE(not GC)
2333 //
2334 // clang-format off
2335 void CodeGen::genEmitCallIndir(int                   callType,
2336                                CORINFO_METHOD_HANDLE methHnd,
2337                                INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
2338                                GenTreeIndir*         indir
2339                                X86_ARG(int argSize),
2340                                emitAttr              retSize
2341                                MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
2342                                const DebugInfo&      di,
2343                                bool                  isJump)
2344 {
2345 #if !defined(TARGET_X86)
2346     int argSize = 0;
2347 #endif // !defined(TARGET_X86)
2348
2349     regNumber iReg = (indir->Base()  != nullptr) ? indir->Base()->GetRegNum() : REG_NA;
2350     regNumber xReg = (indir->Index() != nullptr) ? indir->Index()->GetRegNum() : REG_NA;
2351
2352     // These should have been put in volatile registers to ensure they do not
2353     // get overridden by epilog sequence during tailcall.
2354     noway_assert(!isJump || (iReg == REG_NA) || ((RBM_CALLEE_TRASH & genRegMask(iReg)) != 0));
2355     noway_assert(!isJump || (xReg == REG_NA) || ((RBM_CALLEE_TRASH & genRegMask(xReg)) != 0));
2356
2357     GetEmitter()->emitIns_Call(emitter::EmitCallType(callType),
2358                                methHnd,
2359                                INDEBUG_LDISASM_COMMA(sigInfo)
2360                                nullptr,
2361                                argSize,
2362                                retSize
2363                                MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
2364                                gcInfo.gcVarPtrSetCur,
2365                                gcInfo.gcRegGCrefSetCur,
2366                                gcInfo.gcRegByrefSetCur,
2367                                di,
2368                                iReg,
2369                                xReg,
2370                                indir->Scale(),
2371                                indir->Offset(),
2372                                isJump);
2373 }
2374 // clang-format on
2375
2376 //------------------------------------------------------------------------
2377 // genCodeForCast: Generates the code for GT_CAST.
2378 //
2379 // Arguments:
2380 //    tree - the GT_CAST node.
2381 //
2382 void CodeGen::genCodeForCast(GenTreeOp* tree)
2383 {
2384     assert(tree->OperIs(GT_CAST));
2385
2386     var_types targetType = tree->TypeGet();
2387
2388     if (varTypeIsFloating(targetType) && varTypeIsFloating(tree->gtOp1))
2389     {
2390         // Casts float/double <--> double/float
2391         genFloatToFloatCast(tree);
2392     }
2393     else if (varTypeIsFloating(tree->gtOp1))
2394     {
2395         // Casts float/double --> int32/int64
2396         genFloatToIntCast(tree);
2397     }
2398     else if (varTypeIsFloating(targetType))
2399     {
2400         // Casts int32/uint32/int64/uint64 --> float/double
2401         genIntToFloatCast(tree);
2402     }
2403 #ifndef TARGET_64BIT
2404     else if (varTypeIsLong(tree->gtOp1))
2405     {
2406         genLongToIntCast(tree);
2407     }
2408 #endif // !TARGET_64BIT
2409     else
2410     {
2411         // Casts int <--> int
2412         genIntToIntCast(tree->AsCast());
2413     }
2414     // The per-case functions call genProduceReg()
2415 }
2416
2417 CodeGen::GenIntCastDesc::GenIntCastDesc(GenTreeCast* cast)
2418 {
2419     GenTree* const  src          = cast->CastOp();
2420     const var_types srcType      = genActualType(src);
2421     const bool      srcUnsigned  = cast->IsUnsigned();
2422     const unsigned  srcSize      = genTypeSize(srcType);
2423     const var_types castType     = cast->gtCastType;
2424     const bool      castUnsigned = varTypeIsUnsigned(castType);
2425     const unsigned  castSize     = genTypeSize(castType);
2426     const var_types dstType      = genActualType(cast->TypeGet());
2427     const unsigned  dstSize      = genTypeSize(dstType);
2428     const bool      overflow     = cast->gtOverflow();
2429     const bool      castIsLoad   = !src->isUsedFromReg();
2430
2431     assert(castIsLoad == src->isUsedFromMemory());
2432     assert((srcSize == 4) || (srcSize == genTypeSize(TYP_I_IMPL)));
2433     assert((dstSize == 4) || (dstSize == genTypeSize(TYP_I_IMPL)));
2434
2435     assert(dstSize == genTypeSize(genActualType(castType)));
2436
2437     if (castSize < 4) // Cast to small int type
2438     {
2439         if (overflow)
2440         {
2441             m_checkKind    = CHECK_SMALL_INT_RANGE;
2442             m_checkSrcSize = srcSize;
2443             // Since these are small int types we can compute the min and max
2444             // values of the castType without risk of integer overflow.
2445             const int castNumBits = (castSize * 8) - (castUnsigned ? 0 : 1);
2446             m_checkSmallIntMax    = (1 << castNumBits) - 1;
2447             m_checkSmallIntMin    = (castUnsigned || srcUnsigned) ? 0 : (-m_checkSmallIntMax - 1);
2448
2449             m_extendKind    = COPY;
2450             m_extendSrcSize = dstSize;
2451         }
2452         else
2453         {
2454             m_checkKind = CHECK_NONE;
2455
2456             // Casting to a small type really means widening from that small type to INT/LONG.
2457             m_extendKind    = castUnsigned ? ZERO_EXTEND_SMALL_INT : SIGN_EXTEND_SMALL_INT;
2458             m_extendSrcSize = castSize;
2459         }
2460     }
2461 #ifdef TARGET_64BIT
2462     // castType cannot be (U)LONG on 32 bit targets, such casts should have been decomposed.
2463     // srcType cannot be a small int type since it's the "actual type" of the cast operand.
2464     // This means that widening casts do not occur on 32 bit targets.
2465     else if (castSize > srcSize) // (U)INT to (U)LONG widening cast
2466     {
2467         assert((srcSize == 4) && (castSize == 8));
2468
2469         if (overflow && !srcUnsigned && castUnsigned)
2470         {
2471             // Widening from INT to ULONG, check if the value is positive
2472             m_checkKind    = CHECK_POSITIVE;
2473             m_checkSrcSize = 4;
2474
2475             // This is the only overflow checking cast that requires changing the
2476             // source value (by zero extending), all others copy the value as is.
2477             assert((srcType == TYP_INT) && (castType == TYP_ULONG));
2478             m_extendKind    = ZERO_EXTEND_INT;
2479             m_extendSrcSize = 4;
2480         }
2481         else
2482         {
2483             m_checkKind = CHECK_NONE;
2484
2485             m_extendKind    = srcUnsigned ? ZERO_EXTEND_INT : SIGN_EXTEND_INT;
2486             m_extendSrcSize = 4;
2487         }
2488     }
2489     else if (castSize < srcSize) // (U)LONG to (U)INT narrowing cast
2490     {
2491         assert((srcSize == 8) && (castSize == 4));
2492
2493         if (overflow)
2494         {
2495             if (castUnsigned) // (U)LONG to UINT cast
2496             {
2497                 m_checkKind = CHECK_UINT_RANGE;
2498             }
2499             else if (srcUnsigned) // ULONG to INT cast
2500             {
2501                 m_checkKind = CHECK_POSITIVE_INT_RANGE;
2502             }
2503             else // LONG to INT cast
2504             {
2505                 m_checkKind = CHECK_INT_RANGE;
2506             }
2507
2508             m_checkSrcSize = 8;
2509         }
2510         else
2511         {
2512             m_checkKind = CHECK_NONE;
2513         }
2514
2515 #if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
2516         // For LoongArch64's ISA which is same with the MIPS64 ISA, even the instructions of 32bits operation need
2517         // the upper 32bits be sign-extended to 64 bits.
2518         m_extendKind = SIGN_EXTEND_INT;
2519 #else
2520         m_extendKind = COPY;
2521 #endif
2522         m_extendSrcSize = 4;
2523     }
2524 #endif
2525     else // if (castSize == srcSize) // Sign changing or same type cast
2526     {
2527         assert(castSize == srcSize);
2528
2529         if (overflow && (srcUnsigned != castUnsigned))
2530         {
2531             m_checkKind    = CHECK_POSITIVE;
2532             m_checkSrcSize = srcSize;
2533         }
2534         else
2535         {
2536             m_checkKind = CHECK_NONE;
2537         }
2538
2539         m_extendKind    = COPY;
2540         m_extendSrcSize = srcSize;
2541     }
2542
2543     if (castIsLoad)
2544     {
2545         const var_types srcLoadType = src->TypeGet();
2546
2547         switch (m_extendKind)
2548         {
2549             case ZERO_EXTEND_SMALL_INT: // small type/int/long -> ubyte/ushort
2550                 assert(varTypeIsUnsigned(srcLoadType) || (genTypeSize(srcLoadType) >= genTypeSize(castType)));
2551                 m_extendKind    = LOAD_ZERO_EXTEND_SMALL_INT;
2552                 m_extendSrcSize = min(genTypeSize(srcLoadType), genTypeSize(castType));
2553                 break;
2554
2555             case SIGN_EXTEND_SMALL_INT: // small type/int/long -> byte/short
2556                 assert(varTypeIsSigned(srcLoadType) || (genTypeSize(srcLoadType) >= genTypeSize(castType)));
2557                 m_extendKind    = LOAD_SIGN_EXTEND_SMALL_INT;
2558                 m_extendSrcSize = min(genTypeSize(srcLoadType), genTypeSize(castType));
2559                 break;
2560
2561 #ifdef TARGET_64BIT
2562             case ZERO_EXTEND_INT: // ubyte/ushort/int -> long.
2563                 assert(varTypeIsUnsigned(srcLoadType) || (srcLoadType == TYP_INT));
2564                 m_extendKind    = varTypeIsSmall(srcLoadType) ? LOAD_ZERO_EXTEND_SMALL_INT : LOAD_ZERO_EXTEND_INT;
2565                 m_extendSrcSize = genTypeSize(srcLoadType);
2566                 break;
2567
2568             case SIGN_EXTEND_INT: // byte/short/int -> long.
2569                 assert(varTypeIsSigned(srcLoadType) || (srcLoadType == TYP_INT));
2570                 m_extendKind    = varTypeIsSmall(srcLoadType) ? LOAD_SIGN_EXTEND_SMALL_INT : LOAD_SIGN_EXTEND_INT;
2571                 m_extendSrcSize = genTypeSize(srcLoadType);
2572                 break;
2573 #endif // TARGET_64BIT
2574
2575             case COPY: // long -> long, small type/int/long -> int.
2576                 m_extendKind    = LOAD_SOURCE;
2577                 m_extendSrcSize = 0;
2578                 break;
2579
2580             default:
2581                 unreached();
2582         }
2583     }
2584 }
2585
2586 #if !defined(TARGET_64BIT)
2587 //------------------------------------------------------------------------
2588 // genStoreLongLclVar: Generate code to store a non-enregistered long lclVar
2589 //
2590 // Arguments:
2591 //    treeNode - A TYP_LONG lclVar node.
2592 //
2593 // Return Value:
2594 //    None.
2595 //
2596 // Assumptions:
2597 //    'treeNode' must be a TYP_LONG lclVar node for a lclVar that has NOT been promoted.
2598 //    Its operand must be a GT_LONG node.
2599 //
2600 void CodeGen::genStoreLongLclVar(GenTree* treeNode)
2601 {
2602     emitter* emit = GetEmitter();
2603
2604     GenTreeLclVarCommon* lclNode = treeNode->AsLclVarCommon();
2605     unsigned             lclNum  = lclNode->GetLclNum();
2606     LclVarDsc*           varDsc  = compiler->lvaGetDesc(lclNum);
2607     assert(varDsc->TypeGet() == TYP_LONG);
2608     assert(!varDsc->lvPromoted);
2609     GenTree* op1 = treeNode->AsOp()->gtOp1;
2610
2611     // A GT_LONG is always contained so it cannot have RELOAD or COPY inserted between it and its consumer.
2612     noway_assert(op1->OperIs(GT_LONG));
2613     genConsumeRegs(op1);
2614
2615     GenTree* loVal = op1->gtGetOp1();
2616     GenTree* hiVal = op1->gtGetOp2();
2617
2618     noway_assert((loVal->GetRegNum() != REG_NA) && (hiVal->GetRegNum() != REG_NA));
2619
2620     emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, loVal->GetRegNum(), lclNum, 0);
2621     emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, hiVal->GetRegNum(), lclNum, genTypeSize(TYP_INT));
2622 }
2623 #endif // !defined(TARGET_64BIT)
2624
2625 #if !defined(TARGET_LOONGARCH64) && !defined(TARGET_RISCV64)
2626
2627 //------------------------------------------------------------------------
2628 // genCodeForJcc: Generate code for a GT_JCC node.
2629 //
2630 // Arguments:
2631 //    jcc - The node
2632 //
2633 void CodeGen::genCodeForJcc(GenTreeCC* jcc)
2634 {
2635     assert(compiler->compCurBB->bbJumpKind == BBJ_COND);
2636     assert(jcc->OperIs(GT_JCC));
2637
2638     inst_JCC(jcc->gtCondition, compiler->compCurBB->bbJumpDest);
2639 }
2640
2641 //------------------------------------------------------------------------
2642 // inst_JCC: Generate a conditional branch instruction sequence.
2643 //
2644 // Arguments:
2645 //   condition - The branch condition
2646 //   target    - The basic block to jump to when the condition is true
2647 //
2648 void CodeGen::inst_JCC(GenCondition condition, BasicBlock* target)
2649 {
2650     const GenConditionDesc& desc = GenConditionDesc::Get(condition);
2651
2652     if (desc.oper == GT_NONE)
2653     {
2654         inst_JMP(desc.jumpKind1, target);
2655     }
2656     else if (desc.oper == GT_OR)
2657     {
2658         inst_JMP(desc.jumpKind1, target);
2659         inst_JMP(desc.jumpKind2, target);
2660     }
2661     else // if (desc.oper == GT_AND)
2662     {
2663         BasicBlock* labelNext = genCreateTempLabel();
2664         inst_JMP(emitter::emitReverseJumpKind(desc.jumpKind1), labelNext);
2665         inst_JMP(desc.jumpKind2, target);
2666         genDefineTempLabel(labelNext);
2667     }
2668 }
2669
2670 //------------------------------------------------------------------------
2671 // genCodeForSetcc: Generate code for a GT_SETCC node.
2672 //
2673 // Arguments:
2674 //    setcc - The node
2675 //
2676 void CodeGen::genCodeForSetcc(GenTreeCC* setcc)
2677 {
2678     assert(setcc->OperIs(GT_SETCC));
2679
2680     inst_SETCC(setcc->gtCondition, setcc->TypeGet(), setcc->GetRegNum());
2681     genProduceReg(setcc);
2682 }
2683 #endif // !TARGET_LOONGARCH64 && !TARGET_RISCV64