const char * getRegName(regNumber reg, bool isFloat) { // Special-case REG_NA; it's not in the regNames array, but we might want to print it. if (reg == REG_NA) { return "NA"; } #if defined(_TARGET_X86_) && defined(LEGACY_BACKEND) static const char * const regNames[] = { #define REGDEF(name, rnum, mask, sname) sname, #include "register.h" }; static const char * const floatRegNames[] = { #define REGDEF(name, rnum, mask, sname) sname, #include "registerxmm.h" }; if (isFloat) { assert(reg < ArrLen(floatRegNames)); return floatRegNames[reg]; } else { assert(reg < ArrLen(regNames)); return regNames[reg]; } #elif defined(_TARGET_ARM64_) static const char * const regNames[] = { #define REGDEF(name, rnum, mask, xname, wname) xname, #include "register.h" }; assert(reg < ArrLen(regNames)); return regNames[reg]; #else static const char * const regNames[] = { #define REGDEF(name, rnum, mask, sname) sname, #include "register.h" }; assert(reg < ArrLen(regNames)); return regNames[reg]; #endif }
regNumber RegSet::PickRegFloat(var_types type, RegisterPreference *pref, bool bUsed) { regMaskTP wantedMask; bool tryBest = true; bool tryOk = true; bool bSpill = false; regNumber reg = REG_NA; while (tryOk) { if (pref) { if (tryBest) { wantedMask = pref->best; tryBest = false; } else { assert(tryOk); wantedMask = pref->ok; tryOk = false; } } else// pref is NULL { wantedMask = RBM_ALLFLOAT; tryBest = false; tryOk = false; } // better not have asked for a non-fp register assert((wantedMask & ~RBM_ALLFLOAT) == 0); regMaskTP availMask = RegFreeFloat(); regMaskTP OKmask = availMask & wantedMask; if (OKmask == 0) { if (tryOk) { // the pref->best mask doesn't work so try the pref->ok mask next continue; } if (bUsed) { // Allow used registers to be picked OKmask |= rsGetMaskUsed() & ~rsGetMaskLock(); bSpill = true; } } #if FEATURE_FP_REGALLOC regMaskTP restrictMask = (m_rsCompiler->raConfigRestrictMaskFP() | RBM_FLT_CALLEE_TRASH); #endif for (unsigned i=0; i<ArrLen(pickOrder); i++) { regNumber r = pickOrder[i]; if (!floatRegCanHoldType(r, type)) continue; regMaskTP mask = genRegMaskFloat(r, type); #if FEATURE_FP_REGALLOC if ((mask & restrictMask) != mask) continue; #endif if ((OKmask & mask) == mask) { reg = r; goto RET; } } if (tryOk) { // We couldn't find a register using tryBest continue; } assert(!"Unable to find a free FP virtual register"); NO_WAY("FP register allocator was too optimistic!"); } RET: if (bSpill) { m_rsCompiler->codeGen->SpillFloat(reg); } #if FEATURE_FP_REGALLOC rsSetRegsModified(genRegMaskFloat(reg, type)); #endif return reg; }
const char* getRegNameFloat(regNumber reg, var_types type) { #ifdef _TARGET_ARM_ assert(genIsValidFloatReg(reg)); if (type == TYP_FLOAT) return getRegName(reg); else { const char* regName; switch (reg) { default: assert(!"Bad double register"); regName="d??"; break; case REG_F0: regName = "d0"; break; case REG_F2: regName = "d2"; break; case REG_F4: regName = "d4"; break; case REG_F6: regName = "d6"; break; case REG_F8: regName = "d8"; break; case REG_F10: regName = "d10"; break; case REG_F12: regName = "d12"; break; case REG_F14: regName = "d14"; break; case REG_F16: regName = "d16"; break; case REG_F18: regName = "d18"; break; case REG_F20: regName = "d20"; break; case REG_F22: regName = "d22"; break; case REG_F24: regName = "d24"; break; case REG_F26: regName = "d26"; break; case REG_F28: regName = "d28"; break; case REG_F30: regName = "d30"; break; } return regName; } #elif defined(_TARGET_X86_) && defined(LEGACY_BACKEND) static const char* regNamesFloat[] = { #define REGDEF(name, rnum, mask, sname) sname, #include "registerxmm.h" }; assert((unsigned)reg < ArrLen(regNamesFloat)); return regNamesFloat[reg]; #elif defined(_TARGET_ARM64_) static const char* regNamesFloat[] = { #define REGDEF(name, rnum, mask, xname, wname) xname, #include "register.h" }; assert((unsigned)reg < ArrLen(regNamesFloat)); return regNamesFloat[reg]; #else static const char* regNamesFloat[] = { #define REGDEF(name, rnum, mask, sname) "x" sname, #include "register.h" }; #ifdef FEATURE_AVX_SUPPORT static const char* regNamesYMM[] = { #define REGDEF(name, rnum, mask, sname) "y" sname, #include "register.h" }; #endif // FEATURE_AVX_SUPPORT assert((unsigned)reg < ArrLen(regNamesFloat)); #ifdef FEATURE_AVX_SUPPORT if (type == TYP_SIMD32) { return regNamesYMM[reg]; } #endif // FEATURE_AVX_SUPPORT return regNamesFloat[reg]; #endif }