Skip to content
24 changes: 20 additions & 4 deletions src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1822,21 +1822,37 @@ void CodeGen::genEmitCallWithCurrentGC(EmitCallParams& params)
}

assert(numRegs == 2);
info.returnValueLoc.storeVariableInRegisters(retDesc->GetABIReturnReg(0, call->GetUnmanagedCallConv()),
retDesc->GetABIReturnReg(1, call->GetUnmanagedCallConv()));
regNumber reg1 = retDesc->GetABIReturnReg(0, call->GetUnmanagedCallConv());
regNumber reg2 = retDesc->GetABIReturnReg(1, call->GetUnmanagedCallConv());

// VLT_REG_REG can only encode integer registers. On platforms where structs
// can be returned in a mix of int and float registers (SysV x64, RISC-V),
// skip recording if any register is not an int register.
Comment thread
tommcdon marked this conversation as resolved.
// TODO: Supporting this case is tracked by https://github.com/dotnet/runtime/issues/129344
if (!genIsValidIntReg(reg1) || !genIsValidIntReg(reg2))
{
return;
}

info.returnValueLoc.storeVariableInRegisters(reg1, reg2);
}
else if (varTypeIsFloating(call))
{
#ifdef TARGET_X86
info.returnValueLoc.vlType = VLT_FPSTK;
info.returnValueLoc.vlFPstk.vlfReg = 0;
#else
info.returnValueLoc.storeVariableInRegisters(REG_FLOATRET, REG_NA);
// VLT_REG_FP uses a 0-based FP register index; the DBI adds the
// platform-specific XMM0/V0 base when converting to CorDebugRegister.
Comment thread
tommcdon marked this conversation as resolved.
info.returnValueLoc.vlType = VLT_REG_FP;
info.returnValueLoc.vlReg.vlrReg = (regNumber)(REG_FLOATRET - REG_FP_FIRST);
#endif
Comment thread
tommcdon marked this conversation as resolved.
}
else if (varTypeUsesFloatReg(call))
{
info.returnValueLoc.storeVariableInRegisters(REG_FLOATRET, REG_NA);
// VLT_REG_FP uses a 0-based FP register index.
info.returnValueLoc.vlType = VLT_REG_FP;
info.returnValueLoc.vlReg.vlrReg = (regNumber)(REG_FLOATRET - REG_FP_FIRST);
}
else
{
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/jit/ee_il_dll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -894,14 +894,17 @@ void Compiler::eeDispVar(ICorDebugInfo::NativeVarInfo* var)
{
case CodeGenInterface::VLT_REG:
case CodeGenInterface::VLT_REG_BYREF:
case CodeGenInterface::VLT_REG_FP:
printf("%s", getRegName(var->loc.vlReg.vlrReg));
if (var->loc.vlType == (ICorDebugInfo::VarLocType)CodeGenInterface::VLT_REG_BYREF)
{
printf(" byref");
}
break;

case CodeGenInterface::VLT_REG_FP:
printf("%s", getRegName((regNumber)(var->loc.vlReg.vlrReg + REG_FP_FIRST)));
break;

case CodeGenInterface::VLT_STK:
case CodeGenInterface::VLT_STK_BYREF:
if ((int)var->loc.vlStk.vlsBaseReg != (int)ICorDebugInfo::REGNUM_AMBIENT_SP)
Expand Down
38 changes: 28 additions & 10 deletions src/coreclr/jit/scopeinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ bool CodeGenInterface::siVarLoc::vlIsOnStack() const
//
void CodeGenInterface::siVarLoc::storeVariableInRegisters(regNumber reg, regNumber otherReg)
{
assert(genIsValidIntReg(reg));
assert(otherReg == REG_NA || genIsValidIntReg(otherReg));
Comment thread
tommcdon marked this conversation as resolved.

if (otherReg == REG_NA)
{
// Only one register is used
Expand Down Expand Up @@ -409,10 +412,10 @@ void CodeGenInterface::siVarLoc::siFillRegisterVarLoc(
#ifdef TARGET_64BIT
case TYP_FLOAT:
case TYP_DOUBLE:
// TODO-AMD64-Bug: ndp\clr\src\inc\corinfo.h has a definition of RegNum that only goes up to R15,
// so no XMM registers can get debug information.
// VLT_REG_FP uses a 0-based FP register index; the DBI adds the
// platform-specific XMM0/V0 base when converting to CorDebugRegister.
Comment thread
tommcdon marked this conversation as resolved.
this->vlType = VLT_REG_FP;
this->vlReg.vlrReg = varDsc->GetRegNum();
this->vlReg.vlrReg = (regNumber)(varDsc->GetRegNum() - REG_FP_FIRST);
Comment thread
tommcdon marked this conversation as resolved.
Comment thread
tommcdon marked this conversation as resolved.
Comment thread
tommcdon marked this conversation as resolved.
break;
Comment thread
tommcdon marked this conversation as resolved.

#else // !TARGET_64BIT
Expand Down Expand Up @@ -442,12 +445,9 @@ void CodeGenInterface::siVarLoc::siFillRegisterVarLoc(
{
this->vlType = VLT_REG_FP;

// TODO-AMD64-Bug: ndp\clr\src\inc\corinfo.h has a definition of RegNum that only goes up to R15,
// so no XMM registers can get debug information.
//
// Note: Need to initialize vlrReg field, otherwise during jit dump hitting an assert
// in eeDispVar() --> getRegName() that regNumber is valid.
this->vlReg.vlrReg = varDsc->GetRegNum();
// VLT_REG_FP uses a 0-based FP register index; the DBI adds the
// platform-specific XMM0/V0 base when converting to CorDebugRegister.
Comment thread
tommcdon marked this conversation as resolved.
this->vlReg.vlrReg = (regNumber)(varDsc->GetRegNum() - REG_FP_FIRST);
Comment thread
tommcdon marked this conversation as resolved.
break;
}
#endif // FEATURE_SIMD
Expand Down Expand Up @@ -1736,7 +1736,25 @@ void CodeGen::psiBegProlog()

if (reg1 != REG_NA)
{
varLocation.storeVariableInRegisters(reg1, reg2);
if (genIsValidFloatReg(reg1))
{
// FP parameter in XMM/V register — encode as VLT_REG_FP with
// 0-based FP register index.
varLocation.vlType = VLT_REG_FP;
varLocation.vlReg.vlrReg = (regNumber)(reg1 - REG_FP_FIRST);
}
else
{
// Integer register parameter. On SysV x64, the second segment
// may be in an XMM register for mixed struct passing — drop it
// since VLT_REG_REG cannot encode FP registers.
Comment thread
tommcdon marked this conversation as resolved.
// TODO: Supporting this case is tracked by https://github.com/dotnet/runtime/issues/129344
if (reg2 != REG_NA && !genIsValidIntReg(reg2))
{
reg2 = REG_NA;
}
varLocation.storeVariableInRegisters(reg1, reg2);
}
}
else
{
Expand Down
Loading