Skip to content

Commit 1f32383

Browse files
committed
[CHERIoT] Pass two-cap-sized return values and arguments in registers
1 parent d2286ce commit 1f32383

File tree

3 files changed

+691
-3
lines changed

3 files changed

+691
-3
lines changed

clang/lib/CodeGen/Targets/RISCV.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,35 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
429429
return ABIArgInfo::getIgnore();
430430

431431
bool IsSingleCapRecord = false;
432-
if (auto *RT = Ty->getAs<RecordType>())
432+
bool FitsInTwoRegs = false;
433+
if (auto *RT = dyn_cast<RecordDecl>(Ty->getAsTagDecl())) {
433434
IsSingleCapRecord = Size == getTarget().getCHERICapabilityWidth() &&
434-
getContext().containsCapabilities(RT->getDecl());
435+
getContext().containsCapabilities(RT);
436+
FitsInTwoRegs = IsSingleCapRecord;
437+
438+
// Check if the record fits in two registers, that is:
439+
// 1. it has two fields
440+
// 2. any of the two fields is either a capability or a type whose size can
441+
// fit in the data part of a register
442+
if (!IsSingleCapRecord) {
443+
FitsInTwoRegs = true;
444+
int SeenFields = 0;
445+
for (const FieldDecl *Field : RT->fields()) {
446+
if (++SeenFields > 2) {
447+
FitsInTwoRegs = false;
448+
break;
449+
}
450+
451+
auto FieldTy = Field->getType();
452+
auto FieldInfo = Field->getASTContext().getTypeInfo(FieldTy);
453+
if (!FieldTy->isAnyPointerType() &&
454+
FieldInfo.Width > getTarget().getRegisterWidth()) {
455+
FitsInTwoRegs = false;
456+
break;
457+
}
458+
}
459+
}
460+
}
435461

436462
bool IsCapability = Ty->isCHERICapabilityType(getContext()) ||
437463
IsSingleCapRecord;
@@ -528,7 +554,7 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
528554
return ABIArgInfo::getDirect();
529555
}
530556

531-
if (IsSingleCapRecord)
557+
if (FitsInTwoRegs)
532558
return ABIArgInfo::getDirect();
533559

534560
if (const VectorType *VT = Ty->getAs<VectorType>())

0 commit comments

Comments
 (0)