//------------------------------------------------------------------------ // Compiler::unwindSaveReg: Record a register save. // // Arguments: // reg - The register being saved. // offset - The offset from the current stack pointer where the register is being saved. // void Compiler::unwindSaveReg(regNumber reg, unsigned offset) { assert(compGeneratingProlog); FuncInfoDsc* func = funCurrentFunc(); assert(func->unwindHeader.Version == 1); // Can't call this before unwindBegProlog assert(func->unwindHeader.CountOfUnwindCodes == 0); // Can't call this after unwindReserve if (RBM_CALLEE_SAVED & genRegMask(reg)) { UNWIND_CODE * code; if (offset < 0x80000) { assert(func->unwindCodeSlot > (sizeof(UNWIND_CODE) + sizeof(USHORT))); USHORT * codedSize = (USHORT*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(USHORT)]; code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)]; // As per AMD64 ABI, if saving entire xmm reg, then offset need to be scaled by 16. if (genIsValidFloatReg(reg)) { *codedSize = (USHORT) (offset/16); code->UnwindOp = UWOP_SAVE_XMM128; } else { *codedSize = (USHORT) (offset/8); code->UnwindOp = UWOP_SAVE_NONVOL; } } else { assert(func->unwindCodeSlot > (sizeof(UNWIND_CODE) + sizeof(ULONG))); ULONG * codedSize = (ULONG*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(ULONG)]; *codedSize = offset; code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)]; code->UnwindOp = (genIsValidFloatReg(reg)) ? UWOP_SAVE_XMM128_FAR : UWOP_SAVE_NONVOL_FAR; } code->OpInfo = (BYTE)reg; unsigned int cbProlog = unwindGetCurrentOffset(func); noway_assert((BYTE)cbProlog == cbProlog); code->CodeOffset = (BYTE)cbProlog; } }
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 }