@@ -35,36 +35,6 @@ class RISCVABIInfo : public DefaultABIInfo {
3535 llvm::Type *&Field2Ty,
3636 CharUnits &Field2Off) const ;
3737
38- // / CHERI(oT)-specific: Figure out how many registers are needed to pass a
39- // / value of the given type and size directly in register(s). The value of
40- // / `-1` means that the value should be passed indirectly.
41- // /
42- // / Note: `Size` is in bits.
43- int8_t getCapRegsForStruct (uint64_t Size, QualType Ty) const {
44- auto &T = getTarget ();
45- auto CapWidth = T.getCHERICapabilityWidth ();
46-
47- if (Size % CapWidth)
48- return -1 ;
49-
50- auto *RT = Ty->getAs <RecordType>();
51-
52- StringRef TargetABI = T.getABI ();
53- bool IsCheriot = TargetABI == " cheriot" || TargetABI == " cheriot-baremetal" ;
54-
55- auto Q = Size / CapWidth;
56-
57- if (RT && getContext ().containsCapabilities (RT->getDecl ())) {
58- if (Q == 1 )
59- return 1 ;
60-
61- if (IsCheriot && Q == 2 )
62- return 2 ;
63- }
64-
65- return -1 ;
66- }
67-
6838public:
6939 RISCVABIInfo (CodeGen::CodeGenTypes &CGT, unsigned XLen, unsigned FLen,
7040 bool EABI)
@@ -458,16 +428,19 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
458428 if (isEmptyRecord (getContext (), Ty, true ) && Size == 0 )
459429 return ABIArgInfo::getIgnore ();
460430
461- auto CapRegsForStruct = getCapRegsForStruct (Size, Ty);
462- bool ForcePassInCapRegs = CapRegsForStruct > 0 ;
463- bool IsSingleCapability =
464- Ty->isCHERICapabilityType (getContext ()) || CapRegsForStruct == 1 ;
431+ bool IsSingleCapRecord = false ;
432+ if (auto *RT = Ty->getAs <RecordType>())
433+ IsSingleCapRecord = Size == getTarget ().getCHERICapabilityWidth () &&
434+ getContext ().containsCapabilities (RT->getDecl ());
435+
436+ bool IsCapability = Ty->isCHERICapabilityType (getContext ()) ||
437+ IsSingleCapRecord;
465438
466439 // Capabilities (including single-capability records, which are treated the
467440 // same as a single capability) are passed indirectly for hybrid varargs.
468441 // Anything larger is bigger than 2*XLEN and thus automatically passed
469442 // indirectly anyway.
470- if (!IsFixed && IsSingleCapability &&
443+ if (!IsFixed && IsCapability &&
471444 !getContext ().getTargetInfo ().areAllPointersCapabilities ()) {
472445 if (ArgGPRsLeft)
473446 ArgGPRsLeft -= 1 ;
@@ -522,9 +495,9 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
522495 // TODO: Pairs involving capabilities should be passed in registers too like
523496 // int/fp pairs (requires thought for fp+cap when out of FPRs).
524497 int NeededArgGPRs = 1 ;
525- if (!IsSingleCapability && !IsFixed && NeededAlign == 2 * XLen)
498+ if (!IsCapability && !IsFixed && NeededAlign == 2 * XLen)
526499 NeededArgGPRs = 2 + (EABI && XLen == 32 ? 0 : (ArgGPRsLeft % 2 ));
527- else if (!IsSingleCapability && Size > XLen && Size <= 2 * XLen)
500+ else if (!IsCapability && Size > XLen && Size <= 2 * XLen)
528501 NeededArgGPRs = 2 ;
529502
530503 if (NeededArgGPRs > ArgGPRsLeft) {
@@ -555,7 +528,7 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
555528 return ABIArgInfo::getDirect ();
556529 }
557530
558- if (ForcePassInCapRegs )
531+ if (IsSingleCapRecord )
559532 return ABIArgInfo::getDirect ();
560533
561534 if (const VectorType *VT = Ty->getAs <VectorType>())
@@ -620,18 +593,21 @@ RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
620593 if (EABI && XLen == 32 && !IsCheriot)
621594 TInfo.Align = std::min (TInfo.Align , CharUnits::fromQuantity (4 ));
622595
623- uint64_t Size = TInfo.Width .getQuantity () * 8 ;
596+ bool IsSingleCapRecord = false ;
597+ CharUnits CapabilityWidth =
598+ CharUnits::fromQuantity (getTarget ().getCHERICapabilityWidth () / 8 );
599+ if (const auto *RT = Ty->getAs <RecordType>())
600+ IsSingleCapRecord = TInfo.Width == CapabilityWidth &&
601+ getContext ().containsCapabilities (RT->getDecl ());
624602
625- auto CapRegsForStruct = getCapRegsForStruct (Size, Ty);
626- bool IsSingleCapability =
627- Ty->isCHERICapabilityType (getContext ()) || CapRegsForStruct == 1 ;
603+ bool IsCapability = Ty->isCHERICapabilityType (getContext ()) ||
604+ IsSingleCapRecord;
628605
629606 // Arguments bigger than 2*Xlen bytes are passed indirectly, as are
630607 // capabilities for the hybrid ABI.
631- bool IsIndirect =
632- TInfo.Width > 2 * SlotSize ||
633- (!getContext ().getTargetInfo ().areAllPointersCapabilities () &&
634- IsSingleCapability);
608+ bool IsIndirect = TInfo.Width > 2 * SlotSize ||
609+ (!getContext ().getTargetInfo ().areAllPointersCapabilities () &&
610+ IsCapability);
635611
636612 return emitVoidPtrVAArg (CGF, VAListAddr, Ty, IsIndirect, TInfo, SlotSize,
637613 /* AllowHigherAlign=*/ true , Slot);
0 commit comments