Skip to content

Commit

Permalink
RISC-V: fix passing FP arguments when using system linkage
Browse files Browse the repository at this point in the history
As specified in RISC-V PSABI spec [1], if there's more than 8 FP arguments,
they're passed the same way as integer arguments, that is, in a0 a7 GPRs
if available.

This commit fixes RVSystemLinkage to comply with the RISC-V PSABI
regarding FP arguments.

[1]: https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#hardware-floating-point-calling-convention
  • Loading branch information
janvrany committed Jun 12, 2021
1 parent 86b4a2b commit 38d6646
Showing 1 changed file with 38 additions and 6 deletions.
44 changes: 38 additions & 6 deletions compiler/riscv/codegen/RVSystemLinkage.cpp
Expand Up @@ -294,13 +294,18 @@ TR::RVSystemLinkage::mapStack(TR::ResolvedMethodSymbol *method)
nextFltArgReg++;
mapSingleParameter(parameter, stackIndex, true);
}
else if (nextIntArgReg < getProperties().getNumIntArgRegs())
{
nextIntArgReg++;
mapSingleParameter(parameter, stackIndex, true);
}
else
{
nextFltArgReg = getProperties().getNumFloatArgRegs() + 1;
}
break;
case TR::Aggregate:
TR_ASSERT(false, "Function parameters of aggregate types are not currently supported on AArch64.");
TR_ASSERT(false, "Function parameters of aggregate types are not currently supported on RISC-V.");
break;
default:
TR_ASSERT(false, "Unknown parameter type.");
Expand Down Expand Up @@ -340,13 +345,17 @@ TR::RVSystemLinkage::mapStack(TR::ResolvedMethodSymbol *method)
{
nextFltArgReg++;
}
else if (nextIntArgReg < getProperties().getNumIntArgRegs())
{
nextIntArgReg++;
}
else
{
mapSingleParameter(parameter, stackIndex, false);
}
break;
case TR::Aggregate:
TR_ASSERT(false, "Function parameters of aggregate types are not currently supported on AArch64.");
TR_ASSERT(false, "Function parameters of aggregate types are not currently supported on RISC-V.");
break;
default:
TR_ASSERT(false, "Unknown parameter type.");
Expand Down Expand Up @@ -439,6 +448,12 @@ TR::RVSystemLinkage::createPrologue(TR::Instruction *cursor, List<TR::ParameterS
cursor = generateSTORE(op, firstNode, stackSlot, machine->getRealRegister((TR::RealRegister::RegNum)(TR::RealRegister::fa0 + nextFltArgReg)), codeGen, cursor);
nextFltArgReg++;
}
else if (nextIntArgReg < getProperties().getNumIntArgRegs())
{
op = (parameter->getSize() == 8) ? TR::InstOpCode::_sd : TR::InstOpCode::_sw;
cursor = generateSTORE(op, firstNode, stackSlot, machine->getRealRegister((TR::RealRegister::RegNum)(TR::RealRegister::a0 + nextIntArgReg)), codeGen, cursor);
nextIntArgReg++;
}
else
{
nextFltArgReg = getProperties().getNumFloatArgRegs() + 1;
Expand Down Expand Up @@ -516,6 +531,7 @@ int32_t TR::RVSystemLinkage::buildArgs(TR::Node *callNode,
int32_t argSize = 0;
int32_t numIntegerArgs = 0;
int32_t numFloatArgs = 0;
int32_t numFloatArgsPassedInGPRs = 0;
int32_t totalSize;
int32_t i;

Expand All @@ -538,15 +554,20 @@ int32_t TR::RVSystemLinkage::buildArgs(TR::Node *callNode,
case TR::Int32:
case TR::Int64:
case TR::Address:
if (numIntegerArgs >= properties.getNumIntArgRegs())
if ((numIntegerArgs + numFloatArgsPassedInGPRs) >= properties.getNumIntArgRegs())
numMemArgs++;
numIntegerArgs++;
break;

case TR::Float:
case TR::Double:
if (numFloatArgs >= properties.getNumFloatArgRegs())
{
if ((numIntegerArgs + numFloatArgsPassedInGPRs) < properties.getNumIntArgRegs())
numFloatArgsPassedInGPRs++;
else
numMemArgs++;
}
numFloatArgs++;
break;

Expand All @@ -571,6 +592,7 @@ int32_t TR::RVSystemLinkage::buildArgs(TR::Node *callNode,

numIntegerArgs = 0;
numFloatArgs = 0;
numFloatArgsPassedInGPRs = 0;

for (i = firstArgumentChild; i < callNode->getNumChildren(); i++)
{
Expand All @@ -595,7 +617,7 @@ int32_t TR::RVSystemLinkage::buildArgs(TR::Node *callNode,
else
argRegister = pushIntegerWordArg(child);

if (numIntegerArgs < properties.getNumIntArgRegs())
if ((numIntegerArgs + numFloatArgsPassedInGPRs) < properties.getNumIntArgRegs())
{
if (!cg()->canClobberNodesRegister(child, 0))
{
Expand All @@ -620,7 +642,7 @@ int32_t TR::RVSystemLinkage::buildArgs(TR::Node *callNode,
}
else
{
TR::addDependency(dependencies, argRegister, properties.getIntegerArgumentRegister(numIntegerArgs), TR_GPR, cg());
TR::addDependency(dependencies, argRegister, properties.getIntegerArgumentRegister(numIntegerArgs + numFloatArgsPassedInGPRs), TR_GPR, cg());
}
}
else
Expand Down Expand Up @@ -674,6 +696,16 @@ int32_t TR::RVSystemLinkage::buildArgs(TR::Node *callNode,
TR::addDependency(dependencies, argRegister, properties.getFloatArgumentRegister(numFloatArgs), TR_FPR, cg());
}
}
else if ((numIntegerArgs + numFloatArgsPassedInGPRs) < properties.getNumIntArgRegs())
{
TR::Register *gprRegister = cg()->allocateRegister(TR_GPR);
TR::Register *zero = cg()->machine()->getRealRegister(TR::RealRegister::zero);
op = (childType == TR::Float) ? TR::InstOpCode::_fmv_x_s : TR::InstOpCode::_fmv_x_d;
generateRTYPE(op, callNode, gprRegister, argRegister, zero, cg());

TR::addDependency(dependencies, gprRegister, properties.getIntegerArgumentRegister(numIntegerArgs + numFloatArgsPassedInGPRs), TR_GPR, cg());
numFloatArgsPassedInGPRs++;
}
else
{
// numFloatArgs >= properties.getNumFloatArgRegs()
Expand All @@ -694,7 +726,7 @@ int32_t TR::RVSystemLinkage::buildArgs(TR::Node *callNode,
} // end of for

// NULL deps for unused integer argument registers
for (int i = numIntegerArgs; i < properties.getNumIntArgRegs(); i++)
for (int i = numIntegerArgs + numFloatArgsPassedInGPRs; i < properties.getNumIntArgRegs(); i++)
{
if (i == 0 && resType.isAddress())
{
Expand Down

0 comments on commit 38d6646

Please sign in to comment.