unsigned FreeSSERegs = 0;
};
-enum {
- // Vectorcall only allows the first 6 parameters to be passed in registers.
- VectorcallMaxParamNumAsReg = 6
-};
-
/// X86_32ABIInfo - The X86-32 ABI information.
class X86_32ABIInfo : public SwiftABIInfo {
enum Class {
private:
ABIArgInfo classify(QualType Ty, unsigned &FreeSSERegs, bool IsReturnType,
bool IsVectorCall, bool IsRegCall) const;
- ABIArgInfo reclassifyHvaArgType(QualType Ty, unsigned &FreeSSERegs,
- const ABIArgInfo ¤t) const;
- void computeVectorCallArgs(CGFunctionInfo &FI, unsigned FreeSSERegs,
- bool IsVectorCall, bool IsRegCall) const;
+ ABIArgInfo reclassifyHvaArgForVectorCall(QualType Ty, unsigned &FreeSSERegs,
+ const ABIArgInfo ¤t) const;
X86AVXABILevel AVXLevel;
/*allowHigherAlign*/ false);
}
-ABIArgInfo
-WinX86_64ABIInfo::reclassifyHvaArgType(QualType Ty, unsigned &FreeSSERegs,
- const ABIArgInfo ¤t) const {
- // Assumes vectorCall calling convention.
+ABIArgInfo WinX86_64ABIInfo::reclassifyHvaArgForVectorCall(
+ QualType Ty, unsigned &FreeSSERegs, const ABIArgInfo ¤t) const {
const Type *Base = nullptr;
uint64_t NumElts = 0;
return ABIArgInfo::getDirect();
}
-void WinX86_64ABIInfo::computeVectorCallArgs(CGFunctionInfo &FI,
- unsigned FreeSSERegs,
- bool IsVectorCall,
- bool IsRegCall) const {
- unsigned Count = 0;
- for (auto &I : FI.arguments()) {
- // Vectorcall in x64 only permits the first 6 arguments to be passed
- // as XMM/YMM registers.
- if (Count < VectorcallMaxParamNumAsReg)
- I.info = classify(I.type, FreeSSERegs, false, IsVectorCall, IsRegCall);
- else {
- // Since these cannot be passed in registers, pretend no registers
- // are left.
- unsigned ZeroSSERegsAvail = 0;
- I.info = classify(I.type, /*FreeSSERegs=*/ZeroSSERegsAvail, false,
- IsVectorCall, IsRegCall);
- }
- ++Count;
- }
-
- for (auto &I : FI.arguments()) {
- I.info = reclassifyHvaArgType(I.type, FreeSSERegs, I.info);
- }
-}
-
void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
const unsigned CC = FI.getCallingConvention();
bool IsVectorCall = CC == llvm::CallingConv::X86_VectorCall;
FreeSSERegs = 16;
}
+ unsigned ArgNum = 0;
+ unsigned ZeroSSERegs = 0;
+ for (auto &I : FI.arguments()) {
+ // Vectorcall in x64 only permits the first 6 arguments to be passed as
+ // XMM/YMM registers. After the sixth argument, pretend no vector
+ // registers are left.
+ unsigned *MaybeFreeSSERegs =
+ (IsVectorCall && ArgNum >= 6) ? &ZeroSSERegs : &FreeSSERegs;
+ I.info =
+ classify(I.type, *MaybeFreeSSERegs, false, IsVectorCall, IsRegCall);
+ ++ArgNum;
+ }
+
if (IsVectorCall) {
- computeVectorCallArgs(FI, FreeSSERegs, IsVectorCall, IsRegCall);
- } else {
+ // For vectorcall, assign aggregate HVAs to any free vector registers in a
+ // second pass.
for (auto &I : FI.arguments())
- I.info = classify(I.type, FreeSSERegs, false, IsVectorCall, IsRegCall);
+ I.info = reclassifyHvaArgForVectorCall(I.type, FreeSSERegs, I.info);
}
-
}
Address WinX86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,