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
10 XX Represents the register set, and their states during code generation XX
11 XX Can select an unused register, keeps track of the contents of the XX
12 XX registers, and can spill registers XX
14 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
25 /*****************************************************************************/
28 const regMaskSmall regMasks[] = {
29 #define REGDEF(name, rnum, mask, xname, wname) mask,
32 #else // !_TARGET_ARM64_
33 const regMaskSmall regMasks[] = {
34 #define REGDEF(name, rnum, mask, sname) mask,
40 const regMaskSmall regFPMasks[] = {
41 #define REGDEF(name, rnum, mask, sname) mask,
42 #include "registerfp.h"
44 #endif // _TARGET_X86_
47 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
48 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
51 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
52 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
55 void RegSet::rsClearRegsModified()
57 #ifndef LEGACY_BACKEND
58 assert(m_rsCompiler->lvaDoneFrameLayout < Compiler::FINAL_FRAME_LAYOUT);
59 #endif // !LEGACY_BACKEND
62 if (m_rsCompiler->verbose)
64 printf("Clearing modified regs.\n");
66 rsModifiedRegsMaskInitialized = true;
69 rsModifiedRegsMask = RBM_NONE;
72 void RegSet::rsSetRegsModified(regMaskTP mask DEBUGARG(bool suppressDump))
74 assert(mask != RBM_NONE);
75 assert(rsModifiedRegsMaskInitialized);
77 #ifndef LEGACY_BACKEND
78 // We can't update the modified registers set after final frame layout (that is, during code
79 // generation and after). Ignore prolog and epilog generation: they call register tracking to
80 // modify rbp, for example, even in functions that use rbp as a frame pointer. Make sure normal
81 // code generation isn't actually adding to set of modified registers.
82 // Frame layout is only affected by callee-saved registers, so only ensure that callee-saved
83 // registers aren't modified after final frame layout.
84 assert((m_rsCompiler->lvaDoneFrameLayout < Compiler::FINAL_FRAME_LAYOUT) || m_rsCompiler->compGeneratingProlog ||
85 m_rsCompiler->compGeneratingEpilog ||
86 (((rsModifiedRegsMask | mask) & RBM_CALLEE_SAVED) == (rsModifiedRegsMask & RBM_CALLEE_SAVED)));
87 #endif // !LEGACY_BACKEND
90 if (m_rsCompiler->verbose && !suppressDump)
92 if (rsModifiedRegsMask != (rsModifiedRegsMask | mask))
94 printf("Marking regs modified: ");
97 dspRegMask(rsModifiedRegsMask);
99 dspRegMask(rsModifiedRegsMask | mask);
105 rsModifiedRegsMask |= mask;
108 void RegSet::rsRemoveRegsModified(regMaskTP mask)
110 assert(mask != RBM_NONE);
111 assert(rsModifiedRegsMaskInitialized);
113 #ifndef LEGACY_BACKEND
114 // See comment in rsSetRegsModified().
115 assert((m_rsCompiler->lvaDoneFrameLayout < Compiler::FINAL_FRAME_LAYOUT) || m_rsCompiler->compGeneratingProlog ||
116 m_rsCompiler->compGeneratingEpilog ||
117 (((rsModifiedRegsMask & ~mask) & RBM_CALLEE_SAVED) == (rsModifiedRegsMask & RBM_CALLEE_SAVED)));
118 #endif // !LEGACY_BACKEND
121 if (m_rsCompiler->verbose)
123 printf("Removing modified regs: ");
125 if (rsModifiedRegsMask == (rsModifiedRegsMask & ~mask))
127 printf(" (unchanged)");
132 dspRegMask(rsModifiedRegsMask);
134 dspRegMask(rsModifiedRegsMask & ~mask);
141 rsModifiedRegsMask &= ~mask;
144 void RegSet::SetMaskVars(regMaskTP newMaskVars)
147 if (m_rsCompiler->verbose)
149 printf("\t\t\t\t\t\t\tLive regs: ");
150 if (_rsMaskVars == newMaskVars)
152 printf("(unchanged) ");
156 printRegMaskInt(_rsMaskVars);
157 m_rsCompiler->getEmitter()->emitDispRegSet(_rsMaskVars);
160 printRegMaskInt(newMaskVars);
161 m_rsCompiler->getEmitter()->emitDispRegSet(newMaskVars);
166 _rsMaskVars = newMaskVars;
171 RegSet::rsStressRegsType RegSet::rsStressRegs()
173 #ifndef LEGACY_BACKEND
174 return RS_STRESS_NONE;
175 #else // LEGACY_BACKEND
176 rsStressRegsType val = (rsStressRegsType)JitConfig.JitStressRegs();
177 if (val == RS_STRESS_NONE && m_rsCompiler->compStressCompile(Compiler::STRESS_REGS, 15))
178 val = RS_PICK_BAD_REG;
180 #endif // LEGACY_BACKEND
184 #ifdef LEGACY_BACKEND
185 /*****************************************************************************
186 * Includes 'includeHint' if 'regs' is empty
189 regMaskTP RegSet::rsUseIfZero(regMaskTP regs, regMaskTP includeHint)
191 return regs ? regs : includeHint;
194 /*****************************************************************************
195 * Excludes 'excludeHint' if it results in a non-empty mask
198 regMaskTP RegSet::rsExcludeHint(regMaskTP regs, regMaskTP excludeHint)
200 regMaskTP OKmask = regs & ~excludeHint;
201 return OKmask ? OKmask : regs;
204 /*****************************************************************************
205 * Narrows choice by 'narrowHint' if it results in a non-empty mask
208 regMaskTP RegSet::rsNarrowHint(regMaskTP regs, regMaskTP narrowHint)
210 regMaskTP narrowed = regs & narrowHint;
211 return narrowed ? narrowed : regs;
214 /*****************************************************************************
215 * Excludes 'exclude' from regs if non-zero, or from RBM_ALLINT
218 regMaskTP RegSet::rsMustExclude(regMaskTP regs, regMaskTP exclude)
220 // Try to exclude from current set
221 regMaskTP OKmask = regs & ~exclude;
223 // If current set wont work, exclude from RBM_ALLINT
224 if (OKmask == RBM_NONE)
225 OKmask = (RBM_ALLINT & ~exclude);
232 /*****************************************************************************
234 * The following returns a mask that yields all free registers.
238 regMaskTP RegSet::rsRegMaskFree()
240 /* Any register that is locked must also be marked as 'used' */
242 assert((rsMaskUsed & rsMaskLock) == rsMaskLock);
244 /* Any register that isn't used and doesn't hold a variable is free */
246 return RBM_ALLINT & ~(rsMaskUsed | rsMaskVars | rsMaskResvd);
249 /*****************************************************************************
251 * The following returns a mask of registers that may be grabbed.
255 regMaskTP RegSet::rsRegMaskCanGrab()
257 /* Any register that is locked must also be marked as 'used' */
259 assert((rsMaskUsed & rsMaskLock) == rsMaskLock);
261 /* Any register that isn't locked and doesn't hold a var can be grabbed */
263 regMaskTP result = (RBM_ALLINT & ~(rsMaskLock | rsMaskVars));
267 // On the ARM when we pass structs in registers we set the rsUsedTree[]
268 // to be the full TYP_STRUCT tree, which doesn't allow us to spill/unspill
269 // these argument registers. To fix JitStress issues that can occur
270 // when rsPickReg tries to spill one of these registers we just remove them
271 // from the set of registers that we can grab
273 regMaskTP structArgMask = RBM_NONE;
274 // Load all the variable arguments in registers back to their registers.
275 for (regNumber reg = REG_ARG_FIRST; reg <= REG_ARG_LAST; reg = REG_NEXT(reg))
277 GenTree* regHolds = rsUsedTree[reg];
278 if ((regHolds != NULL) && (regHolds->TypeGet() == TYP_STRUCT))
280 structArgMask |= genRegMask(reg);
283 result &= ~structArgMask;
289 /*****************************************************************************
291 * Pick a free register. It is guaranteed that a register is available.
292 * Note that rsPickReg() can spill a register, whereas rsPickFreeReg() will not.
296 regNumber RegSet::rsPickFreeReg(regMaskTP regMaskHint)
298 regMaskTP freeRegs = rsRegMaskFree();
299 assert(freeRegs != RBM_NONE);
301 regMaskTP regs = rsNarrowHint(freeRegs, regMaskHint);
303 return rsGrabReg(regs);
306 /*****************************************************************************
308 * Mark the given set of registers as used and locked.
312 void RegSet::rsLockReg(regMaskTP regMask)
314 /* Must not be already marked as either used or locked */
316 assert((rsMaskUsed & regMask) == 0);
317 rsMaskUsed |= regMask;
318 assert((rsMaskLock & regMask) == 0);
319 rsMaskLock |= regMask;
322 /*****************************************************************************
324 * Mark an already used set of registers as locked.
328 void RegSet::rsLockUsedReg(regMaskTP regMask)
330 /* Must not be already marked as locked. Must be already marked as used. */
332 assert((rsMaskLock & regMask) == 0);
333 assert((rsMaskUsed & regMask) == regMask);
335 rsMaskLock |= regMask;
338 /*****************************************************************************
340 * Mark the given set of registers as no longer used/locked.
344 void RegSet::rsUnlockReg(regMaskTP regMask)
346 /* Must be currently marked as both used and locked */
348 assert((rsMaskUsed & regMask) == regMask);
349 rsMaskUsed -= regMask;
350 assert((rsMaskLock & regMask) == regMask);
351 rsMaskLock -= regMask;
354 /*****************************************************************************
356 * Mark the given set of registers as no longer locked.
360 void RegSet::rsUnlockUsedReg(regMaskTP regMask)
362 /* Must be currently marked as both used and locked */
364 assert((rsMaskUsed & regMask) == regMask);
365 assert((rsMaskLock & regMask) == regMask);
366 rsMaskLock -= regMask;
369 /*****************************************************************************
371 * Mark the given set of registers as used and locked. It may already have
372 * been marked as used.
376 void RegSet::rsLockReg(regMaskTP regMask, regMaskTP* usedMask)
378 /* Is it already marked as used? */
380 regMaskTP used = (rsMaskUsed & regMask);
381 regMaskTP unused = (regMask & ~used);
392 /*****************************************************************************
394 * Mark the given set of registers as no longer
398 void RegSet::rsUnlockReg(regMaskTP regMask, regMaskTP usedMask)
400 regMaskTP unused = (regMask & ~usedMask);
403 rsUnlockUsedReg(usedMask);
408 #endif // LEGACY_BACKEND
410 #ifdef LEGACY_BACKEND
411 /*****************************************************************************
413 * Assume all registers contain garbage (called at start of codegen and when
414 * we encounter a code label).
418 void RegTracker::rsTrackRegClr()
420 assert(RV_TRASH == 0);
421 memset(rsRegValues, 0, sizeof(rsRegValues));
423 #endif // LEGACY_BACKEND
425 /*****************************************************************************
427 * Trash the rsRegValues associated with a register
431 void RegTracker::rsTrackRegTrash(regNumber reg)
433 /* Keep track of which registers we ever touch */
435 regSet->rsSetRegsModified(genRegMask(reg));
437 #ifdef LEGACY_BACKEND
438 /* Record the new value for the register */
440 rsRegValues[reg].rvdKind = RV_TRASH;
441 #endif // LEGACY_BACKEND
444 #ifdef LEGACY_BACKEND
445 /*****************************************************************************
447 * calls rsTrackRegTrash on the set of registers in regmask
451 void RegTracker::rsTrackRegMaskTrash(regMaskTP regMask)
453 regMaskTP regBit = 1;
455 for (regNumber regNum = REG_FIRST; regNum < REG_COUNT; regNum = REG_NEXT(regNum), regBit <<= 1)
457 if (regBit > regMask)
462 if (regBit & regMask)
464 rsTrackRegTrash(regNum);
468 #endif // LEGACY_BACKEND
470 /*****************************************************************************/
473 void RegTracker::rsTrackRegIntCns(regNumber reg, ssize_t val)
475 assert(genIsValidIntReg(reg));
477 /* Keep track of which registers we ever touch */
479 regSet->rsSetRegsModified(genRegMask(reg));
481 #ifdef LEGACY_BACKEND
482 /* Record the new value for the register */
484 rsRegValues[reg].rvdKind = RV_INT_CNS;
485 rsRegValues[reg].rvdIntCnsVal = val;
489 #ifdef LEGACY_BACKEND
490 /*****************************************************************************/
493 void RegTracker::rsTrackRegLclVarLng(regNumber reg, unsigned var, bool low)
495 assert(genIsValidIntReg(reg));
497 if (compiler->lvaTable[var].lvAddrExposed)
502 /* Keep track of which registers we ever touch */
504 regSet->rsSetRegsModified(genRegMask(reg));
506 /* Record the new value for the register */
508 rsRegValues[reg].rvdKind = (low ? RV_LCL_VAR_LNG_LO : RV_LCL_VAR_LNG_HI);
509 rsRegValues[reg].rvdLclVarNum = var;
512 /*****************************************************************************/
515 bool RegTracker::rsTrackIsLclVarLng(regValKind rvKind)
517 if (compiler->opts.MinOpts() || compiler->opts.compDbgCode)
522 if (rvKind == RV_LCL_VAR_LNG_LO || rvKind == RV_LCL_VAR_LNG_HI)
532 /*****************************************************************************/
535 void RegTracker::rsTrackRegClsVar(regNumber reg, GenTree* clsVar)
537 rsTrackRegTrash(reg);
540 /*****************************************************************************/
543 void RegTracker::rsTrackRegAssign(GenTree* op1, GenTree* op2)
545 /* Constant/bitvalue has precedence over local */
546 switch (rsRegValues[op2->gtRegNum].rvdKind)
553 /* Mark RHS register as containing the value */
558 rsTrackRegLclVar(op2->gtRegNum, op1->gtLclVarCommon.gtLclNum);
561 rsTrackRegClsVar(op2->gtRegNum, op1);
569 /*****************************************************************************
571 * Given a regmask, find the best regPairNo that can be formed
572 * or return REG_PAIR_NONE if no register pair can be formed
575 regPairNo RegSet::rsFindRegPairNo(regMaskTP regAllowedMask)
579 // Remove any special purpose registers such as SP, EBP, etc...
580 regMaskTP specialUseMask = (rsMaskResvd | RBM_SPBASE);
582 specialUseMask |= RBM_FPBASE;
584 if (m_rsCompiler->codeGen->isFramePointerUsed())
585 specialUseMask |= RBM_FPBASE;
588 regAllowedMask &= ~specialUseMask;
590 /* Check if regAllowedMask has zero or one bits set */
591 if ((regAllowedMask & (regAllowedMask - 1)) == 0)
593 /* If so we won't be able to find a reg pair */
594 return REG_PAIR_NONE;
598 if (regAllowedMask & RBM_EAX)
600 /* EAX is available, see if we can pair it with another reg */
602 if (regAllowedMask & RBM_EDX)
604 regPair = REG_PAIR_EAXEDX;
607 if (regAllowedMask & RBM_ECX)
609 regPair = REG_PAIR_EAXECX;
612 if (regAllowedMask & RBM_EBX)
614 regPair = REG_PAIR_EAXEBX;
617 if (regAllowedMask & RBM_ESI)
619 regPair = REG_PAIR_EAXESI;
622 if (regAllowedMask & RBM_EDI)
624 regPair = REG_PAIR_EAXEDI;
627 if (regAllowedMask & RBM_EBP)
629 regPair = REG_PAIR_EAXEBP;
634 if (regAllowedMask & RBM_ECX)
636 /* ECX is available, see if we can pair it with another reg */
638 if (regAllowedMask & RBM_EDX)
640 regPair = REG_PAIR_ECXEDX;
643 if (regAllowedMask & RBM_EBX)
645 regPair = REG_PAIR_ECXEBX;
648 if (regAllowedMask & RBM_ESI)
650 regPair = REG_PAIR_ECXESI;
653 if (regAllowedMask & RBM_EDI)
655 regPair = REG_PAIR_ECXEDI;
658 if (regAllowedMask & RBM_EBP)
660 regPair = REG_PAIR_ECXEBP;
665 if (regAllowedMask & RBM_EDX)
667 /* EDX is available, see if we can pair it with another reg */
669 if (regAllowedMask & RBM_EBX)
671 regPair = REG_PAIR_EDXEBX;
674 if (regAllowedMask & RBM_ESI)
676 regPair = REG_PAIR_EDXESI;
679 if (regAllowedMask & RBM_EDI)
681 regPair = REG_PAIR_EDXEDI;
684 if (regAllowedMask & RBM_EBP)
686 regPair = REG_PAIR_EDXEBP;
691 if (regAllowedMask & RBM_EBX)
693 /* EBX is available, see if we can pair it with another reg */
695 if (regAllowedMask & RBM_ESI)
697 regPair = REG_PAIR_EBXESI;
700 if (regAllowedMask & RBM_EDI)
702 regPair = REG_PAIR_EBXEDI;
705 if (regAllowedMask & RBM_EBP)
707 regPair = REG_PAIR_EBXEBP;
712 if (regAllowedMask & RBM_ESI)
714 /* ESI is available, see if we can pair it with another reg */
716 if (regAllowedMask & RBM_EDI)
718 regPair = REG_PAIR_ESIEDI;
721 if (regAllowedMask & RBM_EBP)
723 regPair = REG_PAIR_EBPESI;
728 if (regAllowedMask & RBM_EDI)
730 /* EDI is available, see if we can pair it with another reg */
732 if (regAllowedMask & RBM_EBP)
734 regPair = REG_PAIR_EBPEDI;
741 // ARM is symmetric, so don't bother to prefer some pairs to others
743 // Iterate the registers in the order specified by rpRegTmpOrder/raRegTmpOrder
745 for (unsigned index1 = 0; index1 < REG_TMP_ORDER_COUNT; index1++)
748 if (m_rsCompiler->rpRegAllocDone)
749 reg1 = raRegTmpOrder[index1];
751 reg1 = rpRegTmpOrder[index1];
753 regMaskTP reg1Mask = genRegMask(reg1);
755 if ((regAllowedMask & reg1Mask) == 0)
758 for (unsigned index2 = index1 + 1; index2 < REG_TMP_ORDER_COUNT; index2++)
761 if (m_rsCompiler->rpRegAllocDone)
762 reg2 = raRegTmpOrder[index2];
764 reg2 = rpRegTmpOrder[index2];
766 regMaskTP reg2Mask = genRegMask(reg2);
768 if ((regAllowedMask & reg2Mask) == 0)
771 regMaskTP pairMask = genRegMask(reg1) | genRegMask(reg2);
773 // if reg1 is larger than reg2 then swap the registers
776 regNumber regT = reg1;
781 regPair = gen2regs2pair(reg1, reg2);
787 assert(!"Unreachable code");
788 regPair = REG_PAIR_NONE;
797 #endif // LEGACY_BACKEND
799 /*****************************************************************************/
801 RegSet::RegSet(Compiler* compiler, GCInfo& gcInfo) : m_rsCompiler(compiler), m_rsGCInfo(gcInfo)
803 /* Initialize the spill logic */
807 /* Initialize the argument register count */
808 // TODO-Cleanup: Consider moving intRegState and floatRegState to RegSet. They used
809 // to be initialized here, but are now initialized in the CodeGen constructor.
810 // intRegState.rsCurRegArgNum = 0;
811 // loatRegState.rsCurRegArgNum = 0;
813 rsMaskResvd = RBM_NONE;
815 #ifdef LEGACY_BACKEND
816 rsMaskMult = RBM_NONE;
817 rsMaskUsed = RBM_NONE;
818 rsMaskLock = RBM_NONE;
819 #endif // LEGACY_BACKEND
821 #ifdef _TARGET_ARMARCH_
822 rsMaskCalleeSaved = RBM_NONE;
823 #endif // _TARGET_ARMARCH_
826 rsMaskPreSpillRegArg = RBM_NONE;
827 rsMaskPreSpillAlign = RBM_NONE;
831 rsModifiedRegsMaskInitialized = false;
835 #ifdef LEGACY_BACKEND
836 /*****************************************************************************
838 * Marks the register that holds the given operand value as 'used'. If 'addr'
839 * is non-zero, the register is part of a complex address mode that needs to
840 * be marked if the register is ever spilled.
843 void RegSet::rsMarkRegUsed(GenTree* tree, GenTree* addr)
849 /* The value must be sitting in a register */
852 assert(tree->InReg());
854 type = tree->TypeGet();
855 regNum = tree->gtRegNum;
857 if (isFloatRegType(type))
858 regMask = genRegMaskFloat(regNum, type);
860 regMask = genRegMask(regNum);
863 if (m_rsCompiler->verbose)
865 printf("\t\t\t\t\t\t\tThe register %s currently holds ", m_rsCompiler->compRegVarName(regNum));
866 Compiler::printTreeID(tree);
870 Compiler::printTreeID(addr);
872 else if (tree->gtOper == GT_CNS_INT)
874 if (tree->IsIconHandle())
875 printf(" / Handle(0x%08p)", dspPtr(tree->gtIntCon.gtIconVal));
877 printf(" / Constant(0x%X)", tree->gtIntCon.gtIconVal);
883 /* Remember whether the register holds a pointer */
885 m_rsGCInfo.gcMarkRegPtrVal(regNum, type);
887 /* No locked register may ever be marked as free */
889 assert((rsMaskLock & rsRegMaskFree()) == 0);
891 /* Is the register used by two different values simultaneously? */
893 if (regMask & rsMaskUsed)
895 /* Save the preceding use information */
897 rsRecMultiReg(regNum, type);
900 /* Set the register's bit in the 'used' bitset */
902 rsMaskUsed |= regMask;
904 /* Remember what values are in what registers, in case we have to spill */
905 assert(regNum != REG_SPBASE);
906 assert(rsUsedTree[regNum] == NULL);
907 rsUsedTree[regNum] = tree;
908 assert(rsUsedAddr[regNum] == NULL);
909 rsUsedAddr[regNum] = addr;
912 void RegSet::rsMarkArgRegUsedByPromotedFieldArg(GenTree* promotedStructArg, regNumber regNum, bool isGCRef)
916 /* The value must be sitting in a register */
918 assert(promotedStructArg);
919 assert(promotedStructArg->TypeGet() == TYP_STRUCT);
921 assert(regNum < MAX_REG_ARG);
922 regMask = genRegMask(regNum);
923 assert((regMask & RBM_ARG_REGS) != RBM_NONE);
926 if (m_rsCompiler->verbose)
928 printf("\t\t\t\t\t\t\tThe register %s currently holds ", m_rsCompiler->compRegVarName(regNum));
929 Compiler::printTreeID(promotedStructArg);
930 if (promotedStructArg->gtOper == GT_CNS_INT)
932 if (promotedStructArg->IsIconHandle())
933 printf(" / Handle(0x%08p)", dspPtr(promotedStructArg->gtIntCon.gtIconVal));
935 printf(" / Constant(0x%X)", promotedStructArg->gtIntCon.gtIconVal);
941 /* Remember whether the register holds a pointer */
943 m_rsGCInfo.gcMarkRegPtrVal(regNum, (isGCRef ? TYP_REF : TYP_INT));
945 /* No locked register may ever be marked as free */
947 assert((rsMaskLock & rsRegMaskFree()) == 0);
949 /* Is the register used by two different values simultaneously? */
951 if (regMask & rsMaskUsed)
953 /* Save the preceding use information */
955 assert(isValidIntArgReg(regNum)); // We are expecting only integer argument registers here
956 rsRecMultiReg(regNum, TYP_I_IMPL);
959 /* Set the register's bit in the 'used' bitset */
961 rsMaskUsed |= regMask;
963 /* Remember what values are in what registers, in case we have to spill */
964 assert(regNum != REG_SPBASE);
965 assert(rsUsedTree[regNum] == 0);
966 rsUsedTree[regNum] = promotedStructArg;
969 /*****************************************************************************
971 * Marks the register pair that holds the given operand value as 'used'.
974 void RegSet::rsMarkRegPairUsed(GenTree* tree)
981 /* The value must be sitting in a register */
984 #if CPU_HAS_FP_SUPPORT
985 assert(tree->gtType == TYP_LONG);
987 assert(tree->gtType == TYP_LONG || tree->gtType == TYP_DOUBLE);
989 assert(tree->InReg());
991 regPair = tree->gtRegPair;
992 regMask = genRegPairMask(regPair);
994 regLo = genRegPairLo(regPair);
995 regHi = genRegPairHi(regPair);
998 if (m_rsCompiler->verbose)
1000 printf("\t\t\t\t\t\t\tThe register %s currently holds ", m_rsCompiler->compRegVarName(regLo));
1001 Compiler::printTreeID(tree);
1003 printf("\t\t\t\t\t\t\tThe register %s currently holds ", m_rsCompiler->compRegVarName(regHi));
1004 Compiler::printTreeID(tree);
1009 /* Neither register obviously holds a pointer value */
1011 m_rsGCInfo.gcMarkRegSetNpt(regMask);
1013 /* No locked register may ever be marked as free */
1015 assert((rsMaskLock & rsRegMaskFree()) == 0);
1017 /* Are the registers used by two different values simultaneously? */
1019 if (rsMaskUsed & genRegMask(regLo))
1021 /* Save the preceding use information */
1023 rsRecMultiReg(regLo, TYP_INT);
1026 if (rsMaskUsed & genRegMask(regHi))
1028 /* Save the preceding use information */
1030 rsRecMultiReg(regHi, TYP_INT);
1033 /* Can't mark a register pair more than once as used */
1035 // assert((regMask & rsMaskUsed) == 0);
1037 /* Mark the registers as 'used' */
1039 rsMaskUsed |= regMask;
1041 /* Remember what values are in what registers, in case we have to spill */
1043 if (regLo != REG_STK)
1045 assert(rsUsedTree[regLo] == 0);
1046 assert(regLo != REG_SPBASE);
1047 rsUsedTree[regLo] = tree;
1050 if (regHi != REG_STK)
1052 assert(rsUsedTree[regHi] == 0);
1053 assert(regHi != REG_SPBASE);
1054 rsUsedTree[regHi] = tree;
1058 /*****************************************************************************
1060 * Returns true if the given tree is currently held in reg.
1061 * Note that reg may by used by multiple trees, in which case we have
1062 * to search rsMultiDesc[reg].
1065 bool RegSet::rsIsTreeInReg(regNumber reg, GenTree* tree)
1067 /* First do the trivial check */
1069 if (rsUsedTree[reg] == tree)
1072 /* If the register is used by multiple trees, we have to search the list
1073 in rsMultiDesc[reg] */
1075 if (genRegMask(reg) & rsMaskMult)
1077 SpillDsc* multiDesc = rsMultiDesc[reg];
1080 for (/**/; multiDesc; multiDesc = multiDesc->spillNext)
1082 if (multiDesc->spillTree == tree)
1085 assert((!multiDesc->spillNext) == (!multiDesc->spillMoreMultis));
1089 /* Not found. It must be spilled */
1093 #endif // LEGACY_BACKEND
1095 /*****************************************************************************
1097 * Finds the SpillDsc corresponding to 'tree' assuming it was spilled from 'reg'.
1100 RegSet::SpillDsc* RegSet::rsGetSpillInfo(GenTree* tree,
1103 #ifdef LEGACY_BACKEND
1105 SpillDsc** pMultiDsc
1106 #endif // LEGACY_BACKEND
1109 /* Normally, trees are unspilled in the order of being spilled due to
1110 the post-order walking of trees during code-gen. However, this will
1111 not be true for something like a GT_ARR_ELEM node */
1112 CLANG_FORMAT_COMMENT_ANCHOR;
1114 #ifdef LEGACY_BACKEND
1115 SpillDsc* multi = rsSpillDesc[reg];
1116 #endif // LEGACY_BACKEND
1120 for (prev = nullptr, dsc = rsSpillDesc[reg]; dsc != nullptr; prev = dsc, dsc = dsc->spillNext)
1122 #ifdef LEGACY_BACKEND
1123 if (prev && !prev->spillMoreMultis)
1125 #endif // LEGACY_BACKEND
1127 if (dsc->spillTree == tree)
1137 #ifdef LEGACY_BACKEND
1140 #endif // LEGACY_BACKEND
1145 #ifdef LEGACY_BACKEND
1146 /*****************************************************************************
1148 * Mark the register set given by the register mask as not used.
1151 void RegSet::rsMarkRegFree(regMaskTP regMask)
1153 /* Are we freeing any multi-use registers? */
1155 if (regMask & rsMaskMult)
1157 rsMultRegFree(regMask);
1161 m_rsGCInfo.gcMarkRegSetNpt(regMask);
1163 regMaskTP regBit = 1;
1165 for (regNumber regNum = REG_FIRST; regNum < REG_COUNT; regNum = REG_NEXT(regNum), regBit <<= 1)
1167 if (regBit > regMask)
1170 if (regBit & regMask)
1173 if (m_rsCompiler->verbose)
1175 printf("\t\t\t\t\t\t\tThe register %s no longer holds ", m_rsCompiler->compRegVarName(regNum));
1176 Compiler::printTreeID(rsUsedTree[regNum]);
1177 if (rsUsedAddr[regNum] != nullptr)
1179 Compiler::printTreeID(rsUsedAddr[regNum]);
1185 GenTree* usedTree = rsUsedTree[regNum];
1186 assert(usedTree != NULL);
1187 rsUsedTree[regNum] = NULL;
1188 rsUsedAddr[regNum] = NULL;
1190 if (usedTree->TypeGet() == TYP_DOUBLE)
1192 regNum = REG_NEXT(regNum);
1195 assert(regBit & regMask);
1196 assert(rsUsedTree[regNum] == NULL);
1197 assert(rsUsedAddr[regNum] == NULL);
1203 /* Remove the register set from the 'used' set */
1205 assert((regMask & rsMaskUsed) == regMask);
1206 rsMaskUsed -= regMask;
1208 /* No locked register may ever be marked as free */
1210 assert((rsMaskLock & rsRegMaskFree()) == 0);
1213 /*****************************************************************************
1215 * Free the register from the given tree. If the register holds other tree,
1216 * it will still be marked as used, else it will be completely free.
1219 void RegSet::rsMarkRegFree(regNumber reg, GenTree* tree)
1221 assert(rsIsTreeInReg(reg, tree));
1222 regMaskTP regMask = genRegMask(reg);
1224 /* If the register is not multi-used, it's easy. Just do the default work */
1226 if (!(regMask & rsMaskMult))
1228 rsMarkRegFree(regMask);
1232 /* The tree is multi-used. We just have to free it off the given tree but
1233 leave other trees which use the register as they are. The register may
1234 not be multi-used after freeing it from the given tree */
1236 /* Is the tree in rsUsedTree[] or in rsMultiDesc[]?
1237 If it is in rsUsedTree[], update rsUsedTree[] */
1239 if (rsUsedTree[reg] == tree)
1245 /* The tree is in rsMultiDesc[] instead of in rsUsedTree[]. Find the desc
1246 corresponding to the tree and just remove it from there */
1248 for (SpillDsc *multiDesc = rsMultiDesc[reg], *prevDesc = NULL; multiDesc;
1249 prevDesc = multiDesc, multiDesc = multiDesc->spillNext)
1251 /* If we find the descriptor with the tree we are looking for,
1254 if (multiDesc->spillTree != tree)
1257 if (prevDesc == NULL)
1259 /* The very first desc in rsMultiDesc[] matched. If there are
1260 no further descs, then the register is no longer multi-used */
1262 if (!multiDesc->spillMoreMultis)
1263 rsMaskMult -= regMask;
1265 rsMultiDesc[reg] = multiDesc->spillNext;
1269 /* There are a couple of other descs before the match. So the
1270 register is still multi-used. However, we may have to
1271 update spillMoreMultis for the previous desc. */
1273 if (!multiDesc->spillMoreMultis)
1274 prevDesc->spillMoreMultis = false;
1276 prevDesc->spillNext = multiDesc->spillNext;
1279 SpillDsc::freeDsc(this, multiDesc);
1282 if (m_rsCompiler->verbose)
1284 printf("\t\t\t\t\t\t\tRegister %s multi-use dec for ", m_rsCompiler->compRegVarName(reg));
1285 Compiler::printTreeID(tree);
1287 Compiler::printTreeID(rsUsedTree[reg]);
1288 printf(" multMask=" REG_MASK_ALL_FMT "\n", rsMaskMult);
1295 assert(!"Didn't find the spilled tree in rsMultiDesc[]");
1298 /*****************************************************************************
1300 * Mark the register set given by the register mask as not used; there may
1301 * be some 'multiple-use' registers in the set.
1304 void RegSet::rsMultRegFree(regMaskTP regMask)
1306 /* Free any multiple-use registers first */
1307 regMaskTP nonMultMask = regMask & ~rsMaskMult;
1308 regMaskTP myMultMask = regMask & rsMaskMult;
1315 for (regNum = REG_FIRST, regBit = 1; regNum < REG_COUNT; regNum = REG_NEXT(regNum), regBit <<= 1)
1317 if (regBit > myMultMask)
1320 if (regBit & myMultMask)
1322 /* Free the multi-use register 'regNum' */
1323 var_types type = rsRmvMultiReg(regNum);
1325 if (genIsValidFloatReg(regNum) && (type == TYP_DOUBLE))
1327 // On ARM32, We skip the second register for a TYP_DOUBLE
1328 regNum = REG_NEXT(regNum);
1331 #endif // _TARGET_ARM_
1336 /* If there are any single-use registers, free them */
1339 rsMarkRegFree(nonMultMask);
1342 /*****************************************************************************
1344 * Returns the number of registers that are currently free which appear in needReg.
1347 unsigned RegSet::rsFreeNeededRegCount(regMaskTP needReg)
1349 regMaskTP regNeededFree = rsRegMaskFree() & needReg;
1350 unsigned cntFree = 0;
1352 /* While some registers are free ... */
1354 while (regNeededFree)
1356 /* Remove the next register bit and bump the count */
1358 regNeededFree -= genFindLowestBit(regNeededFree);
1364 #endif // LEGACY_BACKEND
1366 /*****************************************************************************
1368 * Record the fact that the given register now contains the given local
1369 * variable. Pointers are handled specially since reusing the register
1370 * will extend the lifetime of a pointer register which is not a register
1374 void RegTracker::rsTrackRegLclVar(regNumber reg, unsigned var)
1376 LclVarDsc* varDsc = &compiler->lvaTable[var];
1377 assert(reg != REG_STK);
1378 #if CPU_HAS_FP_SUPPORT
1379 assert(varTypeIsFloating(varDsc->TypeGet()) == false);
1381 #ifdef LEGACY_BACKEND
1382 // Kill the register before doing anything in case we take a
1383 // shortcut out of here
1384 rsRegValues[reg].rvdKind = RV_TRASH;
1387 if (compiler->lvaTable[var].lvAddrExposed)
1392 /* Keep track of which registers we ever touch */
1394 regSet->rsSetRegsModified(genRegMask(reg));
1396 #ifdef LEGACY_BACKEND
1398 /* Is the variable a pointer? */
1400 if (varTypeIsGC(varDsc->TypeGet()))
1402 /* Don't track pointer register vars */
1404 if (varDsc->lvRegister)
1409 /* Don't track when fully interruptible */
1411 if (compiler->genInterruptible)
1416 else if (varDsc->lvNormalizeOnLoad())
1422 if (compiler->verbose)
1424 printf("\t\t\t\t\t\t\tThe register %s now holds V%02u\n", compiler->compRegVarName(reg), var);
1428 /* Record the new value for the register. ptr var needed for
1429 * lifetime extension
1432 rsRegValues[reg].rvdKind = RV_LCL_VAR;
1434 // If this is a cast of a 64 bit int, then we must have the low 32 bits.
1435 if (genActualType(varDsc->TypeGet()) == TYP_LONG)
1437 rsRegValues[reg].rvdKind = RV_LCL_VAR_LNG_LO;
1440 rsRegValues[reg].rvdLclVarNum = var;
1441 #endif // LEGACY_BACKEND
1444 /*****************************************************************************/
1446 #ifdef LEGACY_BACKEND
1447 void RegTracker::rsTrackRegSwap(regNumber reg1, regNumber reg2)
1451 tmp = rsRegValues[reg1];
1452 rsRegValues[reg1] = rsRegValues[reg2];
1453 rsRegValues[reg2] = tmp;
1455 #endif // LEGACY_BACKEND
1457 void RegTracker::rsTrackRegCopy(regNumber reg1, regNumber reg2)
1459 /* Keep track of which registers we ever touch */
1461 assert(reg1 < REG_COUNT);
1462 assert(reg2 < REG_COUNT);
1464 regSet->rsSetRegsModified(genRegMask(reg1));
1466 #ifdef LEGACY_BACKEND
1467 rsRegValues[reg1] = rsRegValues[reg2];
1468 #endif // LEGACY_BACKEND
1471 #ifdef LEGACY_BACKEND
1473 /*****************************************************************************
1474 * One of the operands of this complex address mode has been spilled
1477 void rsAddrSpillOper(GenTree* addr)
1481 assert(addr->gtOper == GT_IND || addr->gtOper == GT_ARR_ELEM || addr->gtOper == GT_LEA ||
1482 addr->gtOper == GT_CMPXCHG);
1484 // GTF_SPILLED_OP2 says "both operands have been spilled"
1485 assert((addr->gtFlags & GTF_SPILLED_OP2) == 0);
1487 if ((addr->gtFlags & GTF_SPILLED_OPER) == 0)
1488 addr->gtFlags |= GTF_SPILLED_OPER;
1490 addr->gtFlags |= GTF_SPILLED_OP2;
1494 void rsAddrUnspillOper(GenTree* addr)
1498 assert(addr->gtOper == GT_IND || addr->gtOper == GT_ARR_ELEM || addr->gtOper == GT_LEA ||
1499 addr->gtOper == GT_CMPXCHG);
1501 assert((addr->gtFlags & GTF_SPILLED_OPER) != 0);
1503 // Both operands spilled? */
1504 if ((addr->gtFlags & GTF_SPILLED_OP2) != 0)
1505 addr->gtFlags &= ~GTF_SPILLED_OP2;
1507 addr->gtFlags &= ~GTF_SPILLED_OPER;
1511 void RegSet::rsSpillRegIfUsed(regNumber reg)
1513 if (rsMaskUsed & genRegMask(reg))
1519 #endif // LEGACY_BACKEND
1521 //------------------------------------------------------------
1522 // rsSpillTree: Spill the tree held in 'reg'.
1525 // reg - Register of tree node that is to be spilled
1526 // tree - GenTree node that is being spilled
1527 // regIdx - Register index identifying the specific result
1528 // register of a multi-reg call node. For single-reg
1529 // producing tree nodes its value is zero.
1535 // RyuJIT backend specific: in case of multi-reg call nodes, GTF_SPILL
1536 // flag associated with the reg that is being spilled is cleared. The
1537 // caller of this method is expected to clear GTF_SPILL flag on call
1538 // node after all of its registers marked for spilling are spilled.
1540 void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */)
1542 assert(tree != nullptr);
1544 GenTreeCall* call = nullptr;
1546 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
1547 GenTreePutArgSplit* splitArg = nullptr;
1548 GenTreeMultiRegOp* multiReg = nullptr;
1551 #ifndef LEGACY_BACKEND
1552 if (tree->IsMultiRegCall())
1554 call = tree->AsCall();
1555 ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
1556 treeType = retTypeDesc->GetReturnRegType(regIdx);
1559 else if (tree->OperIsPutArgSplit())
1561 splitArg = tree->AsPutArgSplit();
1562 treeType = splitArg->GetRegType(regIdx);
1564 else if (tree->OperIsMultiRegOp())
1566 multiReg = tree->AsMultiRegOp();
1567 treeType = multiReg->GetRegType(regIdx);
1569 #endif // _TARGET_ARM_
1571 #endif // !LEGACY_BACKEND
1573 treeType = tree->TypeGet();
1576 var_types tempType = Compiler::tmpNormalizeType(treeType);
1578 bool floatSpill = false;
1580 if (isFloatRegType(treeType))
1583 mask = genRegMaskFloat(reg, treeType);
1587 mask = genRegMask(reg);
1590 rsNeededSpillReg = true;
1592 #ifdef LEGACY_BACKEND
1593 // The register we're spilling must be used but not locked
1594 // or an enregistered variable.
1596 assert((mask & rsMaskUsed) == mask);
1597 assert((mask & rsMaskLock) == 0);
1598 assert((mask & rsMaskVars) == 0);
1599 #endif // LEGACY_BACKEND
1601 #ifndef LEGACY_BACKEND
1602 // We should only be spilling nodes marked for spill,
1603 // vars should be handled elsewhere, and to prevent
1604 // spilling twice clear GTF_SPILL flag on tree node.
1606 // In case of multi-reg call nodes only the spill flag
1607 // associated with the reg is cleared. Spill flag on
1608 // call node should be cleared by the caller of this method.
1609 assert(tree->gtOper != GT_REG_VAR);
1610 assert((tree->gtFlags & GTF_SPILL) != 0);
1612 unsigned regFlags = 0;
1613 if (call != nullptr)
1615 regFlags = call->GetRegSpillFlagByIdx(regIdx);
1616 assert((regFlags & GTF_SPILL) != 0);
1617 regFlags &= ~GTF_SPILL;
1620 else if (splitArg != nullptr)
1622 regFlags = splitArg->GetRegSpillFlagByIdx(regIdx);
1623 assert((regFlags & GTF_SPILL) != 0);
1624 regFlags &= ~GTF_SPILL;
1626 else if (multiReg != nullptr)
1628 regFlags = multiReg->GetRegSpillFlagByIdx(regIdx);
1629 assert((regFlags & GTF_SPILL) != 0);
1630 regFlags &= ~GTF_SPILL;
1632 #endif // _TARGET_ARM_
1635 assert(!varTypeIsMultiReg(tree));
1636 tree->gtFlags &= ~GTF_SPILL;
1638 #endif // !LEGACY_BACKEND
1640 #if CPU_LONG_USES_REGPAIR
1641 // Are we spilling a part of a register pair?
1642 if (treeType == TYP_LONG)
1644 tempType = TYP_I_IMPL;
1645 assert(genRegPairLo(tree->gtRegPair) == reg || genRegPairHi(tree->gtRegPair) == reg);
1649 assert(tree->InReg());
1650 assert(tree->gtRegNum == reg);
1652 #elif defined(_TARGET_ARM_)
1653 assert(tree->gtRegNum == reg || (call != nullptr && call->GetRegNumByIdx(regIdx) == reg) ||
1654 (splitArg != nullptr && splitArg->GetRegNumByIdx(regIdx) == reg) ||
1655 (multiReg != nullptr && multiReg->GetRegNumByIdx(regIdx) == reg));
1657 assert(tree->gtRegNum == reg || (call != nullptr && call->GetRegNumByIdx(regIdx) == reg));
1658 #endif // !CPU_LONG_USES_REGPAIR && !_TARGET_ARM_
1660 // Are any registers free for spillage?
1661 SpillDsc* spill = SpillDsc::alloc(m_rsCompiler, this, tempType);
1663 // Grab a temp to store the spilled value
1664 TempDsc* temp = m_rsCompiler->tmpGetTemp(tempType);
1665 spill->spillTemp = temp;
1666 tempType = temp->tdTempType();
1668 // Remember what it is we have spilled
1669 spill->spillTree = tree;
1670 #ifdef LEGACY_BACKEND
1671 spill->spillAddr = rsUsedAddr[reg];
1672 #endif // LEGACY_BACKEND
1675 if (m_rsCompiler->verbose)
1677 printf("\t\t\t\t\t\t\tThe register %s spilled with ", m_rsCompiler->compRegVarName(reg));
1678 Compiler::printTreeID(spill->spillTree);
1679 #ifdef LEGACY_BACKEND
1680 if (spill->spillAddr != nullptr)
1682 Compiler::printTreeID(spill->spillAddr);
1684 #endif // LEGACY_BACKEND
1688 #ifdef LEGACY_BACKEND
1689 // Is the register part of a complex address mode?
1690 rsAddrSpillOper(rsUsedAddr[reg]);
1691 #endif // LEGACY_BACKEND
1693 // 'lastDsc' is 'spill' for simple cases, and will point to the last
1694 // multi-use descriptor if 'reg' is being multi-used
1695 SpillDsc* lastDsc = spill;
1697 #ifdef LEGACY_BACKEND
1698 if ((rsMaskMult & mask) == 0)
1700 spill->spillMoreMultis = false;
1704 // The register is being multi-used and will have entries in
1705 // rsMultiDesc[reg]. Spill all of them (ie. move them to
1706 // rsSpillDesc[reg]).
1707 // When we unspill the reg, they will all be moved back to
1710 spill->spillMoreMultis = true;
1712 SpillDsc* nextDsc = rsMultiDesc[reg];
1716 assert(nextDsc != nullptr);
1718 // Is this multi-use part of a complex address mode?
1719 rsAddrSpillOper(nextDsc->spillAddr);
1721 // Mark the tree node as having been spilled
1722 rsMarkSpill(nextDsc->spillTree, reg);
1724 // lastDsc points to the last of the multi-spill descrs for 'reg'
1725 nextDsc->spillTemp = temp;
1728 if (m_rsCompiler->verbose)
1731 Compiler::printTreeID(nextDsc->spillTree);
1733 Compiler::printTreeID(nextDsc->spillAddr);
1737 lastDsc->spillNext = nextDsc;
1740 nextDsc = nextDsc->spillNext;
1741 } while (lastDsc->spillMoreMultis);
1743 rsMultiDesc[reg] = nextDsc;
1745 // 'reg' is no longer considered to be multi-used. We will set this
1746 // mask again when this value gets unspilled
1747 rsMaskMult &= ~mask;
1749 #endif // LEGACY_BACKEND
1751 // Insert the spill descriptor(s) in the list
1752 lastDsc->spillNext = rsSpillDesc[reg];
1753 rsSpillDesc[reg] = spill;
1756 if (m_rsCompiler->verbose)
1762 // Generate the code to spill the register
1763 var_types storeType = floatSpill ? treeType : tempType;
1765 m_rsCompiler->codeGen->spillReg(storeType, temp, reg);
1767 // Mark the tree node as having been spilled
1768 rsMarkSpill(tree, reg);
1770 #ifdef LEGACY_BACKEND
1771 // The register is now free
1772 rsMarkRegFree(mask);
1774 // In case of multi-reg call node also mark the specific
1775 // result reg as spilled.
1776 if (call != nullptr)
1778 regFlags |= GTF_SPILLED;
1779 call->SetRegSpillFlagByIdx(regFlags, regIdx);
1782 else if (splitArg != nullptr)
1784 regFlags |= GTF_SPILLED;
1785 splitArg->SetRegSpillFlagByIdx(regFlags, regIdx);
1787 else if (multiReg != nullptr)
1789 regFlags |= GTF_SPILLED;
1790 multiReg->SetRegSpillFlagByIdx(regFlags, regIdx);
1792 #endif // _TARGET_ARM_
1793 #endif //! LEGACY_BACKEND
1796 #if defined(_TARGET_X86_) && !FEATURE_STACK_FP_X87
1797 /*****************************************************************************
1799 * Spill the top of the FP x87 stack.
1801 void RegSet::rsSpillFPStack(GenTreeCall* call)
1805 var_types treeType = call->TypeGet();
1807 spill = SpillDsc::alloc(m_rsCompiler, this, treeType);
1809 /* Grab a temp to store the spilled value */
1811 spill->spillTemp = temp = m_rsCompiler->tmpGetTemp(treeType);
1813 /* Remember what it is we have spilled */
1815 spill->spillTree = call;
1816 SpillDsc* lastDsc = spill;
1818 regNumber reg = call->gtRegNum;
1819 lastDsc->spillNext = rsSpillDesc[reg];
1820 rsSpillDesc[reg] = spill;
1823 if (m_rsCompiler->verbose)
1826 // m_rsCompiler->codeGen->inst_FS_ST(INS_fstp, emitActualTypeSize(treeType), temp, 0);
1827 m_rsCompiler->codeGen->getEmitter()->emitIns_S(INS_fstp, emitActualTypeSize(treeType), temp->tdTempNum(), 0);
1829 /* Mark the tree node as having been spilled */
1831 rsMarkSpill(call, reg);
1833 #endif // defined(_TARGET_X86_) && !FEATURE_STACK_FP_X87
1835 #ifdef LEGACY_BACKEND
1837 /*****************************************************************************
1839 * Spill the given register (which we assume to be currently marked as used).
1842 void RegSet::rsSpillReg(regNumber reg)
1844 /* We must know the value in the register that we are spilling */
1845 GenTree* tree = rsUsedTree[reg];
1848 if (tree == NULL && genIsValidFloatReg(reg) && !genIsValidDoubleReg(reg))
1850 reg = REG_PREV(reg);
1851 assert(rsUsedTree[reg]);
1852 assert(rsUsedTree[reg]->TypeGet() == TYP_DOUBLE);
1853 tree = rsUsedTree[reg];
1857 rsSpillTree(reg, tree);
1859 /* The register no longer holds its original value */
1861 rsUsedTree[reg] = NULL;
1864 /*****************************************************************************
1866 * Spill all registers in 'regMask' that are currently marked as used.
1869 void RegSet::rsSpillRegs(regMaskTP regMask)
1871 /* The registers we're spilling must not be locked,
1872 or enregistered variables */
1874 assert((regMask & rsMaskLock) == 0);
1875 assert((regMask & rsMaskVars) == 0);
1877 /* Only spill what's currently marked as used */
1879 regMask &= rsMaskUsed;
1885 for (regNum = REG_FIRST, regBit = 1; regNum < REG_COUNT; regNum = REG_NEXT(regNum), regBit <<= 1)
1887 if (regMask & regBit)
1891 regMask &= rsMaskUsed;
1899 /*****************************************************************************
1901 * The following table determines the order in which registers are considered
1902 * for internal tree temps to live in
1905 #ifdef LEGACY_BACKEND
1906 extern const regNumber raRegTmpOrder[] = {REG_TMP_ORDER};
1907 extern const regNumber rpRegTmpOrder[] = {REG_PREDICT_ORDER};
1908 #if FEATURE_FP_REGALLOC
1909 extern const regNumber raRegFltTmpOrder[] = {REG_FLT_TMP_ORDER};
1911 #endif // LEGACY_BACKEND
1913 /*****************************************************************************
1915 * Choose a register from the given set in the preferred order (see above);
1916 * if no registers are in the set return REG_STK.
1919 regNumber RegSet::rsPickRegInTmpOrder(regMaskTP regMask)
1921 if (regMask == RBM_NONE)
1924 bool firstPass = true;
1925 regMaskTP avoidMask =
1926 ~rsGetModifiedRegsMask() & RBM_CALLEE_SAVED; // We want to avoid using any new callee saved register
1930 /* Iterate the registers in the order specified by raRegTmpOrder */
1932 for (unsigned index = 0; index < REG_TMP_ORDER_COUNT; index++)
1934 regNumber candidateReg = raRegTmpOrder[index];
1935 regMaskTP candidateMask = genRegMask(candidateReg);
1937 // For a FP base frame, don't use FP register.
1938 if (m_rsCompiler->codeGen->isFramePointerUsed() && (candidateMask == RBM_FPBASE))
1941 // For the first pass avoid selecting a never used register when there are other registers available
1942 if (firstPass && ((candidateMask & avoidMask) != 0))
1945 if (regMask & candidateMask)
1946 return candidateReg;
1949 if (firstPass == true)
1950 firstPass = false; // OK, now we are willing to select a never used register
1958 /*****************************************************************************
1959 * Choose a register from the 'regMask' set and return it. If no registers in
1960 * the set are currently free, one of them will be spilled (even if other
1961 * registers - not in the set - are currently free).
1963 * If you don't require a register from a particular set, you should use rsPickReg() instead.
1965 * rsModifiedRegsMask is modified to include the returned register.
1968 regNumber RegSet::rsGrabReg(regMaskTP regMask)
1975 regMask &= ~rsMaskLock;
1978 /* See if one of the desired registers happens to be free */
1980 OKmask = regMask & rsRegMaskFree();
1982 regNum = rsPickRegInTmpOrder(OKmask);
1983 if (REG_STK != regNum)
1988 /* We'll have to spill one of the registers in 'regMask' */
1990 OKmask = regMask & rsRegMaskCanGrab();
1993 for (regNum = REG_FIRST, regBit = 1; (regBit & OKmask) == 0; regNum = REG_NEXT(regNum), regBit <<= 1)
1995 if (regNum >= REG_COUNT)
1997 assert(!"no register to grab!");
1998 NO_WAY("Could not grab a register, Predictor should have prevented this!");
2002 /* This will be the victim -- spill it */
2005 /* Make sure we did find a register to spill */
2006 assert(genIsValidReg(regNum));
2009 /* Keep track of which registers we ever touch */
2010 rsSetRegsModified(genRegMask(regNum));
2014 /*****************************************************************************
2015 * Find a register to use and return it, spilling if necessary.
2017 * Look for a register in the following order: First, try and find a free register
2018 * in 'regBest' (if 'regBest' is RBM_NONE, skip this step). Second, try to find a
2019 * free register in 'regMask' (if 'regMask' is RBM_NONE, skip this step). Note that
2020 * 'regBest' doesn't need to be a subset of 'regMask'. Third, find any free
2021 * register. Fourth, spill a register. The register to spill will be in 'regMask',
2022 * if 'regMask' is not RBM_NONE.
2024 * Note that 'regMask' and 'regBest' are purely recommendations, and can be ignored;
2025 * the caller can't expect that the returned register will be in those sets. In
2026 * particular, under register stress, we specifically will pick registers not in
2027 * these sets to ensure that callers don't require a register from those sets
2028 * (and to ensure callers can handle the spilling that might ensue).
2030 * Calling rsPickReg() with the default arguments (which sets 'regMask' and 'regBest' to RBM_NONE)
2031 * is equivalent to calling rsGrabReg(rsRegMaskFree()).
2033 * rsModifiedRegsMask is modified to include the returned register.
2036 regNumber RegSet::rsPickReg(regMaskTP regMask, regMaskTP regBest)
2039 regMaskTP spillMask;
2040 regMaskTP canGrabMask;
2043 if (rsStressRegs() >= 1)
2045 /* 'regMask' is purely a recommendation, and callers should be
2046 able to handle the case where it is not satisfied.
2047 The logic here tries to return ~regMask to check that all callers
2048 are prepared to handle such a case */
2050 regMaskTP badRegs = rsMaskMult & rsRegMaskCanGrab();
2052 badRegs = rsUseIfZero(badRegs, rsMaskUsed & rsRegMaskCanGrab());
2053 badRegs = rsUseIfZero(badRegs, rsRegMaskCanGrab());
2054 badRegs = rsExcludeHint(badRegs, regMask);
2056 assert(badRegs != RBM_NONE);
2058 return rsGrabReg(badRegs);
2063 regMaskTP freeMask = rsRegMaskFree();
2067 /* By default we'd prefer to accept all available registers */
2069 regMaskTP OKmask = freeMask;
2071 // OKmask = rsNarrowHint(OKmask, rsUselessRegs());
2073 /* Is there a 'best' register set? */
2084 /* Was a register set recommended by the caller? */
2095 /* Iterate the registers in the order specified by raRegTmpOrder */
2097 regNum = rsPickRegInTmpOrder(OKmask);
2098 if (REG_STK != regNum)
2105 /* Were we considering 'regBest' ? */
2109 /* 'regBest' is no good -- ignore it and try 'regMask' instead */
2115 /* Now let's consider all available registers */
2117 /* Were we limited in our consideration? */
2121 /* We need to spill one of the free registers */
2123 spillMask = freeMask;
2127 /* Did we not consider all free registers? */
2129 if ((regMask & freeMask) != freeMask)
2131 /* The recommended regset didn't work, so try all available regs */
2133 regNum = rsPickRegInTmpOrder(freeMask);
2134 if (REG_STK != regNum)
2138 /* If we're going to spill, might as well go for the right one */
2140 spillMask = regMask;
2143 /* Make sure we can spill some register. */
2145 canGrabMask = rsRegMaskCanGrab();
2146 if ((spillMask & canGrabMask) == 0)
2147 spillMask = canGrabMask;
2151 /* We have no choice but to spill one of the regs */
2153 return rsGrabReg(spillMask);
2157 rsSetRegsModified(genRegMask(regNum));
2161 #endif // LEGACY_BACKEND
2163 /*****************************************************************************
2165 * Get the temp that was spilled from the given register (and free its
2166 * spill descriptor while we're at it). Returns the temp (i.e. local var)
2169 TempDsc* RegSet::rsGetSpillTempWord(regNumber reg, SpillDsc* dsc, SpillDsc* prevDsc)
2171 assert((prevDsc == nullptr) || (prevDsc->spillNext == dsc));
2173 #ifdef LEGACY_BACKEND
2174 /* Is dsc the last of a set of multi-used values */
2176 if (prevDsc && prevDsc->spillMoreMultis && !dsc->spillMoreMultis)
2177 prevDsc->spillMoreMultis = false;
2178 #endif // LEGACY_BACKEND
2180 /* Remove this spill entry from the register's list */
2182 (prevDsc ? prevDsc->spillNext : rsSpillDesc[reg]) = dsc->spillNext;
2184 /* Remember which temp the value is in */
2186 TempDsc* temp = dsc->spillTemp;
2188 SpillDsc::freeDsc(this, dsc);
2190 /* return the temp variable */
2195 #ifdef LEGACY_BACKEND
2196 /*****************************************************************************
2198 * Reload the value that was spilled from the given register (and free its
2199 * spill descriptor while we're at it). Returns the new register (which will
2200 * be a member of 'needReg' if that value is non-zero).
2202 * 'willKeepNewReg' indicates if the caller intends to mark newReg as used.
2203 * If not, then we can't unspill the other multi-used descriptor (if any).
2204 * Instead, we will just hold on to the temp and unspill them
2208 regNumber RegSet::rsUnspillOneReg(GenTree* tree, regNumber oldReg, KeepReg willKeepNewReg, regMaskTP needReg)
2210 /* Was oldReg multi-used when it was spilled? */
2212 SpillDsc *prevDsc, *multiDsc;
2213 SpillDsc* spillDsc = rsGetSpillInfo(tree, oldReg, &prevDsc, &multiDsc);
2214 noway_assert((spillDsc != NULL) && (multiDsc != NULL));
2216 bool multiUsed = multiDsc->spillMoreMultis;
2218 /* We will use multiDsc to walk the rest of the spill list (if it's
2219 multiUsed). As we're going to remove spillDsc from the multiDsc
2220 list in the rsGetSpillTempWord() call we have to take care of the
2221 case where multiDsc==spillDsc. We will set multiDsc as spillDsc->spillNext */
2222 if (multiUsed && multiDsc == spillDsc)
2224 assert(spillDsc->spillNext);
2225 multiDsc = spillDsc->spillNext;
2228 /* Get the temp and free the spill-descriptor */
2230 TempDsc* temp = rsGetSpillTempWord(oldReg, spillDsc, prevDsc);
2232 // Pick a new home for the value:
2233 // This must be a register matching the 'needReg' mask, if it is non-zero.
2234 // Additionally, if 'oldReg' is in 'needMask' and it is free we will select oldReg.
2235 // Also note that the rsGrabReg() call below may cause the chosen register to be spilled.
2243 bool floatUnspill = false;
2245 #if FEATURE_FP_REGALLOC
2246 floatUnspill = genIsValidFloatReg(oldReg);
2251 if (temp->tdTempType() == TYP_DOUBLE)
2252 regType = TYP_DOUBLE;
2254 regType = TYP_FLOAT;
2256 prefMask = genRegMaskFloat(oldReg, regType);
2257 freeMask = RegFreeFloat();
2261 regType = TYP_I_IMPL;
2262 loadType = temp->tdTempType();
2263 prefMask = genRegMask(oldReg);
2264 freeMask = rsRegMaskFree();
2267 if ((((prefMask & needReg) != 0) || (needReg == 0)) && ((prefMask & freeMask) != 0))
2274 RegisterPreference pref(RBM_ALLFLOAT, needReg);
2275 newReg = PickRegFloat(regType, &pref, true);
2279 newReg = rsGrabReg(rsUseIfZero(needReg, RBM_ALLINT));
2282 m_rsCompiler->codeGen->trashReg(newReg);
2284 /* Reload the value from the saved location into the new register */
2286 m_rsCompiler->codeGen->reloadReg(loadType, temp, newReg);
2288 if (multiUsed && (willKeepNewReg == KEEP_REG))
2290 /* We will unspill all the other multi-use trees if the register
2291 is going to be marked as used. If it is not going to be marked
2292 as used, we will have a problem if the new register gets spilled
2296 /* We don't do the extra unspilling for complex address modes,
2297 since someone up the call chain may have a different idea about
2298 what registers are used to form the complex address mode (the
2299 addrReg return value from genMakeAddressable).
2301 Also, it is not safe to unspill all the multi-uses with a TYP_LONG.
2303 Finally, it is not safe to unspill into a different register, because
2304 the caller of genMakeAddressable caches the addrReg return value
2305 (register mask), but when unspilling into a different register it's
2306 not possible to inform the caller that addrReg is now different.
2307 See bug #89946 for an example of this. There is an assert for this
2308 in rsMarkRegFree via genDoneAddressable.
2311 for (SpillDsc* dsc = multiDsc; /**/; dsc = dsc->spillNext)
2313 if ((oldReg != newReg) || (dsc->spillAddr != NULL) || (dsc->spillTree->gtType == TYP_LONG))
2318 if (!dsc->spillMoreMultis)
2320 /* All the remaining multi-uses are fine. We will now
2326 bool bFound = false;
2330 for (pDsc = rsSpillDesc[oldReg], ppPrev = &rsSpillDesc[oldReg];; pDsc = pDsc->spillNext)
2332 if (pDsc == multiDsc)
2334 // We've found the sequence we were searching for
2340 rsAddrUnspillOper(pDsc->spillAddr);
2342 // Mark the tree node as having been unspilled into newReg
2343 rsMarkUnspill(pDsc->spillTree, newReg);
2346 if (!pDsc->spillMoreMultis)
2352 // We link remaining sides of list
2353 *ppPrev = pDsc->spillNext;
2360 ppPrev = &(pDsc->spillNext);
2365 /* pDsc points to the last multi-used descriptor from the spill-list
2366 for the current value (pDsc->spillMoreMultis == false) */
2368 pDsc->spillNext = rsMultiDesc[newReg];
2369 rsMultiDesc[newReg] = multiDsc;
2372 rsMaskMult |= genRegMaskFloat(newReg, regType);
2374 rsMaskMult |= genRegMask(newReg);
2377 if (!multiUsed || (willKeepNewReg == KEEP_REG))
2379 // Free the temp, it's no longer used.
2380 // For multi-used regs that aren't (willKeepNewReg == KEEP_REG), we didn't unspill everything, so
2381 // we need to leave the temp for future unspilling.
2382 m_rsCompiler->tmpRlsTemp(temp);
2387 #endif // LEGACY_BACKEND
2389 //---------------------------------------------------------------------
2390 // rsUnspillInPlace: The given tree operand has been spilled; just mark
2391 // it as unspilled so that we can use it as "normal" local.
2394 // tree - GenTree that needs to be marked as unspilled.
2395 // oldReg - reg of tree that was spilled.
2401 // 1. It is the responsibility of the caller to free the spill temp.
2402 // 2. RyuJIT backend specific: In case of multi-reg call node
2403 // GTF_SPILLED flag associated with reg is cleared. It is the
2404 // responsibility of caller to clear GTF_SPILLED flag on call node
2405 // itself after ensuring there are no outstanding regs in GTF_SPILLED
2408 TempDsc* RegSet::rsUnspillInPlace(GenTree* tree, regNumber oldReg, unsigned regIdx /* =0 */)
2410 assert(!isRegPairType(tree->gtType));
2412 // Get the tree's SpillDsc
2414 SpillDsc* spillDsc = rsGetSpillInfo(tree, oldReg, &prevDsc);
2415 PREFIX_ASSUME(spillDsc != nullptr);
2418 TempDsc* temp = rsGetSpillTempWord(oldReg, spillDsc, prevDsc);
2420 // The value is now unspilled
2421 if (tree->IsMultiRegCall())
2423 GenTreeCall* call = tree->AsCall();
2424 unsigned flags = call->GetRegSpillFlagByIdx(regIdx);
2425 flags &= ~GTF_SPILLED;
2426 call->SetRegSpillFlagByIdx(flags, regIdx);
2428 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
2429 else if (tree->OperIsPutArgSplit())
2431 GenTreePutArgSplit* splitArg = tree->AsPutArgSplit();
2432 unsigned flags = splitArg->GetRegSpillFlagByIdx(regIdx);
2433 flags &= ~GTF_SPILLED;
2434 splitArg->SetRegSpillFlagByIdx(flags, regIdx);
2436 else if (tree->OperIsMultiRegOp())
2438 GenTreeMultiRegOp* multiReg = tree->AsMultiRegOp();
2439 unsigned flags = multiReg->GetRegSpillFlagByIdx(regIdx);
2440 flags &= ~GTF_SPILLED;
2441 multiReg->SetRegSpillFlagByIdx(flags, regIdx);
2443 #endif // !LEGACY_BACKEND && _TARGET_ARM_
2446 tree->gtFlags &= ~GTF_SPILLED;
2450 if (m_rsCompiler->verbose)
2452 printf("\t\t\t\t\t\t\tTree-Node marked unspilled from ");
2453 Compiler::printTreeID(tree);
2461 #ifdef LEGACY_BACKEND
2463 /*****************************************************************************
2465 * The given tree operand has been spilled; reload it into a register that
2466 * is in 'needReg' (if 'needReg' is RBM_NONE, any register will do). If 'keepReg'
2467 * is set to KEEP_REG, we'll mark the new register as used.
2470 void RegSet::rsUnspillReg(GenTree* tree, regMaskTP needReg, KeepReg keepReg)
2472 assert(!isRegPairType(tree->gtType)); // use rsUnspillRegPair()
2473 regNumber oldReg = tree->gtRegNum;
2475 /* Get the SpillDsc for the tree */
2477 SpillDsc* spillDsc = rsGetSpillInfo(tree, oldReg);
2478 PREFIX_ASSUME(spillDsc != NULL);
2480 /* Before spillDsc is stomped on by rsUnspillOneReg(), note whether
2481 * the reg was part of an address mode
2484 GenTree* unspillAddr = spillDsc->spillAddr;
2486 /* Pick a new home for the value */
2488 regNumber newReg = rsUnspillOneReg(tree, oldReg, keepReg, needReg);
2490 /* Mark the tree node as having been unspilled into newReg */
2492 rsMarkUnspill(tree, newReg);
2494 // If this reg was part of a complex address mode, need to clear this flag which
2495 // tells address mode building that a component has been spilled
2497 rsAddrUnspillOper(unspillAddr);
2500 if (m_rsCompiler->verbose)
2502 printf("\t\t\t\t\t\t\tThe register %s unspilled from ", m_rsCompiler->compRegVarName(newReg));
2503 Compiler::printTreeID(tree);
2508 /* Mark the new value as used, if the caller desires so */
2510 if (keepReg == KEEP_REG)
2511 rsMarkRegUsed(tree, unspillAddr);
2513 #endif // LEGACY_BACKEND
2515 void RegSet::rsMarkSpill(GenTree* tree, regNumber reg)
2517 #ifdef LEGACY_BACKEND
2518 tree->SetInReg(false);
2520 tree->gtFlags |= GTF_SPILLED;
2523 #ifdef LEGACY_BACKEND
2525 void RegSet::rsMarkUnspill(GenTree* tree, regNumber reg)
2527 #ifndef _TARGET_AMD64_
2528 assert(tree->gtType != TYP_LONG);
2529 #endif // _TARGET_AMD64_
2531 tree->gtFlags &= ~GTF_SPILLED;
2532 tree->gtRegNum = reg;
2536 /*****************************************************************************
2538 * Choose a register pair from the given set (note: only registers in the
2539 * given set will be considered).
2542 regPairNo RegSet::rsGrabRegPair(regMaskTP regMask)
2550 regMask &= ~rsMaskLock;
2553 /* We'd prefer to choose a free register pair if possible */
2555 OKmask = regMask & rsRegMaskFree();
2557 /* Any takers in the recommended/free set? */
2559 regPair = rsFindRegPairNo(OKmask);
2561 if (regPair != REG_PAIR_NONE)
2563 // The normal early exit
2565 /* Keep track of which registers we ever touch */
2566 rsSetRegsModified(genRegPairMask(regPair));
2571 /* We have no choice but to spill one or two used regs */
2575 /* One (and only one) register is free and acceptable - grab it */
2577 assert(genMaxOneBit(OKmask));
2579 for (reg1 = REG_INT_FIRST; reg1 <= REG_INT_LAST; reg1 = REG_NEXT(reg1))
2581 if (OKmask & genRegMask(reg1))
2584 assert(OKmask & genRegMask(reg1));
2588 /* No register is free and acceptable - we'll have to spill two */
2590 reg1 = rsGrabReg(regMask);
2593 /* Temporarily lock the first register so it doesn't go away */
2595 rsLockReg(genRegMask(reg1));
2597 /* Now grab another register */
2599 reg2 = rsGrabReg(regMask);
2601 /* We can unlock the first register now */
2603 rsUnlockReg(genRegMask(reg1));
2605 /* Convert the two register numbers into a pair */
2608 regPair = gen2regs2pair(reg1, reg2);
2610 regPair = gen2regs2pair(reg2, reg1);
2615 /*****************************************************************************
2617 * Choose a register pair from the given set (if non-zero) or from the set of
2618 * currently available registers (if 'regMask' is zero).
2621 regPairNo RegSet::rsPickRegPair(regMaskTP regMask)
2628 /* By default we'd prefer to accept all available registers */
2630 OKmask = rsRegMaskFree();
2634 /* A register set was recommended by the caller */
2641 regPair = rsFindRegPairNo(OKmask);
2643 if (regPair != REG_PAIR_NONE)
2645 return regPair; // Normal early exit
2649 regMaskTP spillMask;
2651 /* Now let's consider all available registers */
2653 freeMask = rsRegMaskFree();
2655 /* Were we limited in our consideration? */
2659 /* We need to spill two of the free registers */
2661 spillMask = freeMask;
2665 /* Did we not consider all free registers? */
2667 if ((regMask & freeMask) != freeMask && repeat == 0)
2669 /* The recommended regset didn't work, so try all available regs */
2676 /* If we're going to spill, might as well go for the right one */
2678 spillMask = regMask;
2681 /* Make sure that we have at least two bits set */
2683 if (genMaxOneBit(spillMask & rsRegMaskCanGrab()))
2684 spillMask = rsRegMaskCanGrab();
2686 assert(!genMaxOneBit(spillMask));
2688 /* We have no choice but to spill 1/2 of the regs */
2690 return rsGrabRegPair(spillMask);
2693 /*****************************************************************************
2695 * The given tree operand has been spilled; reload it into a register pair
2696 * that is in 'needReg' (if 'needReg' is RBM_NONE, any register pair will do). If
2697 * 'keepReg' is KEEP_REG, we'll mark the new register pair as used. It is
2698 * assumed that the current register pair has been marked as used (modulo
2699 * any spillage, of course).
2702 void RegSet::rsUnspillRegPair(GenTree* tree, regMaskTP needReg, KeepReg keepReg)
2704 assert(isRegPairType(tree->gtType));
2706 regPairNo regPair = tree->gtRegPair;
2707 regNumber regLo = genRegPairLo(regPair);
2708 regNumber regHi = genRegPairHi(regPair);
2710 /* Has the register holding the lower half been spilled? */
2712 if (!rsIsTreeInReg(regLo, tree))
2714 /* Is the upper half already in the right place? */
2716 if (rsIsTreeInReg(regHi, tree))
2718 // Temporarily lock the high part if necessary. If this register is a multi-use register that is shared
2719 // with another tree, the register may already be locked.
2720 const regMaskTP regHiMask = genRegMask(regHi);
2721 const bool lockReg = (rsMaskLock & regHiMask) == 0;
2724 rsLockUsedReg(regHiMask);
2727 /* Pick a new home for the lower half */
2729 regLo = rsUnspillOneReg(tree, regLo, keepReg, needReg);
2731 /* We can unlock the high part now */
2734 rsUnlockUsedReg(regHiMask);
2739 /* Pick a new home for the lower half */
2741 regLo = rsUnspillOneReg(tree, regLo, keepReg, needReg);
2746 /* Free the register holding the lower half */
2748 rsMarkRegFree(genRegMask(regLo));
2751 if (regHi != REG_STK)
2753 /* Has the register holding the upper half been spilled? */
2755 if (!rsIsTreeInReg(regHi, tree))
2757 regMaskTP regLoUsed = RBM_NONE;
2759 // Temporarily lock the low part if necessary. If this register is a multi-use register that is shared
2760 // with another tree, the register may already be locked.
2761 const regMaskTP regLoMask = genRegMask(regLo);
2762 const bool lockReg = (rsMaskLock & regLoMask) == 0;
2765 rsLockReg(regLoMask, ®LoUsed);
2768 /* Pick a new home for the upper half */
2770 regHi = rsUnspillOneReg(tree, regHi, keepReg, needReg);
2772 /* We can unlock the low register now */
2775 rsUnlockReg(regLoMask, regLoUsed);
2780 /* Free the register holding the upper half */
2782 rsMarkRegFree(genRegMask(regHi));
2786 /* The value is now residing in the new register */
2789 tree->gtFlags &= ~GTF_SPILLED;
2790 tree->gtRegPair = gen2regs2pair(regLo, regHi);
2792 /* Mark the new value as used, if the caller desires so */
2794 if (keepReg == KEEP_REG)
2795 rsMarkRegPairUsed(tree);
2798 /*****************************************************************************
2800 * The given register is being used by multiple trees (all of which represent
2801 * the same logical value). Happens mainly because of REDUNDANT_LOAD;
2802 * We don't want to really spill the register as it actually holds the
2803 * value we want. But the multiple trees may be part of different
2805 * Save the previous 'use' info so that when we return the register will
2809 void RegSet::rsRecMultiReg(regNumber reg, var_types type)
2814 if (genIsValidFloatReg(reg) && isFloatRegType(type))
2815 regMask = genRegMaskFloat(reg, type);
2817 regMask = genRegMask(reg);
2820 if (m_rsCompiler->verbose)
2822 printf("\t\t\t\t\t\t\tRegister %s multi-use inc for ", m_rsCompiler->compRegVarName(reg));
2823 Compiler::printTreeID(rsUsedTree[reg]);
2824 printf(" multMask=" REG_MASK_ALL_FMT "\n", rsMaskMult | regMask);
2828 /* The register is supposed to be already used */
2830 assert(regMask & rsMaskUsed);
2832 assert(rsUsedTree[reg]);
2834 /* Allocate/reuse a spill descriptor */
2836 spill = SpillDsc::alloc(m_rsCompiler, this, rsUsedTree[reg]->TypeGet());
2838 /* Record the current 'use' info in the spill descriptor */
2840 spill->spillTree = rsUsedTree[reg];
2841 rsUsedTree[reg] = 0;
2842 spill->spillAddr = rsUsedAddr[reg];
2843 rsUsedAddr[reg] = 0;
2845 /* Remember whether the register is already 'multi-use' */
2847 spill->spillMoreMultis = ((rsMaskMult & regMask) != 0);
2849 /* Insert the new multi-use record in the list for the register */
2851 spill->spillNext = rsMultiDesc[reg];
2852 rsMultiDesc[reg] = spill;
2854 /* This register is now 'multi-use' */
2856 rsMaskMult |= regMask;
2859 /*****************************************************************************
2861 * Free the given register, which is known to have multiple uses.
2864 var_types RegSet::rsRmvMultiReg(regNumber reg)
2868 assert(rsMaskMult & genRegMask(reg));
2871 if (m_rsCompiler->verbose)
2873 printf("\t\t\t\t\t\t\tRegister %s multi-use dec for ", m_rsCompiler->compRegVarName(reg));
2874 Compiler::printTreeID(rsUsedTree[reg]);
2875 printf(" multMask=" REG_MASK_ALL_FMT "\n", rsMaskMult);
2879 /* Get hold of the spill descriptor for the register */
2881 dsc = rsMultiDesc[reg];
2883 rsMultiDesc[reg] = dsc->spillNext;
2885 /* Copy the previous 'use' info from the descriptor */
2887 assert(reg != REG_SPBASE);
2888 rsUsedTree[reg] = dsc->spillTree;
2889 rsUsedAddr[reg] = dsc->spillAddr;
2891 if (!(dsc->spillTree->gtFlags & GTF_SPILLED))
2892 m_rsGCInfo.gcMarkRegPtrVal(reg, dsc->spillTree->TypeGet());
2894 var_types type = dsc->spillTree->TypeGet();
2897 if (genIsValidFloatReg(reg) && isFloatRegType(type))
2898 regMask = genRegMaskFloat(reg, type);
2900 regMask = genRegMask(reg);
2902 /* Is only one use of the register left? */
2904 if (!dsc->spillMoreMultis)
2906 rsMaskMult -= regMask;
2910 if (m_rsCompiler->verbose)
2912 printf("\t\t\t\t\t\t\tRegister %s multi-use dec - now ", m_rsCompiler->compRegVarName(reg));
2913 Compiler::printTreeID(rsUsedTree[reg]);
2914 printf(" multMask=" REG_MASK_ALL_FMT "\n", rsMaskMult);
2918 SpillDsc::freeDsc(this, dsc);
2921 /*****************************************************************************/
2922 /*****************************************************************************
2924 * Search for a register which contains the given constant value.
2925 * Return success/failure and set the register if success.
2926 * If the closeDelta argument is non-NULL then look for a
2927 * register that has a close constant value. For ARM, find
2928 * the closest register value, independent of constant delta.
2929 * For non-ARM, only consider values that are within -128..+127.
2930 * If one is found, *closeDelta is set to the difference that needs
2931 * to be added to the register returned. On x86/amd64, an lea instruction
2932 * is used to set the target register using the register that
2933 * contains the close integer constant.
2936 regNumber RegTracker::rsIconIsInReg(ssize_t val, ssize_t* closeDelta /* = NULL */)
2938 regNumber closeReg = REG_NA;
2940 if (compiler->opts.MinOpts() || compiler->opts.compDbgCode)
2945 for (regNumber reg = REG_INT_FIRST; reg <= REG_INT_LAST; reg = REG_NEXT(reg))
2947 if (rsRegValues[reg].rvdKind == RV_INT_CNS)
2949 ssize_t regCnsVal = rsRegValues[reg].rvdIntCnsVal;
2950 if (regCnsVal == val)
2961 // Find the smallest delta; the caller checks the size
2962 // TODO-CQ: find the smallest delta from a low register?
2963 // That is, is it better to return a high register with a
2964 // small constant delta, or a low register with
2965 // a larger offset? It's better to have a low register with an offset within the low register
2966 // range, or a high register otherwise...
2968 ssize_t regCnsDelta = val - regCnsVal;
2969 if ((closeReg == REG_NA) || (unsigned_abs(regCnsDelta) < unsigned_abs(*closeDelta)))
2972 *closeDelta = regCnsDelta;
2975 if (closeReg == REG_NA)
2977 ssize_t regCnsDelta = val - regCnsVal;
2978 /* Does delta fit inside a byte [-128..127] */
2979 if (regCnsDelta == (signed char)regCnsDelta)
2982 *closeDelta = (int)regCnsDelta;
2990 /* There was not an exact match */
2992 return closeReg; /* will always be REG_NA when closeDelta is NULL */
2995 /*****************************************************************************
2997 * Assume all non-integer registers contain garbage (this is called when
2998 * we encounter a code label that isn't jumped by any block; we need to
2999 * clear pointer values out of the table lest the GC pointer tables get
3003 void RegTracker::rsTrackRegClrPtr()
3005 for (regNumber reg = REG_FIRST; reg < REG_COUNT; reg = REG_NEXT(reg))
3007 /* Preserve constant values */
3009 if (rsRegValues[reg].rvdKind == RV_INT_CNS)
3011 /* Make sure we don't preserve NULL (it's a pointer) */
3013 if (rsRegValues[reg].rvdIntCnsVal != NULL)
3019 /* Preserve variables known to not be pointers */
3021 if (rsRegValues[reg].rvdKind == RV_LCL_VAR)
3023 if (!varTypeIsGC(compiler->lvaTable[rsRegValues[reg].rvdLclVarNum].TypeGet()))
3029 rsRegValues[reg].rvdKind = RV_TRASH;
3033 /*****************************************************************************
3035 * This routine trashes the registers that hold stack GCRef/ByRef variables. (VSW: 561129)
3036 * It should be called at each gc-safe point.
3038 * It returns a mask of the registers that used to contain tracked stack variables that
3043 regMaskTP RegTracker::rsTrashRegsForGCInterruptability()
3045 regMaskTP result = RBM_NONE;
3046 for (regNumber reg = REG_FIRST; reg < REG_COUNT; reg = REG_NEXT(reg))
3048 if (rsRegValues[reg].rvdKind == RV_LCL_VAR)
3050 LclVarDsc* varDsc = &compiler->lvaTable[rsRegValues[reg].rvdLclVarNum];
3052 if (!varTypeIsGC(varDsc->TypeGet()))
3057 // Only stack locals got tracked.
3058 assert(!varDsc->lvRegister);
3060 rsRegValues[reg].rvdKind = RV_TRASH;
3062 result |= genRegMask(reg);
3069 /*****************************************************************************
3071 * Search for a register which contains the given local var.
3072 * Return success/failure and set the register if success.
3073 * Return FALSE on register variables, because otherwise their lifetimes
3074 * can get bungled with respect to pointer tracking.
3077 regNumber RegTracker::rsLclIsInReg(unsigned var)
3079 assert(var < compiler->lvaCount);
3081 if (compiler->opts.MinOpts() || compiler->opts.compDbgCode)
3086 /* return false if register var so genMarkLclVar can do its job */
3088 if (compiler->lvaTable[var].lvRegister)
3093 for (regNumber reg = REG_FIRST; reg < REG_COUNT; reg = REG_NEXT(reg))
3095 if (rsRegValues[reg].rvdLclVarNum == var && rsRegValues[reg].rvdKind == RV_LCL_VAR)
3104 /*****************************************************************************/
3106 regPairNo RegTracker::rsLclIsInRegPair(unsigned var)
3108 assert(var < compiler->lvaCount);
3110 if (compiler->opts.MinOpts() || compiler->opts.compDbgCode)
3112 return REG_PAIR_NONE;
3115 regValKind rvKind = RV_TRASH;
3116 regNumber regNo = DUMMY_INIT(REG_NA);
3118 for (regNumber reg = REG_FIRST; reg < REG_COUNT; reg = REG_NEXT(reg))
3120 if (rvKind != rsRegValues[reg].rvdKind && rsTrackIsLclVarLng(rsRegValues[reg].rvdKind) &&
3121 rsRegValues[reg].rvdLclVarNum == var)
3123 /* first occurrence of this variable ? */
3125 if (rvKind == RV_TRASH)
3128 rvKind = rsRegValues[reg].rvdKind;
3130 else if (rvKind == RV_LCL_VAR_LNG_HI)
3132 /* We found the lower half of the long */
3134 return gen2regs2pair(reg, regNo);
3138 /* We found the upper half of the long */
3140 assert(rvKind == RV_LCL_VAR_LNG_LO);
3141 return gen2regs2pair(regNo, reg);
3146 return REG_PAIR_NONE;
3149 /*****************************************************************************/
3151 void RegTracker::rsTrashLclLong(unsigned var)
3153 if (compiler->opts.MinOpts() || compiler->opts.compDbgCode)
3158 for (regNumber reg = REG_FIRST; reg < REG_COUNT; reg = REG_NEXT(reg))
3160 if (rsTrackIsLclVarLng(rsRegValues[reg].rvdKind) && rsRegValues[reg].rvdLclVarNum == var)
3162 rsRegValues[reg].rvdKind = RV_TRASH;
3167 /*****************************************************************************
3169 * Local's value has changed, mark all regs which contained it as trash.
3172 void RegTracker::rsTrashLcl(unsigned var)
3174 if (compiler->opts.MinOpts() || compiler->opts.compDbgCode)
3179 for (regNumber reg = REG_FIRST; reg < REG_COUNT; reg = REG_NEXT(reg))
3181 if (rsRegValues[reg].rvdKind == RV_LCL_VAR && rsRegValues[reg].rvdLclVarNum == var)
3183 rsRegValues[reg].rvdKind = RV_TRASH;
3187 #endif // LEGACY_BACKEND
3189 /*****************************************************************************
3191 * A little helper to trash the given set of registers.
3192 * Usually used after a call has been generated.
3195 void RegTracker::rsTrashRegSet(regMaskTP regMask)
3197 if (compiler->opts.MinOpts() || compiler->opts.compDbgCode)
3201 regMaskTP regBit = 1;
3202 for (regNumber regNum = REG_FIRST; regMask != 0; regNum = REG_NEXT(regNum), regBit <<= 1)
3204 if (regBit & regMask)
3206 rsTrackRegTrash(regNum);
3212 #ifdef LEGACY_BACKEND
3213 /*****************************************************************************
3215 * Return a mask of registers that hold no useful value.
3218 regMaskTP RegTracker::rsUselessRegs()
3220 if (compiler->opts.MinOpts() || compiler->opts.compDbgCode)
3225 regMaskTP mask = RBM_NONE;
3226 for (regNumber reg = REG_FIRST; reg < REG_COUNT; reg = REG_NEXT(reg))
3228 if (rsRegValues[reg].rvdKind == RV_TRASH)
3230 mask |= genRegMask(reg);
3237 /*****************************************************************************/
3238 #endif // LEGACY_BACKEND
3239 /*****************************************************************************/
3242 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3243 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3247 XX The temporary lclVars allocated by the compiler for code generation XX
3249 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3250 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3253 void Compiler::tmpInit()
3255 #ifdef LEGACY_BACKEND
3256 tmpDoubleSpillMax = 0;
3258 #endif // LEGACY_BACKEND
3266 memset(tmpFree, 0, sizeof(tmpFree));
3267 memset(tmpUsed, 0, sizeof(tmpUsed));
3271 var_types Compiler::tmpNormalizeType(var_types type)
3273 #ifndef LEGACY_BACKEND
3275 type = genActualType(type);
3277 #if defined(FEATURE_SIMD) && !defined(_TARGET_64BIT_)
3278 // For SIMD on 32-bit platforms, we always spill SIMD12 to a 16-byte SIMD16 temp.
3279 // This is because we don't have a single instruction to store 12 bytes. We also
3280 // allocate non-argument locals as 16 bytes; see lvSize().
3281 if (type == TYP_SIMD12)
3285 #endif // defined(FEATURE_SIMD) && !defined(_TARGET_64BIT_)
3287 #else // LEGACY_BACKEND
3288 if (!varTypeIsGC(type))
3290 switch (genTypeStSz(type))
3293 type = TYP_INT; // Maps all 4-byte non-GC types to TYP_INT temps
3296 type = TYP_DOUBLE; // Maps all 8-byte types to TYP_DOUBLE temps
3299 assert(!"unexpected type");
3302 #endif // LEGACY_BACKEND
3307 /*****************************************************************************
3309 * Allocate a temp of the given size (and type, if tracking pointers for
3310 * the garbage collector).
3313 TempDsc* Compiler::tmpGetTemp(var_types type)
3315 type = tmpNormalizeType(type);
3316 unsigned size = genTypeSize(type);
3318 // If TYP_STRUCT ever gets in here we do bad things (tmpSlot returns -1)
3319 noway_assert(size >= sizeof(int));
3321 /* Find the slot to search for a free temp of the right size */
3323 unsigned slot = tmpSlot(size);
3325 /* Look for a temp with a matching type */
3327 TempDsc** last = &tmpFree[slot];
3330 for (temp = *last; temp; last = &temp->tdNext, temp = *last)
3332 /* Does the type match? */
3334 if (temp->tdTempType() == type)
3336 /* We have a match -- remove it from the free list */
3338 *last = temp->tdNext;
3344 /* Do we need to allocate a new temp */
3345 bool isNewTemp = false;
3348 #ifndef LEGACY_BACKEND
3350 noway_assert(temp != nullptr);
3352 #else // LEGACY_BACKEND
3354 if (temp == nullptr)
3360 tmpSize += (unsigned)size;
3363 if (type == TYP_DOUBLE)
3365 // Adjust tmpSize in case it needs alignment
3366 tmpSize += TARGET_POINTER_SIZE;
3368 #endif // _TARGET_ARM_
3370 genEmitter->emitTmpSizeChanged(tmpSize);
3372 temp = new (this, CMK_Unknown) TempDsc(-((int)tmpCount), size, type);
3375 #endif // LEGACY_BACKEND
3380 printf("%s temp #%u, slot %u, size = %u\n", isNewTemp ? "created" : "reused", -temp->tdTempNum(), slot,
3381 temp->tdTempSize());
3386 temp->tdNext = tmpUsed[slot];
3387 tmpUsed[slot] = temp;
3392 #ifndef LEGACY_BACKEND
3394 /*****************************************************************************
3395 * Preallocate 'count' temps of type 'type'. This type must be a normalized
3396 * type (by the definition of tmpNormalizeType()).
3398 * This is used at the end of LSRA, which knows precisely the maximum concurrent
3399 * number of each type of spill temp needed, before code generation. Code generation
3400 * then uses these preallocated temp. If code generation ever asks for more than
3401 * has been preallocated, it is a fatal error.
3404 void Compiler::tmpPreAllocateTemps(var_types type, unsigned count)
3406 assert(type == tmpNormalizeType(type));
3407 unsigned size = genTypeSize(type);
3409 // If TYP_STRUCT ever gets in here we do bad things (tmpSlot returns -1)
3410 noway_assert(size >= sizeof(int));
3412 // Find the slot to search for a free temp of the right size.
3413 // Note that slots are shared by types of the identical size (e.g., TYP_REF and TYP_LONG on AMD64),
3414 // so we can't assert that the slot is empty when we get here.
3416 unsigned slot = tmpSlot(size);
3418 for (unsigned i = 0; i < count; i++)
3424 if (type == TYP_DOUBLE)
3426 // Adjust tmpSize to accommodate possible alignment padding.
3427 // Note that at this point the offsets aren't yet finalized, so we don't yet know if it will be required.
3428 tmpSize += TARGET_POINTER_SIZE;
3430 #endif // _TARGET_ARM_
3432 TempDsc* temp = new (this, CMK_Unknown) TempDsc(-((int)tmpCount), size, type);
3437 printf("pre-allocated temp #%u, slot %u, size = %u\n", -temp->tdTempNum(), slot, temp->tdTempSize());
3441 // Add it to the front of the appropriate slot list.
3442 temp->tdNext = tmpFree[slot];
3443 tmpFree[slot] = temp;
3447 #endif // !LEGACY_BACKEND
3449 /*****************************************************************************
3451 * Release the given temp.
3454 void Compiler::tmpRlsTemp(TempDsc* temp)
3456 assert(temp != nullptr);
3460 /* Add the temp to the 'free' list */
3462 slot = tmpSlot(temp->tdTempSize());
3467 printf("release temp #%u, slot %u, size = %u\n", -temp->tdTempNum(), slot, temp->tdTempSize());
3469 assert(tmpGetCount);
3473 // Remove it from the 'used' list.
3475 TempDsc** last = &tmpUsed[slot];
3477 for (t = *last; t != nullptr; last = &t->tdNext, t = *last)
3481 /* Found it! -- remove it from the 'used' list */
3487 assert(t != nullptr); // We better have found it!
3489 // Add it to the free list.
3491 temp->tdNext = tmpFree[slot];
3492 tmpFree[slot] = temp;
3495 /*****************************************************************************
3496 * Given a temp number, find the corresponding temp.
3498 * When looking for temps on the "free" list, this can only be used after code generation. (This is
3499 * simply because we have an assert to that effect in tmpListBeg(); we could relax that, or hoist
3500 * the assert to the appropriate callers.)
3502 * When looking for temps on the "used" list, this can be used any time.
3504 TempDsc* Compiler::tmpFindNum(int tnum, TEMP_USAGE_TYPE usageType /* = TEMP_USAGE_FREE */) const
3506 assert(tnum < 0); // temp numbers are negative
3508 for (TempDsc* temp = tmpListBeg(usageType); temp != nullptr; temp = tmpListNxt(temp, usageType))
3510 if (temp->tdTempNum() == tnum)
3519 /*****************************************************************************
3521 * A helper function is used to iterate over all the temps.
3524 TempDsc* Compiler::tmpListBeg(TEMP_USAGE_TYPE usageType /* = TEMP_USAGE_FREE */) const
3526 TempDsc* const* tmpLists;
3527 if (usageType == TEMP_USAGE_FREE)
3536 // Return the first temp in the slot for the smallest size
3538 while (slot < (TEMP_SLOT_COUNT - 1) && tmpLists[slot] == nullptr)
3542 TempDsc* temp = tmpLists[slot];
3547 /*****************************************************************************
3548 * Used with tmpListBeg() to iterate over the list of temps.
3551 TempDsc* Compiler::tmpListNxt(TempDsc* curTemp, TEMP_USAGE_TYPE usageType /* = TEMP_USAGE_FREE */) const
3553 assert(curTemp != nullptr);
3555 TempDsc* temp = curTemp->tdNext;
3556 if (temp == nullptr)
3558 unsigned size = curTemp->tdTempSize();
3560 // If there are no more temps in the list, check if there are more
3561 // slots (for bigger sized temps) to walk.
3563 TempDsc* const* tmpLists;
3564 if (usageType == TEMP_USAGE_FREE)
3573 while (size < TEMP_MAX_SIZE && temp == nullptr)
3575 size += sizeof(int);
3576 unsigned slot = tmpSlot(size);
3577 temp = tmpLists[slot];
3580 assert((temp == nullptr) || (temp->tdTempSize() == size));
3587 /*****************************************************************************
3588 * Return 'true' if all allocated temps are free (not in use).
3590 bool Compiler::tmpAllFree() const
3592 // The 'tmpGetCount' should equal the number of things in the 'tmpUsed' lists. This is a convenient place
3594 unsigned usedCount = 0;
3595 for (TempDsc* temp = tmpListBeg(TEMP_USAGE_USED); temp != nullptr; temp = tmpListNxt(temp, TEMP_USAGE_USED))
3599 assert(usedCount == tmpGetCount);
3601 if (tmpGetCount != 0)
3606 for (unsigned i = 0; i < _countof(tmpUsed); i++)
3608 if (tmpUsed[i] != nullptr)
3620 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3621 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3623 XX Register-related utility functions XX
3625 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3626 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3629 /*****************************************************************************
3631 * Returns whether regPair is a combination of two x86 registers or
3632 * contains a pseudo register.
3633 * In debug it also asserts that reg1 and reg2 are not the same.
3636 bool genIsProperRegPair(regPairNo regPair)
3638 regNumber rlo = genRegPairLo(regPair);
3639 regNumber rhi = genRegPairHi(regPair);
3641 assert(regPair >= REG_PAIR_FIRST && regPair <= REG_PAIR_LAST);
3648 if (rlo == REG_L_STK || rhi == REG_L_STK)
3653 if (rlo >= REG_COUNT || rhi >= REG_COUNT)
3658 return (rlo != REG_STK && rhi != REG_STK);
3661 /*****************************************************************************
3663 * Given a register that is an argument register
3664 * returns the next argument register
3666 * Note: that this method will return a non arg register
3667 * when given REG_ARG_LAST
3671 regNumber genRegArgNext(regNumber argReg)
3673 assert(isValidIntArgReg(argReg) || isValidFloatArgReg(argReg));
3678 #ifdef _TARGET_AMD64_
3679 #ifdef UNIX_AMD64_ABI
3681 // Linux x64 ABI: REG_RDI, REG_RSI, REG_RDX, REG_RCX, REG_R8, REG_R9
3682 case REG_ARG_0: // REG_RDI
3683 return REG_ARG_1; // REG_RSI
3684 case REG_ARG_1: // REG_RSI
3685 return REG_ARG_2; // REG_RDX
3686 case REG_ARG_2: // REG_RDX
3687 return REG_ARG_3; // REG_RCX
3688 case REG_ARG_3: // REG_RCX
3689 return REG_ARG_4; // REG_R8
3691 #else // !UNIX_AMD64_ABI
3693 // Windows x64 ABI: REG_RCX, REG_RDX, REG_R8, REG_R9
3694 case REG_ARG_1: // REG_RDX
3695 return REG_ARG_2; // REG_R8
3697 #endif // !UNIX_AMD64_ABI
3698 #endif // _TARGET_AMD64_
3701 return REG_NEXT(argReg);
3705 /*****************************************************************************
3707 * The following table determines the order in which callee-saved registers
3708 * are encoded in GC information at call sites (perhaps among other things).
3709 * In any case, they establish a mapping from ordinal callee-save reg "indices" to
3710 * register numbers and corresponding bitmaps.
3713 const regNumber raRegCalleeSaveOrder[] = {REG_CALLEE_SAVED_ORDER};
3714 const regMaskTP raRbmCalleeSaveOrder[] = {RBM_CALLEE_SAVED_ORDER};
3716 regMaskSmall genRegMaskFromCalleeSavedMask(unsigned short calleeSaveMask)
3718 regMaskSmall res = 0;
3719 for (int i = 0; i < CNT_CALLEE_SAVED; i++)
3721 if ((calleeSaveMask & ((regMaskTP)1 << i)) != 0)
3723 res |= raRbmCalleeSaveOrder[i];
3729 /*****************************************************************************
3731 * Initializes the spill code. Should be called once per function compiled.
3735 void RegSet::rsSpillInit()
3737 /* Clear out the spill and multi-use tables */
3739 memset(rsSpillDesc, 0, sizeof(rsSpillDesc));
3741 #ifdef LEGACY_BACKEND
3742 memset(rsUsedTree, 0, sizeof(rsUsedTree));
3743 memset(rsUsedAddr, 0, sizeof(rsUsedAddr));
3744 memset(rsMultiDesc, 0, sizeof(rsMultiDesc));
3745 rsSpillFloat = nullptr;
3746 #endif // LEGACY_BACKEND
3748 rsNeededSpillReg = false;
3750 /* We don't have any descriptors allocated */
3752 rsSpillFree = nullptr;
3755 /*****************************************************************************
3757 * Shuts down the spill code. Should be called once per function compiled.
3761 void RegSet::rsSpillDone()
3766 /*****************************************************************************
3768 * Begin tracking spills - should be called each time before a pass is made
3769 * over a function body.
3773 void RegSet::rsSpillBeg()
3778 /*****************************************************************************
3780 * Finish tracking spills - should be called each time after a pass is made
3781 * over a function body.
3785 void RegSet::rsSpillEnd()
3790 //****************************************************************************
3791 // Create a new SpillDsc or get one off the free list
3795 RegSet::SpillDsc* RegSet::SpillDsc::alloc(Compiler* pComp, RegSet* regSet, var_types type)
3797 RegSet::SpillDsc* spill;
3798 RegSet::SpillDsc** pSpill;
3800 pSpill = &(regSet->rsSpillFree);
3802 // Allocate spill structure
3806 *pSpill = spill->spillNext;
3810 spill = (RegSet::SpillDsc*)pComp->compGetMem(sizeof(SpillDsc));
3815 //****************************************************************************
3816 // Free a SpillDsc and return it to the rsSpillFree list
3820 void RegSet::SpillDsc::freeDsc(RegSet* regSet, RegSet::SpillDsc* spillDsc)
3822 spillDsc->spillNext = regSet->rsSpillFree;
3823 regSet->rsSpillFree = spillDsc;
3826 /*****************************************************************************
3828 * Make sure no spills are currently active - used for debugging of the code
3835 void RegSet::rsSpillChk()
3837 // All grabbed temps should have been released
3838 assert(m_rsCompiler->tmpGetCount == 0);
3840 for (regNumber reg = REG_FIRST; reg < REG_COUNT; reg = REG_NEXT(reg))
3842 assert(rsSpillDesc[reg] == nullptr);
3844 #ifdef LEGACY_BACKEND
3845 assert(rsUsedTree[reg] == NULL);
3846 assert(rsMultiDesc[reg] == NULL);
3847 #endif // LEGACY_BACKEND
3854 void RegSet::rsSpillChk()
3860 /*****************************************************************************/
3861 #ifdef LEGACY_BACKEND
3864 bool RegTracker::rsIconIsInReg(ssize_t val, regNumber reg)
3866 if (compiler->opts.MinOpts() || compiler->opts.compDbgCode)
3871 if (rsRegValues[reg].rvdKind == RV_INT_CNS && rsRegValues[reg].rvdIntCnsVal == val)
3878 #endif // LEGACY_BACKEND
3879 /*****************************************************************************/