Skip to content

Commit 9e0b1cf

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

File tree

3 files changed

+696
-3
lines changed

3 files changed

+696
-3
lines changed

clang/lib/CodeGen/Targets/RISCV.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,40 @@ 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+
auto *TD = Ty->getAsTagDecl();
434+
if (TD && dyn_cast<RecordDecl>(TD)) {
435+
auto *RD = dyn_cast<RecordDecl>(TD);
433436
IsSingleCapRecord = Size == getTarget().getCHERICapabilityWidth() &&
434-
getContext().containsCapabilities(RT->getDecl());
437+
getContext().containsCapabilities(RD);
438+
FitsInTwoRegs = IsSingleCapRecord;
439+
440+
// Check if the record fits in two registers, that is:
441+
// 1. it has two fields
442+
// 2. any of the two fields is either a capability or a type whose size can
443+
// fit in the data part of a register
444+
if (!IsSingleCapRecord) {
445+
int SeenFields = 0;
446+
for (const FieldDecl *Field : RD->fields()) {
447+
if (++SeenFields > 2) {
448+
FitsInTwoRegs = false;
449+
break;
450+
}
451+
452+
auto FieldTy = Field->getType();
453+
auto FieldInfo = Field->getASTContext().getTypeInfo(FieldTy);
454+
if (!FieldTy->isAnyPointerType() &&
455+
FieldInfo.Width > getTarget().getRegisterWidth()) {
456+
FitsInTwoRegs = false;
457+
break;
458+
}
459+
460+
if (SeenFields == 2) {
461+
FitsInTwoRegs = true;
462+
}
463+
}
464+
}
465+
}
435466

436467
bool IsCapability = Ty->isCHERICapabilityType(getContext()) ||
437468
IsSingleCapRecord;
@@ -528,7 +559,7 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
528559
return ABIArgInfo::getDirect();
529560
}
530561

531-
if (IsSingleCapRecord)
562+
if (FitsInTwoRegs)
532563
return ABIArgInfo::getDirect();
533564

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

0 commit comments

Comments
 (0)