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 // See the LICENSE file in the project root for more information.
5 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8 XX Code Generation Support Methods for Linear Codegen XX
10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
18 #ifndef LEGACY_BACKEND // This file is ONLY used for the RyuJIT backend that uses the linear scan register allocator.
22 //------------------------------------------------------------------------
23 // genCodeForBBlist: Generate code for all the blocks in a method
29 // This is the main method for linear codegen. It calls genCodeForTreeNode
30 // to generate the code for each node in each BasicBlock, and handles BasicBlock
31 // boundaries and branches.
33 void CodeGen::genCodeForBBlist()
41 genInterruptibleUsed = true;
43 // You have to be careful if you create basic blocks from now on
44 compiler->fgSafeBasicBlockCreation = false;
46 // This stress mode is not comptible with fully interruptible GC
47 if (genInterruptible && compiler->opts.compStackCheckOnCall)
49 compiler->opts.compStackCheckOnCall = false;
52 // This stress mode is not comptible with fully interruptible GC
53 if (genInterruptible && compiler->opts.compStackCheckOnRet)
55 compiler->opts.compStackCheckOnRet = false;
59 // Prepare the blocks for exception handling codegen: mark the blocks that needs labels.
60 genPrepForEHCodegen();
62 assert(!compiler->fgFirstBBScratch ||
63 compiler->fgFirstBB == compiler->fgFirstBBScratch); // compiler->fgFirstBBScratch has to be first.
65 /* Initialize the spill tracking logic */
69 /* Initialize the line# tracking logic */
71 if (compiler->opts.compScopeInfo)
76 // The current implementation of switch tables requires the first block to have a label so it
77 // can generate offsets to the switch label targets.
78 // TODO-CQ: remove this when switches have been re-implemented to not use this.
79 if (compiler->fgHasSwitch)
81 compiler->fgFirstBB->bbFlags |= BBF_JMP_TARGET;
84 genPendingCallLabel = nullptr;
86 /* Initialize the pointer tracking code */
88 gcInfo.gcRegPtrSetInit();
89 gcInfo.gcVarPtrSetInit();
91 /* If any arguments live in registers, mark those regs as such */
93 for (varNum = 0, varDsc = compiler->lvaTable; varNum < compiler->lvaCount; varNum++, varDsc++)
95 /* Is this variable a parameter assigned to a register? */
97 if (!varDsc->lvIsParam || !varDsc->lvRegister)
102 /* Is the argument live on entry to the method? */
104 if (!VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex))
109 /* Is this a floating-point argument? */
111 if (varDsc->IsFloatRegType())
116 noway_assert(!varTypeIsFloating(varDsc->TypeGet()));
118 /* Mark the register as holding the variable */
120 regTracker.rsTrackRegLclVar(varDsc->lvRegNum, varNum);
123 unsigned finallyNesting = 0;
125 // Make sure a set is allocated for compiler->compCurLife (in the long case), so we can set it to empty without
126 // allocation at the start of each basic block.
127 VarSetOps::AssignNoCopy(compiler, compiler->compCurLife, VarSetOps::MakeEmpty(compiler));
129 /*-------------------------------------------------------------------------
131 * Walk the basic blocks and generate code for each one
137 for (block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
140 if (compiler->verbose)
142 printf("\n=============== Generating ");
143 block->dspBlockHeader(compiler, true, true);
144 compiler->fgDispBBLiveness(block);
148 assert(LIR::AsRange(block).CheckLIR(compiler));
150 // Figure out which registers hold variables on entry to this block
152 regSet.ClearMaskVars();
153 gcInfo.gcRegGCrefSetCur = RBM_NONE;
154 gcInfo.gcRegByrefSetCur = RBM_NONE;
156 compiler->m_pLinearScan->recordVarLocationsAtStartOfBB(block);
158 genUpdateLife(block->bbLiveIn);
160 // Even if liveness didn't change, we need to update the registers containing GC references.
161 // genUpdateLife will update the registers live due to liveness changes. But what about registers that didn't
162 // change? We cleared them out above. Maybe we should just not clear them out, but update the ones that change
163 // here. That would require handling the changes in recordVarLocationsAtStartOfBB().
165 regMaskTP newLiveRegSet = RBM_NONE;
166 regMaskTP newRegGCrefSet = RBM_NONE;
167 regMaskTP newRegByrefSet = RBM_NONE;
169 VARSET_TP removedGCVars(VarSetOps::MakeEmpty(compiler));
170 VARSET_TP addedGCVars(VarSetOps::MakeEmpty(compiler));
172 VarSetOps::Iter iter(compiler, block->bbLiveIn);
173 unsigned varIndex = 0;
174 while (iter.NextElem(&varIndex))
176 unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
177 LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
179 if (varDsc->lvIsInReg())
181 newLiveRegSet |= varDsc->lvRegMask();
182 if (varDsc->lvType == TYP_REF)
184 newRegGCrefSet |= varDsc->lvRegMask();
186 else if (varDsc->lvType == TYP_BYREF)
188 newRegByrefSet |= varDsc->lvRegMask();
191 if (verbose && VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
193 VarSetOps::AddElemD(compiler, removedGCVars, varIndex);
196 VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
198 else if (compiler->lvaIsGCTracked(varDsc))
201 if (verbose && !VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
203 VarSetOps::AddElemD(compiler, addedGCVars, varIndex);
206 VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
210 regSet.rsMaskVars = newLiveRegSet;
213 if (compiler->verbose)
215 if (!VarSetOps::IsEmpty(compiler, addedGCVars))
217 printf("\t\t\t\t\t\t\tAdded GCVars: ");
218 dumpConvertedVarSet(compiler, addedGCVars);
221 if (!VarSetOps::IsEmpty(compiler, removedGCVars))
223 printf("\t\t\t\t\t\t\tRemoved GCVars: ");
224 dumpConvertedVarSet(compiler, removedGCVars);
230 gcInfo.gcMarkRegSetGCref(newRegGCrefSet DEBUGARG(true));
231 gcInfo.gcMarkRegSetByref(newRegByrefSet DEBUGARG(true));
233 /* Blocks with handlerGetsXcptnObj()==true use GT_CATCH_ARG to
234 represent the exception object (TYP_REF).
235 We mark REG_EXCEPTION_OBJECT as holding a GC object on entry
236 to the block, it will be the first thing evaluated
237 (thanks to GTF_ORDER_SIDEEFF).
240 if (handlerGetsXcptnObj(block->bbCatchTyp))
242 for (GenTree* node : LIR::AsRange(block))
244 if (node->OperGet() == GT_CATCH_ARG)
246 gcInfo.gcMarkRegSetGCref(RBM_EXCEPTION_OBJECT);
252 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
253 genInsertNopForUnwinder(block);
256 /* Start a new code output block */
258 genUpdateCurrentFunclet(block);
260 #ifdef _TARGET_XARCH_
261 if (genAlignLoops && block->bbFlags & BBF_LOOP_HEAD)
263 getEmitter()->emitLoopAlign();
268 if (compiler->opts.dspCode)
270 printf("\n L_M%03u_BB%02u:\n", Compiler::s_compMethodsCount, block->bbNum);
274 block->bbEmitCookie = nullptr;
276 if (block->bbFlags & (BBF_JMP_TARGET | BBF_HAS_LABEL))
278 /* Mark a label and update the current set of live GC refs */
280 block->bbEmitCookie = getEmitter()->emitAddLabel(gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
281 gcInfo.gcRegByrefSetCur, FALSE);
284 if (block == compiler->fgFirstColdBlock)
287 if (compiler->verbose)
289 printf("\nThis is the start of the cold region of the method\n");
292 // We should never have a block that falls through into the Cold section
293 noway_assert(!block->bbPrev->bbFallsThrough());
295 // We require the block that starts the Cold section to have a label
296 noway_assert(block->bbEmitCookie);
297 getEmitter()->emitSetFirstColdIGCookie(block->bbEmitCookie);
300 /* Both stacks are always empty on entry to a basic block */
303 genAdjustStackLevel(block);
304 savedStkLvl = genStackLevel;
306 /* Tell everyone which basic block we're working on */
308 compiler->compCurBB = block;
312 // BBF_INTERNAL blocks don't correspond to any single IL instruction.
313 if (compiler->opts.compDbgInfo && (block->bbFlags & BBF_INTERNAL) &&
314 !compiler->fgBBisScratch(block)) // If the block is the distinguished first scratch block, then no need to
315 // emit a NO_MAPPING entry, immediately after the prolog.
317 genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::NO_MAPPING, true);
320 bool firstMapping = true;
322 #if FEATURE_EH_FUNCLETS
323 if (block->bbFlags & BBF_FUNCLET_BEG)
325 genReserveFuncletProlog(block);
327 #endif // FEATURE_EH_FUNCLETS
329 // Clear compCurStmt and compCurLifeTree.
330 compiler->compCurStmt = nullptr;
331 compiler->compCurLifeTree = nullptr;
333 // Traverse the block in linear order, generating code for each node as we
334 // as we encounter it.
335 CLANG_FORMAT_COMMENT_ANCHOR;
338 // Set the use-order numbers for each node.
341 for (GenTree* node : LIR::AsRange(block).NonPhiNodes())
343 assert((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) == 0);
346 if (node->isContained() || node->IsCopyOrReload())
351 for (GenTree* operand : node->Operands())
353 genNumberOperandUse(operand, useNum);
359 IL_OFFSETX currentILOffset = BAD_IL_OFFSET;
360 for (GenTree* node : LIR::AsRange(block).NonPhiNodes())
362 // Do we have a new IL offset?
363 if (node->OperGet() == GT_IL_OFFSET)
365 genEnsureCodeEmitted(currentILOffset);
366 currentILOffset = node->gtStmt.gtStmtILoffsx;
367 genIPmappingAdd(currentILOffset, firstMapping);
368 firstMapping = false;
372 if (node->OperGet() == GT_IL_OFFSET)
374 noway_assert(node->gtStmt.gtStmtLastILoffs <= compiler->info.compILCodeSize ||
375 node->gtStmt.gtStmtLastILoffs == BAD_IL_OFFSET);
377 if (compiler->opts.dspCode && compiler->opts.dspInstrs &&
378 node->gtStmt.gtStmtLastILoffs != BAD_IL_OFFSET)
380 while (genCurDispOffset <= node->gtStmt.gtStmtLastILoffs)
382 genCurDispOffset += dumpSingleInstr(compiler->info.compCode, genCurDispOffset, "> ");
388 genCodeForTreeNode(node);
389 if (node->gtHasReg() && node->IsUnusedValue())
393 } // end for each node in block
396 // The following set of register spill checks and GC pointer tracking checks used to be
397 // performed at statement boundaries. Now, with LIR, there are no statements, so they are
398 // performed at the end of each block.
399 // TODO: could these checks be performed more frequently? E.g., at each location where
400 // the register allocator says there are no live non-variable registers. Perhaps this could
401 // be done by using the map maintained by LSRA (operandToLocationInfoMap) to mark a node
402 // somehow when, after the execution of that node, there will be no live non-variable registers.
406 /* Make sure we didn't bungle pointer register tracking */
408 regMaskTP ptrRegs = gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur;
409 regMaskTP nonVarPtrRegs = ptrRegs & ~regSet.rsMaskVars;
411 // If return is a GC-type, clear it. Note that if a common
412 // epilog is generated (genReturnBB) it has a void return
413 // even though we might return a ref. We can't use the compRetType
414 // as the determiner because something we are tracking as a byref
415 // might be used as a return value of a int function (which is legal)
416 GenTree* blockLastNode = block->lastNode();
417 if ((blockLastNode != nullptr) && (blockLastNode->gtOper == GT_RETURN) &&
418 (varTypeIsGC(compiler->info.compRetType) ||
419 (blockLastNode->gtOp.gtOp1 != nullptr && varTypeIsGC(blockLastNode->gtOp.gtOp1->TypeGet()))))
421 nonVarPtrRegs &= ~RBM_INTRET;
426 printf("Regset after BB%02u gcr=", block->bbNum);
427 printRegMaskInt(gcInfo.gcRegGCrefSetCur & ~regSet.rsMaskVars);
428 compiler->getEmitter()->emitDispRegSet(gcInfo.gcRegGCrefSetCur & ~regSet.rsMaskVars);
430 printRegMaskInt(gcInfo.gcRegByrefSetCur & ~regSet.rsMaskVars);
431 compiler->getEmitter()->emitDispRegSet(gcInfo.gcRegByrefSetCur & ~regSet.rsMaskVars);
432 printf(", regVars=");
433 printRegMaskInt(regSet.rsMaskVars);
434 compiler->getEmitter()->emitDispRegSet(regSet.rsMaskVars);
438 noway_assert(nonVarPtrRegs == RBM_NONE);
442 if (block->bbNext == nullptr)
444 // Unit testing of the emitter: generate a bunch of instructions into the last block
445 // (it's as good as any, but better than the prolog, which can only be a single instruction
446 // group) then use COMPlus_JitLateDisasm=* to see if the late disassembler
447 // thinks the instructions are the same as we do.
448 #if defined(_TARGET_AMD64_) && defined(LATE_DISASM)
449 genAmd64EmitterUnitTests();
450 #elif defined(_TARGET_ARM64_)
451 genArm64EmitterUnitTests();
452 #endif // _TARGET_ARM64_
454 #endif // defined(DEBUG)
456 // It is possible to reach the end of the block without generating code for the current IL offset.
457 // For example, if the following IR ends the current block, no code will have been generated for
460 // ( 0, 0) [000040] ------------ il_offset void IL offset: 21
462 // N001 ( 0, 0) [000039] ------------ nop void
464 // This can lead to problems when debugging the generated code. To prevent these issues, make sure
465 // we've generated code for the last IL offset we saw in the block.
466 genEnsureCodeEmitted(currentILOffset);
468 if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
472 /* Is this the last block, and are there any open scopes left ? */
474 bool isLastBlockProcessed = (block->bbNext == nullptr);
475 if (block->isBBCallAlwaysPair())
477 isLastBlockProcessed = (block->bbNext->bbNext == nullptr);
480 if (isLastBlockProcessed && siOpenScopeList.scNext)
482 /* This assert no longer holds, because we may insert a throw
483 block to demarcate the end of a try or finally region when they
484 are at the end of the method. It would be nice if we could fix
485 our code so that this throw block will no longer be necessary. */
487 // noway_assert(block->bbCodeOffsEnd != compiler->info.compILCodeSize);
489 siCloseAllOpenScopes();
493 SubtractStackLevel(savedStkLvl);
496 // compCurLife should be equal to the liveOut set, except that we don't keep
497 // it up to date for vars that are not register candidates
498 // (it would be nice to have a xor set function)
500 VARSET_TP extraLiveVars(VarSetOps::Diff(compiler, block->bbLiveOut, compiler->compCurLife));
501 VarSetOps::UnionD(compiler, extraLiveVars, VarSetOps::Diff(compiler, compiler->compCurLife, block->bbLiveOut));
502 VarSetOps::Iter extraLiveVarIter(compiler, extraLiveVars);
503 unsigned extraLiveVarIndex = 0;
504 while (extraLiveVarIter.NextElem(&extraLiveVarIndex))
506 unsigned varNum = compiler->lvaTrackedToVarNum[extraLiveVarIndex];
507 LclVarDsc* varDsc = compiler->lvaTable + varNum;
508 assert(!varDsc->lvIsRegCandidate());
512 /* Both stacks should always be empty on exit from a basic block */
513 noway_assert(genStackLevel == 0);
515 #ifdef _TARGET_AMD64_
516 // On AMD64, we need to generate a NOP after a call that is the last instruction of the block, in several
517 // situations, to support proper exception handling semantics. This is mostly to ensure that when the stack
518 // walker computes an instruction pointer for a frame, that instruction pointer is in the correct EH region.
519 // The document "X64 and ARM ABIs.docx" has more details. The situations:
520 // 1. If the call instruction is in a different EH region as the instruction that follows it.
521 // 2. If the call immediately precedes an OS epilog. (Note that what the JIT or VM consider an epilog might
522 // be slightly different from what the OS considers an epilog, and it is the OS-reported epilog that matters
524 // We handle case #1 here, and case #2 in the emitter.
525 if (getEmitter()->emitIsLastInsCall())
527 // Ok, the last instruction generated is a call instruction. Do any of the other conditions hold?
528 // Note: we may be generating a few too many NOPs for the case of call preceding an epilog. Technically,
529 // if the next block is a BBJ_RETURN, an epilog will be generated, but there may be some instructions
530 // generated before the OS epilog starts, such as a GS cookie check.
531 if ((block->bbNext == nullptr) || !BasicBlock::sameEHRegion(block, block->bbNext))
533 // We only need the NOP if we're not going to generate any more code as part of the block end.
535 switch (block->bbJumpKind)
539 case BBJ_CALLFINALLY:
541 // We're going to generate more code below anyway, so no need for the NOP.
544 case BBJ_EHFINALLYRET:
545 case BBJ_EHFILTERRET:
546 // These are the "epilog follows" case, handled in the emitter.
551 if (block->bbNext == nullptr)
553 // Call immediately before the end of the code; we should never get here .
554 instGen(INS_BREAKPOINT); // This should never get executed
565 // These can't have a call as the last instruction!
568 noway_assert(!"Unexpected bbJumpKind");
573 #endif // _TARGET_AMD64_
575 /* Do we need to generate a jump or return? */
577 switch (block->bbJumpKind)
580 inst_JMP(EJ_jmp, block->bbJumpDest);
588 // If we have a throw at the end of a function or funclet, we need to emit another instruction
589 // afterwards to help the OS unwinder determine the correct context during unwind.
590 // We insert an unexecuted breakpoint instruction in several situations
591 // following a throw instruction:
592 // 1. If the throw is the last instruction of the function or funclet. This helps
593 // the OS unwinder determine the correct context during an unwind from the
595 // 2. If this is this is the last block of the hot section.
596 // 3. If the subsequent block is a special throw block.
597 // 4. On AMD64, if the next block is in a different EH region.
598 if ((block->bbNext == nullptr) || (block->bbNext->bbFlags & BBF_FUNCLET_BEG) ||
599 !BasicBlock::sameEHRegion(block, block->bbNext) ||
600 (!isFramePointerUsed() && compiler->fgIsThrowHlpBlk(block->bbNext)) ||
601 block->bbNext == compiler->fgFirstColdBlock)
603 instGen(INS_BREAKPOINT); // This should never get executed
605 // Do likewise for blocks that end in DOES_NOT_RETURN calls
606 // that were not caught by the above rules. This ensures that
607 // gc register liveness doesn't change across call instructions
608 // in fully-interruptible mode.
611 GenTree* call = block->lastNode();
613 if ((call != nullptr) && (call->gtOper == GT_CALL))
615 if ((call->gtCall.gtCallMoreFlags & GTF_CALL_M_DOES_NOT_RETURN) != 0)
617 instGen(INS_BREAKPOINT); // This should never get executed
624 case BBJ_CALLFINALLY:
625 block = genCallFinally(block);
628 #if FEATURE_EH_FUNCLETS
631 genEHCatchRet(block);
634 case BBJ_EHFINALLYRET:
635 case BBJ_EHFILTERRET:
636 genReserveFuncletEpilog(block);
639 #else // !FEATURE_EH_FUNCLETS
642 noway_assert(!"Unexpected BBJ_EHCATCHRET"); // not used on x86
644 case BBJ_EHFINALLYRET:
645 case BBJ_EHFILTERRET:
646 genEHFinallyOrFilterRet(block);
649 #endif // !FEATURE_EH_FUNCLETS
657 noway_assert(!"Unexpected bbJumpKind");
662 compiler->compCurBB = nullptr;
665 } //------------------ END-FOR each block of the method -------------------
667 /* Nothing is live at this point */
668 genUpdateLife(VarSetOps::MakeEmpty(compiler));
670 /* Finalize the spill tracking logic */
674 /* Finalize the temp tracking logic */
679 if (compiler->verbose)
682 printf("compCycleEstimate = %6d, compSizeEstimate = %5d ", compiler->compCycleEstimate,
683 compiler->compSizeEstimate);
684 printf("%s\n", compiler->info.compFullName);
690 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
691 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
693 XX Register Management XX
695 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
696 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
700 //------------------------------------------------------------------------
701 // genGetAssignedReg: Get the register assigned to the given node
704 // tree - the lclVar node whose assigned register we want
707 // The assigned regNumber
709 regNumber CodeGenInterface::genGetAssignedReg(GenTree* tree)
711 return tree->gtRegNum;
714 //------------------------------------------------------------------------
715 // genSpillVar: Spill a local variable
718 // tree - the lclVar node for the variable being spilled
724 // The lclVar must be a register candidate (lvRegCandidate)
726 void CodeGen::genSpillVar(GenTree* tree)
728 unsigned varNum = tree->gtLclVarCommon.gtLclNum;
729 LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
731 assert(varDsc->lvIsRegCandidate());
733 // We don't actually need to spill if it is already living in memory
734 bool needsSpill = ((tree->gtFlags & GTF_VAR_DEF) == 0 && varDsc->lvIsInReg());
737 // In order for a lclVar to have been allocated to a register, it must not have been aliasable, and can
738 // therefore be store-normalized (rather than load-normalized). In fact, not performing store normalization
739 // can lead to problems on architectures where a lclVar may be allocated to a register that is not
740 // addressable at the granularity of the lclVar's defined type (e.g. x86).
741 var_types lclTyp = genActualType(varDsc->TypeGet());
742 emitAttr size = emitTypeSize(lclTyp);
744 bool restoreRegVar = false;
745 if (tree->gtOper == GT_REG_VAR)
747 tree->SetOper(GT_LCL_VAR);
748 restoreRegVar = true;
751 instruction storeIns = ins_Store(lclTyp, compiler->isSIMDTypeLocalAligned(varNum));
752 #if CPU_LONG_USES_REGPAIR
753 if (varTypeIsMultiReg(tree))
755 assert(varDsc->lvRegNum == genRegPairLo(tree->gtRegPair));
756 assert(varDsc->lvOtherReg == genRegPairHi(tree->gtRegPair));
757 regNumber regLo = genRegPairLo(tree->gtRegPair);
758 regNumber regHi = genRegPairHi(tree->gtRegPair);
759 inst_TT_RV(storeIns, tree, regLo);
760 inst_TT_RV(storeIns, tree, regHi, 4);
765 assert(varDsc->lvRegNum == tree->gtRegNum);
766 inst_TT_RV(storeIns, tree, tree->gtRegNum, 0, size);
771 tree->SetOper(GT_REG_VAR);
774 genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(tree));
775 gcInfo.gcMarkRegSetNpt(varDsc->lvRegMask());
777 if (VarSetOps::IsMember(compiler, gcInfo.gcTrkStkPtrLcls, varDsc->lvVarIndex))
780 if (!VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
782 JITDUMP("\t\t\t\t\t\t\tVar V%02u becoming live\n", varNum);
786 JITDUMP("\t\t\t\t\t\t\tVar V%02u continuing live\n", varNum);
789 VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
793 tree->gtFlags &= ~GTF_SPILL;
794 varDsc->lvRegNum = REG_STK;
795 if (varTypeIsMultiReg(tree))
797 varDsc->lvOtherReg = REG_STK;
801 //------------------------------------------------------------------------
802 // genUpdateVarReg: Update the current register location for a lclVar
805 // varDsc - the LclVarDsc for the lclVar
806 // tree - the lclVar node
809 void CodeGenInterface::genUpdateVarReg(LclVarDsc* varDsc, GenTree* tree)
811 assert(tree->OperIsScalarLocal() || (tree->gtOper == GT_COPY));
812 varDsc->lvRegNum = tree->gtRegNum;
815 //------------------------------------------------------------------------
816 // sameRegAsDst: Return the child that has the same reg as the dst (if any)
819 // tree - the node of interest
820 // other - an out parameter to return the other child
823 // If 'tree' has a child with the same assigned register as its target reg,
824 // that child will be returned, and 'other' will contain the non-matching child.
825 // Otherwise, both other and the return value will be nullptr.
827 GenTree* sameRegAsDst(GenTree* tree, GenTree*& other /*out*/)
829 if (tree->gtRegNum == REG_NA)
835 GenTree* op1 = tree->gtOp.gtOp1;
836 GenTree* op2 = tree->gtOp.gtOp2;
837 if (op1->gtRegNum == tree->gtRegNum)
842 if (op2->gtRegNum == tree->gtRegNum)
854 //------------------------------------------------------------------------
855 // genUnspillRegIfNeeded: Reload the value into a register, if needed
858 // tree - the node of interest.
861 // In the normal case, the value will be reloaded into the register it
862 // was originally computed into. However, if that register is not available,
863 // the register allocator will have allocated a different register, and
864 // inserted a GT_RELOAD to indicate the register into which it should be
867 void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
869 regNumber dstReg = tree->gtRegNum;
870 GenTree* unspillTree = tree;
872 if (tree->gtOper == GT_RELOAD)
874 unspillTree = tree->gtOp.gtOp1;
877 if ((unspillTree->gtFlags & GTF_SPILLED) != 0)
879 if (genIsRegCandidateLocal(unspillTree))
881 // Reset spilled flag, since we are going to load a local variable from its home location.
882 unspillTree->gtFlags &= ~GTF_SPILLED;
884 GenTreeLclVarCommon* lcl = unspillTree->AsLclVarCommon();
885 LclVarDsc* varDsc = &compiler->lvaTable[lcl->gtLclNum];
887 // TODO-Cleanup: The following code could probably be further merged and cleaned up.
888 #ifdef _TARGET_XARCH_
889 // Load local variable from its home location.
890 // In most cases the tree type will indicate the correct type to use for the load.
891 // However, if it is NOT a normalizeOnLoad lclVar (i.e. NOT a small int that always gets
892 // widened when loaded into a register), and its size is not the same as genActualType of
893 // the type of the lclVar, then we need to change the type of the tree node when loading.
894 // This situation happens due to "optimizations" that avoid a cast and
895 // simply retype the node when using long type lclVar as an int.
896 // While loading the int in that case would work for this use of the lclVar, if it is
897 // later used as a long, we will have incorrectly truncated the long.
898 // In the normalizeOnLoad case ins_Load will return an appropriate sign- or zero-
901 var_types treeType = unspillTree->TypeGet();
902 if (treeType != genActualType(varDsc->lvType) && !varTypeIsGC(treeType) && !varDsc->lvNormalizeOnLoad())
904 assert(!varTypeIsGC(varDsc));
905 var_types spillType = genActualType(varDsc->lvType);
906 unspillTree->gtType = spillType;
907 inst_RV_TT(ins_Load(spillType, compiler->isSIMDTypeLocalAligned(lcl->gtLclNum)), dstReg, unspillTree);
908 unspillTree->gtType = treeType;
912 inst_RV_TT(ins_Load(treeType, compiler->isSIMDTypeLocalAligned(lcl->gtLclNum)), dstReg, unspillTree);
914 #elif defined(_TARGET_ARM64_)
915 var_types targetType = unspillTree->gtType;
916 if (targetType != genActualType(varDsc->lvType) && !varTypeIsGC(targetType) && !varDsc->lvNormalizeOnLoad())
918 assert(!varTypeIsGC(varDsc));
919 targetType = genActualType(varDsc->lvType);
921 instruction ins = ins_Load(targetType, compiler->isSIMDTypeLocalAligned(lcl->gtLclNum));
922 emitAttr attr = emitTypeSize(targetType);
923 emitter* emit = getEmitter();
926 attr = varTypeIsFloating(targetType) ? attr : emit->emitInsAdjustLoadStoreAttr(ins, attr);
928 // Load local variable from its home location.
929 inst_RV_TT(ins, dstReg, unspillTree, 0, attr);
930 #elif defined(_TARGET_ARM_)
931 var_types targetType = unspillTree->gtType;
932 instruction ins = ins_Load(targetType, compiler->isSIMDTypeLocalAligned(lcl->gtLclNum));
933 emitAttr attr = emitTypeSize(targetType);
935 // Load local variable from its home location.
936 inst_RV_TT(ins, dstReg, unspillTree, 0, attr);
938 NYI("Unspilling not implemented for this target architecture.");
941 // TODO-Review: We would like to call:
942 // genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(tree));
943 // instead of the following code, but this ends up hitting this assert:
944 // assert((regSet.rsMaskVars & regMask) == 0);
945 // due to issues with LSRA resolution moves.
946 // So, just force it for now. This probably indicates a condition that creates a GC hole!
948 // Extra note: I think we really want to call something like gcInfo.gcUpdateForRegVarMove,
949 // because the variable is not really going live or dead, but that method is somewhat poorly
950 // factored because it, in turn, updates rsMaskVars which is part of RegSet not GCInfo.
951 // TODO-Cleanup: This code exists in other CodeGen*.cpp files, and should be moved to CodeGenCommon.cpp.
953 // Don't update the variable's location if we are just re-spilling it again.
955 if ((unspillTree->gtFlags & GTF_SPILL) == 0)
957 genUpdateVarReg(varDsc, tree);
959 if (VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
961 JITDUMP("\t\t\t\t\t\t\tRemoving V%02u from gcVarPtrSetCur\n", lcl->gtLclNum);
964 VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
967 if (compiler->verbose)
969 printf("\t\t\t\t\t\t\tV%02u in reg ", lcl->gtLclNum);
970 varDsc->PrintVarReg();
971 printf(" is becoming live ");
972 compiler->printTreeID(unspillTree);
977 regSet.AddMaskVars(genGetRegMask(varDsc));
980 gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
982 else if (unspillTree->IsMultiRegCall())
984 GenTreeCall* call = unspillTree->AsCall();
985 ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
986 unsigned regCount = retTypeDesc->GetReturnRegCount();
987 GenTreeCopyOrReload* reloadTree = nullptr;
988 if (tree->OperGet() == GT_RELOAD)
990 reloadTree = tree->AsCopyOrReload();
993 // In case of multi-reg call node, GTF_SPILLED flag on it indicates that
994 // one or more of its result regs are spilled. Call node needs to be
995 // queried to know which specific result regs to be unspilled.
996 for (unsigned i = 0; i < regCount; ++i)
998 unsigned flags = call->GetRegSpillFlagByIdx(i);
999 if ((flags & GTF_SPILLED) != 0)
1001 var_types dstType = retTypeDesc->GetReturnRegType(i);
1002 regNumber unspillTreeReg = call->GetRegNumByIdx(i);
1004 if (reloadTree != nullptr)
1006 dstReg = reloadTree->GetRegNumByIdx(i);
1007 if (dstReg == REG_NA)
1009 dstReg = unspillTreeReg;
1014 dstReg = unspillTreeReg;
1017 TempDsc* t = regSet.rsUnspillInPlace(call, unspillTreeReg, i);
1018 getEmitter()->emitIns_R_S(ins_Load(dstType), emitActualTypeSize(dstType), dstReg, t->tdTempNum(),
1020 compiler->tmpRlsTemp(t);
1021 gcInfo.gcMarkRegPtrVal(dstReg, dstType);
1025 unspillTree->gtFlags &= ~GTF_SPILLED;
1028 else if (unspillTree->OperIsPutArgSplit())
1030 GenTreePutArgSplit* splitArg = unspillTree->AsPutArgSplit();
1031 unsigned regCount = splitArg->gtNumRegs;
1033 // In case of split struct argument node, GTF_SPILLED flag on it indicates that
1034 // one or more of its result regs are spilled. Call node needs to be
1035 // queried to know which specific result regs to be unspilled.
1036 for (unsigned i = 0; i < regCount; ++i)
1038 unsigned flags = splitArg->GetRegSpillFlagByIdx(i);
1039 if ((flags & GTF_SPILLED) != 0)
1041 BYTE* gcPtrs = splitArg->gtGcPtrs;
1042 var_types dstType = splitArg->GetRegType(i);
1043 regNumber dstReg = splitArg->GetRegNumByIdx(i);
1045 TempDsc* t = regSet.rsUnspillInPlace(splitArg, dstReg, i);
1046 getEmitter()->emitIns_R_S(ins_Load(dstType), emitActualTypeSize(dstType), dstReg, t->tdTempNum(),
1048 compiler->tmpRlsTemp(t);
1049 gcInfo.gcMarkRegPtrVal(dstReg, dstType);
1053 unspillTree->gtFlags &= ~GTF_SPILLED;
1055 else if (unspillTree->OperIsMultiRegOp())
1057 GenTreeMultiRegOp* multiReg = unspillTree->AsMultiRegOp();
1058 unsigned regCount = multiReg->GetRegCount();
1060 // In case of split struct argument node, GTF_SPILLED flag on it indicates that
1061 // one or more of its result regs are spilled. Call node needs to be
1062 // queried to know which specific result regs to be unspilled.
1063 for (unsigned i = 0; i < regCount; ++i)
1065 unsigned flags = multiReg->GetRegSpillFlagByIdx(i);
1066 if ((flags & GTF_SPILLED) != 0)
1068 var_types dstType = multiReg->GetRegType(i);
1069 regNumber dstReg = multiReg->GetRegNumByIdx(i);
1071 TempDsc* t = regSet.rsUnspillInPlace(multiReg, dstReg, i);
1072 getEmitter()->emitIns_R_S(ins_Load(dstType), emitActualTypeSize(dstType), dstReg, t->tdTempNum(),
1074 compiler->tmpRlsTemp(t);
1075 gcInfo.gcMarkRegPtrVal(dstReg, dstType);
1079 unspillTree->gtFlags &= ~GTF_SPILLED;
1084 TempDsc* t = regSet.rsUnspillInPlace(unspillTree, unspillTree->gtRegNum);
1085 getEmitter()->emitIns_R_S(ins_Load(unspillTree->gtType), emitActualTypeSize(unspillTree->TypeGet()), dstReg,
1087 compiler->tmpRlsTemp(t);
1089 unspillTree->gtFlags &= ~GTF_SPILLED;
1090 gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
1095 //------------------------------------------------------------------------
1096 // genCopyRegIfNeeded: Copy the given node into the specified register
1099 // node - The node that has been evaluated (consumed).
1100 // needReg - The register in which its value is needed.
1103 // This must be a node that has a register.
1105 void CodeGen::genCopyRegIfNeeded(GenTree* node, regNumber needReg)
1107 assert((node->gtRegNum != REG_NA) && (needReg != REG_NA));
1108 assert(!node->isUsedFromSpillTemp());
1109 if (node->gtRegNum != needReg)
1111 inst_RV_RV(INS_mov, needReg, node->gtRegNum, node->TypeGet());
1115 // Do Liveness update for a subnodes that is being consumed by codegen
1116 // including the logic for reload in case is needed and also takes care
1117 // of locating the value on the desired register.
1118 void CodeGen::genConsumeRegAndCopy(GenTree* node, regNumber needReg)
1120 if (needReg == REG_NA)
1124 regNumber treeReg = genConsumeReg(node);
1125 genCopyRegIfNeeded(node, needReg);
1128 // Check that registers are consumed in the right order for the current node being generated.
1130 void CodeGen::genNumberOperandUse(GenTree* const operand, int& useNum) const
1132 assert(operand != nullptr);
1134 // Ignore argument placeholders.
1135 if (operand->OperGet() == GT_ARGPLACE)
1140 assert(operand->gtUseNum == -1);
1142 if (!operand->isContained() && !operand->IsCopyOrReload())
1144 operand->gtUseNum = useNum;
1149 for (GenTree* operand : operand->Operands())
1151 genNumberOperandUse(operand, useNum);
1156 void CodeGen::genCheckConsumeNode(GenTree* const node)
1158 assert(node != nullptr);
1162 if (node->gtUseNum == -1)
1164 // nothing wrong if the node was not consumed
1166 else if ((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) != 0)
1168 printf("Node was consumed twice:\n");
1169 compiler->gtDispTree(node, nullptr, nullptr, true);
1171 else if ((lastConsumedNode != nullptr) && (node->gtUseNum < lastConsumedNode->gtUseNum))
1173 printf("Nodes were consumed out-of-order:\n");
1174 compiler->gtDispTree(lastConsumedNode, nullptr, nullptr, true);
1175 compiler->gtDispTree(node, nullptr, nullptr, true);
1179 assert((node->OperGet() == GT_CATCH_ARG) || ((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) == 0));
1180 assert((lastConsumedNode == nullptr) || (node->gtUseNum == -1) || (node->gtUseNum > lastConsumedNode->gtUseNum));
1182 node->gtDebugFlags |= GTF_DEBUG_NODE_CG_CONSUMED;
1183 lastConsumedNode = node;
1187 //--------------------------------------------------------------------
1188 // genConsumeReg: Do liveness update for a subnode that is being
1189 // consumed by codegen.
1192 // tree - GenTree node
1195 // Returns the reg number of tree.
1196 // In case of multi-reg call node returns the first reg number
1197 // of the multi-reg return.
1198 regNumber CodeGen::genConsumeReg(GenTree* tree)
1200 if (tree->OperGet() == GT_COPY)
1205 // Handle the case where we have a lclVar that needs to be copied before use (i.e. because it
1206 // interferes with one of the other sources (or the target, if it's a "delayed use" register)).
1207 // TODO-Cleanup: This is a special copyReg case in LSRA - consider eliminating these and
1208 // always using GT_COPY to make the lclVar location explicit.
1209 // Note that we have to do this before calling genUpdateLife because otherwise if we spill it
1210 // the lvRegNum will be set to REG_STK and we will lose track of what register currently holds
1211 // the lclVar (normally when a lclVar is spilled it is then used from its former register
1212 // location, which matches the gtRegNum on the node).
1213 // (Note that it doesn't matter if we call this before or after genUnspillRegIfNeeded
1214 // because if it's on the stack it will always get reloaded into tree->gtRegNum).
1215 if (genIsRegCandidateLocal(tree))
1217 GenTreeLclVarCommon* lcl = tree->AsLclVarCommon();
1218 LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()];
1219 if (varDsc->lvRegNum != REG_STK && varDsc->lvRegNum != tree->gtRegNum)
1221 inst_RV_RV(ins_Copy(tree->TypeGet()), tree->gtRegNum, varDsc->lvRegNum);
1225 genUnspillRegIfNeeded(tree);
1227 // genUpdateLife() will also spill local var if marked as GTF_SPILL by calling CodeGen::genSpillVar
1228 genUpdateLife(tree);
1230 assert(tree->gtHasReg());
1232 // there are three cases where consuming a reg means clearing the bit in the live mask
1233 // 1. it was not produced by a local
1234 // 2. it was produced by a local that is going dead
1235 // 3. it was produced by a local that does not live in that reg (like one allocated on the stack)
1237 if (genIsRegCandidateLocal(tree))
1239 GenTreeLclVarCommon* lcl = tree->AsLclVarCommon();
1240 LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()];
1241 assert(varDsc->lvLRACandidate);
1243 if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
1245 gcInfo.gcMarkRegSetNpt(genRegMask(varDsc->lvRegNum));
1247 else if (varDsc->lvRegNum == REG_STK)
1249 // We have loaded this into a register only temporarily
1250 gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
1255 gcInfo.gcMarkRegSetNpt(tree->gtGetRegMask());
1258 genCheckConsumeNode(tree);
1259 return tree->gtRegNum;
1262 // Do liveness update for an address tree: one of GT_LEA, GT_LCL_VAR, or GT_CNS_INT (for call indirect).
1263 void CodeGen::genConsumeAddress(GenTree* addr)
1265 if (!addr->isContained())
1267 genConsumeReg(addr);
1269 else if (addr->OperGet() == GT_LEA)
1271 genConsumeAddrMode(addr->AsAddrMode());
1275 // do liveness update for a subnode that is being consumed by codegen
1276 void CodeGen::genConsumeAddrMode(GenTreeAddrMode* addr)
1278 genConsumeOperands(addr);
1281 void CodeGen::genConsumeRegs(GenTree* tree)
1283 #if !defined(_TARGET_64BIT_)
1284 if (tree->OperGet() == GT_LONG)
1286 genConsumeRegs(tree->gtGetOp1());
1287 genConsumeRegs(tree->gtGetOp2());
1290 #endif // !defined(_TARGET_64BIT_)
1292 if (tree->isUsedFromSpillTemp())
1294 // spill temps are un-tracked and hence no need to update life
1296 else if (tree->isContained())
1298 if (tree->isIndir())
1300 genConsumeAddress(tree->AsIndir()->Addr());
1302 #ifdef _TARGET_XARCH_
1303 else if (tree->OperIsLocalRead())
1305 // A contained lcl var must be living on stack and marked as reg optional, or not be a
1306 // register candidate.
1307 unsigned varNum = tree->AsLclVarCommon()->GetLclNum();
1308 LclVarDsc* varDsc = compiler->lvaTable + varNum;
1310 noway_assert(varDsc->lvRegNum == REG_STK);
1311 noway_assert(tree->IsRegOptional() || !varDsc->lvLRACandidate);
1313 // Update the life of the lcl var.
1314 genUpdateLife(tree);
1316 #endif // _TARGET_XARCH_
1317 else if (tree->OperIsInitVal())
1319 genConsumeReg(tree->gtGetOp1());
1321 else if (tree->OperIsHWIntrinsic())
1323 genConsumeReg(tree->gtGetOp1());
1328 // (In)Equality operation that produces bool result, when compared
1329 // against Vector zero, marks its Vector Zero operand as contained.
1330 assert(tree->OperIsLeaf() || tree->IsIntegralConstVector(0));
1332 assert(tree->OperIsLeaf());
1338 genConsumeReg(tree);
1342 //------------------------------------------------------------------------
1343 // genConsumeOperands: Do liveness update for the operands of a unary or binary tree
1346 // tree - the GenTreeOp whose operands will have their liveness updated.
1352 // Note that this logic is localized here because we must do the liveness update in
1353 // the correct execution order. This is important because we may have two operands
1354 // that involve the same lclVar, and if one is marked "lastUse" we must handle it
1357 void CodeGen::genConsumeOperands(GenTreeOp* tree)
1359 GenTree* firstOp = tree->gtOp1;
1360 GenTree* secondOp = tree->gtOp2;
1362 if (firstOp != nullptr)
1364 genConsumeRegs(firstOp);
1366 if (secondOp != nullptr)
1368 genConsumeRegs(secondOp);
1372 #if FEATURE_PUT_STRUCT_ARG_STK
1373 //------------------------------------------------------------------------
1374 // genConsumePutStructArgStk: Do liveness update for the operands of a PutArgStk node.
1375 // Also loads in the right register the addresses of the
1376 // src/dst for rep mov operation.
1379 // putArgNode - the PUTARG_STK tree.
1380 // dstReg - the dstReg for the rep move operation.
1381 // srcReg - the srcReg for the rep move operation.
1382 // sizeReg - the sizeReg for the rep move operation.
1388 // sizeReg can be REG_NA when this function is used to consume the dstReg and srcReg
1389 // for copying on the stack a struct with references.
1390 // The source address/offset is determined from the address on the GT_OBJ node, while
1391 // the destination address is the address contained in 'm_stkArgVarNum' plus the offset
1392 // provided in the 'putArgNode'.
1393 // m_stkArgVarNum must be set to the varnum for the local used for placing the "by-value" args on the stack.
1395 void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode,
1400 // The putArgNode children are always contained. We should not consume any registers.
1401 assert(putArgNode->gtGetOp1()->isContained());
1403 // Get the source address.
1404 GenTree* src = putArgNode->gtGetOp1();
1405 assert(varTypeIsStruct(src));
1406 assert((src->gtOper == GT_OBJ) || ((src->gtOper == GT_IND && varTypeIsSIMD(src))));
1407 GenTree* srcAddr = src->gtGetOp1();
1409 size_t size = putArgNode->getArgSize();
1411 assert(dstReg != REG_NA);
1412 assert(srcReg != REG_NA);
1414 // Consume the registers only if they are not contained or set to REG_NA.
1415 if (srcAddr->gtRegNum != REG_NA)
1417 genConsumeReg(srcAddr);
1420 // If the op1 is already in the dstReg - nothing to do.
1421 // Otherwise load the op1 (GT_ADDR) into the dstReg to copy the struct on the stack by value.
1422 CLANG_FORMAT_COMMENT_ANCHOR;
1425 assert(dstReg != REG_SPBASE);
1426 inst_RV_RV(INS_mov, dstReg, REG_SPBASE);
1427 #else // !_TARGET_X86_
1428 GenTree* dstAddr = putArgNode;
1429 if (dstAddr->gtRegNum != dstReg)
1431 // Generate LEA instruction to load the stack of the outgoing var + SlotNum offset (or the incoming arg area
1432 // for tail calls) in RDI.
1433 // Destination is always local (on the stack) - use EA_PTRSIZE.
1434 assert(m_stkArgVarNum != BAD_VAR_NUM);
1435 getEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, dstReg, m_stkArgVarNum, putArgNode->getArgOffset());
1437 #endif // !_TARGET_X86_
1439 if (srcAddr->gtRegNum != srcReg)
1441 if (srcAddr->OperIsLocalAddr())
1443 // The OperLocalAddr is always contained.
1444 assert(srcAddr->isContained());
1445 GenTreeLclVarCommon* lclNode = srcAddr->AsLclVarCommon();
1447 // Generate LEA instruction to load the LclVar address in RSI.
1448 // Source is known to be on the stack. Use EA_PTRSIZE.
1449 unsigned int offset = 0;
1450 if (srcAddr->OperGet() == GT_LCL_FLD_ADDR)
1452 offset = srcAddr->AsLclFld()->gtLclOffs;
1454 getEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, srcReg, lclNode->gtLclNum, offset);
1458 assert(srcAddr->gtRegNum != REG_NA);
1459 // Source is not known to be on the stack. Use EA_BYREF.
1460 getEmitter()->emitIns_R_R(INS_mov, EA_BYREF, srcReg, srcAddr->gtRegNum);
1464 if (sizeReg != REG_NA)
1466 inst_RV_IV(INS_mov, sizeReg, size, EA_PTRSIZE);
1469 #endif // FEATURE_PUT_STRUCT_ARG_STK
1472 //------------------------------------------------------------------------
1473 // genConsumeArgRegSplit: Consume register(s) in Call node to set split struct argument.
1474 // Liveness update for the PutArgSplit node is not needed
1477 // putArgNode - the PUTARG_STK tree.
1482 void CodeGen::genConsumeArgSplitStruct(GenTreePutArgSplit* putArgNode)
1484 assert(putArgNode->OperGet() == GT_PUTARG_SPLIT);
1485 assert(putArgNode->gtHasReg());
1487 genUnspillRegIfNeeded(putArgNode);
1489 // Skip updating GC info
1490 // GC info for all argument registers will be cleared in caller
1492 genCheckConsumeNode(putArgNode);
1496 //------------------------------------------------------------------------
1497 // genSetBlockSize: Ensure that the block size is in the given register
1500 // blkNode - The block node
1501 // sizeReg - The register into which the block's size should go
1504 void CodeGen::genSetBlockSize(GenTreeBlk* blkNode, regNumber sizeReg)
1506 if (sizeReg != REG_NA)
1508 unsigned blockSize = blkNode->Size();
1511 assert((blkNode->gtRsvdRegs & genRegMask(sizeReg)) != 0);
1512 genSetRegToIcon(sizeReg, blockSize);
1516 noway_assert(blkNode->gtOper == GT_STORE_DYN_BLK);
1517 GenTree* sizeNode = blkNode->AsDynBlk()->gtDynamicSize;
1518 if (sizeNode->gtRegNum != sizeReg)
1520 inst_RV_RV(INS_mov, sizeReg, sizeNode->gtRegNum, sizeNode->TypeGet());
1526 //------------------------------------------------------------------------
1527 // genConsumeBlockSrc: Consume the source address register of a block node, if any.
1530 // blkNode - The block node
1532 void CodeGen::genConsumeBlockSrc(GenTreeBlk* blkNode)
1534 GenTree* src = blkNode->Data();
1535 if (blkNode->OperIsCopyBlkOp())
1537 // For a CopyBlk we need the address of the source.
1538 if (src->OperGet() == GT_IND)
1540 src = src->gtOp.gtOp1;
1544 // This must be a local.
1545 // For this case, there is no source address register, as it is a
1546 // stack-based address.
1547 assert(src->OperIsLocal());
1553 if (src->OperIsInitVal())
1555 src = src->gtGetOp1();
1561 //------------------------------------------------------------------------
1562 // genSetBlockSrc: Ensure that the block source is in its allocated register.
1565 // blkNode - The block node
1566 // srcReg - The register in which to set the source (address or init val).
1568 void CodeGen::genSetBlockSrc(GenTreeBlk* blkNode, regNumber srcReg)
1570 GenTree* src = blkNode->Data();
1571 if (blkNode->OperIsCopyBlkOp())
1573 // For a CopyBlk we need the address of the source.
1574 if (src->OperGet() == GT_IND)
1576 src = src->gtOp.gtOp1;
1580 // This must be a local struct.
1581 // Load its address into srcReg.
1582 inst_RV_TT(INS_lea, srcReg, src, 0, EA_BYREF);
1588 if (src->OperIsInitVal())
1590 src = src->gtGetOp1();
1593 genCopyRegIfNeeded(src, srcReg);
1596 //------------------------------------------------------------------------
1597 // genConsumeBlockOp: Ensure that the block's operands are enregistered
1600 // blkNode - The block node
1603 // This ensures that the operands are consumed in the proper order to
1604 // obey liveness modeling.
1606 void CodeGen::genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg)
1608 // We have to consume the registers, and perform any copies, in the actual execution order: dst, src, size.
1610 // Note that the register allocator ensures that the registers ON THE NODES will not interfere
1611 // with one another if consumed (i.e. reloaded or moved to their ASSIGNED reg) in execution order.
1612 // Further, it ensures that they will not interfere with one another if they are then copied
1613 // to the REQUIRED register (if a fixed register requirement) in execution order. This requires,
1614 // then, that we first consume all the operands, then do any necessary moves.
1616 GenTree* const dstAddr = blkNode->Addr();
1618 // First, consume all the sources in order.
1619 genConsumeReg(dstAddr);
1620 genConsumeBlockSrc(blkNode);
1621 if (blkNode->OperGet() == GT_STORE_DYN_BLK)
1623 genConsumeReg(blkNode->AsDynBlk()->gtDynamicSize);
1626 // Next, perform any necessary moves.
1627 genCopyRegIfNeeded(dstAddr, dstReg);
1628 genSetBlockSrc(blkNode, srcReg);
1629 genSetBlockSize(blkNode, sizeReg);
1632 //-------------------------------------------------------------------------
1633 // genProduceReg: do liveness update for register produced by the current
1637 // tree - Gentree node
1641 void CodeGen::genProduceReg(GenTree* tree)
1644 assert((tree->gtDebugFlags & GTF_DEBUG_NODE_CG_PRODUCED) == 0);
1645 tree->gtDebugFlags |= GTF_DEBUG_NODE_CG_PRODUCED;
1648 if (tree->gtFlags & GTF_SPILL)
1650 // Code for GT_COPY node gets generated as part of consuming regs by its parent.
1651 // A GT_COPY node in turn produces reg result and it should never be marked to
1654 // Similarly GT_RELOAD node gets generated as part of consuming regs by its
1655 // parent and should never be marked for spilling.
1656 noway_assert(!tree->IsCopyOrReload());
1658 if (genIsRegCandidateLocal(tree))
1660 // Store local variable to its home location.
1661 // Ensure that lclVar stores are typed correctly.
1662 unsigned varNum = tree->gtLclVarCommon.gtLclNum;
1663 assert(!compiler->lvaTable[varNum].lvNormalizeOnStore() ||
1664 (tree->TypeGet() == genActualType(compiler->lvaTable[varNum].TypeGet())));
1665 inst_TT_RV(ins_Store(tree->gtType, compiler->isSIMDTypeLocalAligned(varNum)), tree, tree->gtRegNum);
1669 // In case of multi-reg call node, spill flag on call node
1670 // indicates that one or more of its allocated regs need to
1671 // be spilled. Call node needs to be further queried to
1672 // know which of its result regs needs to be spilled.
1673 if (tree->IsMultiRegCall())
1675 GenTreeCall* call = tree->AsCall();
1676 ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
1677 unsigned regCount = retTypeDesc->GetReturnRegCount();
1679 for (unsigned i = 0; i < regCount; ++i)
1681 unsigned flags = call->GetRegSpillFlagByIdx(i);
1682 if ((flags & GTF_SPILL) != 0)
1684 regNumber reg = call->GetRegNumByIdx(i);
1685 regSet.rsSpillTree(reg, call, i);
1686 gcInfo.gcMarkRegSetNpt(genRegMask(reg));
1691 else if (tree->OperIsPutArgSplit())
1693 GenTreePutArgSplit* argSplit = tree->AsPutArgSplit();
1694 unsigned regCount = argSplit->gtNumRegs;
1696 for (unsigned i = 0; i < regCount; ++i)
1698 unsigned flags = argSplit->GetRegSpillFlagByIdx(i);
1699 if ((flags & GTF_SPILL) != 0)
1701 regNumber reg = argSplit->GetRegNumByIdx(i);
1702 regSet.rsSpillTree(reg, argSplit, i);
1703 gcInfo.gcMarkRegSetNpt(genRegMask(reg));
1707 else if (tree->OperIsMultiRegOp())
1709 GenTreeMultiRegOp* multiReg = tree->AsMultiRegOp();
1710 unsigned regCount = multiReg->GetRegCount();
1712 for (unsigned i = 0; i < regCount; ++i)
1714 unsigned flags = multiReg->GetRegSpillFlagByIdx(i);
1715 if ((flags & GTF_SPILL) != 0)
1717 regNumber reg = multiReg->GetRegNumByIdx(i);
1718 regSet.rsSpillTree(reg, multiReg, i);
1719 gcInfo.gcMarkRegSetNpt(genRegMask(reg));
1723 #endif // _TARGET_ARM_
1726 regSet.rsSpillTree(tree->gtRegNum, tree);
1727 gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
1730 tree->gtFlags |= GTF_SPILLED;
1731 tree->gtFlags &= ~GTF_SPILL;
1737 genUpdateLife(tree);
1739 // If we've produced a register, mark it as a pointer, as needed.
1740 if (tree->gtHasReg())
1742 // We only mark the register in the following cases:
1743 // 1. It is not a register candidate local. In this case, we're producing a
1744 // register from a local, but the local is not a register candidate. Thus,
1745 // we must be loading it as a temp register, and any "last use" flag on
1746 // the register wouldn't be relevant.
1747 // 2. The register candidate local is going dead. There's no point to mark
1748 // the register as live, with a GC pointer, if the variable is dead.
1749 if (!genIsRegCandidateLocal(tree) || ((tree->gtFlags & GTF_VAR_DEATH) == 0))
1751 // Multi-reg call node will produce more than one register result.
1752 // Mark all the regs produced by call node.
1753 if (tree->IsMultiRegCall())
1755 GenTreeCall* call = tree->AsCall();
1756 ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
1757 unsigned regCount = retTypeDesc->GetReturnRegCount();
1759 for (unsigned i = 0; i < regCount; ++i)
1761 regNumber reg = call->GetRegNumByIdx(i);
1762 var_types type = retTypeDesc->GetReturnRegType(i);
1763 gcInfo.gcMarkRegPtrVal(reg, type);
1766 else if (tree->IsCopyOrReloadOfMultiRegCall())
1768 // we should never see reload of multi-reg call here
1769 // because GT_RELOAD gets generated in reg consuming path.
1770 noway_assert(tree->OperGet() == GT_COPY);
1772 // A multi-reg GT_COPY node produces those regs to which
1773 // copy has taken place.
1774 GenTreeCopyOrReload* copy = tree->AsCopyOrReload();
1775 GenTreeCall* call = copy->gtGetOp1()->AsCall();
1776 ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
1777 unsigned regCount = retTypeDesc->GetReturnRegCount();
1779 for (unsigned i = 0; i < regCount; ++i)
1781 var_types type = retTypeDesc->GetReturnRegType(i);
1782 regNumber fromReg = call->GetRegNumByIdx(i);
1783 regNumber toReg = copy->GetRegNumByIdx(i);
1785 if (toReg != REG_NA)
1787 gcInfo.gcMarkRegPtrVal(toReg, type);
1793 gcInfo.gcMarkRegPtrVal(tree->gtRegNum, tree->TypeGet());
1799 // transfer gc/byref status of src reg to dst reg
1800 void CodeGen::genTransferRegGCState(regNumber dst, regNumber src)
1802 regMaskTP srcMask = genRegMask(src);
1803 regMaskTP dstMask = genRegMask(dst);
1805 if (gcInfo.gcRegGCrefSetCur & srcMask)
1807 gcInfo.gcMarkRegSetGCref(dstMask);
1809 else if (gcInfo.gcRegByrefSetCur & srcMask)
1811 gcInfo.gcMarkRegSetByref(dstMask);
1815 gcInfo.gcMarkRegSetNpt(dstMask);
1819 // generates an ip-relative call or indirect call via reg ('call reg')
1820 // pass in 'addr' for a relative call or 'base' for a indirect register call
1821 // methHnd - optional, only used for pretty printing
1822 // retSize - emitter type of return for GC purposes, should be EA_BYREF, EA_GCREF, or EA_PTRSIZE(not GC)
1825 void CodeGen::genEmitCall(int callType,
1826 CORINFO_METHOD_HANDLE methHnd,
1827 INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
1829 X86_ARG(ssize_t argSize),
1831 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
1832 IL_OFFSETX ilOffset,
1837 #if !defined(_TARGET_X86_)
1838 ssize_t argSize = 0;
1839 #endif // !defined(_TARGET_X86_)
1840 getEmitter()->emitIns_Call(emitter::EmitCallType(callType),
1842 INDEBUG_LDISASM_COMMA(sigInfo)
1846 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
1847 gcInfo.gcVarPtrSetCur,
1848 gcInfo.gcRegGCrefSetCur,
1849 gcInfo.gcRegByrefSetCur,
1850 ilOffset, base, REG_NA, 0, 0, isJump,
1851 emitter::emitNoGChelper(compiler->eeGetHelperNum(methHnd)));
1855 // generates an indirect call via addressing mode (call []) given an indir node
1856 // methHnd - optional, only used for pretty printing
1857 // retSize - emitter type of return for GC purposes, should be EA_BYREF, EA_GCREF, or EA_PTRSIZE(not GC)
1860 void CodeGen::genEmitCall(int callType,
1861 CORINFO_METHOD_HANDLE methHnd,
1862 INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
1864 X86_ARG(ssize_t argSize),
1866 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
1867 IL_OFFSETX ilOffset)
1869 #if !defined(_TARGET_X86_)
1870 ssize_t argSize = 0;
1871 #endif // !defined(_TARGET_X86_)
1872 genConsumeAddress(indir->Addr());
1874 getEmitter()->emitIns_Call(emitter::EmitCallType(callType),
1876 INDEBUG_LDISASM_COMMA(sigInfo)
1880 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
1881 gcInfo.gcVarPtrSetCur,
1882 gcInfo.gcRegGCrefSetCur,
1883 gcInfo.gcRegByrefSetCur,
1885 (indir->Base() != nullptr) ? indir->Base()->gtRegNum : REG_NA,
1886 (indir->Index() != nullptr) ? indir->Index()->gtRegNum : REG_NA,
1892 //------------------------------------------------------------------------
1893 // genCodeForCast: Generates the code for GT_CAST.
1896 // tree - the GT_CAST node.
1898 void CodeGen::genCodeForCast(GenTreeOp* tree)
1900 assert(tree->OperIs(GT_CAST));
1902 var_types targetType = tree->TypeGet();
1904 if (varTypeIsFloating(targetType) && varTypeIsFloating(tree->gtOp1))
1906 // Casts float/double <--> double/float
1907 genFloatToFloatCast(tree);
1909 else if (varTypeIsFloating(tree->gtOp1))
1911 // Casts float/double --> int32/int64
1912 genFloatToIntCast(tree);
1914 else if (varTypeIsFloating(targetType))
1916 // Casts int32/uint32/int64/uint64 --> float/double
1917 genIntToFloatCast(tree);
1919 #ifndef _TARGET_64BIT_
1920 else if (varTypeIsLong(tree->gtOp1))
1922 genLongToIntCast(tree);
1924 #endif // !_TARGET_64BIT_
1927 // Casts int <--> int
1928 genIntToIntCast(tree);
1930 // The per-case functions call genProduceReg()
1933 #endif // !LEGACY_BACKEND