Sync may31 release/8.0-tizen (#510)
[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 #elif defined(TARGET_ARM)
1260 // No normalizing for ARM
1261 #else
1262             NYI("Unspilling not implemented for this target architecture.");
1263 #endif
1264
1265             bool reSpill   = ((unspillTree->gtFlags & GTF_SPILL) != 0);
1266             bool isLastUse = lcl->IsLastUse(0);
1267             genUnspillLocal(lcl->GetLclNum(), unspillType, lcl->AsLclVar(), tree->GetRegNum(), reSpill, isLastUse);
1268         }
1269         else if (unspillTree->IsMultiRegLclVar())
1270         {
1271             // We never have a GT_RELOAD for this case.
1272             assert(tree == unspillTree);
1273
1274             GenTreeLclVar* lclNode  = unspillTree->AsLclVar();
1275             LclVarDsc*     varDsc   = compiler->lvaGetDesc(lclNode);
1276             unsigned       regCount = varDsc->lvFieldCnt;
1277
1278             for (unsigned i = 0; i < regCount; ++i)
1279             {
1280                 GenTreeFlags spillFlags = lclNode->GetRegSpillFlagByIdx(i);
1281                 if ((spillFlags & GTF_SPILLED) != 0)
1282                 {
1283                     regNumber reg         = lclNode->GetRegNumByIdx(i);
1284                     unsigned  fieldVarNum = varDsc->lvFieldLclStart + i;
1285                     bool      reSpill     = ((spillFlags & GTF_SPILL) != 0);
1286                     bool      isLastUse   = lclNode->IsLastUse(i);
1287                     genUnspillLocal(fieldVarNum, compiler->lvaGetDesc(fieldVarNum)->TypeGet(), lclNode, reg, reSpill,
1288                                     isLastUse);
1289                 }
1290             }
1291         }
1292         else if (unspillTree->IsMultiRegNode())
1293         {
1294             // Here we may have a GT_RELOAD, and we will need to use that node ('tree') to
1295             // do the unspilling if needed. However, that tree doesn't have the register
1296             // count, so we use 'unspillTree' for that.
1297             unsigned regCount = unspillTree->GetMultiRegCount(compiler);
1298             for (unsigned i = 0; i < regCount; ++i)
1299             {
1300                 genUnspillRegIfNeeded(tree, i);
1301             }
1302             unspillTree->gtFlags &= ~GTF_SPILLED;
1303         }
1304         else
1305         {
1306             // Here we may have a GT_RELOAD.
1307             // The spill temp allocated for it is associated with the original tree that defined the
1308             // register that it was spilled from.
1309             // So we use 'unspillTree' to recover that spill temp.
1310             TempDsc* t        = regSet.rsUnspillInPlace(unspillTree, unspillTree->GetRegNum());
1311             emitAttr emitType = emitActualTypeSize(unspillTree->TypeGet());
1312             // Reload into the register specified by 'tree' which may be a GT_RELOAD.
1313             regNumber dstReg = tree->GetRegNum();
1314             GetEmitter()->emitIns_R_S(ins_Load(unspillTree->gtType), emitType, dstReg, t->tdTempNum(), 0);
1315             regSet.tmpRlsTemp(t);
1316
1317             unspillTree->gtFlags &= ~GTF_SPILLED;
1318             gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
1319         }
1320     }
1321 }
1322
1323 //------------------------------------------------------------------------
1324 // genCopyRegIfNeeded: Copy the given node into the specified register
1325 //
1326 // Arguments:
1327 //    node - The node that has been evaluated (consumed).
1328 //    needReg - The register in which its value is needed.
1329 //
1330 // Notes:
1331 //    This must be a node that has a register.
1332 //
1333 void CodeGen::genCopyRegIfNeeded(GenTree* node, regNumber needReg)
1334 {
1335     assert((node->GetRegNum() != REG_NA) && (needReg != REG_NA));
1336     assert(!node->isUsedFromSpillTemp());
1337     inst_Mov(node->TypeGet(), needReg, node->GetRegNum(), /* canSkip */ true);
1338 }
1339
1340 // Do Liveness update for a subnodes that is being consumed by codegen
1341 // including the logic for reload in case is needed and also takes care
1342 // of locating the value on the desired register.
1343 void CodeGen::genConsumeRegAndCopy(GenTree* node, regNumber needReg)
1344 {
1345     if (needReg == REG_NA)
1346     {
1347         return;
1348     }
1349     genConsumeReg(node);
1350     genCopyRegIfNeeded(node, needReg);
1351 }
1352
1353 // Check that registers are consumed in the right order for the current node being generated.
1354 #ifdef DEBUG
1355 void CodeGen::genNumberOperandUse(GenTree* const operand, int& useNum) const
1356 {
1357     assert(operand != nullptr);
1358     assert(operand->gtUseNum == -1);
1359
1360     if (!operand->isContained() && !operand->IsCopyOrReload())
1361     {
1362         operand->gtUseNum = useNum;
1363         useNum++;
1364     }
1365     else
1366     {
1367         for (GenTree* op : operand->Operands())
1368         {
1369             genNumberOperandUse(op, useNum);
1370         }
1371     }
1372 }
1373
1374 void CodeGen::genCheckConsumeNode(GenTree* const node)
1375 {
1376     assert(node != nullptr);
1377
1378     if (verbose)
1379     {
1380         if (node->gtUseNum == -1)
1381         {
1382             // nothing wrong if the node was not consumed
1383         }
1384         else if ((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) != 0)
1385         {
1386             printf("Node was consumed twice:\n");
1387             compiler->gtDispTree(node, nullptr, nullptr, true);
1388         }
1389         else if ((lastConsumedNode != nullptr) && (node->gtUseNum < lastConsumedNode->gtUseNum))
1390         {
1391             printf("Nodes were consumed out-of-order:\n");
1392             compiler->gtDispTree(lastConsumedNode, nullptr, nullptr, true);
1393             compiler->gtDispTree(node, nullptr, nullptr, true);
1394         }
1395     }
1396
1397     assert((node->OperGet() == GT_CATCH_ARG) || ((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) == 0));
1398     assert((lastConsumedNode == nullptr) || (node->gtUseNum == -1) || (node->gtUseNum > lastConsumedNode->gtUseNum));
1399
1400     node->gtDebugFlags |= GTF_DEBUG_NODE_CG_CONSUMED;
1401     lastConsumedNode = node;
1402 }
1403 #endif // DEBUG
1404
1405 //--------------------------------------------------------------------
1406 // genConsumeReg: Do liveness update for a single register of a multireg child node
1407 //                that is being consumed by codegen.
1408 //
1409 // Arguments:
1410 //    tree          - GenTree node
1411 //    multiRegIndex - The index of the register to be consumed
1412 //
1413 // Return Value:
1414 //    Returns the reg number for the given multiRegIndex.
1415 //
1416 regNumber CodeGen::genConsumeReg(GenTree* tree, unsigned multiRegIndex)
1417 {
1418     regNumber reg = tree->GetRegByIndex(multiRegIndex);
1419     if (tree->OperIs(GT_COPY))
1420     {
1421         reg = genRegCopy(tree, multiRegIndex);
1422     }
1423     else if (reg == REG_NA)
1424     {
1425         assert(tree->OperIs(GT_RELOAD));
1426         reg = tree->gtGetOp1()->GetRegByIndex(multiRegIndex);
1427         assert(reg != REG_NA);
1428     }
1429     genUnspillRegIfNeeded(tree, multiRegIndex);
1430
1431     // UpdateLifeFieldVar() will return true if local var should be spilled.
1432     if (tree->IsMultiRegLclVar() && treeLifeUpdater->UpdateLifeFieldVar(tree->AsLclVar(), multiRegIndex))
1433     {
1434         GenTreeLclVar* lcl = tree->AsLclVar();
1435         genSpillLocal(lcl->GetLclNum(), lcl->GetFieldTypeByIndex(compiler, multiRegIndex), lcl,
1436                       lcl->GetRegByIndex(multiRegIndex));
1437     }
1438
1439     if (tree->gtSkipReloadOrCopy()->OperIs(GT_LCL_VAR))
1440     {
1441         assert(compiler->lvaEnregMultiRegVars);
1442
1443         GenTreeLclVar* lcl = tree->gtSkipReloadOrCopy()->AsLclVar();
1444         assert(lcl->IsMultiReg());
1445
1446         LclVarDsc* varDsc = compiler->lvaGetDesc(lcl);
1447         assert(varDsc->lvPromoted);
1448         assert(multiRegIndex < varDsc->lvFieldCnt);
1449         unsigned   fieldVarNum = varDsc->lvFieldLclStart + multiRegIndex;
1450         LclVarDsc* fldVarDsc   = compiler->lvaGetDesc(fieldVarNum);
1451         assert(fldVarDsc->lvLRACandidate);
1452
1453         if (fldVarDsc->GetRegNum() == REG_STK)
1454         {
1455             // We have loaded this into a register only temporarily
1456             gcInfo.gcMarkRegSetNpt(genRegMask(reg));
1457         }
1458         else if (lcl->IsLastUse(multiRegIndex))
1459         {
1460             gcInfo.gcMarkRegSetNpt(genRegMask(fldVarDsc->GetRegNum()));
1461         }
1462     }
1463     else
1464     {
1465         gcInfo.gcMarkRegSetNpt(tree->gtGetRegMask());
1466     }
1467     return reg;
1468 }
1469
1470 //--------------------------------------------------------------------
1471 // genConsumeReg: Do liveness update for a subnode that is being
1472 // consumed by codegen.
1473 //
1474 // Arguments:
1475 //    tree - GenTree node
1476 //
1477 // Return Value:
1478 //    Returns the reg number of tree.
1479 //    In case of multi-reg call node returns the first reg number
1480 //    of the multi-reg return.
1481 //
1482 regNumber CodeGen::genConsumeReg(GenTree* tree)
1483 {
1484     if (tree->OperGet() == GT_COPY)
1485     {
1486         genRegCopy(tree);
1487     }
1488
1489     // Handle the case where we have a lclVar that needs to be copied before use (i.e. because it
1490     // interferes with one of the other sources (or the target, if it's a "delayed use" register)).
1491     // TODO-Cleanup: This is a special copyReg case in LSRA - consider eliminating these and
1492     // always using GT_COPY to make the lclVar location explicit.
1493     // Note that we have to do this before calling genUpdateLife because otherwise if we spill it
1494     // the lvRegNum will be set to REG_STK and we will lose track of what register currently holds
1495     // the lclVar (normally when a lclVar is spilled it is then used from its former register
1496     // location, which matches the GetRegNum() on the node).
1497     // (Note that it doesn't matter if we call this before or after genUnspillRegIfNeeded
1498     // because if it's on the stack it will always get reloaded into tree->GetRegNum()).
1499     if (genIsRegCandidateLocal(tree))
1500     {
1501         GenTreeLclVarCommon* lcl    = tree->AsLclVarCommon();
1502         LclVarDsc*           varDsc = compiler->lvaGetDesc(lcl);
1503         if (varDsc->GetRegNum() != REG_STK)
1504         {
1505             var_types regType = varDsc->GetRegisterType(lcl);
1506             inst_Mov(regType, tree->GetRegNum(), varDsc->GetRegNum(), /* canSkip */ true);
1507         }
1508     }
1509
1510     genUnspillRegIfNeeded(tree);
1511
1512     // genUpdateLife() will also spill local var if marked as GTF_SPILL by calling CodeGen::genSpillVar
1513     genUpdateLife(tree);
1514
1515     // there are three cases where consuming a reg means clearing the bit in the live mask
1516     // 1. it was not produced by a local
1517     // 2. it was produced by a local that is going dead
1518     // 3. it was produced by a local that does not live in that reg (like one allocated on the stack)
1519
1520     if (genIsRegCandidateLocal(tree))
1521     {
1522         assert(tree->gtHasReg(compiler));
1523
1524         GenTreeLclVarCommon* lcl    = tree->AsLclVar();
1525         LclVarDsc*           varDsc = compiler->lvaGetDesc(lcl);
1526         assert(varDsc->lvLRACandidate);
1527
1528         if (varDsc->GetRegNum() == REG_STK)
1529         {
1530             // We have loaded this into a register only temporarily
1531             gcInfo.gcMarkRegSetNpt(genRegMask(tree->GetRegNum()));
1532         }
1533         else if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
1534         {
1535             gcInfo.gcMarkRegSetNpt(genRegMask(varDsc->GetRegNum()));
1536         }
1537     }
1538     else if (tree->gtSkipReloadOrCopy()->IsMultiRegLclVar())
1539     {
1540         assert(compiler->lvaEnregMultiRegVars);
1541         GenTreeLclVar* lcl              = tree->gtSkipReloadOrCopy()->AsLclVar();
1542         LclVarDsc*     varDsc           = compiler->lvaGetDesc(lcl);
1543         unsigned       firstFieldVarNum = varDsc->lvFieldLclStart;
1544         for (unsigned i = 0; i < varDsc->lvFieldCnt; ++i)
1545         {
1546             LclVarDsc* fldVarDsc = compiler->lvaGetDesc(firstFieldVarNum + i);
1547             assert(fldVarDsc->lvLRACandidate);
1548             regNumber reg;
1549             if (tree->OperIs(GT_COPY, GT_RELOAD) && (tree->AsCopyOrReload()->GetRegByIndex(i) != REG_NA))
1550             {
1551                 reg = tree->AsCopyOrReload()->GetRegByIndex(i);
1552             }
1553             else
1554             {
1555                 reg = lcl->AsLclVar()->GetRegNumByIdx(i);
1556             }
1557
1558             if (fldVarDsc->GetRegNum() == REG_STK)
1559             {
1560                 // We have loaded this into a register only temporarily
1561                 gcInfo.gcMarkRegSetNpt(genRegMask(reg));
1562             }
1563             else if (lcl->IsLastUse(i))
1564             {
1565                 gcInfo.gcMarkRegSetNpt(genRegMask(fldVarDsc->GetRegNum()));
1566             }
1567         }
1568     }
1569     else
1570     {
1571         gcInfo.gcMarkRegSetNpt(tree->gtGetRegMask());
1572     }
1573
1574     genCheckConsumeNode(tree);
1575     return tree->GetRegNum();
1576 }
1577
1578 // Do liveness update for an address tree: one of GT_LEA, GT_LCL_VAR, or GT_CNS_INT (for call indirect).
1579 void CodeGen::genConsumeAddress(GenTree* addr)
1580 {
1581     if (!addr->isContained())
1582     {
1583         genConsumeReg(addr);
1584     }
1585     else if (addr->OperGet() == GT_LEA)
1586     {
1587         genConsumeAddrMode(addr->AsAddrMode());
1588     }
1589 }
1590
1591 // do liveness update for a subnode that is being consumed by codegen
1592 void CodeGen::genConsumeAddrMode(GenTreeAddrMode* addr)
1593 {
1594     genConsumeOperands(addr);
1595 }
1596
1597 void CodeGen::genConsumeRegs(GenTree* tree)
1598 {
1599 #if !defined(TARGET_64BIT)
1600     if (tree->OperGet() == GT_LONG)
1601     {
1602         genConsumeRegs(tree->gtGetOp1());
1603         genConsumeRegs(tree->gtGetOp2());
1604         return;
1605     }
1606 #endif // !defined(TARGET_64BIT)
1607
1608     if (tree->isUsedFromSpillTemp())
1609     {
1610         // spill temps are un-tracked and hence no need to update life
1611     }
1612     else if (tree->isContained())
1613     {
1614         if (tree->OperIsIndir())
1615         {
1616             genConsumeAddress(tree->AsIndir()->Addr());
1617         }
1618         else if (tree->OperIs(GT_LEA))
1619         {
1620             genConsumeAddress(tree);
1621         }
1622 #if defined(TARGET_XARCH) || defined(TARGET_ARM64)
1623         else if (tree->OperIsCompare())
1624         {
1625             // Compares can be contained by SELECT/compare chains.
1626             genConsumeRegs(tree->gtGetOp1());
1627             genConsumeRegs(tree->gtGetOp2());
1628         }
1629 #endif
1630 #ifdef TARGET_ARM64
1631         else if (tree->OperIs(GT_BFIZ))
1632         {
1633             // Can be contained as part of LEA on ARM64
1634             GenTreeCast* cast = tree->gtGetOp1()->AsCast();
1635             assert(cast->isContained());
1636             genConsumeAddress(cast->CastOp());
1637         }
1638         else if (tree->OperIs(GT_CAST))
1639         {
1640             // Can be contained as part of LEA on ARM64
1641             GenTreeCast* cast = tree->AsCast();
1642             assert(cast->isContained());
1643             genConsumeAddress(cast->CastOp());
1644         }
1645         else if (tree->OperIs(GT_AND))
1646         {
1647             // ANDs may be contained in a chain.
1648             genConsumeRegs(tree->gtGetOp1());
1649             genConsumeRegs(tree->gtGetOp2());
1650         }
1651         else if (tree->OperIsFieldList())
1652         {
1653             for (GenTreeFieldList::Use& use : tree->AsFieldList()->Uses())
1654             {
1655                 GenTree* fieldNode = use.GetNode();
1656                 genConsumeRegs(fieldNode);
1657             }
1658         }
1659 #endif
1660         else if (tree->OperIsLocalRead())
1661         {
1662             // A contained lcl var must be living on stack and marked as reg optional, or not be a
1663             // register candidate.
1664             unsigned   varNum = tree->AsLclVarCommon()->GetLclNum();
1665             LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
1666
1667             noway_assert(varDsc->GetRegNum() == REG_STK);
1668             noway_assert(tree->IsRegOptional() || !varDsc->lvLRACandidate);
1669
1670             // Update the life of the lcl var.
1671             genUpdateLife(tree);
1672         }
1673 #ifdef TARGET_XARCH
1674 #ifdef FEATURE_HW_INTRINSICS
1675         else if (tree->OperIs(GT_HWINTRINSIC))
1676         {
1677             GenTreeHWIntrinsic* hwintrinsic = tree->AsHWIntrinsic();
1678             genConsumeMultiOpOperands(hwintrinsic);
1679         }
1680 #endif // FEATURE_HW_INTRINSICS
1681 #endif // TARGET_XARCH
1682         else if (tree->OperIs(GT_BITCAST, GT_NEG, GT_CAST, GT_LSH, GT_RSH, GT_RSZ, GT_BSWAP, GT_BSWAP16))
1683         {
1684             genConsumeRegs(tree->gtGetOp1());
1685         }
1686         else if (tree->OperIs(GT_MUL))
1687         {
1688             genConsumeRegs(tree->gtGetOp1());
1689             genConsumeRegs(tree->gtGetOp2());
1690         }
1691         else
1692         {
1693 #ifdef FEATURE_SIMD
1694             // (In)Equality operation that produces bool result, when compared
1695             // against Vector zero, marks its Vector Zero operand as contained.
1696             assert(tree->OperIsLeaf() || tree->IsVectorZero());
1697 #else
1698             assert(tree->OperIsLeaf());
1699 #endif
1700         }
1701     }
1702     else
1703     {
1704         genConsumeReg(tree);
1705     }
1706 }
1707
1708 //------------------------------------------------------------------------
1709 // genConsumeOperands: Do liveness update for the operands of a unary or binary tree
1710 //
1711 // Arguments:
1712 //    tree - the GenTreeOp whose operands will have their liveness updated.
1713 //
1714 // Return Value:
1715 //    None.
1716 //
1717 void CodeGen::genConsumeOperands(GenTreeOp* tree)
1718 {
1719     GenTree* firstOp  = tree->gtOp1;
1720     GenTree* secondOp = tree->gtOp2;
1721
1722     if (firstOp != nullptr)
1723     {
1724         genConsumeRegs(firstOp);
1725     }
1726     if (secondOp != nullptr)
1727     {
1728         genConsumeRegs(secondOp);
1729     }
1730 }
1731
1732 #if defined(FEATURE_SIMD) || defined(FEATURE_HW_INTRINSICS)
1733 //------------------------------------------------------------------------
1734 // genConsumeOperands: Do liveness update for the operands of a multi-operand node,
1735 //                     currently GT_HWINTRINSIC
1736 //
1737 // Arguments:
1738 //    tree - the GenTreeMultiOp whose operands will have their liveness updated.
1739 //
1740 // Return Value:
1741 //    None.
1742 //
1743 void CodeGen::genConsumeMultiOpOperands(GenTreeMultiOp* tree)
1744 {
1745     for (GenTree* operand : tree->Operands())
1746     {
1747         genConsumeRegs(operand);
1748     }
1749 }
1750 #endif // defined(FEATURE_SIMD) || defined(FEATURE_HW_INTRINSICS)
1751
1752 #if FEATURE_PUT_STRUCT_ARG_STK
1753 //------------------------------------------------------------------------
1754 // genConsumePutStructArgStk: Do liveness update for the operands of a PutArgStk node.
1755 //                      Also loads in the right register the addresses of the
1756 //                      src/dst for rep mov operation.
1757 //
1758 // Arguments:
1759 //    putArgNode - the PUTARG_STK tree.
1760 //    dstReg     - the dstReg for the rep move operation.
1761 //    srcReg     - the srcReg for the rep move operation.
1762 //    sizeReg    - the sizeReg for the rep move operation.
1763 //
1764 // Return Value:
1765 //    None.
1766 //
1767 // Notes:
1768 //    sizeReg can be REG_NA when this function is used to consume the dstReg and srcReg
1769 //    for copying on the stack a struct with references.
1770 //    The source address/offset is determined from the address on the GT_BLK node, while
1771 //    the destination address is the address contained in 'm_stkArgVarNum' plus the offset
1772 //    provided in the 'putArgNode'.
1773 //    m_stkArgVarNum must be set to  the varnum for the local used for placing the "by-value" args on the stack.
1774
1775 void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode,
1776                                         regNumber         dstReg,
1777                                         regNumber         srcReg,
1778                                         regNumber         sizeReg)
1779 {
1780     // The putArgNode children are always contained. We should not consume any registers.
1781     assert(putArgNode->Data()->isContained());
1782
1783     // Get the source.
1784     GenTree*  src        = putArgNode->Data();
1785     regNumber srcAddrReg = REG_NA;
1786     assert(varTypeIsStruct(src));
1787     assert(src->OperIs(GT_BLK) || src->OperIsLocalRead() || (src->OperIs(GT_IND) && varTypeIsSIMD(src)));
1788
1789     assert(dstReg != REG_NA);
1790     assert(srcReg != REG_NA);
1791
1792     // Consume the register for the source address if needed.
1793     if (src->OperIsIndir())
1794     {
1795         srcAddrReg = genConsumeReg(src->AsIndir()->Addr());
1796     }
1797
1798     // If the op1 is already in the dstReg - nothing to do.
1799     // Otherwise load the op1 (the address) into the dstReg to copy the struct on the stack by value.
1800     CLANG_FORMAT_COMMENT_ANCHOR;
1801
1802 #ifdef TARGET_X86
1803     assert(dstReg != REG_SPBASE);
1804     inst_Mov(TYP_I_IMPL, dstReg, REG_SPBASE, /* canSkip */ false);
1805 #else  // !TARGET_X86
1806     GenTree* dstAddr = putArgNode;
1807     if (dstAddr->GetRegNum() != dstReg)
1808     {
1809         // Generate LEA instruction to load the stack of the outgoing var + SlotNum offset (or the incoming arg area
1810         // for tail calls) in RDI.
1811         // Destination is always local (on the stack) - use EA_PTRSIZE.
1812         assert(m_stkArgVarNum != BAD_VAR_NUM);
1813         GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, dstReg, m_stkArgVarNum, putArgNode->getArgOffset());
1814     }
1815 #endif // !TARGET_X86
1816
1817     if (srcAddrReg != REG_NA)
1818     {
1819         // Source is not known to be on the stack. Use EA_BYREF.
1820         GetEmitter()->emitIns_Mov(INS_mov, EA_BYREF, srcReg, srcAddrReg, /* canSkip */ true);
1821     }
1822     else
1823     {
1824         // Generate LEA instruction to load the LclVar address in RSI.
1825         // Source is known to be on the stack. Use EA_PTRSIZE.
1826         GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, srcReg, src->AsLclVarCommon()->GetLclNum(),
1827                                   src->AsLclVarCommon()->GetLclOffs());
1828     }
1829
1830     if (sizeReg != REG_NA)
1831     {
1832         unsigned size = putArgNode->GetStackByteSize();
1833         inst_RV_IV(INS_mov, sizeReg, size, EA_PTRSIZE);
1834     }
1835 }
1836 #endif // FEATURE_PUT_STRUCT_ARG_STK
1837
1838 #if FEATURE_ARG_SPLIT
1839 //------------------------------------------------------------------------
1840 // genConsumeArgRegSplit: Consume register(s) in Call node to set split struct argument.
1841 //
1842 // Arguments:
1843 //    putArgNode - the PUTARG_STK tree.
1844 //
1845 // Return Value:
1846 //    None.
1847 //
1848 void CodeGen::genConsumeArgSplitStruct(GenTreePutArgSplit* putArgNode)
1849 {
1850     assert(putArgNode->OperGet() == GT_PUTARG_SPLIT);
1851     assert(putArgNode->gtHasReg(compiler));
1852
1853     genUnspillRegIfNeeded(putArgNode);
1854
1855     gcInfo.gcMarkRegSetNpt(putArgNode->gtGetRegMask());
1856
1857     genCheckConsumeNode(putArgNode);
1858 }
1859 #endif // FEATURE_ARG_SPLIT
1860
1861 //------------------------------------------------------------------------
1862 // genPutArgStkFieldList: Generate code for a putArgStk whose source is a GT_FIELD_LIST
1863 //
1864 // Arguments:
1865 //    putArgStk    - The putArgStk node
1866 //    outArgVarNum - The lclVar num for the argument
1867 //
1868 // Notes:
1869 //    The x86 version of this is in codegenxarch.cpp, and doesn't take an
1870 //    outArgVarNum, as it pushes its args onto the stack.
1871 //
1872 #ifndef TARGET_X86
1873 void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArgVarNum)
1874 {
1875     assert(putArgStk->gtOp1->OperIs(GT_FIELD_LIST));
1876
1877     // Evaluate each of the GT_FIELD_LIST items into their register
1878     // and store their register into the outgoing argument area.
1879     const unsigned argOffset = putArgStk->getArgOffset();
1880     for (GenTreeFieldList::Use& use : putArgStk->gtOp1->AsFieldList()->Uses())
1881     {
1882         GenTree* nextArgNode = use.GetNode();
1883         genConsumeReg(nextArgNode);
1884
1885         regNumber reg             = nextArgNode->GetRegNum();
1886         var_types type            = use.GetType();
1887         unsigned  thisFieldOffset = argOffset + use.GetOffset();
1888
1889 // Emit store instructions to store the registers produced by the GT_FIELD_LIST into the outgoing
1890 // argument area.
1891
1892 #if defined(FEATURE_SIMD)
1893         if (type == TYP_SIMD12)
1894         {
1895             GetEmitter()->emitStoreSimd12ToLclOffset(outArgVarNum, thisFieldOffset, reg, nextArgNode);
1896         }
1897         else
1898 #endif // FEATURE_SIMD
1899         {
1900             emitAttr attr = emitTypeSize(type);
1901             GetEmitter()->emitIns_S_R(ins_Store(type), attr, reg, outArgVarNum, thisFieldOffset);
1902         }
1903
1904 // We can't write beyond the arg area unless this is a tail call, in which case we use
1905 // the first stack arg as the base of the incoming arg area.
1906 #ifdef DEBUG
1907         unsigned areaSize = compiler->lvaLclSize(outArgVarNum);
1908 #if FEATURE_FASTTAILCALL
1909         if (putArgStk->gtCall->IsFastTailCall())
1910         {
1911             areaSize = compiler->info.compArgStackSize;
1912         }
1913 #endif
1914
1915         assert((thisFieldOffset + genTypeSize(type)) <= areaSize);
1916 #endif
1917     }
1918 }
1919 #endif // !TARGET_X86
1920
1921 //------------------------------------------------------------------------
1922 // genSetBlockSize: Ensure that the block size is in the given register
1923 //
1924 // Arguments:
1925 //    blkNode - The block node
1926 //    sizeReg - The register into which the block's size should go
1927 //
1928
1929 void CodeGen::genSetBlockSize(GenTreeBlk* blkNode, regNumber sizeReg)
1930 {
1931     if (sizeReg != REG_NA)
1932     {
1933         unsigned blockSize = blkNode->Size();
1934         if (!blkNode->OperIs(GT_STORE_DYN_BLK))
1935         {
1936             assert((blkNode->gtRsvdRegs & genRegMask(sizeReg)) != 0);
1937             // This can go via helper which takes the size as a native uint.
1938             instGen_Set_Reg_To_Imm(EA_PTRSIZE, sizeReg, blockSize);
1939         }
1940         else
1941         {
1942             GenTree* sizeNode = blkNode->AsStoreDynBlk()->gtDynamicSize;
1943             inst_Mov(sizeNode->TypeGet(), sizeReg, sizeNode->GetRegNum(), /* canSkip */ true);
1944         }
1945     }
1946 }
1947
1948 //------------------------------------------------------------------------
1949 // genConsumeBlockSrc: Consume the source address register of a block node, if any.
1950 //
1951 // Arguments:
1952 //    blkNode - The block node
1953
1954 void CodeGen::genConsumeBlockSrc(GenTreeBlk* blkNode)
1955 {
1956     GenTree* src = blkNode->Data();
1957     if (blkNode->OperIsCopyBlkOp())
1958     {
1959         // For a CopyBlk we need the address of the source.
1960         assert(src->isContained());
1961         if (src->OperGet() == GT_IND)
1962         {
1963             src = src->AsOp()->gtOp1;
1964         }
1965         else
1966         {
1967             // This must be a local.
1968             // For this case, there is no source address register, as it is a
1969             // stack-based address.
1970             assert(src->OperIsLocal());
1971             return;
1972         }
1973     }
1974     else
1975     {
1976         if (src->OperIsInitVal())
1977         {
1978             src = src->gtGetOp1();
1979         }
1980     }
1981     genConsumeReg(src);
1982 }
1983
1984 //------------------------------------------------------------------------
1985 // genSetBlockSrc: Ensure that the block source is in its allocated register.
1986 //
1987 // Arguments:
1988 //    blkNode - The block node
1989 //    srcReg  - The register in which to set the source (address or init val).
1990 //
1991 void CodeGen::genSetBlockSrc(GenTreeBlk* blkNode, regNumber srcReg)
1992 {
1993     GenTree* src = blkNode->Data();
1994     if (blkNode->OperIsCopyBlkOp())
1995     {
1996         // For a CopyBlk we need the address of the source.
1997         if (src->OperGet() == GT_IND)
1998         {
1999             src = src->AsOp()->gtOp1;
2000         }
2001         else
2002         {
2003             // This must be a local struct.
2004             // Load its address into srcReg.
2005             unsigned varNum = src->AsLclVarCommon()->GetLclNum();
2006             unsigned offset = src->AsLclVarCommon()->GetLclOffs();
2007             GetEmitter()->emitIns_R_S(INS_lea, EA_BYREF, srcReg, varNum, offset);
2008             return;
2009         }
2010     }
2011     else
2012     {
2013         if (src->OperIsInitVal())
2014         {
2015             src = src->gtGetOp1();
2016         }
2017     }
2018     genCopyRegIfNeeded(src, srcReg);
2019 }
2020
2021 //------------------------------------------------------------------------
2022 // genConsumeBlockOp: Ensure that the block's operands are enregistered
2023 //                    as needed.
2024 // Arguments:
2025 //    blkNode - The block node
2026 //
2027 // Notes:
2028 //    This ensures that the operands are consumed in the proper order to
2029 //    obey liveness modeling.
2030
2031 void CodeGen::genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg)
2032 {
2033     // We have to consume the registers, and perform any copies, in the actual execution order: dst, src, size.
2034     //
2035     // Note that the register allocator ensures that the registers ON THE NODES will not interfere
2036     // with one another if consumed (i.e. reloaded or moved to their ASSIGNED reg) in execution order.
2037     // Further, it ensures that they will not interfere with one another if they are then copied
2038     // to the REQUIRED register (if a fixed register requirement) in execution order.  This requires,
2039     // then, that we first consume all the operands, then do any necessary moves.
2040
2041     GenTree* const dstAddr = blkNode->Addr();
2042
2043     // First, consume all the sources in order, and verify that registers have been allocated appropriately,
2044     // based on the 'gtBlkOpKind'.
2045
2046     // The destination is always in a register; 'genConsumeReg' asserts that.
2047     genConsumeReg(dstAddr);
2048     // The source may be a local or in a register; 'genConsumeBlockSrc' will check that.
2049     genConsumeBlockSrc(blkNode);
2050     // 'genSetBlockSize' (called below) will ensure that a register has been reserved as needed
2051     // in the case where the size is a constant (i.e. it is not GT_STORE_DYN_BLK).
2052     if (blkNode->OperGet() == GT_STORE_DYN_BLK)
2053     {
2054         genConsumeReg(blkNode->AsStoreDynBlk()->gtDynamicSize);
2055     }
2056
2057     // Next, perform any necessary moves.
2058     genCopyRegIfNeeded(dstAddr, dstReg);
2059     genSetBlockSrc(blkNode, srcReg);
2060     genSetBlockSize(blkNode, sizeReg);
2061 }
2062
2063 //-------------------------------------------------------------------------
2064 // genSpillLocal: Generate the actual spill of a local var.
2065 //
2066 // Arguments:
2067 //     varNum    - The variable number of the local to be spilled.
2068 //                 It may be a local field.
2069 //     type      - The type of the local.
2070 //     lclNode   - The node being spilled. Note that for a multi-reg local,
2071 //                 the gtLclNum will be that of the parent struct.
2072 //     regNum    - The register that 'varNum' is currently in.
2073 //
2074 // Return Value:
2075 //     None.
2076 //
2077 void CodeGen::genSpillLocal(unsigned varNum, var_types type, GenTreeLclVar* lclNode, regNumber regNum)
2078 {
2079     const LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
2080     assert(!varDsc->lvNormalizeOnStore() || (type == varDsc->GetStackSlotHomeType()));
2081
2082     // We have a register candidate local that is marked with GTF_SPILL.
2083     // This flag generally means that we need to spill this local.
2084     // The exception is the case of a use of an EH/spill-at-single-def var use that is being "spilled"
2085     // to the stack, indicated by GTF_SPILL (note that all EH lclVar defs are always
2086     // spilled, i.e. write-thru. Likewise, single-def vars that are spilled at its definitions).
2087     // An EH or single-def var use is always valid on the stack (so we don't need to actually spill it),
2088     // but the GTF_SPILL flag records the fact that the register value is going dead.
2089     if (((lclNode->gtFlags & GTF_VAR_DEF) != 0) || (!varDsc->IsAlwaysAliveInMemory()))
2090     {
2091         // Store local variable to its home location.
2092         // Ensure that lclVar stores are typed correctly.
2093         GetEmitter()->emitIns_S_R(ins_Store(type, compiler->isSIMDTypeLocalAligned(varNum)), emitTypeSize(type), regNum,
2094                                   varNum, 0);
2095     }
2096 }
2097
2098 //-------------------------------------------------------------------------
2099 // genProduceReg: do liveness update for register produced by the current
2100 // node in codegen after code has been emitted for it.
2101 //
2102 // Arguments:
2103 //     tree   -  Gentree node
2104 //
2105 // Return Value:
2106 //     None.
2107 void CodeGen::genProduceReg(GenTree* tree)
2108 {
2109 #ifdef DEBUG
2110     assert((tree->gtDebugFlags & GTF_DEBUG_NODE_CG_PRODUCED) == 0);
2111     tree->gtDebugFlags |= GTF_DEBUG_NODE_CG_PRODUCED;
2112 #endif
2113
2114     if (tree->gtFlags & GTF_SPILL)
2115     {
2116         // Code for GT_COPY node gets generated as part of consuming regs by its parent.
2117         // A GT_COPY node in turn produces reg result and it should never be marked to
2118         // spill.
2119         //
2120         // Similarly GT_RELOAD node gets generated as part of consuming regs by its
2121         // parent and should never be marked for spilling.
2122         noway_assert(!tree->IsCopyOrReload());
2123
2124         if (genIsRegCandidateLocal(tree))
2125         {
2126             GenTreeLclVar*   lclNode   = tree->AsLclVar();
2127             const LclVarDsc* varDsc    = compiler->lvaGetDesc(lclNode);
2128             const unsigned   varNum    = lclNode->GetLclNum();
2129             const var_types  spillType = varDsc->GetRegisterType(lclNode);
2130             genSpillLocal(varNum, spillType, lclNode, tree->GetRegNum());
2131         }
2132         else if (tree->IsMultiRegLclVar())
2133         {
2134             assert(compiler->lvaEnregMultiRegVars);
2135
2136             GenTreeLclVar*   lclNode  = tree->AsLclVar();
2137             const LclVarDsc* varDsc   = compiler->lvaGetDesc(lclNode);
2138             const unsigned   regCount = lclNode->GetFieldCount(compiler);
2139
2140             for (unsigned i = 0; i < regCount; ++i)
2141             {
2142                 GenTreeFlags flags = lclNode->GetRegSpillFlagByIdx(i);
2143                 if ((flags & GTF_SPILL) != 0)
2144                 {
2145                     const regNumber reg         = lclNode->GetRegNumByIdx(i);
2146                     const unsigned  fieldVarNum = varDsc->lvFieldLclStart + i;
2147                     const var_types spillType   = compiler->lvaGetDesc(fieldVarNum)->GetRegisterType();
2148                     genSpillLocal(fieldVarNum, spillType, lclNode, reg);
2149                 }
2150             }
2151         }
2152         else
2153         {
2154             if (tree->IsMultiRegNode())
2155             {
2156                 // In case of multi-reg node, spill flag on it indicates that one or more of its allocated regs need to
2157                 // be spilled, and it needs to be further queried to know which of its result regs needs to be spilled.
2158                 const unsigned regCount = tree->GetMultiRegCount(compiler);
2159
2160                 for (unsigned i = 0; i < regCount; ++i)
2161                 {
2162                     GenTreeFlags flags = tree->GetRegSpillFlagByIdx(i);
2163                     if ((flags & GTF_SPILL) != 0)
2164                     {
2165                         regNumber reg = tree->GetRegByIndex(i);
2166                         regSet.rsSpillTree(reg, tree, i);
2167                         gcInfo.gcMarkRegSetNpt(genRegMask(reg));
2168                     }
2169                 }
2170             }
2171             else
2172             {
2173                 regSet.rsSpillTree(tree->GetRegNum(), tree);
2174                 gcInfo.gcMarkRegSetNpt(genRegMask(tree->GetRegNum()));
2175             }
2176
2177             tree->gtFlags |= GTF_SPILLED;
2178             tree->gtFlags &= ~GTF_SPILL;
2179
2180             return;
2181         }
2182     }
2183
2184     // Updating variable liveness after instruction was emitted
2185     genUpdateLife(tree);
2186
2187     // If we've produced a register, mark it as a pointer, as needed.
2188     if (tree->gtHasReg(compiler))
2189     {
2190         // We only mark the register in the following cases:
2191         // 1. It is not a register candidate local. In this case, we're producing a
2192         //    register from a local, but the local is not a register candidate. Thus,
2193         //    we must be loading it as a temp register, and any "last use" flag on
2194         //    the register wouldn't be relevant.
2195         // 2. The register candidate local is going dead. There's no point to mark
2196         //    the register as live, with a GC pointer, if the variable is dead.
2197         if (!genIsRegCandidateLocal(tree) || ((tree->gtFlags & GTF_VAR_DEATH) == 0))
2198         {
2199             // Multi-reg nodes will produce more than one register result.
2200             // Mark all the regs produced by the node.
2201             if (tree->IsMultiRegCall())
2202             {
2203                 const GenTreeCall*    call        = tree->AsCall();
2204                 const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
2205                 const unsigned        regCount    = retTypeDesc->GetReturnRegCount();
2206
2207                 for (unsigned i = 0; i < regCount; ++i)
2208                 {
2209                     regNumber reg  = call->GetRegNumByIdx(i);
2210                     var_types type = retTypeDesc->GetReturnRegType(i);
2211                     gcInfo.gcMarkRegPtrVal(reg, type);
2212                 }
2213             }
2214             else if (tree->IsCopyOrReloadOfMultiRegCall())
2215             {
2216                 // we should never see reload of multi-reg call here
2217                 // because GT_RELOAD gets generated in reg consuming path.
2218                 noway_assert(tree->OperGet() == GT_COPY);
2219
2220                 // A multi-reg GT_COPY node produces those regs to which
2221                 // copy has taken place.
2222                 const GenTreeCopyOrReload* copy        = tree->AsCopyOrReload();
2223                 const GenTreeCall*         call        = copy->gtGetOp1()->AsCall();
2224                 const ReturnTypeDesc*      retTypeDesc = call->GetReturnTypeDesc();
2225                 const unsigned             regCount    = retTypeDesc->GetReturnRegCount();
2226
2227                 for (unsigned i = 0; i < regCount; ++i)
2228                 {
2229                     var_types type  = retTypeDesc->GetReturnRegType(i);
2230                     regNumber toReg = copy->GetRegNumByIdx(i);
2231
2232                     if (toReg != REG_NA)
2233                     {
2234                         gcInfo.gcMarkRegPtrVal(toReg, type);
2235                     }
2236                 }
2237             }
2238             else if (tree->IsMultiRegLclVar())
2239             {
2240                 assert(compiler->lvaEnregMultiRegVars);
2241                 GenTreeLclVar* lclNode  = tree->AsLclVar();
2242                 LclVarDsc*     varDsc   = compiler->lvaGetDesc(lclNode);
2243                 unsigned       regCount = varDsc->lvFieldCnt;
2244                 for (unsigned i = 0; i < regCount; i++)
2245                 {
2246                     if (!lclNode->IsLastUse(i))
2247                     {
2248                         regNumber reg = lclNode->GetRegByIndex(i);
2249                         if (reg != REG_NA)
2250                         {
2251                             var_types type = compiler->lvaGetDesc(varDsc->lvFieldLclStart + i)->TypeGet();
2252                             gcInfo.gcMarkRegPtrVal(reg, type);
2253                         }
2254                     }
2255                 }
2256             }
2257             else
2258             {
2259                 gcInfo.gcMarkRegPtrVal(tree->GetRegNum(), tree->TypeGet());
2260             }
2261         }
2262     }
2263 }
2264
2265 // transfer gc/byref status of src reg to dst reg
2266 void CodeGen::genTransferRegGCState(regNumber dst, regNumber src)
2267 {
2268     regMaskTP srcMask = genRegMask(src);
2269     regMaskTP dstMask = genRegMask(dst);
2270
2271     if (gcInfo.gcRegGCrefSetCur & srcMask)
2272     {
2273         gcInfo.gcMarkRegSetGCref(dstMask);
2274     }
2275     else if (gcInfo.gcRegByrefSetCur & srcMask)
2276     {
2277         gcInfo.gcMarkRegSetByref(dstMask);
2278     }
2279     else
2280     {
2281         gcInfo.gcMarkRegSetNpt(dstMask);
2282     }
2283 }
2284
2285 // generates an ip-relative call or indirect call via reg ('call reg')
2286 //     pass in 'addr' for a relative call or 'base' for a indirect register call
2287 //     methHnd - optional, only used for pretty printing
2288 //     retSize - emitter type of return for GC purposes, should be EA_BYREF, EA_GCREF, or EA_PTRSIZE(not GC)
2289 //
2290 // clang-format off
2291 void CodeGen::genEmitCall(int                   callType,
2292                           CORINFO_METHOD_HANDLE methHnd,
2293                           INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
2294                           void*                 addr
2295                           X86_ARG(int argSize),
2296                           emitAttr              retSize
2297                           MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
2298                           const DebugInfo& di,
2299                           regNumber             base,
2300                           bool                  isJump)
2301 {
2302 #if !defined(TARGET_X86)
2303     int argSize = 0;
2304 #endif // !defined(TARGET_X86)
2305
2306     // This should have been put in volatile registers to ensure it does not
2307     // get overridden by epilog sequence during tailcall.
2308     noway_assert(!isJump || (base == REG_NA) || ((RBM_INT_CALLEE_TRASH & genRegMask(base)) != 0));
2309
2310     GetEmitter()->emitIns_Call(emitter::EmitCallType(callType),
2311                                methHnd,
2312                                INDEBUG_LDISASM_COMMA(sigInfo)
2313                                addr,
2314                                argSize,
2315                                retSize
2316                                MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
2317                                gcInfo.gcVarPtrSetCur,
2318                                gcInfo.gcRegGCrefSetCur,
2319                                gcInfo.gcRegByrefSetCur,
2320                                di, base, REG_NA, 0, 0, isJump);
2321 }
2322 // clang-format on
2323
2324 // generates an indirect call via addressing mode (call []) given an indir node
2325 //     methHnd - optional, only used for pretty printing
2326 //     retSize - emitter type of return for GC purposes, should be EA_BYREF, EA_GCREF, or EA_PTRSIZE(not GC)
2327 //
2328 // clang-format off
2329 void CodeGen::genEmitCallIndir(int                   callType,
2330                                CORINFO_METHOD_HANDLE methHnd,
2331                                INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
2332                                GenTreeIndir*         indir
2333                                X86_ARG(int argSize),
2334                                emitAttr              retSize
2335                                MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
2336                                const DebugInfo&      di,
2337                                bool                  isJump)
2338 {
2339 #if !defined(TARGET_X86)
2340     int argSize = 0;
2341 #endif // !defined(TARGET_X86)
2342
2343     regNumber iReg = (indir->Base()  != nullptr) ? indir->Base()->GetRegNum() : REG_NA;
2344     regNumber xReg = (indir->Index() != nullptr) ? indir->Index()->GetRegNum() : REG_NA;
2345
2346     // These should have been put in volatile registers to ensure they do not
2347     // get overridden by epilog sequence during tailcall.
2348     noway_assert(!isJump || (iReg == REG_NA) || ((RBM_CALLEE_TRASH & genRegMask(iReg)) != 0));
2349     noway_assert(!isJump || (xReg == REG_NA) || ((RBM_CALLEE_TRASH & genRegMask(xReg)) != 0));
2350
2351     GetEmitter()->emitIns_Call(emitter::EmitCallType(callType),
2352                                methHnd,
2353                                INDEBUG_LDISASM_COMMA(sigInfo)
2354                                nullptr,
2355                                argSize,
2356                                retSize
2357                                MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
2358                                gcInfo.gcVarPtrSetCur,
2359                                gcInfo.gcRegGCrefSetCur,
2360                                gcInfo.gcRegByrefSetCur,
2361                                di,
2362                                iReg,
2363                                xReg,
2364                                indir->Scale(),
2365                                indir->Offset(),
2366                                isJump);
2367 }
2368 // clang-format on
2369
2370 //------------------------------------------------------------------------
2371 // genCodeForCast: Generates the code for GT_CAST.
2372 //
2373 // Arguments:
2374 //    tree - the GT_CAST node.
2375 //
2376 void CodeGen::genCodeForCast(GenTreeOp* tree)
2377 {
2378     assert(tree->OperIs(GT_CAST));
2379
2380     var_types targetType = tree->TypeGet();
2381
2382     if (varTypeIsFloating(targetType) && varTypeIsFloating(tree->gtOp1))
2383     {
2384         // Casts float/double <--> double/float
2385         genFloatToFloatCast(tree);
2386     }
2387     else if (varTypeIsFloating(tree->gtOp1))
2388     {
2389         // Casts float/double --> int32/int64
2390         genFloatToIntCast(tree);
2391     }
2392     else if (varTypeIsFloating(targetType))
2393     {
2394         // Casts int32/uint32/int64/uint64 --> float/double
2395         genIntToFloatCast(tree);
2396     }
2397 #ifndef TARGET_64BIT
2398     else if (varTypeIsLong(tree->gtOp1))
2399     {
2400         genLongToIntCast(tree);
2401     }
2402 #endif // !TARGET_64BIT
2403     else
2404     {
2405         // Casts int <--> int
2406         genIntToIntCast(tree->AsCast());
2407     }
2408     // The per-case functions call genProduceReg()
2409 }
2410
2411 CodeGen::GenIntCastDesc::GenIntCastDesc(GenTreeCast* cast)
2412 {
2413     GenTree* const  src          = cast->CastOp();
2414     const var_types srcType      = genActualType(src);
2415     const bool      srcUnsigned  = cast->IsUnsigned();
2416     const unsigned  srcSize      = genTypeSize(srcType);
2417     const var_types castType     = cast->gtCastType;
2418     const bool      castUnsigned = varTypeIsUnsigned(castType);
2419     const unsigned  castSize     = genTypeSize(castType);
2420     const var_types dstType      = genActualType(cast->TypeGet());
2421     const unsigned  dstSize      = genTypeSize(dstType);
2422     const bool      overflow     = cast->gtOverflow();
2423     const bool      castIsLoad   = !src->isUsedFromReg();
2424
2425     assert(castIsLoad == src->isUsedFromMemory());
2426     assert((srcSize == 4) || (srcSize == genTypeSize(TYP_I_IMPL)));
2427     assert((dstSize == 4) || (dstSize == genTypeSize(TYP_I_IMPL)));
2428
2429     assert(dstSize == genTypeSize(genActualType(castType)));
2430
2431     if (castSize < 4) // Cast to small int type
2432     {
2433         if (overflow)
2434         {
2435             m_checkKind    = CHECK_SMALL_INT_RANGE;
2436             m_checkSrcSize = srcSize;
2437             // Since these are small int types we can compute the min and max
2438             // values of the castType without risk of integer overflow.
2439             const int castNumBits = (castSize * 8) - (castUnsigned ? 0 : 1);
2440             m_checkSmallIntMax    = (1 << castNumBits) - 1;
2441             m_checkSmallIntMin    = (castUnsigned || srcUnsigned) ? 0 : (-m_checkSmallIntMax - 1);
2442
2443             m_extendKind    = COPY;
2444             m_extendSrcSize = dstSize;
2445         }
2446         else
2447         {
2448             m_checkKind = CHECK_NONE;
2449
2450             // Casting to a small type really means widening from that small type to INT/LONG.
2451             m_extendKind    = castUnsigned ? ZERO_EXTEND_SMALL_INT : SIGN_EXTEND_SMALL_INT;
2452             m_extendSrcSize = castSize;
2453         }
2454     }
2455 #ifdef TARGET_64BIT
2456     // castType cannot be (U)LONG on 32 bit targets, such casts should have been decomposed.
2457     // srcType cannot be a small int type since it's the "actual type" of the cast operand.
2458     // This means that widening casts do not occur on 32 bit targets.
2459     else if (castSize > srcSize) // (U)INT to (U)LONG widening cast
2460     {
2461         assert((srcSize == 4) && (castSize == 8));
2462
2463         if (overflow && !srcUnsigned && castUnsigned)
2464         {
2465             // Widening from INT to ULONG, check if the value is positive
2466             m_checkKind    = CHECK_POSITIVE;
2467             m_checkSrcSize = 4;
2468
2469             // This is the only overflow checking cast that requires changing the
2470             // source value (by zero extending), all others copy the value as is.
2471             assert((srcType == TYP_INT) && (castType == TYP_ULONG));
2472             m_extendKind    = ZERO_EXTEND_INT;
2473             m_extendSrcSize = 4;
2474         }
2475         else
2476         {
2477             m_checkKind = CHECK_NONE;
2478
2479             m_extendKind    = srcUnsigned ? ZERO_EXTEND_INT : SIGN_EXTEND_INT;
2480             m_extendSrcSize = 4;
2481         }
2482     }
2483     else if (castSize < srcSize) // (U)LONG to (U)INT narrowing cast
2484     {
2485         assert((srcSize == 8) && (castSize == 4));
2486
2487         if (overflow)
2488         {
2489             if (castUnsigned) // (U)LONG to UINT cast
2490             {
2491                 m_checkKind = CHECK_UINT_RANGE;
2492             }
2493             else if (srcUnsigned) // ULONG to INT cast
2494             {
2495                 m_checkKind = CHECK_POSITIVE_INT_RANGE;
2496             }
2497             else // LONG to INT cast
2498             {
2499                 m_checkKind = CHECK_INT_RANGE;
2500             }
2501
2502             m_checkSrcSize = 8;
2503         }
2504         else
2505         {
2506             m_checkKind = CHECK_NONE;
2507         }
2508
2509 #if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
2510         // For LoongArch64's ISA which is same with the MIPS64 ISA, even the instructions of 32bits operation need
2511         // the upper 32bits be sign-extended to 64 bits.
2512         m_extendKind = SIGN_EXTEND_INT;
2513 #else
2514         m_extendKind = COPY;
2515 #endif
2516         m_extendSrcSize = 4;
2517     }
2518 #endif
2519     else // if (castSize == srcSize) // Sign changing or same type cast
2520     {
2521         assert(castSize == srcSize);
2522
2523         if (overflow && (srcUnsigned != castUnsigned))
2524         {
2525             m_checkKind    = CHECK_POSITIVE;
2526             m_checkSrcSize = srcSize;
2527         }
2528         else
2529         {
2530             m_checkKind = CHECK_NONE;
2531         }
2532
2533         m_extendKind    = COPY;
2534         m_extendSrcSize = srcSize;
2535     }
2536
2537     if (castIsLoad)
2538     {
2539         const var_types srcLoadType = src->TypeGet();
2540
2541         switch (m_extendKind)
2542         {
2543             case ZERO_EXTEND_SMALL_INT: // small type/int/long -> ubyte/ushort
2544                 assert(varTypeIsUnsigned(srcLoadType) || (genTypeSize(srcLoadType) >= genTypeSize(castType)));
2545                 m_extendKind    = LOAD_ZERO_EXTEND_SMALL_INT;
2546                 m_extendSrcSize = min(genTypeSize(srcLoadType), genTypeSize(castType));
2547                 break;
2548
2549             case SIGN_EXTEND_SMALL_INT: // small type/int/long -> byte/short
2550                 assert(varTypeIsSigned(srcLoadType) || (genTypeSize(srcLoadType) >= genTypeSize(castType)));
2551                 m_extendKind    = LOAD_SIGN_EXTEND_SMALL_INT;
2552                 m_extendSrcSize = min(genTypeSize(srcLoadType), genTypeSize(castType));
2553                 break;
2554
2555 #ifdef TARGET_64BIT
2556             case ZERO_EXTEND_INT: // ubyte/ushort/int -> long.
2557                 assert(varTypeIsUnsigned(srcLoadType) || (srcLoadType == TYP_INT));
2558                 m_extendKind    = varTypeIsSmall(srcLoadType) ? LOAD_ZERO_EXTEND_SMALL_INT : LOAD_ZERO_EXTEND_INT;
2559                 m_extendSrcSize = genTypeSize(srcLoadType);
2560                 break;
2561
2562             case SIGN_EXTEND_INT: // byte/short/int -> long.
2563                 assert(varTypeIsSigned(srcLoadType) || (srcLoadType == TYP_INT));
2564                 m_extendKind    = varTypeIsSmall(srcLoadType) ? LOAD_SIGN_EXTEND_SMALL_INT : LOAD_SIGN_EXTEND_INT;
2565                 m_extendSrcSize = genTypeSize(srcLoadType);
2566                 break;
2567 #endif // TARGET_64BIT
2568
2569             case COPY: // long -> long, small type/int/long -> int.
2570                 m_extendKind    = LOAD_SOURCE;
2571                 m_extendSrcSize = 0;
2572                 break;
2573
2574             default:
2575                 unreached();
2576         }
2577     }
2578 }
2579
2580 #if !defined(TARGET_64BIT)
2581 //------------------------------------------------------------------------
2582 // genStoreLongLclVar: Generate code to store a non-enregistered long lclVar
2583 //
2584 // Arguments:
2585 //    treeNode - A TYP_LONG lclVar node.
2586 //
2587 // Return Value:
2588 //    None.
2589 //
2590 // Assumptions:
2591 //    'treeNode' must be a TYP_LONG lclVar node for a lclVar that has NOT been promoted.
2592 //    Its operand must be a GT_LONG node.
2593 //
2594 void CodeGen::genStoreLongLclVar(GenTree* treeNode)
2595 {
2596     emitter* emit = GetEmitter();
2597
2598     GenTreeLclVarCommon* lclNode = treeNode->AsLclVarCommon();
2599     unsigned             lclNum  = lclNode->GetLclNum();
2600     LclVarDsc*           varDsc  = compiler->lvaGetDesc(lclNum);
2601     assert(varDsc->TypeGet() == TYP_LONG);
2602     assert(!varDsc->lvPromoted);
2603     GenTree* op1 = treeNode->AsOp()->gtOp1;
2604
2605     // A GT_LONG is always contained so it cannot have RELOAD or COPY inserted between it and its consumer.
2606     noway_assert(op1->OperIs(GT_LONG));
2607     genConsumeRegs(op1);
2608
2609     GenTree* loVal = op1->gtGetOp1();
2610     GenTree* hiVal = op1->gtGetOp2();
2611
2612     noway_assert((loVal->GetRegNum() != REG_NA) && (hiVal->GetRegNum() != REG_NA));
2613
2614     emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, loVal->GetRegNum(), lclNum, 0);
2615     emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, hiVal->GetRegNum(), lclNum, genTypeSize(TYP_INT));
2616 }
2617 #endif // !defined(TARGET_64BIT)
2618
2619 #if !defined(TARGET_LOONGARCH64) && !defined(TARGET_RISCV64)
2620
2621 //------------------------------------------------------------------------
2622 // genCodeForJcc: Generate code for a GT_JCC node.
2623 //
2624 // Arguments:
2625 //    jcc - The node
2626 //
2627 void CodeGen::genCodeForJcc(GenTreeCC* jcc)
2628 {
2629     assert(compiler->compCurBB->bbJumpKind == BBJ_COND);
2630     assert(jcc->OperIs(GT_JCC));
2631
2632     inst_JCC(jcc->gtCondition, compiler->compCurBB->bbJumpDest);
2633 }
2634
2635 //------------------------------------------------------------------------
2636 // inst_JCC: Generate a conditional branch instruction sequence.
2637 //
2638 // Arguments:
2639 //   condition - The branch condition
2640 //   target    - The basic block to jump to when the condition is true
2641 //
2642 void CodeGen::inst_JCC(GenCondition condition, BasicBlock* target)
2643 {
2644     const GenConditionDesc& desc = GenConditionDesc::Get(condition);
2645
2646     if (desc.oper == GT_NONE)
2647     {
2648         inst_JMP(desc.jumpKind1, target);
2649     }
2650     else if (desc.oper == GT_OR)
2651     {
2652         inst_JMP(desc.jumpKind1, target);
2653         inst_JMP(desc.jumpKind2, target);
2654     }
2655     else // if (desc.oper == GT_AND)
2656     {
2657         BasicBlock* labelNext = genCreateTempLabel();
2658         inst_JMP(emitter::emitReverseJumpKind(desc.jumpKind1), labelNext);
2659         inst_JMP(desc.jumpKind2, target);
2660         genDefineTempLabel(labelNext);
2661     }
2662 }
2663
2664 //------------------------------------------------------------------------
2665 // genCodeForSetcc: Generate code for a GT_SETCC node.
2666 //
2667 // Arguments:
2668 //    setcc - The node
2669 //
2670 void CodeGen::genCodeForSetcc(GenTreeCC* setcc)
2671 {
2672     assert(setcc->OperIs(GT_SETCC));
2673
2674     inst_SETCC(setcc->gtCondition, setcc->TypeGet(), setcc->GetRegNum());
2675     genProduceReg(setcc);
2676 }
2677 #endif // !TARGET_LOONGARCH64 && !TARGET_RISCV64