Skip to content

Commit c297697

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

File tree

3 files changed

+699
-3
lines changed

3 files changed

+699
-3
lines changed

clang/lib/CodeGen/Targets/RISCV.cpp

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

436470
bool IsCapability = Ty->isCHERICapabilityType(getContext()) ||
437471
IsSingleCapRecord;
@@ -528,7 +562,7 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
528562
return ABIArgInfo::getDirect();
529563
}
530564

531-
if (IsSingleCapRecord)
565+
if (FitsInTwoRegs)
532566
return ABIArgInfo::getDirect();
533567

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

0 commit comments

Comments
 (0)