Skip to content

Commit a5690a5

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

File tree

3 files changed

+694
-3
lines changed

3 files changed

+694
-3
lines changed

clang/lib/CodeGen/Targets/RISCV.cpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,38 @@ 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+
int SeenFields = 0;
444+
for (const FieldDecl *Field : RT->fields()) {
445+
if (++SeenFields > 2) {
446+
FitsInTwoRegs = false;
447+
break;
448+
}
449+
450+
auto FieldTy = Field->getType();
451+
auto FieldInfo = Field->getASTContext().getTypeInfo(FieldTy);
452+
if (!FieldTy->isAnyPointerType() &&
453+
FieldInfo.Width > getTarget().getRegisterWidth()) {
454+
FitsInTwoRegs = false;
455+
break;
456+
}
457+
458+
if (SeenFields == 2) {
459+
FitsInTwoRegs = true;
460+
}
461+
}
462+
}
463+
}
435464

436465
bool IsCapability = Ty->isCHERICapabilityType(getContext()) ||
437466
IsSingleCapRecord;
@@ -528,7 +557,7 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
528557
return ABIArgInfo::getDirect();
529558
}
530559

531-
if (IsSingleCapRecord)
560+
if (FitsInTwoRegs)
532561
return ABIArgInfo::getDirect();
533562

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

0 commit comments

Comments
 (0)