// get the next argument register which is aligned to 'alignment' # of bytes regNumber alignFloatArgReg(regNumber argReg, int alignment) { assert(isValidFloatArgReg(argReg)); int regsize_alignment = alignment /= REGSIZE_BYTES; if (genMapFloatRegNumToRegArgNum(argReg) % regsize_alignment) argReg = genRegArgNextFloat(argReg); // technically the above should be a 'while' so make sure // we never should have incremented more than once assert(!(genMapFloatRegNumToRegArgNum(argReg) % regsize_alignment)); return argReg; }
unsigned InitVarDscInfo::allocRegArg(var_types type, unsigned numRegs /* = 1 */) { assert(numRegs > 0); unsigned resultArgNum = regArgNum(type); bool isBackFilled = false; #ifdef _TARGET_ARM_ // Check for back-filling if (varTypeIsFloating(type) && // We only back-fill the float registers !anyFloatStackArgs && // Is it legal to back-fill? (We haven't put any FP args on the stack yet) (numRegs == 1) && // Is there a possibility we could back-fill? (fltArgSkippedRegMask != RBM_NONE)) // Is there an available back-fill slot? { // We will never back-fill something greater than a single register // (TYP_FLOAT, or TYP_STRUCT HFA with a single float). This is because // we don't have any types that require > 2 register alignment, so we // can't create a > 1 register alignment hole to back-fill. // Back-fill the register regMaskTP backFillBitMask = genFindLowestBit(fltArgSkippedRegMask); fltArgSkippedRegMask &= ~backFillBitMask; // Remove the back-filled register(s) from the skipped mask resultArgNum = genMapFloatRegNumToRegArgNum(genRegNumFromMask(backFillBitMask)); assert(resultArgNum < MAX_FLOAT_REG_ARG); isBackFilled = true; } #endif // _TARGET_ARM_ if (!isBackFilled) { // We didn't back-fill a register (on ARM), so skip the number of registers that we allocated. #if defined(_TARGET_AMD64_) && !defined(UNIX_AMD64_ABI) // For System V the reg type counters should be independent. nextReg(TYP_INT, numRegs); nextReg(TYP_FLOAT, numRegs); #else nextReg(type, numRegs); #endif } return resultArgNum; }